Skip to content

Commit

Permalink
✨ feat: opt for keyboard indicator
Browse files Browse the repository at this point in the history
  • Loading branch information
summerscar committed Jul 16, 2024
1 parent 621ff18 commit 098939f
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 8 deletions.
20 changes: 17 additions & 3 deletions app/components/home-input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
import { KEYS_TO_BIND } from "@/utils/kr-const";
import { useEventListener, useUpdateEffect } from "ahooks";
import clsx from "clsx";
import { forwardRef, useCallback, useImperativeHandle, useState } from "react";
import {
forwardRef,
useCallback,
useEffect,
useImperativeHandle,
useState,
} from "react";
import { useHotkeys } from "react-hotkeys-hook";

export type HomeInputRef = {
Expand All @@ -12,13 +18,21 @@ export type HomeInputRef = {

const HomeInput = forwardRef<
HomeInputRef,
{ onInput?: (inputKeys: Record<string, boolean>) => void; position?: DOMRect }
>(({ onInput, position }, ref) => {
{
onInput?: (inputKeys: Record<string, boolean>) => void;
position?: DOMRect;
onFocusChange?: (isFocused: boolean) => void;
}
>(({ onInput, position, onFocusChange }, ref) => {
const [currentInputKeys, setCurrentInputKeys] = useState<
Record<string, boolean>
>({});
const [isInputFocused, setIsInputFocused] = useState(false);

useEffect(() => {
onFocusChange?.(isInputFocused);
}, [isInputFocused, onFocusChange]);

const inputRef = useHotkeys<HTMLInputElement>(
[
"esc",
Expand Down
40 changes: 35 additions & 5 deletions app/components/home-status/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import {
parseSpaceStr,
} from "@/utils/convert-input";
import { myeongjo, notoKR } from "@/utils/fonts";
import { isServer } from "@/utils/is-server";
import { hangulToQwerty } from "@/utils/kr-const";
import { useClickAway, useMemoizedFn } from "ahooks";
import { useClickAway, useEventListener, useMemoizedFn } from "ahooks";
import clsx from "clsx";
import { disassembleHangul } from "es-hangul";
import { useLocale } from "next-intl";
Expand All @@ -39,6 +40,7 @@ const HomeStatus = ({
const [curInputIndex, setCurInputIndex] = useState(0);
const [isComplete, setIsComplete] = useState(false);
const [isInputError, setIsInputError] = useState(false);
const [isInputFocused, setIsInputFocused] = useState(false);
const [showKeyboard, setShowKeyboard] = useState(true);
const toggleShowKeyboard = useMemoizedFn(() =>
setShowKeyboard(!showKeyboard),
Expand All @@ -51,12 +53,23 @@ const HomeStatus = ({
handleInputFocus: () => {},
});

useEventListener(
"keyup",
(e) => {
if (isInputFocused) return;
if (e.key === "Enter") {
focusInput();
}
},
{ target: isServer ? undefined : document },
);

/** 计算input光标位置 */
const [inputPosition, setInputPosition] = useState<DOMRect>();
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
useEffect(() => {
if (hangulRef.current) {
inputRef.current.handleInputFocus?.();
focusInput();
}
const hangulEls = hangulRef.current?.children;
if (!hangulEls || curInputIndex >= hangulEls.length) return;
Expand All @@ -66,7 +79,7 @@ const HomeStatus = ({
}, [curInputIndex, curWordIndex]);

useClickAway(() => {
inputRef.current.handleInputBlur?.();
blurInput();
}, hangulRef);

const currentWord = useMemo(() => {
Expand Down Expand Up @@ -282,7 +295,14 @@ const HomeStatus = ({
)}
</div>
{/* 键盘图案 */}
<p className={clsx("w-[80vw] my-2", { invisible: !showKeyboard })}>
<div
className={clsx(
"drop-shadow-xl w-[80vw] my-2 rounded-md overflow-hidden relative",
{
invisible: !showKeyboard,
},
)}
>
<style
// biome-ignore lint/security/noDangerouslySetInnerHtml: <explanation>
dangerouslySetInnerHTML={{
Expand All @@ -294,7 +314,16 @@ const HomeStatus = ({
width={"100%"}
height={"100%"}
/>
</p>
<div
className={clsx(
"transition-all select-none absolute top-0 left-0 w-full h-full bg-gray-400/85 flex items-center justify-center flex-col",
isInputFocused ? "opacity-0" : "opacity-100",
)}
>
<div className="text-3xl">Press 『Enter』 to type !</div>
<div className="text-sm mt-10">tips: Try 『[』『]』.</div>
</div>
</div>
{/* 例句 */}
<div className="flex justify-center flex-col items-center">
<p className={clsx("relative", myeongjo.className)}>
Expand All @@ -316,6 +345,7 @@ const HomeStatus = ({
))}
</div>
<HomeInput
onFocusChange={setIsInputFocused}
onInput={setInputKeys}
position={inputPosition}
ref={inputRef}
Expand Down
3 changes: 3 additions & 0 deletions app/utils/is-server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const isServer = typeof window === "undefined";
const getIsServer = () => typeof window === "undefined";
export { isServer, getIsServer };

0 comments on commit 098939f

Please sign in to comment.