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

@ -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,
};
}

View file

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

View file

@ -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}
/>