View next unread story improvements

This commit is contained in:
Josh Perez 2022-04-28 14:59:09 -04:00 committed by GitHub
parent 9d3498d938
commit 84411fee38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 4 deletions

View file

@ -43,9 +43,23 @@ export const Stories = ({
}); });
const onNextUserStories = useCallback(() => { 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( const storyIndex = stories.findIndex(
x => x.conversationId === conversationIdToView x => x.conversationId === conversationIdToView
); );
// If we've reached the end, close the viewer
if (storyIndex >= stories.length - 1 || storyIndex === -1) { if (storyIndex >= stories.length - 1 || storyIndex === -1) {
setConversationIdToView(undefined); setConversationIdToView(undefined);
return; return;
@ -59,7 +73,8 @@ export const Stories = ({
x => x.conversationId === conversationIdToView x => x.conversationId === conversationIdToView
); );
if (storyIndex <= 0) { if (storyIndex <= 0) {
setConversationIdToView(undefined); // Restart playback on the story if it's the oldest
setConversationIdToView(conversationIdToView);
return; return;
} }
const prevStory = stories[storyIndex - 1]; const prevStory = stories[storyIndex - 1];

View file

@ -37,6 +37,7 @@ function getDefaultProps(): PropsType {
preferredReactionEmoji: ['❤️', '👍', '👎', '😂', '😮', '😢'], preferredReactionEmoji: ['❤️', '👍', '👎', '😂', '😮', '😢'],
queueStoryDownload: action('queueStoryDownload'), queueStoryDownload: action('queueStoryDownload'),
renderEmojiPicker: () => <div />, renderEmojiPicker: () => <div />,
selectedStoryIndex: 0,
stories: [ stories: [
{ {
attachment: fakeAttachment({ 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(); const sender = getDefaultConversation();
return ( return (
<StoryViewer <StoryViewer
{...getDefaultProps()} {...getDefaultProps()}
selectedStoryIndex={5}
stories={Array(20).fill({ stories={Array(20).fill({
attachment: fakeAttachment({ attachment: fakeAttachment({
url: '/fixtures/snow.jpg', url: '/fixtures/snow.jpg',

View file

@ -58,6 +58,7 @@ export type PropsType = {
recentEmojis?: Array<string>; recentEmojis?: Array<string>;
renderEmojiPicker: (props: RenderEmojiPickerProps) => JSX.Element; renderEmojiPicker: (props: RenderEmojiPickerProps) => JSX.Element;
replyState?: ReplyStateType; replyState?: ReplyStateType;
selectedStoryIndex: number;
skinTone?: number; skinTone?: number;
stories: Array<StoryViewType>; stories: Array<StoryViewType>;
views?: Array<string>; views?: Array<string>;
@ -87,11 +88,13 @@ export const StoryViewer = ({
recentEmojis, recentEmojis,
renderEmojiPicker, renderEmojiPicker,
replyState, replyState,
selectedStoryIndex,
skinTone, skinTone,
stories, stories,
views, views,
}: PropsType): JSX.Element => { }: PropsType): JSX.Element => {
const [currentStoryIndex, setCurrentStoryIndex] = useState(0); const [currentStoryIndex, setCurrentStoryIndex] =
useState(selectedStoryIndex);
const [storyDuration, setStoryDuration] = useState<number | undefined>(); const [storyDuration, setStoryDuration] = useState<number | undefined>();
const visibleStory = stories[currentStoryIndex]; const visibleStory = stories[currentStoryIndex];
@ -140,6 +143,13 @@ export const StoryViewer = ({
setHasExpandedCaption(false); setHasExpandedCaption(false);
}, [messageId]); }, [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 // Either we show the next story in the current user's stories or we ask
// for the next user's stories. // for the next user's stories.
const showNextStory = useCallback(() => { const showNextStory = useCallback(() => {

View file

@ -2437,9 +2437,10 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
if (isStory(message.attributes)) { if (isStory(message.attributes)) {
attributes.hasPostedStory = true; attributes.hasPostedStory = true;
} else {
attributes.active_at = now;
} }
attributes.active_at = now;
conversation.set(attributes); conversation.set(attributes);
if ( if (
@ -2542,6 +2543,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
const isGroupStoryReply = const isGroupStoryReply =
isGroup(conversation.attributes) && message.get('storyId'); isGroup(conversation.attributes) && message.get('storyId');
if ( if (
!isStory(message.attributes) &&
!isGroupStoryReply && !isGroupStoryReply &&
(!conversationTimestamp || (!conversationTimestamp ||
message.get('sent_at') > conversationTimestamp) message.get('sent_at') > conversationTimestamp)

View file

@ -52,6 +52,8 @@ export function SmartStoryViewer({
>(getStoriesSelector); >(getStoriesSelector);
const { group, stories } = getStoriesByConversationId(conversationId); const { group, stories } = getStoriesByConversationId(conversationId);
const unreadStoryIndex = stories.findIndex(story => story.isUnread);
const selectedStoryIndex = unreadStoryIndex > 0 ? unreadStoryIndex : 0;
const recentEmojis = useRecentEmojis(); const recentEmojis = useRecentEmojis();
const skinTone = useSelector<StateType, number>(getEmojiSkinTone); const skinTone = useSelector<StateType, number>(getEmojiSkinTone);
@ -86,6 +88,7 @@ export function SmartStoryViewer({
recentEmojis={recentEmojis} recentEmojis={recentEmojis}
renderEmojiPicker={renderEmojiPicker} renderEmojiPicker={renderEmojiPicker}
replyState={replyState} replyState={replyState}
selectedStoryIndex={selectedStoryIndex}
stories={stories} stories={stories}
skinTone={skinTone} skinTone={skinTone}
{...storiesActions} {...storiesActions}