diff --git a/stylesheets/_session.scss b/stylesheets/_session.scss index 3bf6c515a..38916fba1 100644 --- a/stylesheets/_session.scss +++ b/stylesheets/_session.scss @@ -229,7 +229,7 @@ $session_message-container-border-radius: 5px; user-select: none; cursor: pointer; transition: $session-transition-duration; - background-color: rgba(0,0,0,0); + background-color: rgba(0, 0, 0, 0); &.disabled { cursor: default; diff --git a/stylesheets/_session_theme_dark_left_pane.scss b/stylesheets/_session_theme_dark_left_pane.scss index 27f6731f9..bbf93e975 100644 --- a/stylesheets/_session_theme_dark_left_pane.scss +++ b/stylesheets/_session_theme_dark_left_pane.scss @@ -121,6 +121,11 @@ $session-compose-margin: 20px; &__list { height: -webkit-fill-available; + + &-popup { + width: -webkit-fill-available; + position: absolute; + } } &-overlay { @@ -208,7 +213,6 @@ $session-compose-margin: 20px; } } - .session-left-pane-section-content { display: flex; flex-direction: column; @@ -303,6 +307,12 @@ $session-compose-margin: 20px; border-radius: 50%; color: $session-color-white; font-weight: bold; + cursor: pointer; + transition: $session-transition-duration; + + &:hover { + filter: brightness(80%); + } } .left-pane-contact { @@ -310,11 +320,10 @@ $session-compose-margin: 20px; &-content { display: flex; flex-direction: column; - .module-conversation-list-item { &--has-friend-request { - &:first-child{ + &:first-child { border-top: none !important; } @@ -330,16 +339,16 @@ $session-compose-margin: 20px; display: flex; .session-button { - font-size: 11px; - padding: 6px; + font-size: 10px; + padding: 4px; height: auto; margin: 0px; - line-height: 14px; + line-height: 10px; } } } } - + &-content { @include session-dark-background-lighter; } @@ -385,7 +394,6 @@ $session-compose-margin: 20px; background-color: $session-shade-7; } - &__buttons { display: flex; @@ -423,6 +431,13 @@ $session-compose-margin: 20px; fill: $session-color-green; } } + .session-button.square-outline.square.green, + .session-button.square-outline.square.white { + flex-grow: 1; + border: 1px solid $session-shade-8; + height: 50px; + line-height: 50px; + } } } @@ -430,9 +445,9 @@ $session-compose-margin: 20px; font-weight: bold; font-size: 13px; padding: 11px; - border-right:1px solid #2f2f2f !important; - border-top:1px solid #2f2f2f !important; - border-left:1px solid #2f2f2f !important; + border-right: 1px solid #2f2f2f !important; + border-top: 1px solid #2f2f2f !important; + border-left: 1px solid #2f2f2f !important; @include session-dark-background-lighter; } diff --git a/ts/components/ConversationListItem.tsx b/ts/components/ConversationListItem.tsx index ee70dca06..2d73072ec 100644 --- a/ts/components/ConversationListItem.tsx +++ b/ts/components/ConversationListItem.tsx @@ -359,7 +359,7 @@ export class ConversationListItem extends React.PureComponent { {this.renderContextMenu(triggerId)} ); - + } private renderUser() { const { name, phoneNumber, profileName } = this.props; diff --git a/ts/components/LeftPane.tsx b/ts/components/LeftPane.tsx index 14d55eec1..5d4ef374e 100644 --- a/ts/components/LeftPane.tsx +++ b/ts/components/LeftPane.tsx @@ -42,6 +42,8 @@ interface State { interface Props { conversations: Array; friends: Array; + sentFriendsRequest: Array; + receivedFriendsRequest: Array; searchResults?: SearchResultsProps; searchTerm: string; isSecondaryDevice: boolean; @@ -54,7 +56,7 @@ interface Props { export class LeftPane extends React.Component { public state = { - selectedSection: SectionType.Contact, + selectedSection: SectionType.Message, }; public constructor(props: any) { @@ -219,6 +221,8 @@ export class LeftPane extends React.Component { const { openConversationInternal, friends, + sentFriendsRequest, + receivedFriendsRequest, conversations, searchResults, searchTerm, @@ -239,6 +243,8 @@ export class LeftPane extends React.Component { updateSearchTerm={updateSearchTerm} search={search} clearSearch={clearSearch} + sentFriendsRequest={sentFriendsRequest} + receivedFriendsRequest={receivedFriendsRequest} /> ); } diff --git a/ts/components/conversation/ConversationHeader.tsx b/ts/components/conversation/ConversationHeader.tsx index 4973b6b3f..4cdf0b471 100644 --- a/ts/components/conversation/ConversationHeader.tsx +++ b/ts/components/conversation/ConversationHeader.tsx @@ -171,9 +171,7 @@ export class ConversationHeader extends React.Component { return (
- - {title} - + {title} {textEl}
); diff --git a/ts/components/session/LeftPaneContactSection.tsx b/ts/components/session/LeftPaneContactSection.tsx index e15b4695c..511c18e30 100644 --- a/ts/components/session/LeftPaneContactSection.tsx +++ b/ts/components/session/LeftPaneContactSection.tsx @@ -25,6 +25,8 @@ export interface Props { conversations: Array; friends: Array; + receivedFriendsRequest: Array; + sentFriendsRequest: Array; searchResults?: SearchResultsProps; @@ -34,7 +36,15 @@ export interface Props { clearSearch: () => void; } -export class LeftPaneContactSection extends React.Component { +interface State { + showAddContactView: boolean; + selectedTab: number; + addContactRecipientID: string; + showFriendRequestsPopup: boolean; + pubKeyPasted: string; +} + +export class LeftPaneContactSection extends React.Component { private readonly debouncedSearch: (searchTerm: string) => void; public constructor(props: Props) { @@ -43,6 +53,8 @@ export class LeftPaneContactSection extends React.Component { showAddContactView: false, selectedTab: 0, addContactRecipientID: '', + pubKeyPasted: '', + showFriendRequestsPopup: false, }; this.debouncedSearch = debounce(this.search.bind(this), 20); @@ -52,6 +64,9 @@ export class LeftPaneContactSection extends React.Component { this.handleRecipientSessionIDChanged = this.handleRecipientSessionIDChanged.bind( this ); + this.handleToggleFriendRequestPopup = this.handleToggleFriendRequestPopup.bind( + this + ); } public componentWillUnmount() { @@ -73,7 +88,7 @@ export class LeftPaneContactSection extends React.Component { labels, this.handleTabSelected, undefined, - undefined, + this.handleToggleFriendRequestPopup, friendRequestCount ); } @@ -95,39 +110,37 @@ export class LeftPaneContactSection extends React.Component { ); } - public getCurrentFriends(): Array { - const { friends } = this.props; + public renderRowFriendRequest = ({ + index, + key, + style, + }: RowRendererParamsType): JSX.Element | undefined => { + const receivedFriendsRequest = this.props.receivedFriendsRequest; - let friendList = friends; - if (friendList !== undefined) { - friendList = friendList.filter( - friend => friend.type === 'direct' && !friend.isMe - ); - } + const item = receivedFriendsRequest[index]; + const onClick = this.props.openConversationInternal; - return friendList; - } + return ( + + ); + }; public renderRow = ({ index, key, style, }: RowRendererParamsType): JSX.Element | undefined => { - const receivedFriendsRequest = this.getFriendRequests(true); - const sentFriendsRequest = this.getFriendRequests(false); + const { sentFriendsRequest } = this.props; const friends = this.getCurrentFriends(); - - const combined = [ - ...receivedFriendsRequest, - ...sentFriendsRequest, - ...friends, - ]; - + const combined = [...sentFriendsRequest, ...friends]; const item = combined[index]; - let onClick; - if (index >= receivedFriendsRequest.length) { - onClick = this.props.openConversationInternal; - } + const onClick = this.props.openConversationInternal; return ( { } } + private getCurrentFriends(): Array { + const { friends } = this.props; + + let friendList = friends; + if (friendList !== undefined) { + friendList = friendList.filter( + friend => friend.type === 'direct' && !friend.isMe + ); + } + + return friendList; + } + private handleToggleOverlay() { - this.setState((prevState: { showAddContactView: any }) => ({ + this.setState((prevState: { showAddContactView: boolean }) => ({ showAddContactView: !prevState.showAddContactView, })); } + private handleToggleFriendRequestPopup() { + this.setState((prevState: { showFriendRequestsPopup: boolean }) => ({ + showFriendRequestsPopup: !prevState.showFriendRequestsPopup, + })); + } + private handleOnAddContact() { const sessionID = this.state.addContactRecipientID; const error = validateNumber(sessionID, window.i18n); @@ -217,9 +249,16 @@ export class LeftPaneContactSection extends React.Component { } private renderContacts() { + const { showFriendRequestsPopup } = this.state; + const hasReceivedFriendRequest = + this.props.receivedFriendsRequest.length > 0; + return (
{this.renderList()} + {showFriendRequestsPopup && + hasReceivedFriendRequest && + this.renderFriendRequestPopup()} {this.renderBottomButtons()}
); @@ -257,46 +296,39 @@ export class LeftPaneContactSection extends React.Component { ); } - // true: received only, false: sent only - private getFriendRequests( - received: boolean - ): Array { - const { conversations } = this.props; - - let conversationsList = conversations; - if (conversationsList !== undefined) { - if (received) { - conversationsList = conversationsList.filter( - conversation => conversation.hasReceivedFriendRequest - ); - } else { - conversationsList = conversationsList.filter( - conversation => conversation.hasSentFriendRequest - ); - } - } + private renderFriendRequestPopup() { + const frTitle = window.i18n('youHaveFriendRequestFrom'); + const length = this.props.receivedFriendsRequest.length; - return conversationsList || []; + return ( +
+
{frTitle}
+
+ + {({ height, width }) => ( + + )} + +
+
+ ); } private renderList() { - const receivedFriendsRequest = this.getFriendRequests(true); - const sentFriendsRequest = this.getFriendRequests(false); + const { sentFriendsRequest } = this.props; const friends = this.getCurrentFriends(); - - const combined = [ - ...receivedFriendsRequest, - ...sentFriendsRequest, - ...friends, - ]; - - const length = combined.length; - const hasReceivedFriendRequest = receivedFriendsRequest.length > 0; - const frTitle = window.i18n('youHaveFriendRequestFrom'); + const length = sentFriendsRequest.length + friends.length; const list = (
- {hasReceivedFriendRequest &&
{frTitle}
} {({ height, width }) => ( { const shortenedNotificationCount = notificationCount > 9 ? 9 : notificationCount; children.push( -
+
{shortenedNotificationCount}
); diff --git a/ts/state/ducks/conversations.ts b/ts/state/ducks/conversations.ts index ab189d13c..06ff8f458 100644 --- a/ts/state/ducks/conversations.ts +++ b/ts/state/ducks/conversations.ts @@ -53,6 +53,8 @@ export type ConversationType = { isSelected: boolean; isTyping: boolean; isFriend?: boolean; + hasReceivedFriendRequest?: boolean; + hasSentFriendRequest?: boolean; }; export type ConversationLookupType = { [key: string]: ConversationType; diff --git a/ts/state/selectors/conversations.ts b/ts/state/selectors/conversations.ts index bc718a53a..42dbd6717 100644 --- a/ts/state/selectors/conversations.ts +++ b/ts/state/selectors/conversations.ts @@ -10,6 +10,7 @@ import { } from '../ducks/conversations'; import { getIntl, getRegionCode, getUserNumber } from './user'; +import { PropsData as ConversationListItemPropsType } from '../../components/ConversationListItem'; export const getConversations = (state: StateType): ConversationsStateType => state.conversations; @@ -97,6 +98,8 @@ export const _getLeftPaneLists = ( conversations: Array; archivedConversations: Array; friends: Array; + receivedFriendsRequest: Array; + sentFriendsRequest: Array; } => { const values = Object.values(lookup); const sorted = values.sort(comparator); @@ -104,6 +107,8 @@ export const _getLeftPaneLists = ( const conversations: Array = []; const archivedConversations: Array = []; const friends: Array = []; + const receivedFriendsRequest: Array = []; + const sentFriendsRequest: Array = []; const max = sorted.length; for (let i = 0; i < max; i += 1) { @@ -120,6 +125,13 @@ export const _getLeftPaneLists = ( friends.push(conversation); } + if (conversation.hasReceivedFriendRequest) { + receivedFriendsRequest.push(conversation); + } + if (conversation.hasSentFriendRequest) { + sentFriendsRequest.push(conversation); + } + if (!conversation.activeAt) { continue; } @@ -131,7 +143,13 @@ export const _getLeftPaneLists = ( } } - return { conversations, archivedConversations, friends }; + return { + conversations, + archivedConversations, + friends, + receivedFriendsRequest, + sentFriendsRequest, + }; }; export const getLeftPaneLists = createSelector(