From 26995e1873400326d07c425c55c9585008070543 Mon Sep 17 00:00:00 2001 From: William Grant Date: Mon, 3 Apr 2023 14:09:05 +0200 Subject: [PATCH] feat: added new togglable subtitle to header --- .../conversation/ConversationHeader.tsx | 206 ++++++++++++++---- ts/state/selectors/conversations.ts | 2 + 2 files changed, 167 insertions(+), 41 deletions(-) diff --git a/ts/components/conversation/ConversationHeader.tsx b/ts/components/conversation/ConversationHeader.tsx index a518a4e29..f1176994b 100644 --- a/ts/components/conversation/ConversationHeader.tsx +++ b/ts/components/conversation/ConversationHeader.tsx @@ -1,9 +1,9 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Avatar, AvatarSize } from '../avatar/Avatar'; import { contextMenu } from 'react-contexify'; -import styled from 'styled-components'; +import styled, { CSSProperties } from 'styled-components'; import { ConversationNotificationSettingType } from '../../models/conversationAttributes'; import { getConversationHeaderTitleProps, @@ -48,7 +48,10 @@ import { import { SessionIconButton } from '../icon'; import { ConversationHeaderMenu } from '../menu/ConversationHeaderMenu'; import { Flex } from '../basic/Flex'; -import { ExpirationTimerOptions } from '../../util/expiringMessages'; +import { + DisappearingMessageConversationType, + ExpirationTimerOptions, +} from '../../util/expiringMessages'; export interface TimerOption { name: string; @@ -261,15 +264,53 @@ const CallButton = () => { export const StyledSubtitleContainer = styled.div` display: flex; - flex-direction: row; + flex-direction: column; align-items: center; - justify-content: space-between; + justify-content: center; + min-width: 230px; - span:last-child { - margin-bottom: 0; + div:first-child { + span:last-child { + margin-bottom: 0; + } } `; +const StyledSubtitleDot = styled.span<{ active: boolean }>` + border-radius: 50%; + background-color: ${props => + props.active ? 'var(--text-primary-color)' : 'var(--text-secondary-color)'}; + + height: 6px; + width: 6px; + margin: 0 3px; +`; + +const SubtitleDotMenu = ({ + options, + selectedOptionIndex, + style, +}: { + options: Array; + selectedOptionIndex: number; + style: CSSProperties; +}) => ( + + {options.map((option, index) => { + if (!option) { + return null; + } + + return ( + + ); + })} + +); + export type ConversationHeaderTitleProps = { conversationKey: string; isMe: boolean; @@ -279,19 +320,8 @@ export type ConversationHeaderTitleProps = { subscriberCount?: number; isKickedFromGroup: boolean; currentNotificationSetting?: ConversationNotificationSettingType; -}; - -/** - * The subtitle beneath a conversation title when looking at a conversation screen. - * @param props props for subtitle. Text to be displayed - * @returns JSX Element of the subtitle of conversation header - */ -export const ConversationHeaderSubtitle = (props: { text?: string | null }): JSX.Element | null => { - const { text } = props; - if (!text) { - return null; - } - return {text}; + expirationType?: DisappearingMessageConversationType; + expireTimer?: number; }; const ConversationHeaderTitle = () => { @@ -301,17 +331,29 @@ const ConversationHeaderTitle = () => { const convoName = useConversationUsername(headerTitleProps?.conversationKey); const dispatch = useDispatch(); + + const [visibleTitleIndex, setVisibleTitleIndex] = useState(0); + if (!headerTitleProps) { return null; } - const { isGroup, isPublic, members, subscriberCount, isMe, isKickedFromGroup } = headerTitleProps; + const { + isGroup, + isPublic, + members, + subscriberCount, + isMe, + isKickedFromGroup, + expirationType, + expireTimer, + } = headerTitleProps; const { i18n } = window; - if (isMe) { - return
{i18n('noteToSelf')}
; - } + const notificationSubtitle = notificationSetting + ? i18n('notificationSubtitle', [notificationSetting]) + : null; let memberCount = 0; if (isGroup) { @@ -322,37 +364,119 @@ const ConversationHeaderTitle = () => { } } - let memberCountText = ''; + let memberCountSubtitle = null; if (isGroup && memberCount > 0 && !isKickedFromGroup) { const count = String(memberCount); - memberCountText = isPublic ? i18n('activeMembers', [count]) : i18n('members', [count]); + memberCountSubtitle = isPublic ? i18n('activeMembers', [count]) : i18n('members', [count]); } - const notificationSubtitle = notificationSetting - ? window.i18n('notificationSubtitle', [notificationSetting]) + const disappearingMessageSettingText = + expirationType === 'off' + ? window.i18n('disappearingMessagesModeOff') + : expirationType === 'deleteAfterRead' + ? window.i18n('disappearingMessagesModeAfterRead') + : window.i18n('disappearingMessagesModeAfterSend'); + const abbreviatedExpireTime = Boolean(expireTimer) + ? ExpirationTimerOptions.getAbbreviated(expireTimer) : null; - const fullTextSubtitle = memberCountText - ? `${memberCountText} ● ${notificationSubtitle}` - : `${notificationSubtitle}`; + const disappearingMessageSubtitle = `${disappearingMessageSettingText}${ + abbreviatedExpireTime ? ` - ${abbreviatedExpireTime}` : '' + }`; + + const subtitles = [ + notificationSubtitle && notificationSubtitle, + memberCountSubtitle && memberCountSubtitle, + disappearingMessageSubtitle && disappearingMessageSubtitle, + ]; + window.log.info(`WIP: subtitles`, subtitles); + + // const fullTextSubtitle = memberCountText + // ? `${memberCountText} ● ${notificationSubtitle}` + // : `${notificationSubtitle}`; + + const handleTitleCycle = (direction: 1 | -1) => { + let newIndex = visibleTitleIndex + direction; + if (newIndex > subtitles.length - 1) { + newIndex = 0; + } + + if (newIndex < 0) { + newIndex = subtitles.length - 1; + } + + if (subtitles[newIndex]) { + setVisibleTitleIndex(newIndex); + } + }; + + if (isMe) { + // TODO customise for new disappearing message system + return
{i18n('noteToSelf')}
; + } return (
{ - if (isRightPanelOn) { - dispatch(closeRightPanel()); - } else { - dispatch(openRightPanel()); - } - }} + // onClick={() => { + // if (isRightPanelOn) { + // dispatch(closeRightPanel()); + // } else { + // dispatch(openRightPanel()); + // } + // }} role="button" > {convoName} - - - + {subtitles && ( + + + { + handleTitleCycle(-1); + }} + /> + {visibleTitleIndex === 2 && ( + + )} + + {subtitles[visibleTitleIndex]} + + { + handleTitleCycle(1); + }} + /> + + + + )}
); }; diff --git a/ts/state/selectors/conversations.ts b/ts/state/selectors/conversations.ts index 08d59601b..30ba315ed 100644 --- a/ts/state/selectors/conversations.ts +++ b/ts/state/selectors/conversations.ts @@ -563,6 +563,8 @@ export const getConversationHeaderTitleProps = createSelector(getSelectedConvers subscriberCount: state.subscriberCount, isGroup: state.type === 'group', currentNotificationSetting: state.currentNotificationSetting, + expirationType: state.expirationType, + expireTimer: state.expireTimer, }; });