Fixed bug that was causing story playback to not play all unread

Co-authored-by: Alvaro <110414366+alvaro-signal@users.noreply.github.com>
This commit is contained in:
automated-signal 2022-10-10 12:11:29 -07:00 committed by GitHub
parent dcb8e1d7f2
commit 7751bbe702
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 41 deletions

View File

@ -777,7 +777,7 @@ const getSelectedStoryDataForConversationId = (
// Find the index of the storyId provided, or if none provided then find the
// oldest unread story from the user. If all stories are read then we can
// start at the first story.
let currentIndex = 0;
let currentIndex: number | undefined;
let hasUnread = false;
storiesByConversationId.forEach((item, index) => {
if (selectedStoryId && item.messageId === selectedStoryId) {
@ -786,7 +786,7 @@ const getSelectedStoryDataForConversationId = (
if (
!selectedStoryId &&
!currentIndex &&
currentIndex === undefined &&
item.readStatus === ReadStatus.Unread
) {
hasUnread = true;
@ -806,7 +806,7 @@ const getSelectedStoryDataForConversationId = (
});
return {
currentIndex,
currentIndex: currentIndex ?? 0,
hasUnread,
numStories,
storiesByConversationId,
@ -989,35 +989,38 @@ const viewStory: ViewStoryActionCreatorType = (
return;
}
const storiesSelectorState = getStories(state);
const conversationStories =
storyViewMode === StoryViewModeType.Hidden
? storiesSelectorState.hiddenStories
: storiesSelectorState.stories;
const conversationStoryIndex = conversationStories.findIndex(
item => item.conversationId === story.conversationId
);
// 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) {
// Only stories that succeed the current story we're on.
const currentStoryIndex = stories.findIndex(
item => item.messageId === storyId
);
// No hidden stories
const hiddenConversationIds = new Set(getHideStoryConversationIds(state));
const unreadStory = stories.find(
(item, index) =>
index > currentStoryIndex &&
!item.deletedForEveryone &&
item.readStatus === ReadStatus.Unread &&
!hiddenConversationIds.has(item.conversationId)
// TODO: DESKTOP-4341 only stories that succeed the current story we're on.
const unreadStory = conversationStories.find(
item => item.storyView.isUnread
);
if (unreadStory) {
const nextSelectedStoryData = getSelectedStoryDataForConversationId(
dispatch,
getState,
unreadStory.conversationId,
unreadStory.messageId
unreadStory.conversationId
);
dispatch({
type: VIEW_STORY,
payload: {
currentIndex: nextSelectedStoryData.currentIndex,
messageId: unreadStory.messageId,
messageId:
nextSelectedStoryData.storiesByConversationId[
nextSelectedStoryData.currentIndex
].messageId,
numStories: nextSelectedStoryData.numStories,
shouldShowDetailsModal: false,
storyViewMode,
@ -1037,15 +1040,6 @@ const viewStory: ViewStoryActionCreatorType = (
}
}
const storiesSelectorState = getStories(state);
const conversationStories =
storyViewMode === StoryViewModeType.Hidden
? storiesSelectorState.hiddenStories
: storiesSelectorState.stories;
const conversationStoryIndex = conversationStories.findIndex(
item => item.conversationId === story.conversationId
);
if (conversationStoryIndex < 0) {
log.warn('stories.viewStory: No stories found for conversation', {
storiesLength: conversationStories.length,

View File

@ -394,7 +394,6 @@ export const getStories = createSelector(
}
let storiesMap: Map<string, ConversationStoryType>;
if (conversationStory.isHidden) {
storiesMap = hiddenStoriesById;
} else {

View File

@ -31,6 +31,7 @@ import {
import { noopAction } from '../../../state/ducks/noop';
import { reducer as rootReducer } from '../../../state/reducer';
import { dropNull } from '../../../util/dropNull';
import type { UUIDStringType } from '../../../types/UUID';
describe('both/state/ducks/stories', () => {
const getEmptyRootState = () => ({
@ -244,14 +245,29 @@ describe('both/state/ducks/stories', () => {
const storyId1 = uuid();
const storyId2 = uuid();
const storyId3 = uuid();
const getState = getStateFunction([
getStoryData(storyId1),
const convoId1 = uuid();
const convoId2 = uuid();
const convoId3 = uuid();
const getState = getStateFunction(
[
{
...getStoryData(storyId1, convoId1),
readStatus: ReadStatus.Viewed,
},
{
...getStoryData(storyId2, convoId2),
readStatus: ReadStatus.Viewed,
},
getStoryData(storyId3, convoId3),
],
{
...getStoryData(storyId2),
readStatus: ReadStatus.Viewed,
},
getStoryData(storyId3),
]);
[convoId1]: getMockConversation({ id: convoId1 }),
[convoId2]: getMockConversation({ id: convoId2 }),
[convoId3]: getMockConversation({ id: convoId3 }),
}
);
const dispatch = sinon.spy();
viewStory({
@ -277,16 +293,29 @@ describe('both/state/ducks/stories', () => {
const storyId2 = uuid();
const storyId3 = uuid();
const conversationId = uuid();
const conversationIdHide: UUIDStringType = 'test-convo-uuid-hide-story';
const getState = getStateFunction(
[
getStoryData(storyId1),
getStoryData(storyId2, conversationId),
getStoryData(storyId3, conversationId),
{
...getStoryData(storyId1, conversationId),
readStatus: ReadStatus.Viewed,
},
// selector looks up conversation by sourceUuid
{
...getStoryData(storyId2, conversationIdHide),
sourceUuid: conversationIdHide,
},
{
...getStoryData(storyId3, conversationIdHide),
sourceUuid: conversationIdHide,
},
],
{
[conversationId]: getMockConversation({
id: conversationId,
[conversationId]: getMockConversation({ id: conversationId }),
[conversationIdHide]: getMockConversation({
id: conversationIdHide,
hideStory: true,
}),
}
@ -305,6 +334,8 @@ describe('both/state/ducks/stories', () => {
});
});
// TODO: DESKTOP-4341 - removed until implemented
/*
it('does not select stories that precede the currently viewed story', () => {
const storyId1 = uuid();
const storyId2 = uuid();
@ -327,6 +358,7 @@ describe('both/state/ducks/stories', () => {
payload: undefined,
});
});
*/
it('closes the viewer when there are no more unviewed stories', () => {
const storyId1 = uuid();
@ -337,7 +369,10 @@ describe('both/state/ducks/stories', () => {
const getState = getStateFunction(
[
getStoryData(storyId1, conversationId1),
{
...getStoryData(storyId1, conversationId1),
readStatus: ReadStatus.Viewed,
},
{
...getStoryData(storyId2, conversationId2),
readStatus: ReadStatus.Viewed,