mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-02-15 07:28:59 +00:00
GroupMemberLabelEditor: Show dialog on save or permissions error
Co-authored-by: Scott Nonnenberg <scott@signal.org>
This commit is contained in:
@@ -6240,6 +6240,18 @@
|
||||
"messageformat": "Saving changes...",
|
||||
"description": "Accessibility label for button with spinner as we save the user's member label."
|
||||
},
|
||||
"icu:ConversationDetails--member-label--error-title": {
|
||||
"messageformat": "Can’t save member label",
|
||||
"description": "If save of member label failed, a dialog shows. Title of dialog."
|
||||
},
|
||||
"icu:ConversationDetails--member-label--error-generic": {
|
||||
"messageformat": "Check your connection and try again.",
|
||||
"description": "If save of member label failed, a dialog shows. Description of dialog."
|
||||
},
|
||||
"icu:ConversationDetails--member-label--error-permissions": {
|
||||
"messageformat": "Only admins can set member labels in this group.",
|
||||
"description": "If Desktop discovers that permissions have changed since entering the screen, it will show this in an error dialog and exit the pane."
|
||||
},
|
||||
"icu:ConversationDetails--disappearing-messages-label": {
|
||||
"messageformat": "Disappearing messages",
|
||||
"description": "This is the label for the disappearing messages setting panel"
|
||||
|
||||
@@ -9,6 +9,9 @@ import { GroupMemberLabelEditor } from './GroupMemberLabelEditor.dom.js';
|
||||
import { getDefaultConversation } from '../../../test-helpers/getDefaultConversation.std.js';
|
||||
import { ThemeType } from '../../../types/Util.std.js';
|
||||
import { getFakeBadge } from '../../../test-helpers/getFakeBadge.std.js';
|
||||
import { SECOND } from '../../../util/durations/constants.std.js';
|
||||
import { sleep } from '../../../util/sleep.std.js';
|
||||
import { SignalService as Proto } from '../../../protobuf/index.std.js';
|
||||
|
||||
const { i18n } = window.SignalContext;
|
||||
|
||||
@@ -26,7 +29,14 @@ const createProps = (): PropsType => ({
|
||||
ourColor: '160',
|
||||
popPanelForConversation: action('popPanelForConversation'),
|
||||
theme: ThemeType.light,
|
||||
updateGroupMemberLabel: action('changeHasGroupLink'),
|
||||
updateGroupMemberLabel: async (
|
||||
options,
|
||||
callbacks?: { onSuccess?: () => unknown }
|
||||
) => {
|
||||
action('updateGroupMemberLabel')(options);
|
||||
await sleep(SECOND);
|
||||
callbacks?.onSuccess?.();
|
||||
},
|
||||
});
|
||||
|
||||
export function NoExistingLabel(): React.JSX.Element {
|
||||
@@ -62,3 +72,51 @@ export function WithBadge(): React.JSX.Element {
|
||||
|
||||
return <GroupMemberLabelEditor {...props} />;
|
||||
}
|
||||
|
||||
export function ThrowsErrorOnSave(): React.JSX.Element {
|
||||
const props: PropsType = {
|
||||
...createProps(),
|
||||
updateGroupMemberLabel: async (
|
||||
options,
|
||||
callbacks?: { onFailure?: () => unknown }
|
||||
) => {
|
||||
action('updateGroupMemberLabel')(options);
|
||||
await sleep(SECOND);
|
||||
callbacks?.onFailure?.();
|
||||
},
|
||||
};
|
||||
|
||||
return <GroupMemberLabelEditor {...props} />;
|
||||
}
|
||||
|
||||
export function PermissionsError(): React.JSX.Element {
|
||||
const props: PropsType = createProps();
|
||||
|
||||
return (
|
||||
<GroupMemberLabelEditor
|
||||
{...props}
|
||||
group={{
|
||||
...props.group,
|
||||
areWeAdmin: false,
|
||||
accessControlAttributes:
|
||||
Proto.AccessControl.AccessRequired.ADMINISTRATOR,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function PermissionsRestrictedButAdmin(): React.JSX.Element {
|
||||
const props: PropsType = createProps();
|
||||
|
||||
return (
|
||||
<GroupMemberLabelEditor
|
||||
{...props}
|
||||
group={{
|
||||
...props.group,
|
||||
areWeAdmin: true,
|
||||
accessControlAttributes:
|
||||
Proto.AccessControl.AccessRequired.ADMINISTRATOR,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2026 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { useRef, useState } from 'react';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { noop } from 'lodash';
|
||||
|
||||
import { Input } from '../../Input.dom.js';
|
||||
@@ -26,6 +26,8 @@ import {
|
||||
} from '../Message.dom.js';
|
||||
import { ConversationColors } from '../../../types/Colors.std.js';
|
||||
import { WidthBreakpoint } from '../../_util.std.js';
|
||||
import { AxoAlertDialog } from '../../../axo/AxoAlertDialog.dom.js';
|
||||
import { SignalService as Proto } from '../../../protobuf/index.std.js';
|
||||
|
||||
import type { EmojiVariantKey } from '../../fun/data/emojis.std.js';
|
||||
import type {
|
||||
@@ -71,6 +73,11 @@ export function GroupMemberLabelEditor({
|
||||
theme,
|
||||
updateGroupMemberLabel,
|
||||
}: PropsType): React.JSX.Element {
|
||||
const [isShowingGeneralError, setIsShowingGeneralError] =
|
||||
React.useState(false);
|
||||
const [isShowingPermissionsError, setIsShowingPermissionsError] =
|
||||
React.useState(false);
|
||||
|
||||
const messageContainer = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const [labelEmoji, setLabelEmoji] = useState(existingLabelEmoji);
|
||||
@@ -94,6 +101,17 @@ export function GroupMemberLabelEditor({
|
||||
? { labelEmoji, labelString: labelString.trim() }
|
||||
: undefined;
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
!group.areWeAdmin &&
|
||||
group.accessControlAttributes ===
|
||||
Proto.AccessControl.AccessRequired.ADMINISTRATOR &&
|
||||
!isShowingPermissionsError
|
||||
) {
|
||||
setIsShowingPermissionsError(true);
|
||||
}
|
||||
}, [group, isShowingPermissionsError, setIsShowingPermissionsError]);
|
||||
|
||||
return (
|
||||
<div className={tw('mx-auto flex h-full max-w-[640px] flex-col')}>
|
||||
<div>
|
||||
@@ -245,7 +263,8 @@ export function GroupMemberLabelEditor({
|
||||
popPanelForConversation();
|
||||
},
|
||||
onFailure() {
|
||||
// TODO: DESKTOP-9710
|
||||
setIsSaving(false);
|
||||
setIsShowingGeneralError(true);
|
||||
},
|
||||
}
|
||||
);
|
||||
@@ -254,6 +273,68 @@ export function GroupMemberLabelEditor({
|
||||
{i18n('icu:save')}
|
||||
</AxoButton.Root>
|
||||
</div>
|
||||
<AxoAlertDialog.Root
|
||||
open={isShowingGeneralError}
|
||||
onOpenChange={value => {
|
||||
if (!value) {
|
||||
setIsShowingGeneralError(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AxoAlertDialog.Content escape="cancel-is-noop">
|
||||
<AxoAlertDialog.Body>
|
||||
<AxoAlertDialog.Title>
|
||||
{i18n('icu:ConversationDetails--member-label--error-title')}
|
||||
</AxoAlertDialog.Title>
|
||||
<AxoAlertDialog.Description>
|
||||
{i18n('icu:ConversationDetails--member-label--error-generic')}
|
||||
</AxoAlertDialog.Description>
|
||||
</AxoAlertDialog.Body>
|
||||
<AxoAlertDialog.Footer>
|
||||
<AxoAlertDialog.Action
|
||||
variant="primary"
|
||||
arrow={false}
|
||||
onClick={() => {
|
||||
setIsShowingGeneralError(false);
|
||||
}}
|
||||
>
|
||||
{i18n('icu:ok')}
|
||||
</AxoAlertDialog.Action>
|
||||
</AxoAlertDialog.Footer>
|
||||
</AxoAlertDialog.Content>
|
||||
</AxoAlertDialog.Root>
|
||||
<AxoAlertDialog.Root
|
||||
open={isShowingPermissionsError}
|
||||
onOpenChange={value => {
|
||||
if (!value) {
|
||||
setIsShowingPermissionsError(false);
|
||||
popPanelForConversation();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AxoAlertDialog.Content escape="cancel-is-noop">
|
||||
<AxoAlertDialog.Body>
|
||||
<AxoAlertDialog.Title>
|
||||
{i18n('icu:ConversationDetails--member-label--error-title')}
|
||||
</AxoAlertDialog.Title>
|
||||
<AxoAlertDialog.Description>
|
||||
{i18n('icu:ConversationDetails--member-label--error-permissions')}
|
||||
</AxoAlertDialog.Description>
|
||||
</AxoAlertDialog.Body>
|
||||
<AxoAlertDialog.Footer>
|
||||
<AxoAlertDialog.Action
|
||||
variant="primary"
|
||||
arrow={false}
|
||||
onClick={() => {
|
||||
popPanelForConversation();
|
||||
setIsShowingPermissionsError(false);
|
||||
}}
|
||||
>
|
||||
{i18n('icu:ok')}
|
||||
</AxoAlertDialog.Action>
|
||||
</AxoAlertDialog.Footer>
|
||||
</AxoAlertDialog.Content>
|
||||
</AxoAlertDialog.Root>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user