Make unpin all button work

Co-authored-by: Jamie <113370520+jamiebuilds-signal@users.noreply.github.com>
This commit is contained in:
automated-signal
2025-12-16 11:11:57 -06:00
committed by GitHub
parent 5ca8a9779c
commit 1b5b2a1d99
3 changed files with 79 additions and 2 deletions

View File

@@ -1750,6 +1750,22 @@
"messageformat": "Unpin all messages",
"description": "Conversation > Pinned messages panel (view all) > Unpin all messages button"
},
"icu:PinnedMessagesPanel__UnpinAllMessages__ConfirmDialog__Title": {
"messageformat": "Unpin all messages?",
"description": "Conversation > Pinned messages panel (view all) > Unpin all messages button > Confirm Dialog > Title"
},
"icu:PinnedMessagesPanel__UnpinAllMessages__ConfirmDialog__Description--Group": {
"messageformat": "Messages will be unpinned for all group members.",
"description": "Conversation > Pinned messages panel (view all) > Unpin all messages button > Confirm Dialog > Description (in group)"
},
"icu:PinnedMessagesPanel__UnpinAllMessages__ConfirmDialog__Cancel": {
"messageformat": "Cancel",
"description": "Conversation > Pinned messages panel (view all) > Unpin all messages button > Confirm Dialog > Cancel"
},
"icu:PinnedMessagesPanel__UnpinAllMessages__ConfirmDialog__Unpin": {
"messageformat": "Unpin",
"description": "Conversation > Pinned messages panel (view all) > Unpin all messages button > Confirm Dialog > Unpin"
},
"icu:sessionEnded": {
"messageformat": "Secure session reset",
"description": "This is a past tense, informational message. In other words, your secure session has been reset."

View File

@@ -5,6 +5,7 @@ import React, {
forwardRef,
Fragment,
memo,
useCallback,
useMemo,
useRef,
useState,
@@ -26,12 +27,14 @@ import { useSizeObserver } from '../../../hooks/useSizeObserver.dom.js';
import { MessageInteractivity } from '../Message.dom.js';
import { tw } from '../../../axo/tw.dom.js';
import { AxoButton } from '../../../axo/AxoButton.dom.js';
import { AxoAlertDialog } from '../../../axo/AxoAlertDialog.dom.js';
export type PinnedMessagesPanelProps = Readonly<{
i18n: LocalizerType;
conversation: ConversationType;
pinnedMessages: ReadonlyArray<PinnedMessageRenderData>;
canPinMessages: boolean;
onPinnedMessageRemoveAll: () => void;
renderTimelineItem: (props: SmartTimelineItemProps) => JSX.Element;
}>;
@@ -44,6 +47,13 @@ export const PinnedMessagesPanel = memo(function PinnedMessagesPanel(
WidthBreakpoint.Wide
);
const [confirmUnpinAllDialogOpen, setConfirmUnpinAllDialogOpen] =
useState(false);
const handleClickUnpinAll = useCallback(() => {
setConfirmUnpinAllDialogOpen(true);
}, []);
useLayoutEffect(() => {
strictAssert(containerElementRef.current, 'Missing container ref');
const container = containerElementRef.current;
@@ -81,11 +91,49 @@ export const PinnedMessagesPanel = memo(function PinnedMessagesPanel(
</ScrollArea>
{props.canPinMessages && (
<div className={tw('flex items-center justify-center p-2.5')}>
<AxoButton.Root variant="borderless-primary" size="lg">
<AxoButton.Root
variant="borderless-primary"
size="lg"
onClick={handleClickUnpinAll}
>
{i18n('icu:PinnedMessagesPanel__UnpinAllMessages')}
</AxoButton.Root>
</div>
)}
<AxoAlertDialog.Root
open={confirmUnpinAllDialogOpen}
onOpenChange={setConfirmUnpinAllDialogOpen}
>
<AxoAlertDialog.Content escape="cancel-is-noop">
<AxoAlertDialog.Body>
<AxoAlertDialog.Title>
{i18n(
'icu:PinnedMessagesPanel__UnpinAllMessages__ConfirmDialog__Title'
)}
</AxoAlertDialog.Title>
<AxoAlertDialog.Description>
{i18n(
'icu:PinnedMessagesPanel__UnpinAllMessages__ConfirmDialog__Description--Group'
)}
</AxoAlertDialog.Description>
</AxoAlertDialog.Body>
<AxoAlertDialog.Footer>
<AxoAlertDialog.Cancel>
{i18n(
'icu:PinnedMessagesPanel__UnpinAllMessages__ConfirmDialog__Cancel'
)}
</AxoAlertDialog.Cancel>
<AxoAlertDialog.Action
variant="primary"
onClick={props.onPinnedMessageRemoveAll}
>
{i18n(
'icu:PinnedMessagesPanel__UnpinAllMessages__ConfirmDialog__Unpin'
)}
</AxoAlertDialog.Action>
</AxoAlertDialog.Footer>
</AxoAlertDialog.Content>
</AxoAlertDialog.Root>
</div>
);
});

View File

@@ -1,7 +1,7 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { memo } from 'react';
import React, { memo, useCallback } from 'react';
import { useSelector } from 'react-redux';
import { getIntl } from '../selectors/user.std.js';
import { getConversationByIdSelector } from '../selectors/conversations.dom.js';
@@ -11,6 +11,8 @@ import type { SmartTimelineItemProps } from './TimelineItem.preload.js';
import { SmartTimelineItem } from './TimelineItem.preload.js';
import { getPinnedMessages } from '../selectors/pinnedMessages.dom.js';
import { canPinMessages as getCanPinMessages } from '../selectors/message.preload.js';
import { usePinnedMessagesActions } from '../ducks/pinnedMessages.preload.js';
import { useConversationsActions } from '../ducks/conversations.preload.js';
export type SmartPinnedMessagesPanelProps = Readonly<{
conversationId: string;
@@ -26,6 +28,7 @@ export const SmartPinnedMessagesPanel = memo(function SmartPinnedMessagesPanel(
const i18n = useSelector(getIntl);
const conversationSelector = useSelector(getConversationByIdSelector);
const conversation = conversationSelector(props.conversationId);
const { popPanelForConversation } = useConversationsActions();
strictAssert(
conversation,
@@ -35,6 +38,15 @@ export const SmartPinnedMessagesPanel = memo(function SmartPinnedMessagesPanel(
const pinnedMessages = useSelector(getPinnedMessages);
const canPinMessages = getCanPinMessages(conversation);
const { onPinnedMessageRemove } = usePinnedMessagesActions();
const handlePinnedMessageRemoveAll = useCallback(() => {
popPanelForConversation();
for (const { pinnedMessage } of pinnedMessages) {
onPinnedMessageRemove(pinnedMessage.messageId);
}
}, [popPanelForConversation, pinnedMessages, onPinnedMessageRemove]);
return (
<PinnedMessagesPanel
i18n={i18n}
@@ -42,6 +54,7 @@ export const SmartPinnedMessagesPanel = memo(function SmartPinnedMessagesPanel(
pinnedMessages={pinnedMessages}
renderTimelineItem={renderTimelineItem}
canPinMessages={canPinMessages}
onPinnedMessageRemoveAll={handlePinnedMessageRemoveAll}
/>
);
});