mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 05:25:40 +09:00
feat(app): let the pinned messages popout be resized (#1948)
This commit is contained in:
1 parent
dceb9061d9
commit
6cd30d893a
2 files changed
+83
-7
No files matched your search
@@ -1,14 +1,11 @@
|
|||||||
/* SPDX-License-Identifier: AGPL-3.0-or-later */
|
/* SPDX-License-Identifier: AGPL-3.0-or-later */
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
--pins-popout-max-height: min(calc(100vh - 7.5rem), 45rem);
|
|
||||||
--pins-popout-header-height: 4.25rem;
|
--pins-popout-header-height: 4.25rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 30rem;
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-height: 12.5rem;
|
box-sizing: border-box;
|
||||||
max-height: var(--pins-popout-max-height);
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
border: 0.0625rem solid var(--background-modifier-accent);
|
border: 0.0625rem solid var(--background-modifier-accent);
|
||||||
@@ -28,10 +25,8 @@
|
|||||||
flex: 1 1 0%;
|
flex: 1 1 0%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
max-height: calc(var(--pins-popout-max-height) - var(--pins-popout-header-height));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@@ -46,3 +41,10 @@
|
|||||||
width: 1.5rem;
|
width: 1.5rem;
|
||||||
color: var(--text-primary-muted);
|
color: var(--text-primary-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(html.channel-pins-popout-resizing),
|
||||||
|
:global(html.channel-pins-popout-resizing) * {
|
||||||
|
cursor: var(--channel-pins-popout-resize-cursor, nwse-resize) !important;
|
||||||
|
user-select: none !important;
|
||||||
|
-webkit-user-select: none !important;
|
||||||
|
}
|
||||||
@@ -3,19 +3,88 @@
|
|||||||
import {ChannelPinsContent} from '@app/features/app/components/shared/ChannelPinsContent';
|
import {ChannelPinsContent} from '@app/features/app/components/shared/ChannelPinsContent';
|
||||||
import styles from '@app/features/channel/components/popouts/ChannelPinsPopout.module.css';
|
import styles from '@app/features/channel/components/popouts/ChannelPinsPopout.module.css';
|
||||||
import type {Channel} from '@app/features/channel/models/Channel';
|
import type {Channel} from '@app/features/channel/models/Channel';
|
||||||
|
import {remFromPx} from '@app/features/theme/layout/RemFromPx';
|
||||||
|
import {RESIZABLE_PANE_DEFAULT_VIEWPORT_PADDING, useResizablePane} from '@app/features/ui/hooks/useResizablePane';
|
||||||
|
import {
|
||||||
|
type ResizablePaneHandleLabels,
|
||||||
|
ResizablePaneHandles,
|
||||||
|
} from '@app/features/ui/resizable_pane/ResizablePaneHandles';
|
||||||
import {msg} from '@lingui/core/macro';
|
import {msg} from '@lingui/core/macro';
|
||||||
import {useLingui} from '@lingui/react/macro';
|
import {useLingui} from '@lingui/react/macro';
|
||||||
import {PushPinIcon} from '@phosphor-icons/react';
|
import {PushPinIcon} from '@phosphor-icons/react';
|
||||||
import {observer} from 'mobx-react-lite';
|
import {observer} from 'mobx-react-lite';
|
||||||
|
import {useRef} from 'react';
|
||||||
|
|
||||||
const PINNED_MESSAGES_DESCRIPTOR = msg({
|
const PINNED_MESSAGES_DESCRIPTOR = msg({
|
||||||
message: 'Pinned messages',
|
message: 'Pinned messages',
|
||||||
comment: 'Button or menu action label in the channel pins popout. Keep it concise.',
|
comment: 'Button or menu action label in the channel pins popout. Keep it concise.',
|
||||||
});
|
});
|
||||||
|
const RESIZE_PINS_TOP_DESCRIPTOR = msg({
|
||||||
|
message: 'Resize pinned messages from the top edge',
|
||||||
|
comment: 'Accessible label for the top resize handle on the channel pins popout.',
|
||||||
|
});
|
||||||
|
const RESIZE_PINS_BOTTOM_DESCRIPTOR = msg({
|
||||||
|
message: 'Resize pinned messages from the bottom edge',
|
||||||
|
comment: 'Accessible label for the bottom resize handle on the channel pins popout.',
|
||||||
|
});
|
||||||
|
const RESIZE_PINS_LEFT_DESCRIPTOR = msg({
|
||||||
|
message: 'Resize pinned messages from the left edge',
|
||||||
|
comment: 'Accessible label for the left resize handle on the channel pins popout.',
|
||||||
|
});
|
||||||
|
const RESIZE_PINS_RIGHT_DESCRIPTOR = msg({
|
||||||
|
message: 'Resize pinned messages from the right edge',
|
||||||
|
comment: 'Accessible label for the right resize handle on the channel pins popout.',
|
||||||
|
});
|
||||||
|
const RESIZE_PINS_TOP_LEFT_DESCRIPTOR = msg({
|
||||||
|
message: 'Resize pinned messages from top left',
|
||||||
|
comment: 'Accessible label for the top-left resize handle on the channel pins popout.',
|
||||||
|
});
|
||||||
|
const RESIZE_PINS_TOP_RIGHT_DESCRIPTOR = msg({
|
||||||
|
message: 'Resize pinned messages from top right',
|
||||||
|
comment: 'Accessible label for the top-right resize handle on the channel pins popout.',
|
||||||
|
});
|
||||||
|
const RESIZE_PINS_BOTTOM_LEFT_DESCRIPTOR = msg({
|
||||||
|
message: 'Resize pinned messages from bottom left',
|
||||||
|
comment: 'Accessible label for the bottom-left resize handle on the channel pins popout.',
|
||||||
|
});
|
||||||
|
const RESIZE_PINS_BOTTOM_RIGHT_DESCRIPTOR = msg({
|
||||||
|
message: 'Resize pinned messages from bottom right',
|
||||||
|
comment: 'Accessible label for the bottom-right resize handle on the channel pins popout.',
|
||||||
|
});
|
||||||
|
|
||||||
|
const CHANNEL_PINS_POPOUT_DEFAULT_SIZE = {width: 480, height: 640};
|
||||||
|
const CHANNEL_PINS_POPOUT_MIN_SIZE = {width: 320, height: 200};
|
||||||
|
const CHANNEL_PINS_POPOUT_RESIZING_CLASS = 'channel-pins-popout-resizing';
|
||||||
|
const CHANNEL_PINS_POPOUT_RESIZE_CURSOR_PROPERTY = '--channel-pins-popout-resize-cursor';
|
||||||
|
const CHANNEL_PINS_RESIZE_HANDLE_LABELS: ResizablePaneHandleLabels = {
|
||||||
|
top: RESIZE_PINS_TOP_DESCRIPTOR,
|
||||||
|
bottom: RESIZE_PINS_BOTTOM_DESCRIPTOR,
|
||||||
|
left: RESIZE_PINS_LEFT_DESCRIPTOR,
|
||||||
|
right: RESIZE_PINS_RIGHT_DESCRIPTOR,
|
||||||
|
'top-left': RESIZE_PINS_TOP_LEFT_DESCRIPTOR,
|
||||||
|
'top-right': RESIZE_PINS_TOP_RIGHT_DESCRIPTOR,
|
||||||
|
'bottom-left': RESIZE_PINS_BOTTOM_LEFT_DESCRIPTOR,
|
||||||
|
'bottom-right': RESIZE_PINS_BOTTOM_RIGHT_DESCRIPTOR,
|
||||||
|
};
|
||||||
|
|
||||||
export const ChannelPinsPopout = observer(({channel, onClose}: {channel: Channel; onClose?: () => void}) => {
|
export const ChannelPinsPopout = observer(({channel, onClose}: {channel: Channel; onClose?: () => void}) => {
|
||||||
const {i18n} = useLingui();
|
const {i18n} = useLingui();
|
||||||
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
const {size, getHandleProps} = useResizablePane(containerRef, {
|
||||||
|
storageKey: 'fluxer:ui:channel-pins-popout-size',
|
||||||
|
defaultSize: CHANNEL_PINS_POPOUT_DEFAULT_SIZE,
|
||||||
|
minSize: CHANNEL_PINS_POPOUT_MIN_SIZE,
|
||||||
|
viewportPadding: RESIZABLE_PANE_DEFAULT_VIEWPORT_PADDING,
|
||||||
|
resizingClassName: CHANNEL_PINS_POPOUT_RESIZING_CLASS,
|
||||||
|
cursorProperty: CHANNEL_PINS_POPOUT_RESIZE_CURSOR_PROPERTY,
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<div className={styles.container} data-flx="channel.channel-pins-popout.container">
|
<div
|
||||||
|
ref={containerRef}
|
||||||
|
className={styles.container}
|
||||||
|
style={{width: remFromPx(size.width), height: remFromPx(size.height)}}
|
||||||
|
data-flx="channel.channel-pins-popout.container"
|
||||||
|
>
|
||||||
<div className={styles.header} data-flx="channel.channel-pins-popout.header">
|
<div className={styles.header} data-flx="channel.channel-pins-popout.header">
|
||||||
<PushPinIcon className={styles.iconLarge} data-flx="channel.channel-pins-popout.icon-large" />
|
<PushPinIcon className={styles.iconLarge} data-flx="channel.channel-pins-popout.icon-large" />
|
||||||
<h1 className={styles.title} data-flx="channel.channel-pins-popout.title">
|
<h1 className={styles.title} data-flx="channel.channel-pins-popout.title">
|
||||||
@@ -29,6 +98,11 @@ export const ChannelPinsPopout = observer(({channel, onClose}: {channel: Channel
|
|||||||
data-flx="channel.channel-pins-popout.channel-pins-content"
|
data-flx="channel.channel-pins-popout.channel-pins-content"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<ResizablePaneHandles
|
||||||
|
getHandleProps={getHandleProps}
|
||||||
|
labels={CHANNEL_PINS_RESIZE_HANDLE_LABELS}
|
||||||
|
data-flx="channel.channel-pins-popout.resizable-pane-handles"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user