From 111bb7018876eb906ad4da860d2bfc985f6d1c22 Mon Sep 17 00:00:00 2001 From: ayumi-signal <143036029+ayumi-signal@users.noreply.github.com> Date: Wed, 12 Jun 2024 13:40:06 -0700 Subject: [PATCH] Share call link via signal while in call --- _locales/en/messages.json | 4 ++++ ts/components/CallManager.stories.tsx | 1 + ts/components/CallManager.tsx | 18 ++++++++++++++++++ ts/components/CallingAdhocCallInfo.stories.tsx | 1 + ts/components/CallingAdhocCallInfo.tsx | 16 ++++++++++++++++ ts/components/ForwardMessagesModal.stories.tsx | 1 + ts/components/ForwardMessagesModal.tsx | 8 +++++++- ts/state/smart/CallManager.tsx | 3 +++ ts/state/smart/ForwardMessagesModal.tsx | 6 +++++- 9 files changed, 56 insertions(+), 2 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 184cb92f6eb..4407054f5a8 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -3690,6 +3690,10 @@ "messageformat": "Copy call link", "description": "Menu item in the in-call info popup for call link calls. The action is to add the call link to the clipboard." }, + "icu:CallingAdhocCallInfo__ShareViaSignal": { + "messageformat": "Share call link via Signal", + "description": "Menu item in the in-call info popup for call link calls. Clicking the item opens the sharing dialog where you can send the call link to your Signal contacts or groups." + }, "icu:CallingAdhocCallInfo__RemoveClient": { "messageformat": "Remove this person from the call", "description": "Button in the in-call info popup for call link calls showing all participants. The action is to remove the participant from the call." diff --git a/ts/components/CallManager.stories.tsx b/ts/components/CallManager.stories.tsx index 3dbed81c3bd..b8c782b4e7a 100644 --- a/ts/components/CallManager.stories.tsx +++ b/ts/components/CallManager.stories.tsx @@ -113,6 +113,7 @@ const createProps = (storyProps: Partial = {}): PropsType => ({ setPresenting: action('toggle-presenting'), setRendererCanvas: action('set-renderer-canvas'), setOutgoingRing: action('set-outgoing-ring'), + showShareCallLinkViaSignal: action('show-share-call-link-via-signal'), startCall: action('start-call'), stopRingtone: action('stop-ringtone'), switchToPresentationView: action('switch-to-presentation-view'), diff --git a/ts/components/CallManager.tsx b/ts/components/CallManager.tsx index 0f8bb1d7f96..3648029469e 100644 --- a/ts/components/CallManager.tsx +++ b/ts/components/CallManager.tsx @@ -126,6 +126,10 @@ export type PropsType = { setOutgoingRing: (_: boolean) => void; setPresenting: (_?: PresentedSource) => void; setRendererCanvas: (_: SetRendererCanvasType) => void; + showShareCallLinkViaSignal: ( + callLink: CallLinkType, + i18n: LocalizerType + ) => void; stopRingtone: () => unknown; switchToPresentationView: () => void; switchFromPresentationView: () => void; @@ -184,6 +188,7 @@ function ActiveCallManager({ setPresenting, setRendererCanvas, setOutgoingRing, + showShareCallLinkViaSignal, startCall, switchToPresentationView, switchFromPresentationView, @@ -267,6 +272,15 @@ function ActiveCallManager({ } }, [callLink]); + const handleShareCallLinkViaSignal = useCallback(() => { + if (!callLink) { + log.error('Missing call link'); + return; + } + + showShareCallLinkViaSignal(callLink, i18n); + }, [callLink, i18n, showShareCallLinkViaSignal]); + let isCallFull: boolean; let showCallLobby: boolean; let groupMembers: @@ -379,6 +393,7 @@ function ActiveCallManager({ participants={peekedParticipants} onClose={toggleParticipants} onCopyCallLink={onCopyCallLink} + onShareCallLinkViaSignal={handleShareCallLinkViaSignal} removeClient={removeClient} /> ) : ( @@ -472,6 +487,7 @@ function ActiveCallManager({ participants={groupCallParticipantsForParticipantsList} onClose={toggleParticipants} onCopyCallLink={onCopyCallLink} + onShareCallLinkViaSignal={handleShareCallLinkViaSignal} removeClient={removeClient} /> ) : ( @@ -527,6 +543,7 @@ export function CallManager({ setOutgoingRing, setPresenting, setRendererCanvas, + showShareCallLinkViaSignal, startCall, stopRingtone, switchFromPresentationView, @@ -616,6 +633,7 @@ export function CallManager({ setOutgoingRing={setOutgoingRing} setPresenting={setPresenting} setRendererCanvas={setRendererCanvas} + showShareCallLinkViaSignal={showShareCallLinkViaSignal} startCall={startCall} switchFromPresentationView={switchFromPresentationView} switchToPresentationView={switchToPresentationView} diff --git a/ts/components/CallingAdhocCallInfo.stories.tsx b/ts/components/CallingAdhocCallInfo.stories.tsx index 5abbdc112cd..6e7fd24e659 100644 --- a/ts/components/CallingAdhocCallInfo.stories.tsx +++ b/ts/components/CallingAdhocCallInfo.stories.tsx @@ -66,6 +66,7 @@ const createProps = (overrideProps: Partial = {}): PropsType => ({ participants: overrideProps.participants || [], onClose: action('on-close'), onCopyCallLink: action('on-copy-call-link'), + onShareCallLinkViaSignal: action('on-share-call-link-via-signal'), removeClient: overrideProps.removeClient || action('remove-client'), }); diff --git a/ts/components/CallingAdhocCallInfo.tsx b/ts/components/CallingAdhocCallInfo.tsx index 28e5a4fd3a4..8ffe7b5d4aa 100644 --- a/ts/components/CallingAdhocCallInfo.tsx +++ b/ts/components/CallingAdhocCallInfo.tsx @@ -39,6 +39,7 @@ export type PropsType = { readonly participants: Array; readonly onClose: () => void; readonly onCopyCallLink: () => void; + readonly onShareCallLinkViaSignal: () => void; readonly removeClient: ((payload: RemoveClientType) => void) | null; }; @@ -142,6 +143,7 @@ export function CallingAdhocCallInfo({ participants, onClose, onCopyCallLink, + onShareCallLinkViaSignal, removeClient, }: PropsType): JSX.Element | null { const [isUnknownContactDialogVisible, setIsUnknownContactDialogVisible] = @@ -150,6 +152,10 @@ export function CallingAdhocCallInfo({ () => setIsUnknownContactDialogVisible(false), [setIsUnknownContactDialogVisible] ); + const onClickShareCallLinkViaSignal = React.useCallback(() => { + onClose(); + onShareCallLinkViaSignal(); + }, [onClose, onShareCallLinkViaSignal]); const [knownParticipants, unknownParticipants] = React.useMemo< [Array, Array] @@ -323,6 +329,16 @@ export function CallingAdhocCallInfo({ {i18n('icu:CallingAdhocCallInfo__CopyLink')} + diff --git a/ts/components/ForwardMessagesModal.stories.tsx b/ts/components/ForwardMessagesModal.stories.tsx index 2ae62a51b45..a0ec491ce87 100644 --- a/ts/components/ForwardMessagesModal.stories.tsx +++ b/ts/components/ForwardMessagesModal.stories.tsx @@ -52,6 +52,7 @@ const useProps = (overrideProps: Partial = {}): PropsType => ({ doForwardMessages: action('doForwardMessages'), getPreferredBadge: () => undefined, i18n, + isInFullScreenCall: false, linkPreviewForSource: () => undefined, onClose: action('onClose'), onChange: action('onChange'), diff --git a/ts/components/ForwardMessagesModal.tsx b/ts/components/ForwardMessagesModal.tsx index ec07df0dadb..93f99d3c08b 100644 --- a/ts/components/ForwardMessagesModal.tsx +++ b/ts/components/ForwardMessagesModal.tsx @@ -43,6 +43,7 @@ import { type MessageForwardDraft, } from '../types/ForwardDraft'; import { missingCaseError } from '../util/missingCaseError'; +import { Theme } from '../util/theme'; export enum ForwardMessagesModalType { Forward, @@ -58,6 +59,7 @@ export type DataPropsType = { drafts: ReadonlyArray; getPreferredBadge: PreferredBadgeSelectorType; i18n: LocalizerType; + isInFullScreenCall: boolean; linkPreviewForSource: ( source: LinkPreviewSourceType @@ -90,6 +92,7 @@ export function ForwardMessagesModal({ linkPreviewForSource, getPreferredBadge, i18n, + isInFullScreenCall, onClose, onChange, removeLinkPreview, @@ -309,6 +312,8 @@ export function ForwardMessagesModal({ throw missingCaseError(type); } + const modalTheme = isInFullScreenCall ? Theme.Dark : undefined; + return ( <> {cannotMessage && ( @@ -329,7 +334,8 @@ export function ForwardMessagesModal({ onBackButtonClick={isEditingMessage ? handleBackOrClose : undefined} moduleClassName="module-ForwardMessageModal" title={title} - useFocusTrap={false} + theme={modalTheme} + useFocusTrap={isInFullScreenCall} padded={false} modalFooter={footer} noMouseClose diff --git a/ts/state/smart/CallManager.tsx b/ts/state/smart/CallManager.tsx index 89baebcae0c..a841ea981e7 100644 --- a/ts/state/smart/CallManager.tsx +++ b/ts/state/smart/CallManager.tsx @@ -55,6 +55,7 @@ import { SmartCallingDeviceSelection } from './CallingDeviceSelection'; import { renderEmojiPicker } from './renderEmojiPicker'; import { renderReactionPicker } from './renderReactionPicker'; import { isSharingPhoneNumberWithEverybody as getIsSharingPhoneNumberWithEverybody } from '../../util/phoneNumberSharingMode'; +import { useGlobalModalActions } from '../ducks/globalModals'; function renderDeviceSelection(): JSX.Element { return ; @@ -454,6 +455,7 @@ export const SmartCallManager = memo(function SmartCallManager() { toggleSettings, } = useCallingActions(); const { pauseVoiceNotePlayer } = useAudioPlayerActions(); + const { showShareCallLinkViaSignal } = useGlobalModalActions(); return ( >( () => { @@ -153,6 +156,7 @@ function SmartForwardMessagesModalInner({ linkPreviewForSource={linkPreviewForSource} getPreferredBadge={getPreferredBadge} i18n={i18n} + isInFullScreenCall={isInFullScreenCall} onClose={closeModal} onChange={handleChange} regionCode={regionCode}