diff --git a/ts/components/conversation/conversation-details/GroupMemberLabelEditor.dom.tsx b/ts/components/conversation/conversation-details/GroupMemberLabelEditor.dom.tsx
index 0da56454d4..66350c6714 100644
--- a/ts/components/conversation/conversation-details/GroupMemberLabelEditor.dom.tsx
+++ b/ts/components/conversation/conversation-details/GroupMemberLabelEditor.dom.tsx
@@ -12,7 +12,6 @@ import {
isEmojiVariantValue,
} from '../../fun/data/emojis.std.js';
import { FunEmojiPickerButton } from '../../fun/FunButton.dom.js';
-
import { tw } from '../../../axo/tw.dom.js';
import { AxoButton } from '../../../axo/AxoButton.dom.js';
import {
@@ -28,6 +27,12 @@ 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 { Avatar, AvatarSize } from '../../Avatar.dom.js';
+import { UserText } from '../../UserText.dom.js';
+import { GroupMemberLabel } from '../ContactName.dom.js';
+import { useConfirmDiscard } from '../../../hooks/useConfirmDiscard.dom.js';
+import { NavTab } from '../../../types/Nav.std.js';
+import { PanelType } from '../../../types/Panels.std.js';
import type { EmojiVariantKey } from '../../fun/data/emojis.std.js';
import type {
@@ -36,9 +41,7 @@ import type {
} from '../../../state/ducks/conversations.preload.js';
import type { LocalizerType, ThemeType } from '../../../types/Util.std.js';
import type { PreferredBadgeSelectorType } from '../../../state/selectors/badges.preload.js';
-import { Avatar, AvatarSize } from '../../Avatar.dom.js';
-import { UserText } from '../../UserText.dom.js';
-import { GroupMemberLabel } from '../ContactName.dom.js';
+import type { Location } from '../../../types/Nav.std.js';
export type PropsDataType = {
existingLabelEmoji: string | undefined;
@@ -63,6 +66,21 @@ export type PropsType = PropsDataType & {
updateGroupMemberLabel: UpdateGroupMemberLabelType;
};
+// We don't want to render any panel behind it as we animate it in, if we weren't already
+// showing the ConversationDetails pane.
+export function getLeafPanelOnly(
+ location: Location,
+ conversationId: string | undefined
+): boolean {
+ return (
+ !conversationId ||
+ location.tab !== NavTab.Chats ||
+ location.details.conversationId !== conversationId ||
+ location.details.panels?.watermark === -1 ||
+ location.details.panels?.stack[0]?.type !== PanelType.ConversationDetails
+ );
+}
+
function getEmojiVariantKey(value: string): EmojiVariantKey | undefined {
if (isEmojiVariantValue(value)) {
return getEmojiVariantKeyByValue(value);
@@ -126,6 +144,19 @@ export function GroupMemberLabelEditor({
}
}, [group, isShowingPermissionsError, setIsShowingPermissionsError]);
+ const tryClose = React.useRef<() => void | undefined>();
+ const [confirmDiscardModal, confirmDiscardIf] = useConfirmDiscard({
+ i18n,
+ name: 'GroupMemberLabelEditor',
+ tryClose,
+ });
+
+ const onTryClose = React.useCallback(() => {
+ const discardChanges = noop;
+ confirmDiscardIf(isDirty, discardChanges);
+ }, [confirmDiscardIf, isDirty]);
+ tryClose.current = onTryClose;
+
return (
@@ -367,6 +398,7 @@ export function GroupMemberLabelEditor({
{i18n('icu:save')}
+ {confirmDiscardModal}
{
diff --git a/ts/state/ducks/nav.std.ts b/ts/state/ducks/nav.std.ts
index 11bed629f8..90c93a455f 100644
--- a/ts/state/ducks/nav.std.ts
+++ b/ts/state/ducks/nav.std.ts
@@ -350,6 +350,7 @@ export function reducer(
...state.selectedLocation.details.panels,
isAnimating: false,
wasAnimated: true,
+ leafPanelOnly: false,
},
},
},
diff --git a/ts/state/selectors/nav.std.ts b/ts/state/selectors/nav.std.ts
index 397d6c75ff..717b1d5029 100644
--- a/ts/state/selectors/nav.std.ts
+++ b/ts/state/selectors/nav.std.ts
@@ -60,6 +60,7 @@ export const getActivePanel = createSelector(
type PanelInformationType = {
currPanel: PanelArgsType | undefined;
+ leafPanelOnly?: boolean;
direction: 'push' | 'pop';
prevPanel: PanelArgsType | undefined;
};
@@ -72,7 +73,7 @@ export const getPanelInformation = createSelector(
return;
}
- const { direction, watermark } = panels;
+ const { direction, watermark, leafPanelOnly } = panels;
if (!direction) {
return;
@@ -86,6 +87,7 @@ export const getPanelInformation = createSelector(
currPanel,
direction,
prevPanel,
+ leafPanelOnly,
};
}
);
diff --git a/ts/state/smart/AboutContactModal.preload.tsx b/ts/state/smart/AboutContactModal.preload.tsx
index 93dd8f38f0..600416bb55 100644
--- a/ts/state/smart/AboutContactModal.preload.tsx
+++ b/ts/state/smart/AboutContactModal.preload.tsx
@@ -21,9 +21,15 @@ import { getAddedByForOurPendingInvitation } from '../../util/getAddedByForOurPe
import { getItems } from '../selectors/items.dom.js';
import { isFeaturedEnabledSelector } from '../../util/isFeatureEnabled.dom.js';
import { getCanAddLabel } from '../../types/GroupMemberLabels.std.js';
-import { createLogger } from '../../logging/log.std.js';
-
-const log = createLogger('SmartAboutContactModal');
+import { useNavActions } from '../ducks/nav.std.js';
+import { PanelType } from '../../types/Panels.std.js';
+import {
+ NavTab,
+ ProfileEditorPage,
+ SettingsPage,
+} from '../../types/Nav.std.js';
+import { getSelectedLocation } from '../selectors/nav.std.js';
+import { getLeafPanelOnly } from '../../components/conversation/conversation-details/GroupMemberLabelEditor.dom.js';
function isFromOrAddedByTrustedContact(
conversation: ConversationType
@@ -57,10 +63,6 @@ export const SmartAboutContactModal = memo(function SmartAboutContactModal() {
remoteConfig: items.remoteConfig,
prodKey: 'desktop.groupMemberLabels.edit.prod',
});
- // TODO: DESKTOP-9711
- log.info(
- `Not using feature flag of ${isEditMemberLabelEnabled}; hardcoding to false`
- );
const sharedGroupNames = useSharedGroupNamesOnMount(contactId ?? '');
@@ -88,6 +90,10 @@ export const SmartAboutContactModal = memo(function SmartAboutContactModal() {
toggleNotePreviewModal,
toggleProfileNameWarningModal,
} = useGlobalModalActions();
+ const { changeLocation } = useNavActions();
+
+ const selectedLocation = useSelector(getSelectedLocation);
+ const leafPanelOnly = getLeafPanelOnly(selectedLocation, conversationId);
const handleOpenNotePreviewModal = useCallback(() => {
strictAssert(contactId != null, 'contactId is required');
@@ -107,7 +113,7 @@ export const SmartAboutContactModal = memo(function SmartAboutContactModal() {
contactLabelString={contactLabelString}
contactNameColor={contactNameColor}
fromOrAddedByTrustedContact={isFromOrAddedByTrustedContact(contact)}
- isEditMemberLabelEnabled={false}
+ isEditMemberLabelEnabled={isEditMemberLabelEnabled}
isSignalConnection={isSignalConnection(contact)}
onClose={toggleAboutContactModal}
onOpenNotePreviewModal={handleOpenNotePreviewModal}
@@ -115,6 +121,46 @@ export const SmartAboutContactModal = memo(function SmartAboutContactModal() {
conversationId ? isPendingAvatarDownload(conversationId) : false
}
sharedGroupNames={sharedGroupNames}
+ showProfileEditor={() => {
+ changeLocation({
+ tab: NavTab.Settings,
+ details: {
+ page: SettingsPage.Profile,
+ state: ProfileEditorPage.ProfileName,
+ },
+ });
+ toggleAboutContactModal(undefined);
+ }}
+ showQRCodeScreen={() => {
+ changeLocation({
+ tab: NavTab.Settings,
+ details: {
+ page: SettingsPage.Profile,
+ state: ProfileEditorPage.UsernameLink,
+ },
+ });
+ toggleAboutContactModal(undefined);
+ }}
+ showEditMemberLabelScreen={() => {
+ changeLocation({
+ tab: NavTab.Chats,
+ details: {
+ conversationId,
+ panels: {
+ direction: 'push' as const,
+ isAnimating: false,
+ leafPanelOnly,
+ stack: [
+ { type: PanelType.ConversationDetails },
+ { type: PanelType.GroupMemberLabelEditor },
+ ],
+ wasAnimated: false,
+ watermark: 1,
+ },
+ },
+ });
+ toggleAboutContactModal(undefined);
+ }}
startAvatarDownload={
conversationId ? () => startAvatarDownload(conversationId) : undefined
}
diff --git a/ts/state/smart/ConversationPanel.preload.tsx b/ts/state/smart/ConversationPanel.preload.tsx
index f22818bd0c..3ac93e9954 100644
--- a/ts/state/smart/ConversationPanel.preload.tsx
+++ b/ts/state/smart/ConversationPanel.preload.tsx
@@ -209,7 +209,12 @@ export const ConversationPanel = memo(function ConversationPanel({
return null;
}
- const { currPanel: activePanel, direction, prevPanel } = panelInformation;
+ const {
+ currPanel: activePanel,
+ direction,
+ leafPanelOnly,
+ prevPanel,
+ } = panelInformation;
if (!direction) {
return null;
@@ -248,13 +253,15 @@ export const ConversationPanel = memo(function ConversationPanel({
if (direction === 'push' && activePanel) {
return (
<>
- {lastPanelDoneAnimating !== prevPanel && prevPanel && (
-
- )}
+ {!leafPanelOnly &&
+ lastPanelDoneAnimating !== prevPanel &&
+ prevPanel && (
+
+ )}
user.ourAci && membership.aci === user.ourAci
);
const hasLabel = Boolean(contactMembership?.labelString);
const canAddLabel = getCanAddLabel(conversation, contactMembership);
- const { toggleGroupMemberLabelInfoModal } = useGlobalModalActions();
+ const { toggleGroupMemberLabelInfoModal, hideContactModal } =
+ useGlobalModalActions();
return (
toggleGroupMemberLabelInfoModal(undefined)}
showEditMemberLabelScreen={() => {
- // TODO: DESKTOP-9711
- throw new Error('Not yet implemented');
+ changeLocation({
+ tab: NavTab.Chats,
+ details: {
+ conversationId,
+ panels: {
+ direction: 'push' as const,
+ isAnimating: false,
+ leafPanelOnly,
+ stack: [
+ { type: PanelType.ConversationDetails },
+ { type: PanelType.GroupMemberLabelEditor },
+ ],
+ wasAnimated: false,
+ watermark: 1,
+ },
+ },
+ });
+ toggleGroupMemberLabelInfoModal(undefined);
+ hideContactModal();
}}
/>
);
diff --git a/ts/types/Nav.std.ts b/ts/types/Nav.std.ts
index 29c1d22b40..ff91c2b894 100644
--- a/ts/types/Nav.std.ts
+++ b/ts/types/Nav.std.ts
@@ -23,10 +23,12 @@ export type ChatDetails = ReadonlyDeep<{
}>;
export type PanelInfo = {
- isAnimating: boolean;
- wasAnimated: boolean;
direction: 'push' | 'pop' | undefined;
+ isAnimating: boolean;
+ // When navigating deep into a panel stack, we only want to render the leaf panel
+ leafPanelOnly?: boolean;
stack: ReadonlyArray;
+ wasAnimated: boolean;
watermark: number;
};