(feat): add hotkeys
This commit is contained in:
parent
915568f739
commit
85633a1c81
27 changed files with 1014 additions and 33 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import Input from "@tensamin/markdown/input";
|
||||
import Input, { type InputController } from "@tensamin/markdown/input";
|
||||
import {
|
||||
Card,
|
||||
CardHeader,
|
||||
|
|
@ -7,7 +7,7 @@ import {
|
|||
PopoverTrigger,
|
||||
} from "@methanium/ui";
|
||||
import { useStorage } from "@tensamin/storage/context";
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
import React, { useCallback, useEffect, useState, useRef } from "react";
|
||||
import { Button } from "@methanium/ui";
|
||||
|
||||
import { Plus, Laugh, FileVideo } from "lucide-react";
|
||||
|
|
@ -22,13 +22,17 @@ import GifPicker from "./gifPicker";
|
|||
import EmojiPicker from "./emojiPicker";
|
||||
import { useEmojiRanks, useRecordEmojiUse } from "./emojiRanks";
|
||||
import ReplyBox from "./replyBox";
|
||||
import { useHotkey } from "@tensamin/hotkeys";
|
||||
import { editLastMessageHotkey } from "../hotkeys";
|
||||
|
||||
export default function InputComponent({
|
||||
value,
|
||||
setValue,
|
||||
onEditLastMessage,
|
||||
}: {
|
||||
value: string;
|
||||
setValue: (value: string) => void;
|
||||
onEditLastMessage: () => void;
|
||||
}) {
|
||||
const [invertEnterBehavior, setInvertEnterBehavior] = useState(false);
|
||||
|
||||
|
|
@ -52,6 +56,58 @@ export default function InputComponent({
|
|||
width: number;
|
||||
height: number;
|
||||
}>();
|
||||
const composerRef = useRef<InputController | null>(null);
|
||||
const setComposer = useCallback((controller: InputController | null) => {
|
||||
composerRef.current = controller;
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const frame = requestAnimationFrame(() => composerRef.current?.focus());
|
||||
return () => cancelAnimationFrame(frame);
|
||||
}, [userId]);
|
||||
|
||||
useEffect(() => {
|
||||
const focusComposerOnType = (event: KeyboardEvent) => {
|
||||
const composer = composerRef.current;
|
||||
const target = event.target;
|
||||
if (
|
||||
!composer ||
|
||||
composer.hasFocus() ||
|
||||
event.defaultPrevented ||
|
||||
event.isComposing ||
|
||||
event.ctrlKey ||
|
||||
event.metaKey ||
|
||||
event.altKey ||
|
||||
event.key.length !== 1
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
target instanceof HTMLElement &&
|
||||
(target.isContentEditable ||
|
||||
target.closest(
|
||||
'button, a[href], input, textarea, select, summary, [contenteditable], [role], [tabindex]:not([tabindex="-1"])',
|
||||
))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
composer.focus();
|
||||
composer.insertText(event.key);
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", focusComposerOnType, true);
|
||||
return () =>
|
||||
window.removeEventListener("keydown", focusComposerOnType, true);
|
||||
}, []);
|
||||
|
||||
useHotkey(editLastMessageHotkey, onEditLastMessage, {
|
||||
enabled: value.length === 0,
|
||||
ignoreInputs: false,
|
||||
target: inputBoxRef,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
void load("settings.reverse_enter_behavior").then((shouldInvert) => {
|
||||
|
|
@ -195,6 +251,7 @@ export default function InputComponent({
|
|||
{/* reply */}
|
||||
{replyTo !== undefined && (
|
||||
<ReplyBox
|
||||
edited={replyMessage?.Edited}
|
||||
content={replyMessage?.Content}
|
||||
loading={!replyMessage}
|
||||
onDismiss={() => setReplyTo(undefined)}
|
||||
|
|
@ -212,6 +269,7 @@ export default function InputComponent({
|
|||
<CardHeader className="relative p-0 flex flex-col">
|
||||
<Input
|
||||
className="w-full"
|
||||
onControllerChange={setComposer}
|
||||
paddingY="13px"
|
||||
paddingX="13px"
|
||||
placeholder="Send a message..."
|
||||
|
|
|
|||
Loading…
Reference in a new issue