From 6f7094bc19c34982597a75102b6653f1288d352e Mon Sep 17 00:00:00 2001
From: Josh Perez <60019601+josh-signal@users.noreply.github.com>
Date: Mon, 22 Aug 2022 13:44:23 -0400
Subject: [PATCH] Allow paging through My Stories

---
 ts/components/MyStories.tsx                   |   4 +-
 ts/components/Stories.tsx                     |   7 +-
 ts/components/StoriesPane.tsx                 |   3 +-
 ts/components/StoryListItem.tsx               |  11 +-
 ts/components/StoryViewer.stories.tsx         |   4 +
 ts/components/StoryViewer.tsx                 |  33 +++-
 ts/components/conversation/ContactModal.tsx   |   9 +-
 .../conversation/ConversationHeader.tsx       |   9 +-
 .../conversation/ConversationHero.tsx         |   9 +-
 ts/components/conversation/Message.tsx        |   3 +
 ts/state/ducks/stories.ts                     | 169 ++++++++++--------
 ts/state/selectors/stories.ts                 |  12 +-
 ts/state/smart/StoryViewer.tsx                |   7 +-
 ts/types/Stories.ts                           |   8 +-
 14 files changed, 166 insertions(+), 122 deletions(-)

diff --git a/ts/components/MyStories.tsx b/ts/components/MyStories.tsx
index 4931c5adba..9741a1543a 100644
--- a/ts/components/MyStories.tsx
+++ b/ts/components/MyStories.tsx
@@ -85,7 +85,7 @@ export const MyStories = ({
                     onClick={() =>
                       viewStory({
                         storyId: story.messageId,
-                        storyViewMode: StoryViewModeType.Single,
+                        storyViewMode: StoryViewModeType.User,
                       })
                     }
                     type="button"
@@ -148,7 +148,7 @@ export const MyStories = ({
                       onClick: () => {
                         viewStory({
                           storyId: story.messageId,
-                          storyViewMode: StoryViewModeType.Single,
+                          storyViewMode: StoryViewModeType.User,
                           shouldShowDetailsModal: true,
                         });
                       },
diff --git a/ts/components/Stories.tsx b/ts/components/Stories.tsx
index fb87808e19..f6228f27a6 100644
--- a/ts/components/Stories.tsx
+++ b/ts/components/Stories.tsx
@@ -16,7 +16,10 @@ import type { LocalizerType } from '../types/Util';
 import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
 import type { PropsType as SmartStoryCreatorPropsType } from '../state/smart/StoryCreator';
 import type { ShowToastActionCreatorType } from '../state/ducks/toast';
-import type { ViewStoryActionCreatorType } from '../state/ducks/stories';
+import type {
+  ViewUserStoriesActionCreatorType,
+  ViewStoryActionCreatorType,
+} from '../state/ducks/stories';
 import { MyStories } from './MyStories';
 import { StoriesPane } from './StoriesPane';
 import { Theme, themeClassName } from '../util/theme';
@@ -40,7 +43,7 @@ export type PropsType = {
   stories: Array<ConversationStoryType>;
   toggleHideStories: (conversationId: string) => unknown;
   toggleStoriesView: () => unknown;
-  viewUserStories: (conversationId: string) => unknown;
+  viewUserStories: ViewUserStoriesActionCreatorType;
   viewStory: ViewStoryActionCreatorType;
 };
 
diff --git a/ts/components/StoriesPane.tsx b/ts/components/StoriesPane.tsx
index 581dd59453..0df2f84ea8 100644
--- a/ts/components/StoriesPane.tsx
+++ b/ts/components/StoriesPane.tsx
@@ -17,6 +17,7 @@ import type {
 import type { LocalizerType } from '../types/Util';
 import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
 import type { ShowToastActionCreatorType } from '../state/ducks/toast';
+import type { ViewUserStoriesActionCreatorType } from '../state/ducks/stories';
 import { ContextMenu } from './ContextMenu';
 import { MyStoriesButton } from './MyStoriesButton';
 import { SearchInput } from './SearchInput';
@@ -76,7 +77,7 @@ export type PropsType = {
   stories: Array<ConversationStoryType>;
   toggleHideStories: (conversationId: string) => unknown;
   toggleStoriesView: () => unknown;
-  viewUserStories: (conversationId: string) => unknown;
+  viewUserStories: ViewUserStoriesActionCreatorType;
 };
 
 export const StoriesPane = ({
diff --git a/ts/components/StoryListItem.tsx b/ts/components/StoryListItem.tsx
index 79df56c346..370bc76b4f 100644
--- a/ts/components/StoryListItem.tsx
+++ b/ts/components/StoryListItem.tsx
@@ -7,6 +7,7 @@ import type { ConversationType } from '../state/ducks/conversations';
 import type { ConversationStoryType, StoryViewType } from '../types/Stories';
 import type { LocalizerType } from '../types/Util';
 import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
+import type { ViewUserStoriesActionCreatorType } from '../state/ducks/stories';
 import { Avatar, AvatarSize } from './Avatar';
 import { ConfirmationDialog } from './ConfirmationDialog';
 import { ContextMenu } from './ContextMenu';
@@ -24,10 +25,7 @@ export type PropsType = Pick<ConversationStoryType, 'group' | 'isHidden'> & {
   onHideStory: (conversationId: string) => unknown;
   queueStoryDownload: (storyId: string) => unknown;
   story: StoryViewType;
-  viewUserStories: (
-    conversationId: string,
-    shouldShowDetailsModal?: boolean
-  ) => unknown;
+  viewUserStories: ViewUserStoriesActionCreatorType;
 };
 
 function StoryListItemAvatar({
@@ -138,7 +136,8 @@ export const StoryListItem = ({
           {
             icon: 'StoryListItem__icon--info',
             label: i18n('StoryListItem__info'),
-            onClick: () => viewUserStories(conversationId, true),
+            onClick: () =>
+              viewUserStories({ conversationId, shouldShowDetailsModal: true }),
           },
           {
             icon: 'StoryListItem__icon--chat',
@@ -149,7 +148,7 @@ export const StoryListItem = ({
         moduleClassName={classNames('StoryListItem', {
           'StoryListItem--hidden': isHidden,
         })}
-        onClick={() => viewUserStories(conversationId)}
+        onClick={() => viewUserStories({ conversationId })}
         popperOptions={{
           placement: 'bottom',
           strategy: 'absolute',
diff --git a/ts/components/StoryViewer.stories.tsx b/ts/components/StoryViewer.stories.tsx
index adf82ff14b..468bade015 100644
--- a/ts/components/StoryViewer.stories.tsx
+++ b/ts/components/StoryViewer.stories.tsx
@@ -7,6 +7,7 @@ import React from 'react';
 import type { PropsType } from './StoryViewer';
 import enMessages from '../../_locales/en/messages.json';
 import { SendStatus } from '../messages/MessageSendState';
+import { StoryViewModeType } from '../types/Stories';
 import { StoryViewer } from './StoryViewer';
 import { VIDEO_MP4 } from '../types/MIME';
 import { fakeAttachment } from '../test-both/helpers/fakeAttachment';
@@ -57,6 +58,9 @@ export default {
     story: {
       defaultValue: getFakeStoryView(),
     },
+    storyViewMode: {
+      defaultValue: StoryViewModeType.All,
+    },
     toggleHasAllStoriesMuted: { action: true },
     viewStory: { action: true },
   },
diff --git a/ts/components/StoryViewer.tsx b/ts/components/StoryViewer.tsx
index 027d597f5c..1eef5af83b 100644
--- a/ts/components/StoryViewer.tsx
+++ b/ts/components/StoryViewer.tsx
@@ -83,7 +83,7 @@ export type PropsType = {
   showToast: ShowToastActionCreatorType;
   skinTone?: number;
   story: StoryViewType;
-  storyViewMode?: StoryViewModeType;
+  storyViewMode: StoryViewModeType;
   toggleHasAllStoriesMuted: () => unknown;
   viewStory: ViewStoryActionCreatorType;
 };
@@ -303,9 +303,22 @@ export const StoryViewer = ({
     log.info('stories.markStoryRead', { messageId });
   }, [markStoryRead, messageId]);
 
+  const canFreelyNavigateStories =
+    storyViewMode === StoryViewModeType.All ||
+    storyViewMode === StoryViewModeType.Unread;
+
+  const canNavigateLeft =
+    (storyViewMode === StoryViewModeType.User && currentIndex > 0) ||
+    canFreelyNavigateStories;
+
+  const canNavigateRight =
+    (storyViewMode === StoryViewModeType.User &&
+      currentIndex < numStories - 1) ||
+    canFreelyNavigateStories;
+
   const navigateStories = useCallback(
     (ev: KeyboardEvent) => {
-      if (ev.key === 'ArrowRight') {
+      if (canNavigateRight && ev.key === 'ArrowRight') {
         viewStory({
           storyId: story.messageId,
           storyViewMode,
@@ -313,7 +326,7 @@ export const StoryViewer = ({
         });
         ev.preventDefault();
         ev.stopPropagation();
-      } else if (ev.key === 'ArrowLeft') {
+      } else if (canNavigateLeft && ev.key === 'ArrowLeft') {
         viewStory({
           storyId: story.messageId,
           storyViewMode,
@@ -323,7 +336,13 @@ export const StoryViewer = ({
         ev.stopPropagation();
       }
     },
-    [story.messageId, storyViewMode, viewStory]
+    [
+      canNavigateLeft,
+      canNavigateRight,
+      story.messageId,
+      storyViewMode,
+      viewStory,
+    ]
   );
 
   useEffect(() => {
@@ -383,8 +402,6 @@ export const StoryViewer = ({
   const replyCount = replies.length;
   const viewCount = views.length;
 
-  const hasPrevNextArrows = storyViewMode !== StoryViewModeType.Single;
-
   const canMuteStory = isVideoAttachment(attachment);
   const isStoryMuted = hasAllStoriesMuted || !canMuteStory;
 
@@ -453,7 +470,7 @@ export const StoryViewer = ({
           style={{ background: getStoryBackground(attachment) }}
         />
         <div className="StoryViewer__content">
-          {hasPrevNextArrows && (
+          {canNavigateLeft && (
             <button
               aria-label={i18n('back')}
               className={classNames(
@@ -685,7 +702,7 @@ export const StoryViewer = ({
               )}
             </div>
           </div>
-          {hasPrevNextArrows && (
+          {canNavigateRight && (
             <button
               aria-label={i18n('forward')}
               className={classNames(
diff --git a/ts/components/conversation/ContactModal.tsx b/ts/components/conversation/ContactModal.tsx
index 8e289c11da..5bf5e08de7 100644
--- a/ts/components/conversation/ContactModal.tsx
+++ b/ts/components/conversation/ContactModal.tsx
@@ -11,6 +11,8 @@ import type {
 import type { BadgeType } from '../../badges/types';
 import type { HasStories } from '../../types/Stories';
 import type { LocalizerType, ThemeType } from '../../types/Util';
+import type { ViewUserStoriesActionCreatorType } from '../../state/ducks/stories';
+import { StoryViewModeType } from '../../types/Stories';
 import * as log from '../../logging/log';
 import { About } from './About';
 import { Avatar } from '../Avatar';
@@ -42,7 +44,7 @@ type PropsActionType = {
   toggleAdmin: (conversationId: string, contactId: string) => void;
   toggleSafetyNumberModal: (conversationId: string) => unknown;
   updateConversationModelSharedGroups: (conversationId: string) => void;
-  viewUserStories: (cid: string) => unknown;
+  viewUserStories: ViewUserStoriesActionCreatorType;
 };
 
 export type PropsType = PropsDataType & PropsActionType;
@@ -179,7 +181,10 @@ export const ContactModal = ({
               name={contact.name}
               onClick={() => {
                 if (conversation && hasStories) {
-                  viewUserStories(conversation.id);
+                  viewUserStories({
+                    conversationId: conversation.id,
+                    storyViewMode: StoryViewModeType.User,
+                  });
                 } else {
                   setView(ContactModalView.ShowingAvatar);
                 }
diff --git a/ts/components/conversation/ConversationHeader.tsx b/ts/components/conversation/ConversationHeader.tsx
index a2bd2b1320..40404bf9b9 100644
--- a/ts/components/conversation/ConversationHeader.tsx
+++ b/ts/components/conversation/ConversationHeader.tsx
@@ -21,6 +21,8 @@ import type { LocalizerType, ThemeType } from '../../types/Util';
 import type { ConversationType } from '../../state/ducks/conversations';
 import type { BadgeType } from '../../badges/types';
 import type { HasStories } from '../../types/Stories';
+import type { ViewUserStoriesActionCreatorType } from '../../state/ducks/stories';
+import { StoryViewModeType } from '../../types/Stories';
 import { getMuteOptions } from '../../util/getMuteOptions';
 import * as expirationTimer from '../../util/expirationTimer';
 import { missingCaseError } from '../../util/missingCaseError';
@@ -90,7 +92,7 @@ export type PropsActionsType = {
   onArchive: () => void;
   onMarkUnread: () => void;
   onMoveToInbox: () => void;
-  viewUserStories: (cid: string) => unknown;
+  viewUserStories: ViewUserStoriesActionCreatorType;
 };
 
 export type PropsHousekeepingType = {
@@ -232,7 +234,10 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
           onClick={
             hasStories
               ? () => {
-                  viewUserStories(id);
+                  viewUserStories({
+                    conversationId: id,
+                    storyViewMode: StoryViewModeType.User,
+                  });
                 }
               : undefined
           }
diff --git a/ts/components/conversation/ConversationHero.tsx b/ts/components/conversation/ConversationHero.tsx
index 087e7fae53..dd3c9056d3 100644
--- a/ts/components/conversation/ConversationHero.tsx
+++ b/ts/components/conversation/ConversationHero.tsx
@@ -10,6 +10,8 @@ import { GroupDescription } from './GroupDescription';
 import { SharedGroupNames } from '../SharedGroupNames';
 import type { LocalizerType, ThemeType } from '../../types/Util';
 import type { HasStories } from '../../types/Stories';
+import type { ViewUserStoriesActionCreatorType } from '../../state/ducks/stories';
+import { StoryViewModeType } from '../../types/Stories';
 import { ConfirmationDialog } from '../ConfirmationDialog';
 import { Button, ButtonSize, ButtonVariant } from '../Button';
 import { shouldBlurAvatar } from '../../util/shouldBlurAvatar';
@@ -30,7 +32,7 @@ export type Props = {
   unblurredAvatarPath?: string;
   updateSharedGroups: () => unknown;
   theme: ThemeType;
-  viewUserStories: (cid: string) => unknown;
+  viewUserStories: ViewUserStoriesActionCreatorType;
 } & Omit<AvatarProps, 'onClick' | 'size' | 'noteToSelf'>;
 
 const renderMembershipRow = ({
@@ -146,7 +148,10 @@ export const ConversationHero = ({
     avatarOnClick = unblurAvatar;
   } else if (hasStories) {
     avatarOnClick = () => {
-      viewUserStories(id);
+      viewUserStories({
+        conversationId: id,
+        storyViewMode: StoryViewModeType.User,
+      });
     };
   }
 
diff --git a/ts/components/conversation/Message.tsx b/ts/components/conversation/Message.tsx
index c2f7682785..90413ca47a 100644
--- a/ts/components/conversation/Message.tsx
+++ b/ts/components/conversation/Message.tsx
@@ -1556,6 +1556,9 @@ export class Message extends React.PureComponent<Props, State> {
           isViewOnce={false}
           moduleClassName="StoryReplyQuote"
           onClick={() => {
+            if (!storyReplyContext.storyId) {
+              return;
+            }
             viewStory({
               storyId: storyReplyContext.storyId,
               storyViewMode: StoryViewModeType.Single,
diff --git a/ts/state/ducks/stories.ts b/ts/state/ducks/stories.ts
index 9f8098e937..bc6d897745 100644
--- a/ts/state/ducks/stories.ts
+++ b/ts/state/ducks/stories.ts
@@ -78,6 +78,7 @@ export type SelectedStoryDataType = {
   messageId: string;
   numStories: number;
   shouldShowDetailsModal: boolean;
+  storyViewMode: StoryViewModeType;
 };
 
 // State
@@ -94,7 +95,6 @@ export type StoriesStateType = {
     verifiedUuids: Array<string>;
   };
   readonly stories: Array<StoryDataType>;
-  readonly storyViewMode?: StoryViewModeType;
 };
 
 // Actions
@@ -172,12 +172,7 @@ type ToggleViewActionType = {
 
 type ViewStoryActionType = {
   type: typeof VIEW_STORY;
-  payload:
-    | {
-        selectedStoryData: SelectedStoryDataType;
-        storyViewMode: StoryViewModeType;
-      }
-    | undefined;
+  payload: SelectedStoryDataType | undefined;
 };
 
 export type StoriesActionType =
@@ -787,10 +782,17 @@ const getSelectedStoryDataForConversationId = (
   };
 };
 
-function viewUserStories(
-  conversationId: string,
-  shouldShowDetailsModal = false
-): ThunkAction<void, RootStateType, unknown, ViewStoryActionType> {
+export type ViewUserStoriesActionCreatorType = (opts: {
+  conversationId: string;
+  shouldShowDetailsModal?: boolean;
+  storyViewMode?: StoryViewModeType;
+}) => unknown;
+
+const viewUserStories: ViewUserStoriesActionCreatorType = ({
+  conversationId,
+  shouldShowDetailsModal = false,
+  storyViewMode,
+}): ThunkAction<void, RootStateType, unknown, ViewStoryActionType> => {
   return (dispatch, getState) => {
     const { currentIndex, hasUnread, numStories, storiesByConversationId } =
       getSelectedStoryDataForConversationId(dispatch, getState, conversationId);
@@ -800,37 +802,36 @@ function viewUserStories(
     dispatch({
       type: VIEW_STORY,
       payload: {
-        selectedStoryData: {
-          currentIndex,
-          messageId: story.messageId,
-          numStories,
-          shouldShowDetailsModal,
-        },
-        storyViewMode: hasUnread
-          ? StoryViewModeType.Unread
-          : StoryViewModeType.All,
+        currentIndex,
+        messageId: story.messageId,
+        numStories,
+        shouldShowDetailsModal,
+        storyViewMode:
+          storyViewMode ||
+          (hasUnread ? StoryViewModeType.Unread : StoryViewModeType.All),
       },
     });
   };
-}
+};
 
-export type ViewStoryActionCreatorType = (opts: {
-  closeViewer?: boolean;
-  storyId?: string;
-  storyViewMode?: StoryViewModeType;
-  viewDirection?: StoryViewDirectionType;
-  shouldShowDetailsModal?: boolean;
-}) => unknown;
+export type ViewStoryActionCreatorType = (
+  opts:
+    | {
+        closeViewer: true;
+      }
+    | {
+        storyId: string;
+        storyViewMode: StoryViewModeType;
+        viewDirection?: StoryViewDirectionType;
+        shouldShowDetailsModal?: boolean;
+      }
+) => unknown;
 
-const viewStory: ViewStoryActionCreatorType = ({
-  closeViewer,
-  shouldShowDetailsModal = false,
-  storyId,
-  storyViewMode,
-  viewDirection,
-}): ThunkAction<void, RootStateType, unknown, ViewStoryActionType> => {
+const viewStory: ViewStoryActionCreatorType = (
+  opts
+): ThunkAction<void, RootStateType, unknown, ViewStoryActionType> => {
   return (dispatch, getState) => {
-    if (closeViewer || !storyId || !storyViewMode) {
+    if ('closeViewer' in opts) {
       dispatch({
         type: VIEW_STORY,
         payload: undefined,
@@ -838,6 +839,13 @@ const viewStory: ViewStoryActionCreatorType = ({
       return;
     }
 
+    const {
+      shouldShowDetailsModal = false,
+      storyId,
+      storyViewMode,
+      viewDirection,
+    } = opts;
+
     const state = getState();
     const { stories } = state.stories;
 
@@ -852,6 +860,11 @@ const viewStory: ViewStoryActionCreatorType = ({
     );
 
     if (!story) {
+      log.warn('stories.viewStory: No story found', storyId);
+      dispatch({
+        type: VIEW_STORY,
+        payload: undefined,
+      });
       return;
     }
 
@@ -868,12 +881,10 @@ const viewStory: ViewStoryActionCreatorType = ({
       dispatch({
         type: VIEW_STORY,
         payload: {
-          selectedStoryData: {
-            currentIndex,
-            messageId: storyId,
-            numStories,
-            shouldShowDetailsModal,
-          },
+          currentIndex,
+          messageId: storyId,
+          numStories,
+          shouldShowDetailsModal,
           storyViewMode,
         },
       });
@@ -891,12 +902,10 @@ const viewStory: ViewStoryActionCreatorType = ({
       dispatch({
         type: VIEW_STORY,
         payload: {
-          selectedStoryData: {
-            currentIndex: nextIndex,
-            messageId: nextStory.messageId,
-            numStories,
-            shouldShowDetailsModal: false,
-          },
+          currentIndex: nextIndex,
+          messageId: nextStory.messageId,
+          numStories,
+          shouldShowDetailsModal: false,
           storyViewMode,
         },
       });
@@ -911,18 +920,25 @@ const viewStory: ViewStoryActionCreatorType = ({
       dispatch({
         type: VIEW_STORY,
         payload: {
-          selectedStoryData: {
-            currentIndex: nextIndex,
-            messageId: nextStory.messageId,
-            numStories,
-            shouldShowDetailsModal: false,
-          },
+          currentIndex: nextIndex,
+          messageId: nextStory.messageId,
+          numStories,
+          shouldShowDetailsModal: false,
           storyViewMode,
         },
       });
       return;
     }
 
+    // We were just viewing a single user's stories. Close the viewer.
+    if (storyViewMode === StoryViewModeType.User) {
+      dispatch({
+        type: VIEW_STORY,
+        payload: undefined,
+      });
+      return;
+    }
+
     // Are there any unviewed stories left? If so we should play the unviewed
     // stories first. But only if we're going "next"
     if (viewDirection === StoryViewDirectionType.Next) {
@@ -940,12 +956,10 @@ const viewStory: ViewStoryActionCreatorType = ({
         dispatch({
           type: VIEW_STORY,
           payload: {
-            selectedStoryData: {
-              currentIndex: nextSelectedStoryData.currentIndex,
-              messageId: unreadStory.messageId,
-              numStories: nextSelectedStoryData.numStories,
-              shouldShowDetailsModal: false,
-            },
+            currentIndex: nextSelectedStoryData.currentIndex,
+            messageId: unreadStory.messageId,
+            numStories: nextSelectedStoryData.numStories,
+            shouldShowDetailsModal: false,
             storyViewMode,
           },
         });
@@ -959,6 +973,13 @@ const viewStory: ViewStoryActionCreatorType = ({
     );
 
     if (conversationStoryIndex < 0) {
+      log.warn('stories.viewStory: No stories found for conversation', {
+        storiesLength: conversationStories.length,
+      });
+      dispatch({
+        type: VIEW_STORY,
+        payload: undefined,
+      });
       return;
     }
 
@@ -1001,13 +1022,10 @@ const viewStory: ViewStoryActionCreatorType = ({
       dispatch({
         type: VIEW_STORY,
         payload: {
-          selectedStoryData: {
-            currentIndex: 0,
-            messageId:
-              nextSelectedStoryData.storiesByConversationId[0].messageId,
-            numStories: nextSelectedStoryData.numStories,
-            shouldShowDetailsModal: false,
-          },
+          currentIndex: 0,
+          messageId: nextSelectedStoryData.storiesByConversationId[0].messageId,
+          numStories: nextSelectedStoryData.numStories,
+          shouldShowDetailsModal: false,
           storyViewMode,
         },
       });
@@ -1039,13 +1057,10 @@ const viewStory: ViewStoryActionCreatorType = ({
       dispatch({
         type: VIEW_STORY,
         payload: {
-          selectedStoryData: {
-            currentIndex: 0,
-            messageId:
-              nextSelectedStoryData.storiesByConversationId[0].messageId,
-            numStories: nextSelectedStoryData.numStories,
-            shouldShowDetailsModal: false,
-          },
+          currentIndex: 0,
+          messageId: nextSelectedStoryData.storiesByConversationId[0].messageId,
+          numStories: nextSelectedStoryData.numStories,
+          shouldShowDetailsModal: false,
           storyViewMode,
         },
       });
@@ -1105,7 +1120,6 @@ export function reducer(
       selectedStoryData: isShowingStoriesView
         ? undefined
         : state.selectedStoryData,
-      storyViewMode: isShowingStoriesView ? undefined : state.storyViewMode,
     };
   }
 
@@ -1341,12 +1355,9 @@ export function reducer(
   }
 
   if (action.type === VIEW_STORY) {
-    const { selectedStoryData, storyViewMode } = action.payload || {};
-
     return {
       ...state,
-      selectedStoryData,
-      storyViewMode,
+      selectedStoryData: action.payload,
     };
   }
 
diff --git a/ts/state/selectors/stories.ts b/ts/state/selectors/stories.ts
index 1ca862fcc7..35125b7529 100644
--- a/ts/state/selectors/stories.ts
+++ b/ts/state/selectors/stories.ts
@@ -263,25 +263,15 @@ export const getStories = createSelector(
   getConversationSelector,
   getDistributionListSelector,
   getStoriesState,
-  shouldShowStoriesView,
   (
     conversationSelector,
     distributionListSelector,
-    { stories }: Readonly<StoriesStateType>,
-    isShowingStoriesView
+    { stories }: Readonly<StoriesStateType>
   ): {
     hiddenStories: Array<ConversationStoryType>;
     myStories: Array<MyStoryType>;
     stories: Array<ConversationStoryType>;
   } => {
-    if (!isShowingStoriesView) {
-      return {
-        hiddenStories: [],
-        myStories: [],
-        stories: [],
-      };
-    }
-
     const hiddenStoriesById = new Map<string, ConversationStoryType>();
     const myStoriesById = new Map<string, MyStoryType>();
     const storiesById = new Map<string, ConversationStoryType>();
diff --git a/ts/state/smart/StoryViewer.tsx b/ts/state/smart/StoryViewer.tsx
index 6fa5e014e5..015f1c9b24 100644
--- a/ts/state/smart/StoryViewer.tsx
+++ b/ts/state/smart/StoryViewer.tsx
@@ -6,7 +6,6 @@ import { useSelector } from 'react-redux';
 
 import type { GetConversationByIdType } from '../selectors/conversations';
 import type { LocalizerType } from '../../types/Util';
-import type { StoryViewModeType } from '../../types/Stories';
 import type { StateType } from '../reducer';
 import type { SelectedStoryDataType } from '../ducks/stories';
 import { StoryViewer } from '../../components/StoryViewer';
@@ -69,10 +68,6 @@ export function SmartStoryViewer(): JSX.Element | null {
   );
   const { conversationStory, storyView } = storyInfo;
 
-  const storyViewMode = useSelector<StateType, StoryViewModeType | undefined>(
-    state => state.stories.storyViewMode
-  );
-
   const recentEmojis = useRecentEmojis();
   const skinTone = useSelector<StateType, number>(getEmojiSkinTone);
   const replyState = useSelector(getStoryReplies);
@@ -120,7 +115,7 @@ export function SmartStoryViewer(): JSX.Element | null {
       showToast={showToast}
       skinTone={skinTone}
       story={storyView}
-      storyViewMode={storyViewMode}
+      storyViewMode={selectedStoryData.storyViewMode}
       toggleHasAllStoriesMuted={toggleHasAllStoriesMuted}
       {...storiesActions}
     />
diff --git a/ts/types/Stories.ts b/ts/types/Stories.ts
index 8dfc285272..21f4269ae8 100644
--- a/ts/types/Stories.ts
+++ b/ts/types/Stories.ts
@@ -104,10 +104,16 @@ export enum StoryViewDirectionType {
   Previous = 'Previous',
 }
 
+// Type of stories to view before closing the viewer
+// All = All the stories in order
+// Single = A single story. Like when clicking on a qouted story
+// Unread = View only unread stories
+// User = All of a user's stories
 export enum StoryViewModeType {
-  Unread = 'Unread',
   All = 'All',
   Single = 'Single',
+  Unread = 'Unread',
+  User = 'User',
 }
 
 export type StoryDistributionListWithMembersDataType = Omit<