From 87a8385629213f769cebadc591410abfdbf077f6 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Tue, 6 Jul 2021 14:40:45 +1000 Subject: [PATCH] move timerOptions to redux --- .../conversation/ConversationHeader.tsx | 4 +-- ts/components/session/SessionInboxView.tsx | 11 +++++++ .../conversation/SessionConversation.tsx | 11 ------- .../conversation/SessionRightPanel.tsx | 8 +++-- .../session/menu/ConversationHeaderMenu.tsx | 11 +------ ts/components/session/menu/Menu.tsx | 8 +++-- ts/state/ducks/timerOptions.tsx | 30 +++++++++++++++++++ ts/state/ducks/userConfig.tsx | 2 +- ts/state/reducer.ts | 3 ++ ts/state/selectors/timerOptions.ts | 4 +++ 10 files changed, 63 insertions(+), 29 deletions(-) create mode 100644 ts/state/ducks/timerOptions.tsx create mode 100644 ts/state/selectors/timerOptions.ts diff --git a/ts/components/conversation/ConversationHeader.tsx b/ts/components/conversation/ConversationHeader.tsx index f18548455..b6ae2595b 100644 --- a/ts/components/conversation/ConversationHeader.tsx +++ b/ts/components/conversation/ConversationHeader.tsx @@ -16,6 +16,7 @@ import { import { contextMenu } from 'react-contexify'; import { DefaultTheme, withTheme } from 'styled-components'; import { ConversationNotificationSettingType } from '../../models/conversation'; +import autoBind from 'auto-bind'; export interface TimerOption { name: string; @@ -51,7 +52,6 @@ interface Props { expirationSettingName?: string; showBackButton: boolean; - timerOptions: Array; notificationForConvo: Array; currentNotificationSetting: ConversationNotificationSettingType; hasNickname?: boolean; @@ -75,7 +75,7 @@ class ConversationHeaderInner extends React.Component { public constructor(props: Props) { super(props); - this.onAvatarClick = this.onAvatarClick.bind(this); + autoBind(this); } public renderBackButton() { diff --git a/ts/components/session/SessionInboxView.tsx b/ts/components/session/SessionInboxView.tsx index 900fb9453..8c0edafe2 100644 --- a/ts/components/session/SessionInboxView.tsx +++ b/ts/components/session/SessionInboxView.tsx @@ -22,6 +22,7 @@ import { SessionMainPanel } from '../SessionMainPanel'; // tslint:disable-next-line: no-submodule-imports import { PersistGate } from 'redux-persist/integration/react'; import { persistStore } from 'redux-persist'; +import { TimerOptionsArray, TimerOptionsState } from '../../state/ducks/timerOptions'; // Workaround: A react component's required properties are filtering up through connect() // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31363 @@ -90,6 +91,13 @@ export class SessionInboxView extends React.Component { const fullFilledConversations = await Promise.all(filledConversations); + const timerOptions: TimerOptionsArray = window.Whisper.ExpirationTimerOptions.map( + (item: any) => ({ + name: item.getName(), + value: item.get('seconds'), + }) + ); + const initialState: StateType = { conversations: { conversationLookup: makeLookup(fullFilledConversations, 'id'), @@ -106,6 +114,9 @@ export class SessionInboxView extends React.Component { onionPaths: initialOnionPathState, modals: initialModalState, userConfig: initialUserConfigState, + timerOptions: { + timerOptions, + }, }; this.store = createStore(initialState); diff --git a/ts/components/session/conversation/SessionConversation.tsx b/ts/components/session/conversation/SessionConversation.tsx index 3fb14dff9..b6d67e03f 100644 --- a/ts/components/session/conversation/SessionConversation.tsx +++ b/ts/components/session/conversation/SessionConversation.tsx @@ -312,7 +312,6 @@ export class SessionConversation extends React.Component { isShowing={showOptionsPane} /> - ) ); } @@ -381,10 +380,6 @@ export class SessionConversation extends React.Component { left: conversation.get('left'), expirationSettingName, showBackButton: Boolean(messageDetailShowProps), - timerOptions: window.Whisper.ExpirationTimerOptions.map((item: any) => ({ - name: item.getName(), - value: item.get('seconds'), - })), notificationForConvo, currentNotificationSetting: conversation.get('triggerNotificationsFor'), hasNickname: !!conversation.getNickname(), @@ -466,12 +461,6 @@ export class SessionConversation extends React.Component { isPublic: conversation.isPublic(), isAdmin, isBlocked: conversation.isBlocked(), - - timerOptions: window.Whisper.ExpirationTimerOptions.map((item: any) => ({ - name: item.getName(), - value: item.get('seconds'), - })), - onGoBack: () => { this.toggleRightPanel(); }, diff --git a/ts/components/session/conversation/SessionRightPanel.tsx b/ts/components/session/conversation/SessionRightPanel.tsx index 8b346ea11..2e9f4ebf8 100644 --- a/ts/components/session/conversation/SessionRightPanel.tsx +++ b/ts/components/session/conversation/SessionRightPanel.tsx @@ -36,6 +36,8 @@ import { ItemClickEvent } from '../../conversation/media-gallery/types/ItemClick import { MediaItemType } from '../../LightboxGallery'; // tslint:disable-next-line: no-submodule-imports import useInterval from 'react-use/lib/useInterval'; +import { useSelector } from 'react-redux'; +import { getTimerOptions } from '../../../state/selectors/timerOptions'; type Props = { id: string; @@ -44,7 +46,6 @@ type Props = { phoneNumber: string; memberCount: number; avatarPath: string | null; - timerOptions: Array; isPublic: boolean; isAdmin: boolean; isKickedFromGroup: boolean; @@ -194,6 +195,8 @@ export const SessionRightPanelWithDetails = (props: Props) => { const [onItemClick, setOnItemClick] = useState(undefined); const theme = useTheme(); + console.warn('props', props); + useEffect(() => { let isRunning = true; @@ -269,7 +272,6 @@ export const SessionRightPanelWithDetails = (props: Props) => { id, memberCount, name, - timerOptions, isKickedFromGroup, left, isPublic, @@ -289,6 +291,8 @@ export const SessionRightPanelWithDetails = (props: Props) => { ? window.i18n('youLeftTheGroup') : window.i18n('leaveGroup'); + const timerOptions = useSelector(getTimerOptions).timerOptions; + const disappearingMessagesOptions = timerOptions.map(option => { return { content: option.name, diff --git a/ts/components/session/menu/ConversationHeaderMenu.tsx b/ts/components/session/menu/ConversationHeaderMenu.tsx index 40b9f97c8..836d1dd5c 100644 --- a/ts/components/session/menu/ConversationHeaderMenu.tsx +++ b/ts/components/session/menu/ConversationHeaderMenu.tsx @@ -28,7 +28,6 @@ export type PropsConversationHeaderMenu = { left?: boolean; isGroup: boolean; isAdmin: boolean; - timerOptions: Array; notificationForConvo: Array; currentNotificationSetting: ConversationNotificationSettingType; isPrivate: boolean; @@ -46,7 +45,6 @@ export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => { isGroup, isKickedFromGroup, isAdmin, - timerOptions, isBlocked, isPrivate, left, @@ -58,14 +56,7 @@ export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => { return ( <> - {getDisappearingMenuItem( - isPublic, - isKickedFromGroup, - left, - isBlocked, - timerOptions, - conversationId - )} + {getDisappearingMenuItem(isPublic, isKickedFromGroup, left, isBlocked, conversationId)} {getNotificationForConvoMenuItem( isKickedFromGroup, left, diff --git a/ts/components/session/menu/Menu.tsx b/ts/components/session/menu/Menu.tsx index 2a40b0fa4..83ef7f8f1 100644 --- a/ts/components/session/menu/Menu.tsx +++ b/ts/components/session/menu/Menu.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { NotificationForConvoOption, TimerOption } from '../../conversation/ConversationHeader'; import { Item, Submenu } from 'react-contexify'; import { ConversationNotificationSettingType } from '../../../models/conversation'; -import { useDispatch } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import { changeNickNameModal, updateConfirmModal } from '../../../state/ducks/modalDialog'; import { getConversationController } from '../../../session/conversations'; import { @@ -22,6 +22,7 @@ import { unblockConvoById, } from '../../../interactions/conversationInteractions'; import { SessionButtonColor } from '../SessionButton'; +import { getTimerOptions } from '../../../state/selectors/timerOptions'; function showTimerOptions( isPublic: boolean, @@ -278,7 +279,6 @@ export function getDisappearingMenuItem( isKickedFromGroup: boolean | undefined, left: boolean | undefined, isBlocked: boolean | undefined, - timerOptions: Array, conversationId: string ): JSX.Element | null { if ( @@ -291,13 +291,15 @@ export function getDisappearingMenuItem( ) { const isRtlMode = isRtlBody(); + const timerOptions = useSelector(getTimerOptions).timerOptions; + return ( // Remove the && false to make context menu work with RTL support - {(timerOptions || []).map(item => ( + {timerOptions.map(item => ( { diff --git a/ts/state/ducks/timerOptions.tsx b/ts/state/ducks/timerOptions.tsx new file mode 100644 index 000000000..1f7295688 --- /dev/null +++ b/ts/state/ducks/timerOptions.tsx @@ -0,0 +1,30 @@ +/** + * This slice is intended for the user configurable settings for the client such as appearance, autoplaying of links etc. + * Anything setting under the cog wheel tab. + */ +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + +type TimerOptionsEntry = { name: string; value: number }; +export type TimerOptionsArray = Array; + +export type TimerOptionsState = { + timerOptions: TimerOptionsArray; +}; + +export const initialTimerOptionsState: TimerOptionsState = { + timerOptions: [], +}; + +const timerOptionSlice = createSlice({ + name: 'timerOptions', + initialState: initialTimerOptionsState, + reducers: { + updateTimerOptions: (_state, action: PayloadAction) => { + return { timerOptions: action.payload }; + }, + }, +}); + +const { actions, reducer } = timerOptionSlice; +export const { updateTimerOptions } = actions; +export const timerOptionReducer = reducer; diff --git a/ts/state/ducks/userConfig.tsx b/ts/state/ducks/userConfig.tsx index c4f7d4568..1c704e2b4 100644 --- a/ts/state/ducks/userConfig.tsx +++ b/ts/state/ducks/userConfig.tsx @@ -2,7 +2,7 @@ * This slice is intended for the user configurable settings for the client such as appearance, autoplaying of links etc. * Anything setting under the cog wheel tab. */ -import { createSlice, PayloadAction } from '@reduxjs/toolkit'; +import { createSlice } from '@reduxjs/toolkit'; export interface UserConfigState { audioAutoplay: boolean; diff --git a/ts/state/reducer.ts b/ts/state/reducer.ts index e757789d8..743d06f87 100644 --- a/ts/state/reducer.ts +++ b/ts/state/reducer.ts @@ -13,6 +13,7 @@ import { import { defaultOnionReducer as onionPaths, OnionState } from './ducks/onion'; import { modalReducer as modals, ModalState } from './ducks/modalDialog'; import { userConfigReducer as userConfig, UserConfigState } from './ducks/userConfig'; +import { timerOptionReducer as timerOptions, TimerOptionsState } from './ducks/timerOptions'; export type StateType = { search: SearchStateType; @@ -25,6 +26,7 @@ export type StateType = { onionPaths: OnionState; modals: ModalState; userConfig: UserConfigState; + timerOptions: TimerOptionsState; }; export const reducers = { @@ -38,6 +40,7 @@ export const reducers = { onionPaths, modals, userConfig, + timerOptions, }; // Making this work would require that our reducer signature supported AnyAction, not diff --git a/ts/state/selectors/timerOptions.ts b/ts/state/selectors/timerOptions.ts new file mode 100644 index 000000000..bda714d5d --- /dev/null +++ b/ts/state/selectors/timerOptions.ts @@ -0,0 +1,4 @@ +import { StateType } from '../reducer'; +import { TimerOptionsState } from '../ducks/timerOptions'; + +export const getTimerOptions = (state: StateType): TimerOptionsState => state.timerOptions;