View next unread story improvements
This commit is contained in:
parent
9d3498d938
commit
84411fee38
5 changed files with 36 additions and 4 deletions
|
@ -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];
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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(() => {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue