mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2025-12-20 02:08:57 +00:00
PinnedMessagesPanel: Add footer with Unpin all messages button
This commit is contained in:
@@ -1682,6 +1682,10 @@
|
||||
"messageformat": "Pinned messages",
|
||||
"description": "Conversation > Pinned messages panel (view all) > Title"
|
||||
},
|
||||
"icu:PinnedMessagesPanel__UnpinAllMessages": {
|
||||
"messageformat": "Unpin all messages",
|
||||
"description": "Conversation > Pinned messages panel (view all) > Unpin all messages button"
|
||||
},
|
||||
"icu:sessionEnded": {
|
||||
"messageformat": "Secure session reset",
|
||||
"description": "This is a past tense, informational message. In other words, your secure session has been reset."
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
height: 100%;
|
||||
inset-inline-start: 0;
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
@@ -28,12 +27,13 @@
|
||||
// Used for centering EmptyState in All Media view
|
||||
position: relative;
|
||||
|
||||
overflow-y: auto;
|
||||
flex-grow: 1;
|
||||
padding-top: calc(
|
||||
#{variables.$header-height} + var(--title-bar-drag-area-height)
|
||||
);
|
||||
|
||||
&--padding {
|
||||
padding-inline: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&__header {
|
||||
flex-shrink: 0;
|
||||
@@ -44,7 +44,6 @@
|
||||
#{variables.$header-height} + var(--title-bar-drag-area-height)
|
||||
);
|
||||
padding-top: var(--title-bar-drag-area-height);
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
z-index: variables.$z-index-base;
|
||||
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
import React, { Fragment, memo, useMemo, useRef, useState } from 'react';
|
||||
import type { ForwardedRef, ReactNode } from 'react';
|
||||
import React, {
|
||||
forwardRef,
|
||||
Fragment,
|
||||
memo,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { useLayoutEffect } from '@react-aria/utils';
|
||||
import type { LocalizerType } from '../../../types/I18N.std.js';
|
||||
import type { ConversationType } from '../../../state/ducks/conversations.preload.js';
|
||||
@@ -16,6 +24,8 @@ import { getWidthBreakpoint } from '../../../util/timelineUtil.std.js';
|
||||
import { strictAssert } from '../../../util/assert.std.js';
|
||||
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';
|
||||
|
||||
export type PinnedMessagesPanelProps = Readonly<{
|
||||
i18n: LocalizerType;
|
||||
@@ -27,6 +37,7 @@ export type PinnedMessagesPanelProps = Readonly<{
|
||||
export const PinnedMessagesPanel = memo(function PinnedMessagesPanel(
|
||||
props: PinnedMessagesPanelProps
|
||||
) {
|
||||
const { i18n } = props;
|
||||
const containerElementRef = useRef<HTMLDivElement>(null);
|
||||
const [containerWidthBreakpoint, setContainerWidthBreakpoint] = useState(
|
||||
WidthBreakpoint.Wide
|
||||
@@ -42,19 +53,9 @@ export const PinnedMessagesPanel = memo(function PinnedMessagesPanel(
|
||||
setContainerWidthBreakpoint(getWidthBreakpoint(size.width));
|
||||
});
|
||||
|
||||
const scrollerLock = useMemo(() => {
|
||||
return createScrollerLock('PinnedMessagesPanel', () => {
|
||||
// noop - we probably don't need to do anything here because the only
|
||||
// thing that can happen is the pinned messages getting removed/added
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<AxoScrollArea.Root scrollbarWidth="wide">
|
||||
<AxoScrollArea.Viewport>
|
||||
<AxoScrollArea.Content>
|
||||
<div ref={containerElementRef}>
|
||||
<ScrollerLockContext.Provider value={scrollerLock}>
|
||||
<div className={tw('flex h-full flex-col')}>
|
||||
<ScrollArea ref={containerElementRef}>
|
||||
{props.pinnedMessages.map((pinnedMessage, pinnedMessageIndex) => {
|
||||
const next = props.pinnedMessages[pinnedMessageIndex + 1];
|
||||
const prev = props.pinnedMessages[pinnedMessageIndex - 1];
|
||||
@@ -76,6 +77,36 @@ export const PinnedMessagesPanel = memo(function PinnedMessagesPanel(
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
</ScrollArea>
|
||||
<div className={tw('flex items-center justify-center p-2.5')}>
|
||||
<AxoButton.Root variant="borderless-primary" size="lg">
|
||||
{i18n('icu:PinnedMessagesPanel__UnpinAllMessages')}
|
||||
</AxoButton.Root>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
const ScrollArea = forwardRef(function ScrollArea(
|
||||
props: { children: ReactNode },
|
||||
ref: ForwardedRef<HTMLDivElement>
|
||||
) {
|
||||
const scrollerLock = useMemo(() => {
|
||||
return createScrollerLock('PinnedMessagesPanel', () => {
|
||||
// noop - we probably don't need to do anything here because the only
|
||||
// thing that can happen is the pinned messages getting removed/added
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<AxoScrollArea.Root scrollbarWidth="wide">
|
||||
<AxoScrollArea.Hint edge="top" />
|
||||
<AxoScrollArea.Hint edge="bottom" />
|
||||
<AxoScrollArea.Viewport>
|
||||
<AxoScrollArea.Content>
|
||||
<div ref={ref}>
|
||||
<ScrollerLockContext.Provider value={scrollerLock}>
|
||||
{props.children}
|
||||
</ScrollerLockContext.Provider>
|
||||
</div>
|
||||
</AxoScrollArea.Content>
|
||||
|
||||
@@ -11,6 +11,7 @@ import React, {
|
||||
useState,
|
||||
} from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import classNames from 'classnames';
|
||||
import type { PanelRenderType } from '../../types/Panels.std.js';
|
||||
import { createLogger } from '../../logging/log.std.js';
|
||||
import { PanelType } from '../../types/Panels.std.js';
|
||||
@@ -322,7 +323,14 @@ const PanelContainer = forwardRef<
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="ConversationPanel__body" ref={focusRef}>
|
||||
<div
|
||||
className={classNames(
|
||||
'ConversationPanel__body',
|
||||
panel.type !== PanelType.PinnedMessages &&
|
||||
'ConversationPanel__body--padding'
|
||||
)}
|
||||
ref={focusRef}
|
||||
>
|
||||
<PanelElement conversationId={conversationId} panel={panel} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user