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 );