diff --git a/ts/components/Stories.tsx b/ts/components/Stories.tsx index 25a7a784e6..4b87c6d7f2 100644 --- a/ts/components/Stories.tsx +++ b/ts/components/Stories.tsx @@ -43,9 +43,23 @@ export const Stories = ({ }); const onNextUserStories = useCallback(() => { + // First find the next unread story if there are any + const nextUnreadIndex = stories.findIndex(conversationStory => + conversationStory.stories.some(story => story.isUnread) + ); + + if (nextUnreadIndex >= 0) { + const nextStory = stories[nextUnreadIndex]; + setConversationIdToView(nextStory.conversationId); + return; + } + + // If not then play the next available story const storyIndex = stories.findIndex( x => x.conversationId === conversationIdToView ); + + // If we've reached the end, close the viewer if (storyIndex >= stories.length - 1 || storyIndex === -1) { setConversationIdToView(undefined); return; @@ -59,7 +73,8 @@ export const Stories = ({ x => x.conversationId === conversationIdToView ); if (storyIndex <= 0) { - setConversationIdToView(undefined); + // Restart playback on the story if it's the oldest + setConversationIdToView(conversationIdToView); return; } const prevStory = stories[storyIndex - 1]; diff --git a/ts/components/StoryViewer.stories.tsx b/ts/components/StoryViewer.stories.tsx index ec30ba46df..9da966249d 100644 --- a/ts/components/StoryViewer.stories.tsx +++ b/ts/components/StoryViewer.stories.tsx @@ -37,6 +37,7 @@ function getDefaultProps(): PropsType { preferredReactionEmoji: ['❤️', '👍', '👎', '😂', '😮', '😢'], queueStoryDownload: action('queueStoryDownload'), renderEmojiPicker: () =>
, + selectedStoryIndex: 0, stories: [ { attachment: fakeAttachment({ @@ -106,11 +107,12 @@ story.add('Multi story', () => { ); }); -story.add('So many stories', () => { +story.add('So many stories (start on story 4)', () => { const sender = getDefaultConversation(); return ( ; renderEmojiPicker: (props: RenderEmojiPickerProps) => JSX.Element; replyState?: ReplyStateType; + selectedStoryIndex: number; skinTone?: number; stories: Array; views?: Array; @@ -87,11 +88,13 @@ export const StoryViewer = ({ recentEmojis, renderEmojiPicker, replyState, + selectedStoryIndex, skinTone, stories, views, }: PropsType): JSX.Element => { - const [currentStoryIndex, setCurrentStoryIndex] = useState(0); + const [currentStoryIndex, setCurrentStoryIndex] = + useState(selectedStoryIndex); const [storyDuration, setStoryDuration] = useState(); const visibleStory = stories[currentStoryIndex]; @@ -140,6 +143,13 @@ export const StoryViewer = ({ setHasExpandedCaption(false); }, [messageId]); + // In case we want to change the story we're viewing from 0 -> N + useEffect(() => { + if (selectedStoryIndex) { + setCurrentStoryIndex(selectedStoryIndex); + } + }, [selectedStoryIndex]); + // Either we show the next story in the current user's stories or we ask // for the next user's stories. const showNextStory = useCallback(() => { diff --git a/ts/models/messages.ts b/ts/models/messages.ts index ddd13c0efe..a01a31372c 100644 --- a/ts/models/messages.ts +++ b/ts/models/messages.ts @@ -2437,9 +2437,10 @@ export class MessageModel extends window.Backbone.Model { if (isStory(message.attributes)) { attributes.hasPostedStory = true; + } else { + attributes.active_at = now; } - attributes.active_at = now; conversation.set(attributes); if ( @@ -2542,6 +2543,7 @@ export class MessageModel extends window.Backbone.Model { const isGroupStoryReply = isGroup(conversation.attributes) && message.get('storyId'); if ( + !isStory(message.attributes) && !isGroupStoryReply && (!conversationTimestamp || message.get('sent_at') > conversationTimestamp) diff --git a/ts/state/smart/StoryViewer.tsx b/ts/state/smart/StoryViewer.tsx index 06afed896a..3ebdaae781 100644 --- a/ts/state/smart/StoryViewer.tsx +++ b/ts/state/smart/StoryViewer.tsx @@ -52,6 +52,8 @@ export function SmartStoryViewer({ >(getStoriesSelector); const { group, stories } = getStoriesByConversationId(conversationId); + const unreadStoryIndex = stories.findIndex(story => story.isUnread); + const selectedStoryIndex = unreadStoryIndex > 0 ? unreadStoryIndex : 0; const recentEmojis = useRecentEmojis(); const skinTone = useSelector(getEmojiSkinTone); @@ -86,6 +88,7 @@ export function SmartStoryViewer({ recentEmojis={recentEmojis} renderEmojiPicker={renderEmojiPicker} replyState={replyState} + selectedStoryIndex={selectedStoryIndex} stories={stories} skinTone={skinTone} {...storiesActions}