feat: implement room list reordering and animation hooks; add scroll to latest behavior settings
This commit is contained in:
@@ -34,7 +34,7 @@ import FocusTrap from 'focus-trap-react';
|
||||
import { Page, PageContent, PageHeader } from '../../../components/page';
|
||||
import { SequenceCard } from '../../../components/sequence-card';
|
||||
import { useSetting } from '../../../state/hooks/settings';
|
||||
import { DateFormat, EmojiStyle, MessageLayout, MessageSpacing, settingsAtom } from '../../../state/settings';
|
||||
import { DateFormat, EmojiStyle, MessageLayout, MessageSpacing, ScrollToLatestBehavior, settingsAtom } from '../../../state/settings';
|
||||
import { SettingTile } from '../../../components/setting-tile';
|
||||
import { KeySymbol } from '../../../utils/key-symbol';
|
||||
import { isMacOS } from '../../../utils/user-agent';
|
||||
@@ -984,6 +984,83 @@ function SelectMessageSpacing() {
|
||||
);
|
||||
}
|
||||
|
||||
function SelectScrollToLatestBehavior() {
|
||||
const [menuCords, setMenuCords] = useState<RectCords>();
|
||||
const [scrollToLatestBehavior, setScrollToLatestBehavior] = useSetting(
|
||||
settingsAtom,
|
||||
'scrollToLatestBehavior'
|
||||
);
|
||||
|
||||
const behaviors = [
|
||||
{ value: ScrollToLatestBehavior.Always, label: 'Always' },
|
||||
{ value: ScrollToLatestBehavior.OnNewMessage, label: 'On New Message' },
|
||||
{ value: ScrollToLatestBehavior.Never, label: 'Never' },
|
||||
];
|
||||
|
||||
const handleMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
|
||||
setMenuCords(evt.currentTarget.getBoundingClientRect());
|
||||
};
|
||||
|
||||
const handleSelect = (behavior: ScrollToLatestBehavior) => {
|
||||
setScrollToLatestBehavior(behavior);
|
||||
setMenuCords(undefined);
|
||||
};
|
||||
|
||||
const currentLabel = behaviors.find((b) => b.value === scrollToLatestBehavior)?.label ?? 'Always';
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
size="300"
|
||||
variant="Secondary"
|
||||
outlined
|
||||
fill="Soft"
|
||||
radii="300"
|
||||
after={<Icon size="300" src={Icons.ChevronBottom} />}
|
||||
onClick={handleMenu}
|
||||
>
|
||||
<Text size="T300">{currentLabel}</Text>
|
||||
</Button>
|
||||
<PopOut
|
||||
anchor={menuCords}
|
||||
offset={5}
|
||||
position="Bottom"
|
||||
align="End"
|
||||
content={
|
||||
<FocusTrap
|
||||
focusTrapOptions={{
|
||||
initialFocus: false,
|
||||
onDeactivate: () => setMenuCords(undefined),
|
||||
clickOutsideDeactivates: true,
|
||||
isKeyForward: (evt: KeyboardEvent) =>
|
||||
evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
|
||||
isKeyBackward: (evt: KeyboardEvent) =>
|
||||
evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
|
||||
escapeDeactivates: stopPropagation,
|
||||
}}
|
||||
>
|
||||
<Menu>
|
||||
<Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
|
||||
{behaviors.map((item) => (
|
||||
<MenuItem
|
||||
key={item.value}
|
||||
size="300"
|
||||
variant={scrollToLatestBehavior === item.value ? 'Primary' : 'Surface'}
|
||||
radii="300"
|
||||
onClick={() => handleSelect(item.value)}
|
||||
>
|
||||
<Text size="T300">{item.label}</Text>
|
||||
</MenuItem>
|
||||
))}
|
||||
</Box>
|
||||
</Menu>
|
||||
</FocusTrap>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function Messages() {
|
||||
const [legacyUsernameColor, setLegacyUsernameColor] = useSetting(
|
||||
settingsAtom,
|
||||
@@ -1011,6 +1088,12 @@ function Messages() {
|
||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||
<SettingTile title="Message Spacing" after={<SelectMessageSpacing />} />
|
||||
</SequenceCard>
|
||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||
<SettingTile
|
||||
title="Scroll to Latest on Room Reselect"
|
||||
after={<SelectScrollToLatestBehavior />}
|
||||
/>
|
||||
</SequenceCard>
|
||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||
<SettingTile
|
||||
title="Legacy Username Color"
|
||||
|
||||
Reference in New Issue
Block a user