From cee27886540a3f612fe71a6b4455ae18e656c017 Mon Sep 17 00:00:00 2001
From: Jamie Kyle <113370520+jamiebuilds-signal@users.noreply.github.com>
Date: Tue, 30 Jul 2024 11:39:24 -0700
Subject: [PATCH] Add editing to call details pane
---
_locales/en/messages.json | 24 ++++++++-
app/spell_check.ts | 2 +-
stylesheets/components/CallLinkEditModal.scss | 5 --
.../CallLinkRestrictionsSelect.scss | 7 +++
.../components/ConversationDetails.scss | 8 +++
stylesheets/manifest.scss | 1 +
ts/components/CallLinkAddNameModal.tsx | 36 ++++++++++---
ts/components/CallLinkDetails.tsx | 42 ++++++++++++++-
ts/components/CallLinkEditModal.tsx | 39 +++++---------
ts/components/CallLinkRestrictionsSelect.tsx | 44 +++++++++++++++
.../ConversationDetailsIcon.tsx | 1 +
ts/services/LinkPreview.ts | 5 +-
ts/services/calling.ts | 51 ++++--------------
ts/state/ducks/calling.ts | 22 +++++---
ts/state/smart/CallLinkAddNameModal.tsx | 7 ++-
ts/state/smart/CallLinkDetails.tsx | 20 ++++++-
ts/test-electron/state/ducks/calling_test.ts | 10 +---
ts/test-node/util/unicodeSlice_test.ts | 39 ++++++++++++++
ts/types/CallLink.ts | 20 ++++---
ts/util/callLinks.ts | 8 ++-
ts/util/onCallLinkUpdateSync.ts | 4 +-
ts/util/unicodeSlice.ts | 53 +++++++++++++++++++
22 files changed, 330 insertions(+), 118 deletions(-)
create mode 100644 stylesheets/components/CallLinkRestrictionsSelect.scss
create mode 100644 ts/components/CallLinkRestrictionsSelect.tsx
create mode 100644 ts/test-node/util/unicodeSlice_test.ts
create mode 100644 ts/util/unicodeSlice.ts
diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 4466aea2e4..3171e2f389 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -7289,6 +7289,18 @@
"messageformat": "Join",
"description": "Call History > Call Link Details > Join Button"
},
+ "icu:CallLinkDetails__AddCallNameLabel": {
+ "messageformat": "Add call name",
+ "description": "Call History > Call Link Details > Add Call Name Button > Label"
+ },
+ "icu:CallLinkDetails__EditCallNameLabel": {
+ "messageformat": "Edit call name",
+ "description": "Call History > Call Link Details > Edit Call Name Button > Label"
+ },
+ "icu:CallLinkDetails__ApproveAllMembersLabel": {
+ "messageformat": "Approve all members",
+ "description": "Call History > Call Link Details > Approve All Members > Label"
+ },
"icu:CallLinkDetails__CopyLink": {
"messageformat": "Copy link",
"description": "Call History > Call Link Details > Copy Link Button"
@@ -7309,15 +7321,19 @@
"messageformat": "Add call name",
"description": "Call Link Edit Modal > Add Call Name Button > Label"
},
+ "icu:CallLinkEditModal__EditCallNameLabel": {
+ "messageformat": "Edit call name",
+ "description": "Call Link Edit Modal > Edit Call Name Button > Label"
+ },
"icu:CallLinkEditModal__InputLabel--ApproveAllMembers": {
"messageformat": "Approve all members",
"description": "Call Link Edit Modal > Approve All Members Checkbox > Label"
},
- "icu:CallLinkEditModal__ApproveAllMembers__Option--Off": {
+ "icu:CallLinkRestrictionsSelect__Option--Off": {
"messageformat": "Off",
"description": "Call Link Edit Modal > Approve All Members Checkbox > Option > Off"
},
- "icu:CallLinkEditModal__ApproveAllMembers__Option--On": {
+ "icu:CallLinkRestrictionsSelect__Option--On": {
"messageformat": "On",
"description": "Call Link Edit Modal > Approve All Members Checkbox > Option > On"
},
@@ -7325,6 +7341,10 @@
"messageformat": "Add call name",
"description": "Call Link Add Name Modal > Title"
},
+ "icu:CallLinkAddNameModal__Title--Edit": {
+ "messageformat": "Edit call name",
+ "description": "Call Link Add Name Modal (When editing existing name) > Title"
+ },
"icu:CallLinkAddNameModal__NameLabel": {
"messageformat": "Call name",
"description": "Call Link Add Name Modal > Name Input > Label"
diff --git a/app/spell_check.ts b/app/spell_check.ts
index d644f58c19..4b512bc4ed 100644
--- a/app/spell_check.ts
+++ b/app/spell_check.ts
@@ -13,7 +13,7 @@ import { strictAssert } from '../ts/util/assert';
import type { LoggerType } from '../ts/types/Logging';
import { handleAttachmentRequest } from './attachment_channel';
-export const FAKE_DEFAULT_LOCALE = 'en-x-ignore'; // -x- is an extension space for attaching other metadata to the locale
+export const FAKE_DEFAULT_LOCALE = 'und'; // 'und' is the BCP 47 subtag for "undetermined"
strictAssert(
new Intl.Locale(FAKE_DEFAULT_LOCALE).toString() === FAKE_DEFAULT_LOCALE,
diff --git a/stylesheets/components/CallLinkEditModal.scss b/stylesheets/components/CallLinkEditModal.scss
index 9e76ddd040..5a405ab087 100644
--- a/stylesheets/components/CallLinkEditModal.scss
+++ b/stylesheets/components/CallLinkEditModal.scss
@@ -160,8 +160,3 @@
height: 1px;
background: $color-black-alpha-12;
}
-
-// Overriding default style
-.CallLinkEditModal__RowSelect.module-select select {
- min-width: 0;
-}
diff --git a/stylesheets/components/CallLinkRestrictionsSelect.scss b/stylesheets/components/CallLinkRestrictionsSelect.scss
new file mode 100644
index 0000000000..4bef16e2fe
--- /dev/null
+++ b/stylesheets/components/CallLinkRestrictionsSelect.scss
@@ -0,0 +1,7 @@
+// Copyright 2024 Signal Messenger, LLC
+// SPDX-License-Identifier: AGPL-3.0-only
+
+// Overriding default style
+.CallLinkRestrictionsSelect.module-select select {
+ min-width: 0;
+}
diff --git a/stylesheets/components/ConversationDetails.scss b/stylesheets/components/ConversationDetails.scss
index da7cccdaf4..53fa84d143 100644
--- a/stylesheets/components/ConversationDetails.scss
+++ b/stylesheets/components/ConversationDetails.scss
@@ -153,6 +153,14 @@
}
}
+ &--approveAllMembers {
+ &::after {
+ @include details-icon(
+ '../images/icons/v3/person/person-check-compact.svg'
+ );
+ }
+ }
+
&--link {
&::after {
@include details-icon('../images/icons/v3/link/link.svg');
diff --git a/stylesheets/manifest.scss b/stylesheets/manifest.scss
index 42536f0046..54b673b8a9 100644
--- a/stylesheets/manifest.scss
+++ b/stylesheets/manifest.scss
@@ -53,6 +53,7 @@
@import './components/CallLinkAddNameModal.scss';
@import './components/CallLinkDetails.scss';
@import './components/CallLinkEditModal.scss';
+@import './components/CallLinkRestrictionsSelect.scss';
@import './components/CallingRaisedHandsList.scss';
@import './components/CallingRaisedHandsToasts.scss';
@import './components/CallingReactionsToasts.scss';
diff --git a/ts/components/CallLinkAddNameModal.tsx b/ts/components/CallLinkAddNameModal.tsx
index 7b817a55e9..f983c72736 100644
--- a/ts/components/CallLinkAddNameModal.tsx
+++ b/ts/components/CallLinkAddNameModal.tsx
@@ -1,13 +1,16 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
-import React, { useCallback, useState } from 'react';
+import React, { useCallback, useMemo, useState } from 'react';
import { v4 as generateUuid } from 'uuid';
import { Modal } from './Modal';
import type { LocalizerType } from '../types/I18N';
import { Button, ButtonVariant } from './Button';
import { Avatar, AvatarSize } from './Avatar';
import { Input } from './Input';
-import type { CallLinkType } from '../types/CallLink';
+import {
+ CallLinkNameMaxByteLength,
+ type CallLinkType,
+} from '../types/CallLink';
import { getColorForCallLink } from '../util/getColorForCallLink';
export type CallLinkAddNameModalProps = Readonly<{
@@ -27,18 +30,25 @@ export function CallLinkAddNameModal({
const [nameId] = useState(() => generateUuid());
const [nameInput, setNameInput] = useState(callLink.name);
+ const parsedForm = useMemo(() => {
+ const name = nameInput.trim();
+ if (name === callLink.name) {
+ return null;
+ }
+ return { name };
+ }, [nameInput, callLink]);
+
const handleNameInputChange = useCallback((nextNameInput: string) => {
setNameInput(nextNameInput);
}, []);
const handleSubmit = useCallback(() => {
- const nameValue = nameInput.trim();
- if (nameValue === callLink.name) {
+ if (parsedForm == null) {
return;
}
- onUpdateCallLinkName(nameValue);
+ onUpdateCallLinkName(parsedForm.name);
onClose();
- }, [nameInput, callLink, onUpdateCallLinkName, onClose]);
+ }, [parsedForm, onUpdateCallLinkName, onClose]);
return (
{i18n('icu:cancel')}
-
diff --git a/ts/components/CallLinkDetails.tsx b/ts/components/CallLinkDetails.tsx
index 92ad777c87..e6c4591adb 100644
--- a/ts/components/CallLinkDetails.tsx
+++ b/ts/components/CallLinkDetails.tsx
@@ -10,13 +10,15 @@ import {
IconType,
} from './conversation/conversation-details/ConversationDetailsIcon';
import { PanelRow } from './conversation/conversation-details/PanelRow';
-import type { CallLinkType } from '../types/CallLink';
+import type { CallLinkRestrictions, CallLinkType } from '../types/CallLink';
import { linkCallRoute } from '../util/signalRoutes';
import { drop } from '../util/drop';
import { Avatar, AvatarSize } from './Avatar';
import { Button, ButtonSize, ButtonVariant } from './Button';
import { copyCallLink } from '../util/copyLinksWithToast';
import { getColorForCallLink } from '../util/getColorForCallLink';
+import { isCallLinkAdmin } from '../util/callLinks';
+import { CallLinkRestrictionsSelect } from './CallLinkRestrictionsSelect';
function toUrlWithoutProtocol(url: URL): string {
return `${url.hostname}${url.pathname}${url.search}${url.hash}`;
@@ -26,16 +28,20 @@ export type CallLinkDetailsProps = Readonly<{
callHistoryGroup: CallHistoryGroup;
callLink: CallLinkType;
i18n: LocalizerType;
+ onOpenCallLinkAddNameModal: () => void;
onStartCallLinkLobby: () => void;
onShareCallLinkViaSignal: () => void;
+ onUpdateCallLinkRestrictions: (restrictions: CallLinkRestrictions) => void;
}>;
export function CallLinkDetails({
callHistoryGroup,
callLink,
i18n,
+ onOpenCallLinkAddNameModal,
onStartCallLinkLobby,
onShareCallLinkViaSignal,
+ onUpdateCallLinkRestrictions,
}: CallLinkDetailsProps): JSX.Element {
const webUrl = linkCallRoute.toWebUrl({
key: callLink.rootKey,
@@ -80,6 +86,40 @@ export function CallLinkDetails({
callHistoryGroup={callHistoryGroup}
i18n={i18n}
/>
+ {isCallLinkAdmin(callLink) && (
+
+
+ }
+ label={
+ callLink.name === ''
+ ? i18n('icu:CallLinkDetails__AddCallNameLabel')
+ : i18n('icu:CallLinkDetails__EditCallNameLabel')
+ }
+ onClick={onOpenCallLinkAddNameModal}
+ />
+
+ }
+ label={i18n('icu:CallLinkDetails__ApproveAllMembersLabel')}
+ right={
+
+ }
+ />
+
+ )}
- {i18n('icu:CallLinkEditModal__AddCallNameLabel')}
+
+ {callLink.name === ''
+ ? i18n('icu:CallLinkEditModal__AddCallNameLabel')
+ : i18n('icu:CallLinkEditModal__EditCallNameLabel')}
+
@@ -171,27 +172,11 @@ export function CallLinkEditModal({
{i18n('icu:CallLinkEditModal__InputLabel--ApproveAllMembers')}
-