From c3bb3b152e9d479ec583cf908f358f3b87c0d0a8 Mon Sep 17 00:00:00 2001
From: Josh Perez <60019601+josh-signal@users.noreply.github.com>
Date: Fri, 29 Jul 2022 16:22:55 -0400
Subject: [PATCH] Update selectedStoryData whenever its story changes
---
ts/components/App.tsx | 7 +++----
ts/state/ducks/stories.ts | 18 ++++++++++--------
ts/state/selectors/stories.ts | 27 +++++++++++++++++++++++++++
ts/state/smart/App.tsx | 4 ++--
ts/state/smart/StoryViewer.tsx | 16 +++++++++++-----
5 files changed, 53 insertions(+), 19 deletions(-)
diff --git a/ts/components/App.tsx b/ts/components/App.tsx
index 1ac4b0b32..8736f4324 100644
--- a/ts/components/App.tsx
+++ b/ts/components/App.tsx
@@ -9,7 +9,6 @@ import classNames from 'classnames';
import type { ExecuteMenuRoleType } from './TitleBarContainer';
import type { LocaleMessagesType } from '../types/I18N';
import type { MenuOptionsType, MenuActionType } from '../types/menu';
-import type { SelectedStoryDataType } from '../state/ducks/stories';
import type { ToastType } from '../state/ducks/toast';
import { AppViewType } from '../state/ducks/app';
import { Inbox } from './Inbox';
@@ -30,7 +29,7 @@ type PropsType = {
renderGlobalModalContainer: () => JSX.Element;
isShowingStoriesView: boolean;
renderStories: () => JSX.Element;
- selectedStoryData?: SelectedStoryDataType;
+ hasSelectedStoryData: boolean;
renderStoryViewer: () => JSX.Element;
requestVerification: (
type: 'sms' | 'voice',
@@ -59,6 +58,7 @@ export const App = ({
executeMenuRole,
getPreferredBadge,
hasInitialLoadCompleted,
+ hasSelectedStoryData,
hideMenuBar,
hideToast,
i18n,
@@ -81,7 +81,6 @@ export const App = ({
requestVerification,
selectedConversationId,
selectedMessage,
- selectedStoryData,
showConversation,
showWhatsNewModal,
theme,
@@ -181,7 +180,7 @@ export const App = ({
{renderGlobalModalContainer()}
{renderCallManager()}
{isShowingStoriesView && renderStories()}
- {selectedStoryData && renderStoryViewer()}
+ {hasSelectedStoryData && renderStoryViewer()}
{contents}
diff --git a/ts/state/ducks/stories.ts b/ts/state/ducks/stories.ts
index cd14ca869..e69a683bb 100644
--- a/ts/state/ducks/stories.ts
+++ b/ts/state/ducks/stories.ts
@@ -62,9 +62,9 @@ export type StoryDataType = {
export type SelectedStoryDataType = {
currentIndex: number;
+ messageId: string;
numStories: number;
shouldShowDetailsModal: boolean;
- story: StoryDataType;
};
// State
@@ -631,9 +631,9 @@ function viewUserStories(
payload: {
selectedStoryData: {
currentIndex,
+ messageId: story.messageId,
numStories,
shouldShowDetailsModal,
- story,
},
storyViewMode: hasUnread
? StoryViewModeType.Unread
@@ -699,9 +699,9 @@ const viewStory: ViewStoryActionCreatorType = ({
payload: {
selectedStoryData: {
currentIndex,
+ messageId: storyId,
numStories,
shouldShowDetailsModal,
- story,
},
storyViewMode,
},
@@ -722,9 +722,9 @@ const viewStory: ViewStoryActionCreatorType = ({
payload: {
selectedStoryData: {
currentIndex: nextIndex,
+ messageId: nextStory.messageId,
numStories,
shouldShowDetailsModal: false,
- story: nextStory,
},
storyViewMode,
},
@@ -742,9 +742,9 @@ const viewStory: ViewStoryActionCreatorType = ({
payload: {
selectedStoryData: {
currentIndex: nextIndex,
+ messageId: nextStory.messageId,
numStories,
shouldShowDetailsModal: false,
- story: nextStory,
},
storyViewMode,
},
@@ -771,9 +771,9 @@ const viewStory: ViewStoryActionCreatorType = ({
payload: {
selectedStoryData: {
currentIndex: nextSelectedStoryData.currentIndex,
+ messageId: unreadStory.messageId,
numStories: nextSelectedStoryData.numStories,
shouldShowDetailsModal: false,
- story: unreadStory,
},
storyViewMode,
},
@@ -832,9 +832,10 @@ const viewStory: ViewStoryActionCreatorType = ({
payload: {
selectedStoryData: {
currentIndex: 0,
+ messageId:
+ nextSelectedStoryData.storiesByConversationId[0].messageId,
numStories: nextSelectedStoryData.numStories,
shouldShowDetailsModal: false,
- story: nextSelectedStoryData.storiesByConversationId[0],
},
storyViewMode,
},
@@ -869,9 +870,10 @@ const viewStory: ViewStoryActionCreatorType = ({
payload: {
selectedStoryData: {
currentIndex: 0,
+ messageId:
+ nextSelectedStoryData.storiesByConversationId[0].messageId,
numStories: nextSelectedStoryData.numStories,
shouldShowDetailsModal: false,
- story: nextSelectedStoryData.storiesByConversationId[0],
},
storyViewMode,
},
diff --git a/ts/state/selectors/stories.ts b/ts/state/selectors/stories.ts
index 5cdbf5136..ed7a01c5e 100644
--- a/ts/state/selectors/stories.ts
+++ b/ts/state/selectors/stories.ts
@@ -40,6 +40,11 @@ export const shouldShowStoriesView = createSelector(
({ isShowingStoriesView }): boolean => isShowingStoriesView
);
+export const hasSelectedStoryData = createSelector(
+ getStoriesState,
+ ({ selectedStoryData }): boolean => Boolean(selectedStoryData)
+);
+
export const getSelectedStoryData = createSelector(
getStoriesState,
({ selectedStoryData }): SelectedStoryDataType | undefined =>
@@ -370,3 +375,25 @@ export const getHasStoriesSelector = createSelector(
: HasStories.Read;
}
);
+
+export const getStoryByIdSelector = createSelector(
+ getStoriesState,
+ ({ stories }) =>
+ (
+ conversationSelector: GetConversationByIdType,
+ messageId: string
+ ):
+ | { conversationStory: ConversationStoryType; storyView: StoryViewType }
+ | undefined => {
+ const story = stories.find(item => item.messageId === messageId);
+
+ if (!story) {
+ return;
+ }
+
+ return {
+ conversationStory: getConversationStory(conversationSelector, story),
+ storyView: getStoryView(conversationSelector, story),
+ };
+ }
+);
diff --git a/ts/state/smart/App.tsx b/ts/state/smart/App.tsx
index 638a7b23b..fe291ac52 100644
--- a/ts/state/smart/App.tsx
+++ b/ts/state/smart/App.tsx
@@ -25,7 +25,7 @@ import {
getMenuOptions,
} from '../selectors/user';
import {
- getSelectedStoryData,
+ hasSelectedStoryData,
shouldShowStoriesView,
} from '../selectors/stories';
import { getHideMenuBar } from '../selectors/items';
@@ -65,7 +65,7 @@ const mapStateToProps = (state: StateType) => {
),
- selectedStoryData: getSelectedStoryData(state),
+ hasSelectedStoryData: hasSelectedStoryData(state),
renderStoryViewer: () => (
diff --git a/ts/state/smart/StoryViewer.tsx b/ts/state/smart/StoryViewer.tsx
index 274b563ab..722dfeb86 100644
--- a/ts/state/smart/StoryViewer.tsx
+++ b/ts/state/smart/StoryViewer.tsx
@@ -20,10 +20,9 @@ import {
import { getIntl } from '../selectors/user';
import { getPreferredBadgeSelector } from '../selectors/badges';
import {
- getConversationStory,
getSelectedStoryData,
getStoryReplies,
- getStoryView,
+ getStoryByIdSelector,
} from '../selectors/stories';
import { renderEmojiPicker } from './renderEmojiPicker';
import { strictAssert } from '../../util/assert';
@@ -57,11 +56,18 @@ export function SmartStoryViewer(): JSX.Element | null {
getConversationSelector
);
- const storyView = getStoryView(conversationSelector, selectedStoryData.story);
- const conversationStory = getConversationStory(
+ const getStoryById = useSelector(getStoryByIdSelector);
+
+ const storyInfo = getStoryById(
conversationSelector,
- selectedStoryData.story
+ selectedStoryData.messageId
);
+ strictAssert(
+ storyInfo,
+ 'StoryViewer: selected story does not exist in stories'
+ );
+ const { conversationStory, storyView } = storyInfo;
+
const storyViewMode = useSelector(
state => state.stories.storyViewMode
);