diff --git a/_locales/en/messages.json b/_locales/en/messages.json index f408cf856..1df506564 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -2424,5 +2424,8 @@ }, "createGroup": { "message": "Create Group" + }, + "yourPublicKey": { + "message": "Your Public Key" } } diff --git a/stylesheets/_session.scss b/stylesheets/_session.scss index 0714a286b..f77bda385 100644 --- a/stylesheets/_session.scss +++ b/stylesheets/_session.scss @@ -139,6 +139,10 @@ div, span, label { user-select: none; + + &::selection { + background: $session-shade-17; + } } $session-gradient-green: linear-gradient( diff --git a/stylesheets/_session_signin.scss b/stylesheets/_session_signin.scss index ff857939f..d278151c2 100644 --- a/stylesheets/_session_signin.scss +++ b/stylesheets/_session_signin.scss @@ -114,11 +114,6 @@ padding-top: 2em; } - &__unique-session-id { - @include registration-label-mixin; - padding-top: 3em; - } - &__entry-fields { margin: 0px; padding-bottom: 30px; @@ -229,6 +224,7 @@ padding: 20px 5px 20px 5px; display: inline-block; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + user-select: all; } } diff --git a/stylesheets/_session_theme_dark_left_pane.scss b/stylesheets/_session_theme_dark_left_pane.scss index 0a4115089..b51188e49 100644 --- a/stylesheets/_session_theme_dark_left_pane.scss +++ b/stylesheets/_session_theme_dark_left_pane.scss @@ -190,6 +190,7 @@ $session-compose-margin: 20px; margin: 0px 20px; width: -webkit-fill-available; flex-shrink: 0; + user-select: all; } .session-button { @@ -278,7 +279,6 @@ $session-compose-margin: 20px; font-weight: bold; } - .left-pane-contact { &-section, &-content { @@ -289,7 +289,7 @@ $session-compose-margin: 20px; &-bottom-buttons { display: flex; flex-direction: row; - + .session-button.square-outline.square.green, .session-button.square-outline.square.white { flex-grow: 1; @@ -298,4 +298,20 @@ $session-compose-margin: 20px; line-height: 50px; } } -} \ No newline at end of file +} + +.panel-text-divider { + width: 100%; + text-align: center; + border-bottom: 1px solid $session-color-dark-grey; + line-height: 0.1em; + margin: 50px 0 50px; + + span { + padding: 5px 10px; + border-radius: 50px; + background-color: $session-shade-18; + color: $session-color-light-grey; + border: 1px solid $session-color-dark-grey; + } +} diff --git a/ts/components/LeftPane.tsx b/ts/components/LeftPane.tsx index 14bc64eff..e55f11744 100644 --- a/ts/components/LeftPane.tsx +++ b/ts/components/LeftPane.tsx @@ -8,6 +8,18 @@ import { PropsData as SearchResultsProps } from './SearchResults'; import { SearchOptions } from '../types/Search'; import { LeftPaneSectionHeader } from './session/LeftPaneSectionHeader'; import { LeftPaneContactSection } from './session/LeftPaneContactSection'; +import { + SessionIconButton, + SessionIconSize, + SessionIconType, +} from './session/icon'; +import { SessionIdEditable } from './session/SessionIdEditable'; +import { UserSearchDropdown } from './session/UserSearchDropdown'; +import { + SessionButton, + SessionButtonColor, + SessionButtonType, +} from './session/SessionButton'; // from https://github.com/bvaughn/react-virtualized/blob/fb3484ed5dcc41bffae8eab029126c0fb8f7abc0/source/List/types.js#L5 export type RowRendererParamsType = { @@ -19,7 +31,6 @@ export type RowRendererParamsType = { style: Object; }; - interface State { selectedSection: SectionType; } @@ -38,7 +49,7 @@ interface Props { export class LeftPane extends React.Component { public state = { - selectedSection: SectionType.Message, + selectedSection: SectionType.Contact, }; public constructor(props: any) { @@ -144,4 +155,79 @@ export class LeftPane extends React.Component { /> ); } + + static renderClosableOverlay( + isAddContactView: boolean, + onChangeSessionID: any, + onCloseClick: any, + onButtonClick: any, + searchTerm: string, + searchResults?: any, + updateSearch?: any + ): JSX.Element { + const title = isAddContactView + ? window.i18n('addContact') + : window.i18n('enterRecipient'); + const buttonText = isAddContactView + ? window.i18n('addContact') + : window.i18n('message'); + const ourSessionID = window.textsecure.storage.user.getNumber(); + + return ( +
+
+ +
+

{title}

+

{window.i18n('enterSessionID')}

+
+
+
+
+ + +
+ {window.i18n('usersCanShareTheir...')} +
+ {isAddContactView ||

{window.i18n('or')}

} + + {isAddContactView || ( + + )} + + {isAddContactView && ( +
+ {window.i18n('yourPublicKey')} +
+ )} + + {isAddContactView && ( + + )} + +
+ ); + } } diff --git a/ts/components/session/LeftPaneContactSection.tsx b/ts/components/session/LeftPaneContactSection.tsx index 067ce6e9b..b86fc1557 100644 --- a/ts/components/session/LeftPaneContactSection.tsx +++ b/ts/components/session/LeftPaneContactSection.tsx @@ -5,8 +5,12 @@ import { PropsData as SearchResultsProps } from '../SearchResults'; import { debounce } from 'lodash'; import { cleanSearchTerm } from '../../util/cleanSearchTerm'; import { SearchOptions } from '../../types/Search'; -import { LeftPane, RowRendererParamsType } from '../LeftPane'; -import { SessionButton, SessionButtonType, SessionButtonColor } from './SessionButton'; +import { LeftPane } from '../LeftPane'; +import { + SessionButton, + SessionButtonType, + SessionButtonColor, +} from './SessionButton'; import { AutoSizer, List } from 'react-virtualized'; export interface Props { @@ -35,6 +39,7 @@ export class LeftPaneContactSection extends React.Component { this.debouncedSearch = debounce(this.search.bind(this), 20); this.handleTabSelected = this.handleTabSelected.bind(this); + this.handleToggleOverlay = this.handleToggleOverlay.bind(this); } public componentWillUnmount() { @@ -42,29 +47,49 @@ export class LeftPaneContactSection extends React.Component { } public handleTabSelected(tabType: number) { - this.setState({selectedTab: tabType}); + this.setState({ selectedTab: tabType, showAddContactView: false }); } - public renderHeader(): JSX.Element|undefined { + public renderHeader(): JSX.Element | undefined { const labels = [window.i18n('contactsHeader'), window.i18n('lists')]; - return LeftPane.renderHeader(labels, this.handleTabSelected, undefined, null); + return LeftPane.renderHeader( + labels, + this.handleTabSelected, + undefined, + null + ); } public render(): JSX.Element { return (
{this.renderHeader()} - {this.state.showAddContactView || this.renderContacts()} + {this.state.showAddContactView + ? LeftPane.renderClosableOverlay( + true, + undefined, + this.handleToggleOverlay, + undefined, + '' + ) + : this.renderContacts()}
); } + private handleToggleOverlay() { + this.setState((prevState: { showAddContactView: any }) => ({ + showAddContactView: !prevState.showAddContactView, + })); + } + private renderContacts() { return (
{this.renderList()} {this.renderBottomButtons()} -
); + + ); } private renderBottomButtons(): JSX.Element { @@ -74,11 +99,28 @@ export class LeftPaneContactSection extends React.Component { const createGroup = window.i18n('createGroup'); return (
- - {selectedTab === 0 ? : - } + + {selectedTab === 0 ? ( + + ) : ( + + )}
- ) + ); } public getCurrentConversations(): @@ -97,47 +139,50 @@ export class LeftPaneContactSection extends React.Component { } private renderList() { - // const conversations = this.getCurrentConversations(); + const conversations = this.getCurrentConversations(); - // if (!conversations) { - // throw new Error( - // 'render: must provided conversations if no search results are provided' - // ); - // } + if (!conversations) { + throw new Error( + 'render: must provided conversations if no search results are provided' + ); + } - // const length = conversations.length; - // const listKey = 0; + console.log('conversations length;', conversations.length); // Note: conversations is not a known prop for List, but it is required to ensure that // it re-renders when our conversation data changes. Otherwise it would just render // on startup and scroll. const list = (
- - {({ height, width }) => ( - - )} - + + {({ height, width }) => ( + + )} +
); return [list]; } + public renderRow() { + return undefined; + } - public renderRow = ({ - // index, - // key, - // style, - }: RowRendererParamsType): JSX.Element|undefined => { + // public renderRow = ({ + // , + // }: // index, + // key, + // style, + // RowRendererParamsType): JSX.Element | undefined => { // const { openConversationInternal } = this.props; // const conversations = this.getCurrentConversations(); @@ -157,10 +202,8 @@ export class LeftPaneContactSection extends React.Component { // i18n={window.i18n} // /> // ); - return undefined; - }; - - + // return undefined; + // }; public updateSearch(searchTerm: string) { const { updateSearchTerm, clearSearch } = this.props; diff --git a/ts/components/session/LeftPaneMessageSection.tsx b/ts/components/session/LeftPaneMessageSection.tsx index 7bcd0e281..0cd39b439 100644 --- a/ts/components/session/LeftPaneMessageSection.tsx +++ b/ts/components/session/LeftPaneMessageSection.tsx @@ -9,20 +9,12 @@ import { PropsData as SearchResultsProps, SearchResults, } from '../SearchResults'; -import { - SessionButton, - SessionButtonColor, - SessionButtonType, -} from './SessionButton'; import { SessionSearchInput } from './SessionSearchInput'; import { debounce } from 'lodash'; import { cleanSearchTerm } from '../../util/cleanSearchTerm'; import { SearchOptions } from '../../types/Search'; -import { SessionIconButton, SessionIconSize, SessionIconType } from './icon'; -import { SessionIdEditable } from './SessionIdEditable'; -import { UserSearchDropdown } from './UserSearchDropdown'; import { validateNumber } from '../../types/PhoneNumber'; -import { RowRendererParamsType, LeftPane } from '../LeftPane'; +import { RowRendererParamsType, LeftPane } from '../LeftPane'; export interface Props { searchTerm: string; @@ -38,8 +30,6 @@ export interface Props { clearSearch: () => void; } - - export class LeftPaneMessageSection extends React.Component { private readonly updateSearchBound: (searchedString: string) => void; private readonly debouncedSearch: (searchTerm: string) => void; @@ -167,57 +157,20 @@ export class LeftPaneMessageSection extends React.Component {
{this.renderHeader()} {this.state.showComposeView - ? this.renderCompose() + ? LeftPane.renderClosableOverlay( + false, + this.handleOnPasteSessionID, + this.handleComposeClick, + this.handleMessageButtonClick, + this.props.searchTerm, + this.props.searchResults, + this.updateSearchBound + ) : this.renderConversations()}
); } - public renderCompose(): JSX.Element { - const { searchResults } = this.props; - - return ( -
-
- -
-

{window.i18n('enterRecipient')}

-

{window.i18n('enterSessionID')}

-
-
-
-
- - -
- {window.i18n('usersCanShareTheir...')} -
-

{window.i18n('or')}

- - - -
- ); - } - public renderConversations() { return (
diff --git a/ts/components/session/RegistrationTabs.tsx b/ts/components/session/RegistrationTabs.tsx index c60961a3a..0c570c7f0 100644 --- a/ts/components/session/RegistrationTabs.tsx +++ b/ts/components/session/RegistrationTabs.tsx @@ -504,7 +504,10 @@ export class RegistrationTabs extends React.Component<{}, State> { } private renderTermsConditionAgreement() { - // FIXME link to our Terms and Conditions and privacy statement + // FIXME + console.log( + 'FIXME: add link to our Terms and Conditions and privacy statement' + ); return (
diff --git a/ts/components/session/SessionIdEditable.tsx b/ts/components/session/SessionIdEditable.tsx index a568c1969..ee6a17930 100644 --- a/ts/components/session/SessionIdEditable.tsx +++ b/ts/components/session/SessionIdEditable.tsx @@ -2,6 +2,7 @@ import React from 'react'; interface Props { placeholder: string; + text?: string; editable?: boolean; onChange?: any; } @@ -13,7 +14,7 @@ export class SessionIdEditable extends React.PureComponent { } public render() { - const { placeholder, editable, onChange } = this.props; + const { placeholder, editable, onChange, text } = this.props; return (
{ onChange(e); } }} - /> + > + {text} +
); } }