/* * Wire * Copyright (C) 2023 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 React, {useMemo, useState} from 'react'; import {AddUsersFailure, AddUsersFailureReasons} from '@wireapp/core/lib/conversation'; import {container} from 'tsyringe'; import {Button, ButtonVariant, Link, LinkVariant} from '@wireapp/react-ui-kit'; import * as Icon from 'Components/Icon'; import {getUserName} from 'Components/UserName'; import {Config} from 'src/script/Config'; import {User} from 'src/script/entity/User'; import {UserState} from 'src/script/user/UserState'; import {useKoSubscribableChildren} from 'Util/ComponentUtil'; import {t} from 'Util/LocalizerUtil'; import {matchQualifiedIds} from 'Util/QualifiedId'; import {backendErrorLink, warning} from './ContentMessage/Warnings/Warnings.styles'; import {MessageTime} from './MessageTime'; import {useMessageFocusedTabIndex} from './util'; import {FailedToAddUsersMessage as FailedToAddUsersMessageEntity} from '../../../entity/message/FailedToAddUsersMessage'; export interface FailedToAddUsersMessageProps { isMessageFocused: boolean; message: FailedToAddUsersMessageEntity; userState?: UserState; } const config = Config.getConfig(); const reasonToMessageDataMap = { [AddUsersFailureReasons.NON_FEDERATING_BACKENDS]: { link: { url: config.URL.SUPPORT.OFFLINE_BACKEND, name: 'go-offline-backend', }, translationLabel: 'NonFederatingBackends', }, [AddUsersFailureReasons.UNREACHABLE_BACKENDS]: { link: {url: config.URL.SUPPORT.OFFLINE_BACKEND, name: 'go-offline-backend'}, translationLabel: 'OfflineBackend', }, [AddUsersFailureReasons.OFFLINE_FOR_TOO_LONG]: { link: {url: config.URL.SUPPORT.OFFLINE_BACKEND, name: 'go-offline-backend'}, translationLabel: 'OfflineForTooLong', }, } as const; interface MessageDetailsProps { failure: AddUsersFailure; isMessageFocused: boolean; allUsers: User[]; } const MessageDetails = ({failure, isMessageFocused, allUsers}: MessageDetailsProps) => { const messageFocusedTabIndex = useMessageFocusedTabIndex(isMessageFocused); const {users: userIds, reason} = failure; const users = useMemo(() => { const users: User[] = userIds.reduce((previous, current) => { const foundUser = allUsers.find(user => matchQualifiedIds(current, user.qualifiedId)); return foundUser ? [...previous, foundUser] : previous; }, []); return users; }, [allUsers, userIds]); const baseTranslationKey = users.length === 1 ? 'failedToAddParticipantsSingularDetails' : 'failedToAddParticipantsPluralDetails'; const uniqueDomains = 'backends' in failure ? Array.from(new Set(failure.backends)) : undefined; const domainStr = uniqueDomains && uniqueDomains.join(', '); const {link, translationLabel} = reasonToMessageDataMap[reason]; const learnMoreLink = ( <> {' '} {t('offlineBackendLearnMore')} ); return (

getUserName(user)) .join(', '), ...(domainStr && {domain: domainStr}), }), }} /> {learnMoreLink}

); }; const FailedToAddUsersMessage: React.FC = ({ isMessageFocused, message, userState = container.resolve(UserState), }) => { const messageFocusedTabIndex = useMessageFocusedTabIndex(isMessageFocused); const [isOpen, setIsOpen] = useState(false); const {timestamp} = useKoSubscribableChildren(message, ['timestamp']); const {users: allUsers} = useKoSubscribableChildren(userState, ['users']); const {failures} = message; const allUserIds = useMemo(() => failures.flatMap(failure => failure.users), [failures]); const totalNumberOfUsers = allUserIds.length; if (allUserIds.length === 0) { return null; } // These will be used if we've only failed to add a single user const firstUser = allUsers.find(user => matchQualifiedIds(allUserIds[0], user.qualifiedId)); const {link, translationLabel} = reasonToMessageDataMap[failures[0].reason]; const learnMore = ( <> {' '} {t('offlineBackendLearnMore')} ); return ( <>
{totalNumberOfUsers <= 1 && firstUser && (

{learnMore}

)} {totalNumberOfUsers > 1 && (

)}

{isOpen && failures.map((failure, index) => ( ))} {totalNumberOfUsers > 1 && (
)}
); }; export {FailedToAddUsersMessage};