fix: fix enter send message on macos (merge #151 from yongman/fix-enter-macos)

This commit is contained in:
Minghan Zhang 2024-03-30 09:46:58 +08:00 committed by GitHub
commit b9690b4aa2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 23 additions and 14 deletions

View File

@ -74,7 +74,7 @@ import {
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
} from "@/components/ui/dialog.tsx"; } from "@/components/ui/dialog.tsx";
import { getUniqueList, parseNumber } from "@/utils/base.ts"; import { getUniqueList, isEnter, parseNumber } from "@/utils/base.ts";
import { defaultChannelModels } from "@/admin/channel.ts"; import { defaultChannelModels } from "@/admin/channel.ts";
import { getPricing } from "@/admin/datasets/charge.ts"; import { getPricing } from "@/admin/datasets/charge.ts";
import { useAllModels } from "@/admin/hook.tsx"; import { useAllModels } from "@/admin/hook.tsx";
@ -102,9 +102,9 @@ function reducer(state: ChargeProps, action: any): ChargeProps {
if (action.payload.trim().length === 0) return state; if (action.payload.trim().length === 0) return state;
return state.models.includes(action.payload) return state.models.includes(action.payload)
? { ? {
...state, ...state,
models: state.models.filter((model) => model !== action.payload), models: state.models.filter((model) => model !== action.payload),
} }
: { ...state, models: [...state.models, action.payload] }; : { ...state, models: [...state.models, action.payload] };
case "remove-model": case "remove-model":
return { return {
@ -469,7 +469,7 @@ function ChargeEditor({
onChange={(e) => setModel(e.target.value)} onChange={(e) => setModel(e.target.value)}
placeholder={t("admin.channels.model")} placeholder={t("admin.channels.model")}
onKeyDown={(e) => { onKeyDown={(e) => {
if (e.key === "Enter") { if (isEnter(e)) {
dispatch({ type: "add-model", payload: model }); dispatch({ type: "add-model", payload: model });
setModel(""); setModel("");
} }

View File

@ -53,7 +53,7 @@ import {
} from "lucide-react"; } from "lucide-react";
import { Input } from "@/components/ui/input.tsx"; import { Input } from "@/components/ui/input.tsx";
import PopupDialog, { popupTypes } from "@/components/PopupDialog.tsx"; import PopupDialog, { popupTypes } from "@/components/PopupDialog.tsx";
import { getNumber, parseNumber } from "@/utils/base.ts"; import { getNumber, isEnter, parseNumber } from "@/utils/base.ts";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { selectUsername } from "@/store/auth.ts"; import { selectUsername } from "@/store/auth.ts";
import { PaginationAction } from "@/components/ui/pagination.tsx"; import { PaginationAction } from "@/components/ui/pagination.tsx";
@ -378,7 +378,7 @@ function UserTable() {
value={search} value={search}
onChange={(e) => setSearch(e.target.value)} onChange={(e) => setSearch(e.target.value)}
onKeyDown={async (e) => { onKeyDown={async (e) => {
if (e.key === "Enter") await update(); if (isEnter(e)) await update();
}} }}
/> />
<Button size={`icon`} className={`flex-shrink-0 ml-2`} onClick={update}> <Button size={`icon`} className={`flex-shrink-0 ml-2`} onClick={update}>

View File

@ -50,6 +50,7 @@ import Paragraph, {
} from "@/components/Paragraph.tsx"; } from "@/components/Paragraph.tsx";
import { MultiCombobox } from "@/components/ui/multi-combobox.tsx"; import { MultiCombobox } from "@/components/ui/multi-combobox.tsx";
import { useChannelModels } from "@/admin/hook.tsx"; import { useChannelModels } from "@/admin/hook.tsx";
import { isEnter } from "@/utils/base.ts";
type CustomActionProps = { type CustomActionProps = {
onPost: (model: string) => void; onPost: (model: string) => void;
@ -73,7 +74,7 @@ function CustomAction({ onPost }: CustomActionProps) {
className={`rounded-r-none`} className={`rounded-r-none`}
onChange={(e) => setModel(e.target.value)} onChange={(e) => setModel(e.target.value)}
onKeyDown={(e) => { onKeyDown={(e) => {
if (e.key === "Enter") post(); if (isEnter(e)) post();
}} }}
/> />
<Button className={`rounded-l-none`} onClick={post}> <Button className={`rounded-l-none`} onClick={post}>

View File

@ -6,6 +6,7 @@ import { useSelector } from "react-redux";
import { senderSelector } from "@/store/settings.ts"; import { senderSelector } from "@/store/settings.ts";
import { blobEvent } from "@/events/blob.ts"; import { blobEvent } from "@/events/blob.ts";
import { cn } from "@/components/ui/lib/utils.ts"; import { cn } from "@/components/ui/lib/utils.ts";
import { isEnter } from "@/utils/base.ts";
type ChatInputProps = { type ChatInputProps = {
className?: string; className?: string;
@ -41,7 +42,7 @@ function ChatInput({
}} }}
placeholder={sender ? t("chat.placeholder-enter") : t("chat.placeholder")} placeholder={sender ? t("chat.placeholder-enter") : t("chat.placeholder")}
onKeyDown={async (e) => { onKeyDown={async (e) => {
if (e.key === "Enter") { if (isEnter(e)) {
if (sender) { if (sender) {
// on Enter, clear the input // on Enter, clear the input
// on Ctrl + Enter or Shift + Enter, keep the input // on Ctrl + Enter or Shift + Enter, keep the input

View File

@ -19,7 +19,7 @@ import Require, { LengthRangeRequired } from "@/components/Require.tsx";
import { Button } from "@/components/ui/button.tsx"; import { Button } from "@/components/ui/button.tsx";
import { formReducer, isTextInRange } from "@/utils/form.ts"; import { formReducer, isTextInRange } from "@/utils/form.ts";
import { doLogin, LoginForm } from "@/api/auth.ts"; import { doLogin, LoginForm } from "@/api/auth.ts";
import { getErrorMessage } from "@/utils/base.ts"; import { getErrorMessage, isEnter } from "@/utils/base.ts";
function DeepAuth() { function DeepAuth() {
const { toast } = useToast(); const { toast } = useToast();
@ -146,7 +146,7 @@ function Login() {
useEffect(() => { useEffect(() => {
// listen to enter key and auto submit // listen to enter key and auto submit
const listener = async (e: KeyboardEvent) => { const listener = async (e: KeyboardEvent) => {
if (e.key === "Enter") await onSubmit(); if (isEnter(e)) await onSubmit();
}; };
document.addEventListener("keydown", listener); document.addEventListener("keydown", listener);

View File

@ -13,6 +13,7 @@ import { handleGenerationData } from "@/utils/processor.ts";
import { selectModel } from "@/store/chat.ts"; import { selectModel } from "@/store/chat.ts";
import ModelFinder from "@/components/home/ModelFinder.tsx"; import ModelFinder from "@/components/home/ModelFinder.tsx";
import { appLogo } from "@/conf/env.ts"; import { appLogo } from "@/conf/env.ts";
import { isEnter } from "@/utils/base.ts";
type WrapperProps = { type WrapperProps = {
onSend?: (value: string, model: string) => boolean; onSend?: (value: string, model: string) => boolean;
@ -73,9 +74,9 @@ function Wrapper({ onSend }: WrapperProps) {
const target = ref.current as HTMLInputElement | null; const target = ref.current as HTMLInputElement | null;
if (!target) return; if (!target) return;
target.focus(); target.focus();
target.removeEventListener("keydown", () => {}); target.removeEventListener("keydown", () => { });
target.addEventListener("keydown", (e) => { target.addEventListener("keydown", (e) => {
if (e.key === "Enter") { if (isEnter(e)) {
// cannot use model here, because model is not updated // cannot use model here, because model is not updated
handleSend(modelRef.current); handleSend(modelRef.current);
} }
@ -85,7 +86,7 @@ function Wrapper({ onSend }: WrapperProps) {
ref.current && ref.current &&
(ref.current as HTMLInputElement).removeEventListener( (ref.current as HTMLInputElement).removeEventListener(
"keydown", "keydown",
() => {}, () => { },
); );
}; };
}, [ref]); }, [ref]);

View File

@ -1,3 +1,5 @@
import React from "react";
export function insert<T>(arr: T[], idx: number, value: T): T[] { export function insert<T>(arr: T[], idx: number, value: T): T[] {
return [...arr.slice(0, idx), value, ...arr.slice(idx)]; return [...arr.slice(0, idx), value, ...arr.slice(idx)];
} }
@ -92,6 +94,10 @@ export function isUrl(value: string): boolean {
} }
} }
export function isEnter<T extends HTMLElement>(e: React.KeyboardEvent<T> | KeyboardEvent): boolean {
return e.key === "Enter" && e.keyCode != 229;
}
export function resetJsArray<T>(arr: T[], target: T[]): T[] { export function resetJsArray<T>(arr: T[], target: T[]): T[] {
/** /**
* this function is used to reset an array to another array without changing the *pointer * this function is used to reset an array to another array without changing the *pointer