Process incoming story messages

This commit is contained in:
Josh Perez 2022-03-04 16:14:52 -05:00 committed by GitHub
parent df7cdfacc7
commit eb91eb6fec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
84 changed files with 4382 additions and 652 deletions

View file

@ -58,6 +58,13 @@ export const getUsernamesEnabled = createSelector(
isRemoteConfigFlagEnabled(remoteConfig, 'desktop.usernames')
);
export const getStoriesEnabled = createSelector(
getRemoteConfig,
(remoteConfig: ConfigMapType): boolean =>
isRemoteConfigFlagEnabled(remoteConfig, 'desktop.internalUser') ||
isRemoteConfigFlagEnabled(remoteConfig, 'desktop.stories')
);
export const getDefaultConversationColor = createSelector(
getItems,
(

View file

@ -129,6 +129,12 @@ export function isOutgoing(
return message.type === 'outgoing';
}
export function isStory(
message: Pick<MessageWithUIFieldsType, 'type'>
): boolean {
return message.type === 'story';
}
export function hasErrors(
message: Pick<MessageWithUIFieldsType, 'errors'>
): boolean {
@ -1502,7 +1508,9 @@ function canReplyOrReact(
);
}
if (isIncoming(message)) {
// If we get past all the other checks above then we can always reply or
// react if the message type is "incoming" | "story"
if (isIncoming(message) || isStory(message)) {
return true;
}

View file

@ -0,0 +1,98 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { createSelector } from 'reselect';
import { pick } from 'lodash';
import type {
ConversationStoryType,
StoryViewType,
} from '../../components/StoryListItem';
import type { StateType } from '../reducer';
import type { StoriesStateType } from '../ducks/stories';
import { ReadStatus } from '../../messages/MessageReadStatus';
import { getConversationSelector } from './conversations';
export const getStoriesState = (state: StateType): StoriesStateType =>
state.stories;
export const shouldShowStoriesView = createSelector(
getStoriesState,
({ isShowingStoriesView }): boolean => isShowingStoriesView
);
export const getStories = createSelector(
getConversationSelector,
getStoriesState,
(
conversationSelector,
{ stories }: Readonly<StoriesStateType>
): {
hiddenStories: Array<ConversationStoryType>;
stories: Array<ConversationStoryType>;
} => {
const storiesById = new Map<string, ConversationStoryType>();
const hiddenStoriesById = new Map<string, ConversationStoryType>();
stories.forEach(story => {
const sender = pick(
conversationSelector(story.sourceUuid || story.source),
[
'acceptedMessageRequest',
'avatarPath',
'color',
'firstName',
'hideStory',
'id',
'isMe',
'name',
'profileName',
'sharedGroupNames',
'title',
]
);
const conversation = pick(conversationSelector(story.conversationId), [
'id',
'title',
]);
const { attachment, timestamp } = pick(story, [
'attachment',
'timestamp',
]);
let storiesMap: Map<string, ConversationStoryType>;
if (sender.hideStory) {
storiesMap = hiddenStoriesById;
} else {
storiesMap = storiesById;
}
const storyView: StoryViewType = {
attachment,
isUnread: story.readStatus === ReadStatus.Unread,
messageId: story.messageId,
selectedReaction: story.selectedReaction,
sender,
timestamp,
};
const conversationStory = storiesMap.get(conversation.id) || {
conversationId: conversation.id,
group: conversation.id !== sender.id ? conversation : undefined,
isHidden: Boolean(sender.hideStory),
stories: [],
};
storiesMap.set(conversation.id, {
...conversationStory,
stories: [...conversationStory.stories, storyView],
});
});
return {
hiddenStories: Array.from(hiddenStoriesById.values()),
stories: Array.from(storiesById.values()),
};
}
);