/* * Wire * Copyright (C) 2022 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ import {useEffect, useState} from 'react'; import {amplify} from 'amplify'; import {WebAppEvents} from '@wireapp/webapp-events'; import * as Icon from 'Components/Icon'; import {showDetailViewModal} from 'Components/Modals/DetailViewModal'; import {ConversationRepository} from 'src/script/conversation/ConversationRepository'; import {ContentMessage} from 'src/script/entity/message/ContentMessage'; import {generateConversationUrl} from 'src/script/router/routeGenerator'; import {createNavigate} from 'src/script/router/routerBindings'; import {useKoSubscribableChildren} from 'Util/ComponentUtil'; import {t} from 'Util/LocalizerUtil'; import {CollectionDetails} from './CollectionDetails'; import {CollectionSection} from './CollectionSection'; import {FullSearch} from './FullSearch'; import {Category, isOfCategory} from './utils'; import {AssetRepository} from '../../../../assets/AssetRepository'; import {MessageRepository} from '../../../../conversation/MessageRepository'; import {Conversation} from '../../../../entity/Conversation'; import {User} from '../../../../entity/User'; import {MessageCategory} from '../../../../message/MessageCategory'; interface CollectionDetailsProps { conversation: Conversation; conversationRepository: ConversationRepository; assetRepository: AssetRepository; messageRepository: MessageRepository; selfUser: User; } type Categories = Record; function splitIntoCategories(messages: ContentMessage[]): Categories { return messages.reduce( (categories, message) => { if (message.isExpired()) { return categories; } if (isOfCategory('images', message)) { categories.images.push(message); } else if (isOfCategory('audio', message)) { categories.audio.push(message); } else if (isOfCategory('files', message)) { categories.files.push(message); } else if (isOfCategory('links', message)) { categories.links.push(message); } return categories; }, { audio: [], files: [], images: [], links: [], }, ); } const Collection = ({ conversation, conversationRepository, assetRepository, messageRepository, selfUser, }: CollectionDetailsProps) => { const [searchTerm, setSearchTerm] = useState(''); const {display_name} = useKoSubscribableChildren(conversation, ['display_name']); const [messages, setMessages] = useState([]); const [detailCategory, setDetailCategory] = useState(undefined); useEffect(() => { conversationRepository .getEventsForCategory(conversation, MessageCategory.LINK_PREVIEW) .then(allMessages => setMessages(allMessages as ContentMessage[])); }, []); useEffect(() => { const addItem = (message: ContentMessage) => { setMessages(oldMessages => [message].concat(oldMessages)); }; const removeItem = (messageId: string, conversationId: string) => { if (conversation.id !== conversationId) { // A message from a different converation, nothing to do return; } setMessages(oldMessages => oldMessages.filter(message => message.id !== messageId)); }; const removeMessage = (message: ContentMessage) => { removeItem(message.id, message.conversation_id); }; amplify.subscribe(WebAppEvents.CONVERSATION.EPHEMERAL_MESSAGE_TIMEOUT, removeMessage); amplify.subscribe(WebAppEvents.CONVERSATION.MESSAGE.ADDED, addItem); amplify.subscribe(WebAppEvents.CONVERSATION.MESSAGE.REMOVED, removeItem); return () => { amplify.unsubscribe(WebAppEvents.CONVERSATION.EPHEMERAL_MESSAGE_TIMEOUT, removeMessage); amplify.unsubscribe(WebAppEvents.CONVERSATION.MESSAGE.ADDED, addItem); amplify.unsubscribe(WebAppEvents.CONVERSATION.MESSAGE.REMOVED, removeItem); }; }, []); const categories = splitIntoCategories(messages); const {images, audio, links, files} = categories; const onImageClick = (message: ContentMessage) => { showDetailViewModal({ assetRepository, conversationRepository, currentMessageEntity: message, messageRepository, selfUser, }); }; if (detailCategory && categories[detailCategory].length > 0) { return ( setDetailCategory(undefined)} onImageClick={onImageClick} /> ); } const content = searchTerm ? null : ( <> setDetailCategory('images')} onImageClick={onImageClick} label={t('collectionSectionImages')} > setDetailCategory('links')} label={t('collectionSectionLinks')} > setDetailCategory('audio')} label={t('collectionSectionAudio')} > setDetailCategory('files')} label={t('collectionSectionFiles')} > ); return (

{display_name}

conversationRepository.searchInConversation(conversation, query)} change={setSearchTerm} click={message => amplify.publish(WebAppEvents.CONVERSATION.SHOW, conversation, {exposeMessage: message})} /> {content}
); }; export {Collection};