mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-10-31 08:13:50 +00:00
49 lines
1.8 KiB
TypeScript
49 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect } from "react";
|
|
import { useTranslations } from "next-intl";
|
|
import { isEditableEventTarget } from "@/lib/keyboard";
|
|
import { clearUndoHistory, undoLatest } from "@/lib/undo-history";
|
|
import { useSettingsStore } from "@/stores/settings-store";
|
|
import { toast } from "@/stores/toast-store";
|
|
|
|
/**
|
|
* Whether a key press asks to undo: Ctrl+Z (⌘Z) outside text fields, or `z`
|
|
* alone while single-key shortcuts are on. Never while a modal dialog is
|
|
* open or while typing, where the keys belong to the dialog or the field.
|
|
*/
|
|
export function isUndoKey(e: KeyboardEvent, singleKeyShortcuts: boolean): boolean {
|
|
if (e.defaultPrevented || e.repeat) return false;
|
|
// The physical key, so it works on any keyboard layout.
|
|
const isZ = e.code ? e.code === "KeyZ" : e.key.toLowerCase() === "z";
|
|
if (!isZ || e.altKey || e.shiftKey) return false;
|
|
const mod = e.ctrlKey || e.metaKey;
|
|
if (!mod && !singleKeyShortcuts) return false;
|
|
if (isEditableEventTarget(e)) return false;
|
|
if (document.querySelector('[aria-modal="true"]')) return false;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Undo from the keyboard in Mail: the newest action in the undo history
|
|
* (lib/undo-history) is put back, then the one before it, and so on.
|
|
*/
|
|
export function useUndoShortcut({ enabled, signedIn }: { enabled: boolean; signedIn: boolean }) {
|
|
const t = useTranslations("notifications");
|
|
|
|
useEffect(() => {
|
|
if (!signedIn) clearUndoHistory();
|
|
}, [signedIn]);
|
|
|
|
useEffect(() => {
|
|
if (!enabled) return;
|
|
const onKeyDown = (e: KeyboardEvent) => {
|
|
if (!isUndoKey(e, useSettingsStore.getState().singleKeyShortcuts)) return;
|
|
e.preventDefault();
|
|
if (!undoLatest()) toast.info(t("nothing_to_undo"));
|
|
};
|
|
window.addEventListener("keydown", onKeyDown);
|
|
return () => window.removeEventListener("keydown", onKeyDown);
|
|
}, [enabled, t]);
|
|
}
|