Allow paging through My Stories

This commit is contained in:
Josh Perez 2022-08-22 13:44:23 -04:00 committed by GitHub
parent 70bdbe33d5
commit 6f7094bc19
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 166 additions and 122 deletions

View file

@ -85,7 +85,7 @@ export const MyStories = ({
onClick={() => onClick={() =>
viewStory({ viewStory({
storyId: story.messageId, storyId: story.messageId,
storyViewMode: StoryViewModeType.Single, storyViewMode: StoryViewModeType.User,
}) })
} }
type="button" type="button"
@ -148,7 +148,7 @@ export const MyStories = ({
onClick: () => { onClick: () => {
viewStory({ viewStory({
storyId: story.messageId, storyId: story.messageId,
storyViewMode: StoryViewModeType.Single, storyViewMode: StoryViewModeType.User,
shouldShowDetailsModal: true, shouldShowDetailsModal: true,
}); });
}, },

View file

@ -16,7 +16,10 @@ import type { LocalizerType } from '../types/Util';
import type { PreferredBadgeSelectorType } from '../state/selectors/badges'; import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
import type { PropsType as SmartStoryCreatorPropsType } from '../state/smart/StoryCreator'; import type { PropsType as SmartStoryCreatorPropsType } from '../state/smart/StoryCreator';
import type { ShowToastActionCreatorType } from '../state/ducks/toast'; 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 { MyStories } from './MyStories';
import { StoriesPane } from './StoriesPane'; import { StoriesPane } from './StoriesPane';
import { Theme, themeClassName } from '../util/theme'; import { Theme, themeClassName } from '../util/theme';
@ -40,7 +43,7 @@ export type PropsType = {
stories: Array<ConversationStoryType>; stories: Array<ConversationStoryType>;
toggleHideStories: (conversationId: string) => unknown; toggleHideStories: (conversationId: string) => unknown;
toggleStoriesView: () => unknown; toggleStoriesView: () => unknown;
viewUserStories: (conversationId: string) => unknown; viewUserStories: ViewUserStoriesActionCreatorType;
viewStory: ViewStoryActionCreatorType; viewStory: ViewStoryActionCreatorType;
}; };

View file

@ -17,6 +17,7 @@ import type {
import type { LocalizerType } from '../types/Util'; import type { LocalizerType } from '../types/Util';
import type { PreferredBadgeSelectorType } from '../state/selectors/badges'; import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
import type { ShowToastActionCreatorType } from '../state/ducks/toast'; import type { ShowToastActionCreatorType } from '../state/ducks/toast';
import type { ViewUserStoriesActionCreatorType } from '../state/ducks/stories';
import { ContextMenu } from './ContextMenu'; import { ContextMenu } from './ContextMenu';
import { MyStoriesButton } from './MyStoriesButton'; import { MyStoriesButton } from './MyStoriesButton';
import { SearchInput } from './SearchInput'; import { SearchInput } from './SearchInput';
@ -76,7 +77,7 @@ export type PropsType = {
stories: Array<ConversationStoryType>; stories: Array<ConversationStoryType>;
toggleHideStories: (conversationId: string) => unknown; toggleHideStories: (conversationId: string) => unknown;
toggleStoriesView: () => unknown; toggleStoriesView: () => unknown;
viewUserStories: (conversationId: string) => unknown; viewUserStories: ViewUserStoriesActionCreatorType;
}; };
export const StoriesPane = ({ export const StoriesPane = ({

View file

@ -7,6 +7,7 @@ import type { ConversationType } from '../state/ducks/conversations';
import type { ConversationStoryType, StoryViewType } from '../types/Stories'; import type { ConversationStoryType, StoryViewType } from '../types/Stories';
import type { LocalizerType } from '../types/Util'; import type { LocalizerType } from '../types/Util';
import type { PreferredBadgeSelectorType } from '../state/selectors/badges'; import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
import type { ViewUserStoriesActionCreatorType } from '../state/ducks/stories';
import { Avatar, AvatarSize } from './Avatar'; import { Avatar, AvatarSize } from './Avatar';
import { ConfirmationDialog } from './ConfirmationDialog'; import { ConfirmationDialog } from './ConfirmationDialog';
import { ContextMenu } from './ContextMenu'; import { ContextMenu } from './ContextMenu';
@ -24,10 +25,7 @@ export type PropsType = Pick<ConversationStoryType, 'group' | 'isHidden'> & {
onHideStory: (conversationId: string) => unknown; onHideStory: (conversationId: string) => unknown;
queueStoryDownload: (storyId: string) => unknown; queueStoryDownload: (storyId: string) => unknown;
story: StoryViewType; story: StoryViewType;
viewUserStories: ( viewUserStories: ViewUserStoriesActionCreatorType;
conversationId: string,
shouldShowDetailsModal?: boolean
) => unknown;
}; };
function StoryListItemAvatar({ function StoryListItemAvatar({
@ -138,7 +136,8 @@ export const StoryListItem = ({
{ {
icon: 'StoryListItem__icon--info', icon: 'StoryListItem__icon--info',
label: i18n('StoryListItem__info'), label: i18n('StoryListItem__info'),
onClick: () => viewUserStories(conversationId, true), onClick: () =>
viewUserStories({ conversationId, shouldShowDetailsModal: true }),
}, },
{ {
icon: 'StoryListItem__icon--chat', icon: 'StoryListItem__icon--chat',
@ -149,7 +148,7 @@ export const StoryListItem = ({
moduleClassName={classNames('StoryListItem', { moduleClassName={classNames('StoryListItem', {
'StoryListItem--hidden': isHidden, 'StoryListItem--hidden': isHidden,
})} })}
onClick={() => viewUserStories(conversationId)} onClick={() => viewUserStories({ conversationId })}
popperOptions={{ popperOptions={{
placement: 'bottom', placement: 'bottom',
strategy: 'absolute', strategy: 'absolute',

View file

@ -7,6 +7,7 @@ import React from 'react';
import type { PropsType } from './StoryViewer'; import type { PropsType } from './StoryViewer';
import enMessages from '../../_locales/en/messages.json'; import enMessages from '../../_locales/en/messages.json';
import { SendStatus } from '../messages/MessageSendState'; import { SendStatus } from '../messages/MessageSendState';
import { StoryViewModeType } from '../types/Stories';
import { StoryViewer } from './StoryViewer'; import { StoryViewer } from './StoryViewer';
import { VIDEO_MP4 } from '../types/MIME'; import { VIDEO_MP4 } from '../types/MIME';
import { fakeAttachment } from '../test-both/helpers/fakeAttachment'; import { fakeAttachment } from '../test-both/helpers/fakeAttachment';
@ -57,6 +58,9 @@ export default {
story: { story: {
defaultValue: getFakeStoryView(), defaultValue: getFakeStoryView(),
}, },
storyViewMode: {
defaultValue: StoryViewModeType.All,
},
toggleHasAllStoriesMuted: { action: true }, toggleHasAllStoriesMuted: { action: true },
viewStory: { action: true }, viewStory: { action: true },
}, },

View file

@ -83,7 +83,7 @@ export type PropsType = {
showToast: ShowToastActionCreatorType; showToast: ShowToastActionCreatorType;
skinTone?: number; skinTone?: number;
story: StoryViewType; story: StoryViewType;
storyViewMode?: StoryViewModeType; storyViewMode: StoryViewModeType;
toggleHasAllStoriesMuted: () => unknown; toggleHasAllStoriesMuted: () => unknown;
viewStory: ViewStoryActionCreatorType; viewStory: ViewStoryActionCreatorType;
}; };
@ -303,9 +303,22 @@ export const StoryViewer = ({
log.info('stories.markStoryRead', { messageId }); log.info('stories.markStoryRead', { messageId });
}, [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( const navigateStories = useCallback(
(ev: KeyboardEvent) => { (ev: KeyboardEvent) => {
if (ev.key === 'ArrowRight') { if (canNavigateRight && ev.key === 'ArrowRight') {
viewStory({ viewStory({
storyId: story.messageId, storyId: story.messageId,
storyViewMode, storyViewMode,
@ -313,7 +326,7 @@ export const StoryViewer = ({
}); });
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
} else if (ev.key === 'ArrowLeft') { } else if (canNavigateLeft && ev.key === 'ArrowLeft') {
viewStory({ viewStory({
storyId: story.messageId, storyId: story.messageId,
storyViewMode, storyViewMode,
@ -323,7 +336,13 @@ export const StoryViewer = ({
ev.stopPropagation(); ev.stopPropagation();
} }
}, },
[story.messageId, storyViewMode, viewStory] [
canNavigateLeft,
canNavigateRight,
story.messageId,
storyViewMode,
viewStory,
]
); );
useEffect(() => { useEffect(() => {
@ -383,8 +402,6 @@ export const StoryViewer = ({
const replyCount = replies.length; const replyCount = replies.length;
const viewCount = views.length; const viewCount = views.length;
const hasPrevNextArrows = storyViewMode !== StoryViewModeType.Single;
const canMuteStory = isVideoAttachment(attachment); const canMuteStory = isVideoAttachment(attachment);
const isStoryMuted = hasAllStoriesMuted || !canMuteStory; const isStoryMuted = hasAllStoriesMuted || !canMuteStory;
@ -453,7 +470,7 @@ export const StoryViewer = ({
style={{ background: getStoryBackground(attachment) }} style={{ background: getStoryBackground(attachment) }}
/> />
<div className="StoryViewer__content"> <div className="StoryViewer__content">
{hasPrevNextArrows && ( {canNavigateLeft && (
<button <button
aria-label={i18n('back')} aria-label={i18n('back')}
className={classNames( className={classNames(
@ -685,7 +702,7 @@ export const StoryViewer = ({
)} )}
</div> </div>
</div> </div>
{hasPrevNextArrows && ( {canNavigateRight && (
<button <button
aria-label={i18n('forward')} aria-label={i18n('forward')}
className={classNames( className={classNames(

View file

@ -11,6 +11,8 @@ import type {
import type { BadgeType } from '../../badges/types'; import type { BadgeType } from '../../badges/types';
import type { HasStories } from '../../types/Stories'; import type { HasStories } from '../../types/Stories';
import type { LocalizerType, ThemeType } from '../../types/Util'; 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 * as log from '../../logging/log';
import { About } from './About'; import { About } from './About';
import { Avatar } from '../Avatar'; import { Avatar } from '../Avatar';
@ -42,7 +44,7 @@ type PropsActionType = {
toggleAdmin: (conversationId: string, contactId: string) => void; toggleAdmin: (conversationId: string, contactId: string) => void;
toggleSafetyNumberModal: (conversationId: string) => unknown; toggleSafetyNumberModal: (conversationId: string) => unknown;
updateConversationModelSharedGroups: (conversationId: string) => void; updateConversationModelSharedGroups: (conversationId: string) => void;
viewUserStories: (cid: string) => unknown; viewUserStories: ViewUserStoriesActionCreatorType;
}; };
export type PropsType = PropsDataType & PropsActionType; export type PropsType = PropsDataType & PropsActionType;
@ -179,7 +181,10 @@ export const ContactModal = ({
name={contact.name} name={contact.name}
onClick={() => { onClick={() => {
if (conversation && hasStories) { if (conversation && hasStories) {
viewUserStories(conversation.id); viewUserStories({
conversationId: conversation.id,
storyViewMode: StoryViewModeType.User,
});
} else { } else {
setView(ContactModalView.ShowingAvatar); setView(ContactModalView.ShowingAvatar);
} }

View file

@ -21,6 +21,8 @@ import type { LocalizerType, ThemeType } from '../../types/Util';
import type { ConversationType } from '../../state/ducks/conversations'; import type { ConversationType } from '../../state/ducks/conversations';
import type { BadgeType } from '../../badges/types'; import type { BadgeType } from '../../badges/types';
import type { HasStories } from '../../types/Stories'; import type { HasStories } from '../../types/Stories';
import type { ViewUserStoriesActionCreatorType } from '../../state/ducks/stories';
import { StoryViewModeType } from '../../types/Stories';
import { getMuteOptions } from '../../util/getMuteOptions'; import { getMuteOptions } from '../../util/getMuteOptions';
import * as expirationTimer from '../../util/expirationTimer'; import * as expirationTimer from '../../util/expirationTimer';
import { missingCaseError } from '../../util/missingCaseError'; import { missingCaseError } from '../../util/missingCaseError';
@ -90,7 +92,7 @@ export type PropsActionsType = {
onArchive: () => void; onArchive: () => void;
onMarkUnread: () => void; onMarkUnread: () => void;
onMoveToInbox: () => void; onMoveToInbox: () => void;
viewUserStories: (cid: string) => unknown; viewUserStories: ViewUserStoriesActionCreatorType;
}; };
export type PropsHousekeepingType = { export type PropsHousekeepingType = {
@ -232,7 +234,10 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
onClick={ onClick={
hasStories hasStories
? () => { ? () => {
viewUserStories(id); viewUserStories({
conversationId: id,
storyViewMode: StoryViewModeType.User,
});
} }
: undefined : undefined
} }

View file

@ -10,6 +10,8 @@ import { GroupDescription } from './GroupDescription';
import { SharedGroupNames } from '../SharedGroupNames'; import { SharedGroupNames } from '../SharedGroupNames';
import type { LocalizerType, ThemeType } from '../../types/Util'; import type { LocalizerType, ThemeType } from '../../types/Util';
import type { HasStories } from '../../types/Stories'; import type { HasStories } from '../../types/Stories';
import type { ViewUserStoriesActionCreatorType } from '../../state/ducks/stories';
import { StoryViewModeType } from '../../types/Stories';
import { ConfirmationDialog } from '../ConfirmationDialog'; import { ConfirmationDialog } from '../ConfirmationDialog';
import { Button, ButtonSize, ButtonVariant } from '../Button'; import { Button, ButtonSize, ButtonVariant } from '../Button';
import { shouldBlurAvatar } from '../../util/shouldBlurAvatar'; import { shouldBlurAvatar } from '../../util/shouldBlurAvatar';
@ -30,7 +32,7 @@ export type Props = {
unblurredAvatarPath?: string; unblurredAvatarPath?: string;
updateSharedGroups: () => unknown; updateSharedGroups: () => unknown;
theme: ThemeType; theme: ThemeType;
viewUserStories: (cid: string) => unknown; viewUserStories: ViewUserStoriesActionCreatorType;
} & Omit<AvatarProps, 'onClick' | 'size' | 'noteToSelf'>; } & Omit<AvatarProps, 'onClick' | 'size' | 'noteToSelf'>;
const renderMembershipRow = ({ const renderMembershipRow = ({
@ -146,7 +148,10 @@ export const ConversationHero = ({
avatarOnClick = unblurAvatar; avatarOnClick = unblurAvatar;
} else if (hasStories) { } else if (hasStories) {
avatarOnClick = () => { avatarOnClick = () => {
viewUserStories(id); viewUserStories({
conversationId: id,
storyViewMode: StoryViewModeType.User,
});
}; };
} }

View file

@ -1556,6 +1556,9 @@ export class Message extends React.PureComponent<Props, State> {
isViewOnce={false} isViewOnce={false}
moduleClassName="StoryReplyQuote" moduleClassName="StoryReplyQuote"
onClick={() => { onClick={() => {
if (!storyReplyContext.storyId) {
return;
}
viewStory({ viewStory({
storyId: storyReplyContext.storyId, storyId: storyReplyContext.storyId,
storyViewMode: StoryViewModeType.Single, storyViewMode: StoryViewModeType.Single,

View file

@ -78,6 +78,7 @@ export type SelectedStoryDataType = {
messageId: string; messageId: string;
numStories: number; numStories: number;
shouldShowDetailsModal: boolean; shouldShowDetailsModal: boolean;
storyViewMode: StoryViewModeType;
}; };
// State // State
@ -94,7 +95,6 @@ export type StoriesStateType = {
verifiedUuids: Array<string>; verifiedUuids: Array<string>;
}; };
readonly stories: Array<StoryDataType>; readonly stories: Array<StoryDataType>;
readonly storyViewMode?: StoryViewModeType;
}; };
// Actions // Actions
@ -172,12 +172,7 @@ type ToggleViewActionType = {
type ViewStoryActionType = { type ViewStoryActionType = {
type: typeof VIEW_STORY; type: typeof VIEW_STORY;
payload: payload: SelectedStoryDataType | undefined;
| {
selectedStoryData: SelectedStoryDataType;
storyViewMode: StoryViewModeType;
}
| undefined;
}; };
export type StoriesActionType = export type StoriesActionType =
@ -787,10 +782,17 @@ const getSelectedStoryDataForConversationId = (
}; };
}; };
function viewUserStories( export type ViewUserStoriesActionCreatorType = (opts: {
conversationId: string, conversationId: string;
shouldShowDetailsModal = false shouldShowDetailsModal?: boolean;
): ThunkAction<void, RootStateType, unknown, ViewStoryActionType> { storyViewMode?: StoryViewModeType;
}) => unknown;
const viewUserStories: ViewUserStoriesActionCreatorType = ({
conversationId,
shouldShowDetailsModal = false,
storyViewMode,
}): ThunkAction<void, RootStateType, unknown, ViewStoryActionType> => {
return (dispatch, getState) => { return (dispatch, getState) => {
const { currentIndex, hasUnread, numStories, storiesByConversationId } = const { currentIndex, hasUnread, numStories, storiesByConversationId } =
getSelectedStoryDataForConversationId(dispatch, getState, conversationId); getSelectedStoryDataForConversationId(dispatch, getState, conversationId);
@ -800,37 +802,36 @@ function viewUserStories(
dispatch({ dispatch({
type: VIEW_STORY, type: VIEW_STORY,
payload: { payload: {
selectedStoryData: {
currentIndex, currentIndex,
messageId: story.messageId, messageId: story.messageId,
numStories, numStories,
shouldShowDetailsModal, shouldShowDetailsModal,
}, storyViewMode:
storyViewMode: hasUnread storyViewMode ||
? StoryViewModeType.Unread (hasUnread ? StoryViewModeType.Unread : StoryViewModeType.All),
: StoryViewModeType.All,
}, },
}); });
}; };
} };
export type ViewStoryActionCreatorType = (opts: { export type ViewStoryActionCreatorType = (
closeViewer?: boolean; opts:
storyId?: string; | {
storyViewMode?: StoryViewModeType; closeViewer: true;
}
| {
storyId: string;
storyViewMode: StoryViewModeType;
viewDirection?: StoryViewDirectionType; viewDirection?: StoryViewDirectionType;
shouldShowDetailsModal?: boolean; shouldShowDetailsModal?: boolean;
}) => unknown; }
) => unknown;
const viewStory: ViewStoryActionCreatorType = ({ const viewStory: ViewStoryActionCreatorType = (
closeViewer, opts
shouldShowDetailsModal = false, ): ThunkAction<void, RootStateType, unknown, ViewStoryActionType> => {
storyId,
storyViewMode,
viewDirection,
}): ThunkAction<void, RootStateType, unknown, ViewStoryActionType> => {
return (dispatch, getState) => { return (dispatch, getState) => {
if (closeViewer || !storyId || !storyViewMode) { if ('closeViewer' in opts) {
dispatch({ dispatch({
type: VIEW_STORY, type: VIEW_STORY,
payload: undefined, payload: undefined,
@ -838,6 +839,13 @@ const viewStory: ViewStoryActionCreatorType = ({
return; return;
} }
const {
shouldShowDetailsModal = false,
storyId,
storyViewMode,
viewDirection,
} = opts;
const state = getState(); const state = getState();
const { stories } = state.stories; const { stories } = state.stories;
@ -852,6 +860,11 @@ const viewStory: ViewStoryActionCreatorType = ({
); );
if (!story) { if (!story) {
log.warn('stories.viewStory: No story found', storyId);
dispatch({
type: VIEW_STORY,
payload: undefined,
});
return; return;
} }
@ -868,12 +881,10 @@ const viewStory: ViewStoryActionCreatorType = ({
dispatch({ dispatch({
type: VIEW_STORY, type: VIEW_STORY,
payload: { payload: {
selectedStoryData: {
currentIndex, currentIndex,
messageId: storyId, messageId: storyId,
numStories, numStories,
shouldShowDetailsModal, shouldShowDetailsModal,
},
storyViewMode, storyViewMode,
}, },
}); });
@ -891,12 +902,10 @@ const viewStory: ViewStoryActionCreatorType = ({
dispatch({ dispatch({
type: VIEW_STORY, type: VIEW_STORY,
payload: { payload: {
selectedStoryData: {
currentIndex: nextIndex, currentIndex: nextIndex,
messageId: nextStory.messageId, messageId: nextStory.messageId,
numStories, numStories,
shouldShowDetailsModal: false, shouldShowDetailsModal: false,
},
storyViewMode, storyViewMode,
}, },
}); });
@ -911,18 +920,25 @@ const viewStory: ViewStoryActionCreatorType = ({
dispatch({ dispatch({
type: VIEW_STORY, type: VIEW_STORY,
payload: { payload: {
selectedStoryData: {
currentIndex: nextIndex, currentIndex: nextIndex,
messageId: nextStory.messageId, messageId: nextStory.messageId,
numStories, numStories,
shouldShowDetailsModal: false, shouldShowDetailsModal: false,
},
storyViewMode, storyViewMode,
}, },
}); });
return; 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 // Are there any unviewed stories left? If so we should play the unviewed
// stories first. But only if we're going "next" // stories first. But only if we're going "next"
if (viewDirection === StoryViewDirectionType.Next) { if (viewDirection === StoryViewDirectionType.Next) {
@ -940,12 +956,10 @@ const viewStory: ViewStoryActionCreatorType = ({
dispatch({ dispatch({
type: VIEW_STORY, type: VIEW_STORY,
payload: { payload: {
selectedStoryData: {
currentIndex: nextSelectedStoryData.currentIndex, currentIndex: nextSelectedStoryData.currentIndex,
messageId: unreadStory.messageId, messageId: unreadStory.messageId,
numStories: nextSelectedStoryData.numStories, numStories: nextSelectedStoryData.numStories,
shouldShowDetailsModal: false, shouldShowDetailsModal: false,
},
storyViewMode, storyViewMode,
}, },
}); });
@ -959,6 +973,13 @@ const viewStory: ViewStoryActionCreatorType = ({
); );
if (conversationStoryIndex < 0) { if (conversationStoryIndex < 0) {
log.warn('stories.viewStory: No stories found for conversation', {
storiesLength: conversationStories.length,
});
dispatch({
type: VIEW_STORY,
payload: undefined,
});
return; return;
} }
@ -1001,13 +1022,10 @@ const viewStory: ViewStoryActionCreatorType = ({
dispatch({ dispatch({
type: VIEW_STORY, type: VIEW_STORY,
payload: { payload: {
selectedStoryData: {
currentIndex: 0, currentIndex: 0,
messageId: messageId: nextSelectedStoryData.storiesByConversationId[0].messageId,
nextSelectedStoryData.storiesByConversationId[0].messageId,
numStories: nextSelectedStoryData.numStories, numStories: nextSelectedStoryData.numStories,
shouldShowDetailsModal: false, shouldShowDetailsModal: false,
},
storyViewMode, storyViewMode,
}, },
}); });
@ -1039,13 +1057,10 @@ const viewStory: ViewStoryActionCreatorType = ({
dispatch({ dispatch({
type: VIEW_STORY, type: VIEW_STORY,
payload: { payload: {
selectedStoryData: {
currentIndex: 0, currentIndex: 0,
messageId: messageId: nextSelectedStoryData.storiesByConversationId[0].messageId,
nextSelectedStoryData.storiesByConversationId[0].messageId,
numStories: nextSelectedStoryData.numStories, numStories: nextSelectedStoryData.numStories,
shouldShowDetailsModal: false, shouldShowDetailsModal: false,
},
storyViewMode, storyViewMode,
}, },
}); });
@ -1105,7 +1120,6 @@ export function reducer(
selectedStoryData: isShowingStoriesView selectedStoryData: isShowingStoriesView
? undefined ? undefined
: state.selectedStoryData, : state.selectedStoryData,
storyViewMode: isShowingStoriesView ? undefined : state.storyViewMode,
}; };
} }
@ -1341,12 +1355,9 @@ export function reducer(
} }
if (action.type === VIEW_STORY) { if (action.type === VIEW_STORY) {
const { selectedStoryData, storyViewMode } = action.payload || {};
return { return {
...state, ...state,
selectedStoryData, selectedStoryData: action.payload,
storyViewMode,
}; };
} }

View file

@ -263,25 +263,15 @@ export const getStories = createSelector(
getConversationSelector, getConversationSelector,
getDistributionListSelector, getDistributionListSelector,
getStoriesState, getStoriesState,
shouldShowStoriesView,
( (
conversationSelector, conversationSelector,
distributionListSelector, distributionListSelector,
{ stories }: Readonly<StoriesStateType>, { stories }: Readonly<StoriesStateType>
isShowingStoriesView
): { ): {
hiddenStories: Array<ConversationStoryType>; hiddenStories: Array<ConversationStoryType>;
myStories: Array<MyStoryType>; myStories: Array<MyStoryType>;
stories: Array<ConversationStoryType>; stories: Array<ConversationStoryType>;
} => { } => {
if (!isShowingStoriesView) {
return {
hiddenStories: [],
myStories: [],
stories: [],
};
}
const hiddenStoriesById = new Map<string, ConversationStoryType>(); const hiddenStoriesById = new Map<string, ConversationStoryType>();
const myStoriesById = new Map<string, MyStoryType>(); const myStoriesById = new Map<string, MyStoryType>();
const storiesById = new Map<string, ConversationStoryType>(); const storiesById = new Map<string, ConversationStoryType>();

View file

@ -6,7 +6,6 @@ import { useSelector } from 'react-redux';
import type { GetConversationByIdType } from '../selectors/conversations'; import type { GetConversationByIdType } from '../selectors/conversations';
import type { LocalizerType } from '../../types/Util'; import type { LocalizerType } from '../../types/Util';
import type { StoryViewModeType } from '../../types/Stories';
import type { StateType } from '../reducer'; import type { StateType } from '../reducer';
import type { SelectedStoryDataType } from '../ducks/stories'; import type { SelectedStoryDataType } from '../ducks/stories';
import { StoryViewer } from '../../components/StoryViewer'; import { StoryViewer } from '../../components/StoryViewer';
@ -69,10 +68,6 @@ export function SmartStoryViewer(): JSX.Element | null {
); );
const { conversationStory, storyView } = storyInfo; const { conversationStory, storyView } = storyInfo;
const storyViewMode = useSelector<StateType, StoryViewModeType | undefined>(
state => state.stories.storyViewMode
);
const recentEmojis = useRecentEmojis(); const recentEmojis = useRecentEmojis();
const skinTone = useSelector<StateType, number>(getEmojiSkinTone); const skinTone = useSelector<StateType, number>(getEmojiSkinTone);
const replyState = useSelector(getStoryReplies); const replyState = useSelector(getStoryReplies);
@ -120,7 +115,7 @@ export function SmartStoryViewer(): JSX.Element | null {
showToast={showToast} showToast={showToast}
skinTone={skinTone} skinTone={skinTone}
story={storyView} story={storyView}
storyViewMode={storyViewMode} storyViewMode={selectedStoryData.storyViewMode}
toggleHasAllStoriesMuted={toggleHasAllStoriesMuted} toggleHasAllStoriesMuted={toggleHasAllStoriesMuted}
{...storiesActions} {...storiesActions}
/> />

View file

@ -104,10 +104,16 @@ export enum StoryViewDirectionType {
Previous = 'Previous', 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 { export enum StoryViewModeType {
Unread = 'Unread',
All = 'All', All = 'All',
Single = 'Single', Single = 'Single',
Unread = 'Unread',
User = 'User',
} }
export type StoryDistributionListWithMembersDataType = Omit< export type StoryDistributionListWithMembersDataType = Omit<