From d3a27a6442f63efd16f527393b715429d0ad77ba Mon Sep 17 00:00:00 2001 From: Peter Thatcher Date: Thu, 4 Jun 2020 11:16:19 -0700 Subject: [PATCH] Calling support --- _locales/en/messages.json | 132 ++++- app/permissions.js | 20 +- background.html | 27 +- build/entitlements.mac.plist | 2 + images/icons/v2/mic-off-solid-28.svg | 1 + images/icons/v2/mic-solid-28.svg | 1 + images/icons/v2/phone-down-24.svg | 1 + images/icons/v2/phone-down-28.svg | 1 + images/icons/v2/phone-right-outline-24.svg | 1 + images/icons/v2/phone-right-solid-24.svg | 1 + images/icons/v2/video-off-solid-24.svg | 1 + images/icons/v2/video-off-solid-28.svg | 1 + images/icons/v2/video-outline-24.svg | 1 + images/icons/v2/video-solid-24.svg | 1 + images/icons/v2/video-solid-28.svg | 1 + js/background.js | 20 + js/models/conversations.js | 24 + js/models/messages.js | 13 + js/modules/signal.js | 8 + js/notifications.js | 20 +- js/permissions_popup_start.js | 19 +- js/settings_start.js | 6 + js/views/conversation_view.js | 16 + js/views/inbox_view.js | 15 + js/views/settings_view.js | 63 +++ main.js | 133 +++-- package.json | 8 +- permissions_popup_preload.js | 4 +- preload.js | 89 ++++ protos/SignalService.proto | 58 ++- settings.html | 29 ++ settings_preload.js | 11 + sounds/navigation-cancel.ogg | Bin 0 -> 7561 bytes sounds/ringtone_minimal.ogg | Bin 0 -> 154631 bytes stylesheets/_index.scss | 6 + stylesheets/_modules.scss | 484 ++++++++++++++++++ stylesheets/_settings.scss | 6 + test/index.html | 27 +- ts/components/CallManager.stories.tsx | 65 +++ ts/components/CallManager.tsx | 77 +++ ts/components/CallScreen.stories.tsx | 120 +++++ ts/components/CallScreen.tsx | 380 ++++++++++++++ ts/components/IncomingCallBar.stories.tsx | 101 ++++ ts/components/IncomingCallBar.tsx | 158 ++++++ ts/components/ShortcutGuide.tsx | 21 + .../conversation/CallingNotification.tsx | 94 ++++ .../ConversationHeader.stories.tsx | 6 + .../conversation/ConversationHeader.tsx | 52 ++ .../conversation/TimelineItem.stories.tsx | 180 ++++++- ts/components/conversation/TimelineItem.tsx | 11 + ts/services/bounce.ts | 34 ++ ts/services/calling.ts | 464 +++++++++++++++++ ts/services/notify.ts | 34 ++ ts/shims/bounceAppIcon.ts | 9 + ts/state/actions.ts | 2 + ts/state/ducks/calling.ts | 417 +++++++++++++++ ts/state/ducks/conversations.ts | 3 +- ts/state/reducer.ts | 8 + ts/state/roots/createCallManager.tsx | 16 + ts/state/smart/CallManager.tsx | 23 + ts/textsecure.d.ts | 69 ++- ts/textsecure/MessageReceiver.ts | 16 +- ts/textsecure/SendMessage.ts | 23 + ts/textsecure/WebAPI.ts | 10 + ts/types/Calling.ts | 8 + ts/util/Sound.ts | 75 +++ ts/util/callingPermissions.ts | 10 + ts/util/callingTones.ts | 44 ++ ts/util/lint/exceptions.json | 210 +++++--- ts/window.d.ts | 50 +- tslint.json | 3 + yarn.lock | 11 + 72 files changed, 3864 insertions(+), 191 deletions(-) create mode 100644 images/icons/v2/mic-off-solid-28.svg create mode 100644 images/icons/v2/mic-solid-28.svg create mode 100644 images/icons/v2/phone-down-24.svg create mode 100644 images/icons/v2/phone-down-28.svg create mode 100644 images/icons/v2/phone-right-outline-24.svg create mode 100644 images/icons/v2/phone-right-solid-24.svg create mode 100644 images/icons/v2/video-off-solid-24.svg create mode 100644 images/icons/v2/video-off-solid-28.svg create mode 100644 images/icons/v2/video-outline-24.svg create mode 100644 images/icons/v2/video-solid-24.svg create mode 100644 images/icons/v2/video-solid-28.svg create mode 100755 sounds/navigation-cancel.ogg create mode 100755 sounds/ringtone_minimal.ogg create mode 100644 ts/components/CallManager.stories.tsx create mode 100644 ts/components/CallManager.tsx create mode 100644 ts/components/CallScreen.stories.tsx create mode 100644 ts/components/CallScreen.tsx create mode 100644 ts/components/IncomingCallBar.stories.tsx create mode 100644 ts/components/IncomingCallBar.tsx create mode 100644 ts/components/conversation/CallingNotification.tsx create mode 100644 ts/services/bounce.ts create mode 100644 ts/services/calling.ts create mode 100644 ts/services/notify.ts create mode 100644 ts/shims/bounceAppIcon.ts create mode 100644 ts/state/ducks/calling.ts create mode 100644 ts/state/roots/createCallManager.tsx create mode 100644 ts/state/smart/CallManager.tsx create mode 100644 ts/types/Calling.ts create mode 100644 ts/util/Sound.ts create mode 100644 ts/util/callingPermissions.ts create mode 100644 ts/util/callingTones.ts diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 8ffe46b5e0b3..df98b17d9c7a 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -853,6 +853,14 @@ "message": "To send audio messages, allow Signal Desktop to access your microphone.", "description": "Shown if the user attempts to send an audio message without audio permssions turned on" }, + "audioCallingPermissionNeeded": { + "message": "For calling, you must allow Signal Desktop to access your microphone.", + "description": "Shown if the user attempts access the microphone for calling without audio permssions turned on" + }, + "videoCallingPermissionNeeded": { + "message": "For video calling, you must allow Signal Desktop to access your camera.", + "description": "Shown if the user attempts access the camera for video calling without video permssions turned on" + }, "allowAccess": { "message": "Allow Access", "description": "Button shown in popup asking to enable microphon/video permissions to send audio messages" @@ -1101,12 +1109,28 @@ "message": "Theme", "description": "Header for theme settings" }, + "calling": { + "message": "Calling", + "description": "Header for calling options on the settings screen" + }, + "alwaysRelayCallsDescription": { + "message": "Always relay calls", + "description": "Description of the always relay calls setting" + }, + "alwaysRelayCallsDetail": { + "message": "Relay all calls through the Signal server to avoid revealing your IP address to your contact. Enabling will reduce call quality.", + "description": "Details describing the always relay calls setting" + }, "permissions": { "message": "Permissions", "description": "Header for permissions section of settings" }, "mediaPermissionsDescription": { - "message": "Allow access to camera and microphone", + "message": "Allow access to the microphone", + "description": "Description of the media permission description" + }, + "mediaCameraPermissionsDescription": { + "message": "Allow access to the camera", "description": "Description of the media permission description" }, "general": { @@ -1539,6 +1563,18 @@ "message": "Play audio notification", "description": "Description for audio notification setting" }, + "callRingtoneNotificationDescription": { + "message": "Play calling sounds", + "description": "Description for call ringtone notification setting" + }, + "callSystemNotificationDescription": { + "message": "Show notifications for calls", + "description": "Description for call notification setting" + }, + "incomingCallNotificationDescription": { + "message": "Enable incoming calls", + "description": "Description for incoming calls setting" + }, "safetyNumberChanged": { "message": "Safety Number has changed", "description": "A notification shown in the conversation when a contact reinstalls" @@ -2074,6 +2110,18 @@ "message": "Close current conversation", "description": "Shown in the shortcuts guide" }, + "Keyboard--calling-header": { + "message": "Calling", + "description": "Header of the keyboard shortcuts guide - calling section" + }, + "Keyboard--toggle-audio": { + "message": "Toggle mute on and off", + "description": "Shown in the shortcuts guide" + }, + "Keyboard--toggle-video": { + "message": "Toggle video on and off", + "description": "Shown in the shortcuts guide" + }, "close-popup": { "message": "Close Popup", "description": "Used as alt text for any button closing a popup" @@ -2533,5 +2581,87 @@ "example": "Jeff Smith" } } + }, + "acceptCall": { + "message": "Answer", + "description": "Shown in tooltip for the button to accept a call (audio or video)" + }, + "acceptCallWithoutVideo": { + "message": "Answer without video", + "description": "Shown in tooltip for the button to accept a video call without video" + }, + "declineCall": { + "message": "Decline", + "description": "Shown in tooltip for the button to decline a call (audio or video)" + }, + "declinedIncomingAudioCall": { + "message": "You declined an audio call", + "description": "Shown in conversation history when you declined an incoming audio call" + }, + "declinedIncomingVideoCall": { + "message": "You declined a video call", + "description": "Shown in conversation history when you declined an incoming video call" + }, + "acceptedIncomingAudioCall": { + "message": "Incoming audio call", + "description": "Shown in conversation history when you accepted an incoming audio call" + }, + "acceptedIncomingVideoCall": { + "message": "Incoming video call", + "description": "Shown in conversation history when you accepted an incoming video call" + }, + "missedIncomingAudioCall": { + "message": "Missed audio call", + "description": "Shown in conversation history when you missed an incoming audio call" + }, + "missedIncomingVideoCall": { + "message": "Missed video call", + "description": "Shown in conversation history when you missed an incoming video call" + }, + "acceptedOutgoingAudioCall": { + "message": "Outgoing audio call", + "description": "Shown in conversation history when you made an outgoing audio call" + }, + "acceptedOutgoingVideoCall": { + "message": "Outgoing video call", + "description": "Shown in conversation history when you made an outgoing video call" + }, + "missedOrDeclinedOutgoingAudioCall": { + "message": "Unanswered audio call", + "description": "Shown in conversation history when your audio call is missed or declined" + }, + "missedOrDeclinedOutgoingVideoCall": { + "message": "Unanswered video call", + "description": "Shown in conversation history when your video call is missed or declined" + }, + "incomingAudioCall": { + "message": "Incoming audio call...", + "description": "Shown in both the incoming call bar and notification for an incoming audio call" + }, + "incomingVideoCall": { + "message": "Incoming video call...", + "description": "Shown in both the incoming call bar and notification for an incoming video call" + }, + "outgoingCallPrering": { + "message": "Calling...", + "description": "Shown in the call screen when placing an outgoing call that isn't ringing yet" + }, + "outgoingCallRinging": { + "message": "Ringing...", + "description": "Shown in the call screen when placing an outgoing call that is now ringing" + }, + "callReconnecting": { + "message": "Reconnecting...", + "description": "Shown in the call screen when the call is reconnecting due to network issues" + }, + "callDuration": { + "message": "Signal $duration$", + "description": "Shown in the call screen to indicate how long the call has been connected", + "placeholders": { + "duration": { + "content": "$1", + "example": "00:01" + } + } } } diff --git a/app/permissions.js b/app/permissions.js index 20697a33dda5..3b012cfafa74 100644 --- a/app/permissions.js +++ b/app/permissions.js @@ -7,7 +7,7 @@ const PERMISSIONS = { notifications: true, // required to show OS notifications for new messages // Off by default, can be enabled by user - media: false, // required for access to microphone, used for voice notes + media: false, // required for access to microphone and camera, used for voice notes and calling // Not allowed geolocation: false, @@ -17,9 +17,21 @@ const PERMISSIONS = { }; function _createPermissionHandler(userConfig) { - return (webContents, permission, callback) => { - // We default 'media' permission to false, but the user can override that - if (permission === 'media' && userConfig.get('mediaPermissions')) { + return (webContents, permission, callback, details) => { + // We default 'media' permission to false, but the user can override that for + // the microphone and camera. + if ( + permission === 'media' && + details.mediaTypes.includes('audio') && + userConfig.get('mediaPermissions') + ) { + return callback(true); + } + if ( + permission === 'media' && + details.mediaTypes.includes('video') && + userConfig.get('mediaCameraPermissions') + ) { return callback(true); } diff --git a/background.html b/background.html index 3ae938283a2f..9588693274f1 100644 --- a/background.html +++ b/background.html @@ -52,22 +52,25 @@