mirror of https://github.com/usememos/memos.git
chore: remove unused keyboard shortcuts
This commit is contained in:
parent
02f39c2a59
commit
ef8e3cfb99
|
|
@ -6,15 +6,7 @@ import type { FocusModeExitButtonProps, FocusModeOverlayProps } from "../types";
|
|||
export function FocusModeOverlay({ isActive, onToggle }: FocusModeOverlayProps) {
|
||||
if (!isActive) return null;
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className={FOCUS_MODE_STYLES.backdrop}
|
||||
onClick={onToggle}
|
||||
onKeyDown={(e) => e.key === "Escape" && onToggle()}
|
||||
aria-label="Exit focus mode"
|
||||
/>
|
||||
);
|
||||
return <button type="button" className={FOCUS_MODE_STYLES.backdrop} onClick={onToggle} aria-label="Exit focus mode" />;
|
||||
}
|
||||
|
||||
export function FocusModeExitButton({ isActive, onToggle, title }: FocusModeExitButtonProps) {
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ export const FOCUS_MODE_STYLES = {
|
|||
exitButton: "absolute top-2 right-2 z-10 opacity-60 hover:opacity-100",
|
||||
} as const;
|
||||
|
||||
export const FOCUS_MODE_TOGGLE_KEY = "f";
|
||||
export const FOCUS_MODE_EXIT_KEY = "Escape";
|
||||
|
||||
export const EDITOR_HEIGHT = {
|
||||
// Max height for normal mode - focus mode uses flex-1 to grow dynamically
|
||||
normal: "max-h-[50vh]",
|
||||
|
|
|
|||
|
|
@ -1,30 +1,16 @@
|
|||
import { useEffect } from "react";
|
||||
import { FOCUS_MODE_TOGGLE_KEY } from "../constants";
|
||||
import type { EditorRefActions } from "../Editor";
|
||||
|
||||
interface UseKeyboardOptions {
|
||||
onSave: () => void;
|
||||
onToggleFocusMode?: () => void;
|
||||
}
|
||||
|
||||
export const useKeyboard = (_editorRef: React.RefObject<EditorRefActions | null>, options: UseKeyboardOptions) => {
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
// Cmd/Ctrl + Enter to save
|
||||
if ((event.metaKey || event.ctrlKey) && event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
options.onSave();
|
||||
return;
|
||||
}
|
||||
|
||||
// 'f' key to toggle focus mode (only if no modifiers and not in input)
|
||||
if (event.key === FOCUS_MODE_TOGGLE_KEY && !event.metaKey && !event.ctrlKey && !event.altKey && !event.shiftKey) {
|
||||
const target = event.target as HTMLElement;
|
||||
// Don't trigger if user is typing in an input/textarea
|
||||
if (target.tagName !== "INPUT" && target.tagName !== "TEXTAREA" && !target.isContentEditable) {
|
||||
event.preventDefault();
|
||||
options.onToggleFocusMode?.();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -62,8 +62,7 @@ const MemoEditorImpl: React.FC<MemoEditorProps> = ({
|
|||
dispatch(actions.toggleFocusMode());
|
||||
};
|
||||
|
||||
// Keyboard shortcuts
|
||||
useKeyboard(editorRef, { onSave: handleSave, onToggleFocusMode: handleToggleFocusMode });
|
||||
useKeyboard(editorRef, { onSave: handleSave });
|
||||
|
||||
async function handleSave() {
|
||||
// Validate before saving
|
||||
|
|
|
|||
|
|
@ -5,31 +5,10 @@ import MemoEditor from "../MemoEditor";
|
|||
import PreviewImageDialog from "../PreviewImageDialog";
|
||||
import { MemoBody, MemoHeader } from "./components";
|
||||
import { MEMO_CARD_BASE_CLASSES } from "./constants";
|
||||
import { useImagePreview, useKeyboardShortcuts, useMemoActions, useMemoHandlers, useMemoViewDerivedState, useNsfwContent } from "./hooks";
|
||||
import { useImagePreview, useMemoActions, useMemoHandlers, useMemoViewDerivedState, useNsfwContent } from "./hooks";
|
||||
import { MemoViewContext } from "./MemoViewContext";
|
||||
import type { MemoViewProps } from "./types";
|
||||
|
||||
/**
|
||||
* MemoView component displays a memo card with all its content, metadata, and interactive elements.
|
||||
*
|
||||
* Features:
|
||||
* - Displays memo content with markdown rendering
|
||||
* - Shows creator information and timestamps
|
||||
* - Supports inline editing with keyboard shortcuts (e = edit, a = archive)
|
||||
* - Handles NSFW content blurring
|
||||
* - Image preview on click
|
||||
* - Comments, reactions, and relations
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <MemoView
|
||||
* memo={memoData}
|
||||
* showCreator
|
||||
* showVisibility
|
||||
* compact={false}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
const MemoView: React.FC<MemoViewProps> = (props: MemoViewProps) => {
|
||||
const { memo: memoData, className } = props;
|
||||
const cardRef = useRef<HTMLDivElement>(null);
|
||||
|
|
@ -40,7 +19,7 @@ const MemoView: React.FC<MemoViewProps> = (props: MemoViewProps) => {
|
|||
const { isArchived, readonly, parentPage } = useMemoViewDerivedState(memoData, props.parentPage);
|
||||
const { nsfw, showNSFWContent, toggleNsfwVisibility } = useNsfwContent(memoData, props.showNsfwContent);
|
||||
const { previewState, openPreview, setPreviewOpen } = useImagePreview();
|
||||
const { archiveMemo, unpinMemo } = useMemoActions(memoData, isArchived);
|
||||
const { unpinMemo } = useMemoActions(memoData, isArchived);
|
||||
|
||||
const handleEditorConfirm = () => setShowEditor(false);
|
||||
const handleEditorCancel = () => setShowEditor(false);
|
||||
|
|
@ -53,14 +32,6 @@ const MemoView: React.FC<MemoViewProps> = (props: MemoViewProps) => {
|
|||
openEditor,
|
||||
openPreview,
|
||||
});
|
||||
useKeyboardShortcuts(cardRef, {
|
||||
enabled: true,
|
||||
readonly,
|
||||
showEditor,
|
||||
isArchived,
|
||||
onEdit: openEditor,
|
||||
onArchive: archiveMemo,
|
||||
});
|
||||
|
||||
const contextValue = useMemo(
|
||||
() => ({
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
export const MEMO_CARD_BASE_CLASSES =
|
||||
"relative group flex flex-col justify-start items-start bg-card w-full px-4 py-3 mb-2 gap-2 text-card-foreground rounded-lg border border-border transition-colors";
|
||||
|
||||
export const KEYBOARD_SHORTCUTS = { EDIT: "e", ARCHIVE: "a" } as const;
|
||||
|
||||
export const TEXT_INPUT_TYPES = ["text", "search", "email", "password", "url", "tel", "number"] as const;
|
||||
|
||||
export const RELATIVE_TIME_THRESHOLD_MS = 1000 * 60 * 60 * 24;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
export { useImagePreview } from "./useImagePreview";
|
||||
export { useKeyboardShortcuts } from "./useKeyboardShortcuts";
|
||||
export { useMemoActions } from "./useMemoActions";
|
||||
export { useMemoHandlers } from "./useMemoHandlers";
|
||||
export { useMemoViewDerivedState } from "./useMemoViewDerivedState";
|
||||
|
|
|
|||
|
|
@ -1,48 +0,0 @@
|
|||
import { useEffect } from "react";
|
||||
import { KEYBOARD_SHORTCUTS, TEXT_INPUT_TYPES } from "../constants";
|
||||
|
||||
export interface UseKeyboardShortcutsOptions {
|
||||
enabled: boolean;
|
||||
readonly: boolean;
|
||||
showEditor: boolean;
|
||||
isArchived: boolean;
|
||||
onEdit: () => void;
|
||||
onArchive: () => Promise<void>;
|
||||
}
|
||||
|
||||
const isTextInputElement = (element: HTMLElement | null): boolean => {
|
||||
if (!element) return false;
|
||||
if (element.isContentEditable) return true;
|
||||
if (element instanceof HTMLTextAreaElement) return true;
|
||||
if (element instanceof HTMLInputElement) {
|
||||
return TEXT_INPUT_TYPES.includes(element.type as (typeof TEXT_INPUT_TYPES)[number]);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const useKeyboardShortcuts = (cardRef: React.RefObject<HTMLDivElement | null>, options: UseKeyboardShortcutsOptions) => {
|
||||
const { enabled, readonly, showEditor, isArchived, onEdit, onArchive } = options;
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled || readonly || showEditor || !cardRef.current) return;
|
||||
|
||||
const cardEl = cardRef.current;
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
const target = event.target as HTMLElement | null;
|
||||
if (!cardEl.contains(target) || isTextInputElement(target)) return;
|
||||
if (event.metaKey || event.ctrlKey || event.altKey) return;
|
||||
|
||||
const key = event.key.toLowerCase();
|
||||
if (key === KEYBOARD_SHORTCUTS.EDIT) {
|
||||
event.preventDefault();
|
||||
onEdit();
|
||||
} else if (key === KEYBOARD_SHORTCUTS.ARCHIVE && !isArchived) {
|
||||
event.preventDefault();
|
||||
onArchive();
|
||||
}
|
||||
};
|
||||
|
||||
cardEl.addEventListener("keydown", handleKeyDown);
|
||||
return () => cardEl.removeEventListener("keydown", handleKeyDown);
|
||||
}, [enabled, readonly, showEditor, isArchived, onEdit, onArchive, cardRef]);
|
||||
};
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { SearchIcon } from "lucide-react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useRef, useState } from "react";
|
||||
import { useMemoFilterContext } from "@/contexts/MemoFilterContext";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
|
@ -11,18 +11,6 @@ const SearchBar = () => {
|
|||
const [queryText, setQueryText] = useState("");
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const handleGlobalShortcut = (event: KeyboardEvent) => {
|
||||
if ((event.metaKey || event.ctrlKey) && event.key === "/") {
|
||||
event.preventDefault();
|
||||
inputRef.current?.focus();
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleGlobalShortcut);
|
||||
return () => window.removeEventListener("keydown", handleGlobalShortcut);
|
||||
}, []);
|
||||
|
||||
const onTextChange = (event: React.FormEvent<HTMLInputElement>) => {
|
||||
setQueryText(event.currentTarget.value);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ const LocationMarker = (props: MarkerProps) => {
|
|||
// Call the parent onChange function.
|
||||
props.onChange(e.latlng);
|
||||
},
|
||||
locationfound() { },
|
||||
locationfound() {},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -224,12 +224,19 @@ const LeafletMap = (props: MapProps) => {
|
|||
const position = props.latlng || DEFAULT_CENTER_LAT_LNG;
|
||||
|
||||
return (
|
||||
<MapContainer className="w-full h-72" center={position} zoom={13} scrollWheelZoom={false} zoomControl={false} attributionControl={false}>
|
||||
<MapContainer
|
||||
className="w-full h-72"
|
||||
center={position}
|
||||
zoom={13}
|
||||
scrollWheelZoom={false}
|
||||
zoomControl={false}
|
||||
attributionControl={false}
|
||||
>
|
||||
<ThemedTileLayer />
|
||||
<LocationMarker position={position} readonly={props.readonly} onChange={props.onChange ? props.onChange : () => { }} />
|
||||
<LocationMarker position={position} readonly={props.readonly} onChange={props.onChange ? props.onChange : () => {}} />
|
||||
<MapControls position={props.latlng} />
|
||||
<MapCleanup />
|
||||
</MapContainer >
|
||||
</MapContainer>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue