Let the sidebar be resized by dragging its edge
The sidebar's right edge is now a splitter, like the one between the message list and the reading pane: drag it between 240 and 480px, move it with the arrow keys, double-click to put it back. The width is a device setting, and stays null until someone drags, so a width set in the reader's own CSS through --sidebar-w is kept until they choose otherwise. Hidden on a phone, where the sidebar is a drawer, and while collapsed. Arrow keys on either splitter moved the pane and never saved it: the keyboard path called onResize without onEnd. It ends each key press now, and both views keep the in-progress size in a ref as well as state, so the end reads the value set in the same tick. The message-list splitter's accessible name was an untranslated literal. It goes through translate() now, and it and the sidebar's new name are in all nine catalogues. Closes #345
This commit is contained in:
@@ -385,18 +385,24 @@ export function MailView({ mailboxId, threadId, search }: { mailboxId?: string;
|
||||
const layoutRef = useRef<HTMLDivElement>(null);
|
||||
const updateSettings = useSettings((s) => s.update);
|
||||
const [liveSize, setLiveSize] = useState<number | null>(null);
|
||||
// Mirrors liveSize for the end of a key press, which follows the resize in
|
||||
// the same tick -- before the state could have come back round.
|
||||
const liveSizeRef = useRef<number | null>(null);
|
||||
const paneSize = liveSize ?? (settings.readingPane === "bottom" ? settings.listPaneHeight : settings.listPaneWidth);
|
||||
const onSplit = (delta: number) => {
|
||||
const el = layoutRef.current;
|
||||
const total = el ? (settings.readingPane === "bottom" ? el.clientHeight : el.clientWidth) : 1200;
|
||||
const min = settings.readingPane === "bottom" ? 160 : 320;
|
||||
const max = Math.max(min, total - (settings.readingPane === "bottom" ? 200 : 420));
|
||||
setLiveSize((cur) => Math.min(max, Math.max(min, (cur ?? paneSize) + delta)));
|
||||
const next = Math.min(max, Math.max(min, (liveSizeRef.current ?? paneSize) + delta));
|
||||
liveSizeRef.current = next;
|
||||
setLiveSize(next);
|
||||
};
|
||||
const onSplitEnd = () => {
|
||||
if (liveSize == null) return;
|
||||
updateSettings(settings.readingPane === "bottom" ? { listPaneHeight: liveSize } : { listPaneWidth: liveSize });
|
||||
const size = liveSizeRef.current;
|
||||
liveSizeRef.current = null;
|
||||
setLiveSize(null);
|
||||
if (size != null) updateSettings(settings.readingPane === "bottom" ? { listPaneHeight: size } : { listPaneWidth: size });
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -416,7 +422,7 @@ export function MailView({ mailboxId, threadId, search }: { mailboxId?: string;
|
||||
/>
|
||||
)}
|
||||
{showList && showReading && settings.readingPane !== "off" && !narrow && (
|
||||
<Splitter direction={settings.readingPane === "bottom" ? "horizontal" : "vertical"} onResize={onSplit} onEnd={onSplitEnd} onReset={() => updateSettings(settings.readingPane === "bottom" ? { listPaneHeight: 340 } : { listPaneWidth: 520 })} ariaLabel="Resize message list" />
|
||||
<Splitter direction={settings.readingPane === "bottom" ? "horizontal" : "vertical"} onResize={onSplit} onEnd={onSplitEnd} onReset={() => updateSettings(settings.readingPane === "bottom" ? { listPaneHeight: 340 } : { listPaneWidth: 520 })} ariaLabel={translate("Resize message list")} />
|
||||
)}
|
||||
{showReading && (
|
||||
<div className="mail-reading-pane">
|
||||
|
||||
Reference in New Issue
Block a user