Skip to content

Commit

Permalink
fix: 修复首次进入设置提示 toast
Browse files Browse the repository at this point in the history
  • Loading branch information
codexu committed Dec 24, 2024
1 parent e6ad1ff commit c91dde4
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 28 deletions.
39 changes: 24 additions & 15 deletions src/app/core/setting/model-select.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { ControllerRenderProps } from "react-hook-form";
import { fetchAiModels } from "@/lib/ai";
import { useEffect, useState } from "react";
import { useCallback, useEffect, useState } from "react";
import { AiModel } from "@/lib/ai.types";
import { Store } from "@tauri-apps/plugin-store";
import useSettingStore from "@/stores/setting";
import { toast } from "@/hooks/use-toast";
import { debounce } from "lodash-es";

export function ModelSelect({ field }: { field: ControllerRenderProps }) {
const [models, setModels] = useState<AiModel[]>([])
Expand All @@ -17,36 +19,43 @@ export function ModelSelect({ field }: { field: ControllerRenderProps }) {
if (value) {
setDefaultModel(value as string)
}

const res = (await fetchAiModels()) as {
data: AiModel[]
}
res.data = res.data.filter((model, index, self) => {
return index === self.findIndex((m) => {
return m.id === model.id
if ('error' in res) {
toast({
title: '获取模型失败',
description: (res as { error: { message: string } }).error.message,
variant: 'destructive',
duration: 2000,
})
})
res.data.sort((a, b) => {
// 按名称排序
return a.id.localeCompare(b.id)
})
setModels(res.data)
} else {
res.data = res.data.filter((model, index, self) => {
return index === self.findIndex((m) => {
return m.id === model.id
})
})
res.data.sort((a, b) => {
return a.id.localeCompare(b.id)
})
setModels(res.data)
}
}

const debounceInit = useCallback(debounce(init, 1000), []);

function changeHandler(value: string) {
if (value) {
field.onChange(value)
}
}

useEffect(() => {
if (apiKey) {
init()
}
if (apiKey) debounceInit()
}, [apiKey])

return (
<Select onValueChange={changeHandler} value={field.value} defaultValue={defaultModel} disabled={field.disabled}>
<Select onValueChange={changeHandler} value={field.value} defaultValue={defaultModel} disabled={models.length === 0}>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="选择模型" />
</SelectTrigger>
Expand Down
37 changes: 26 additions & 11 deletions src/app/core/setting/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import {
FormMessage,
} from "@/components/ui/form"
import { Store } from "@tauri-apps/plugin-store"
import { useEffect, useState } from "react"
import { toast } from "@/hooks/use-toast"
import { useCallback, useEffect, useState } from "react"
import { debounce, upperFirst } from 'lodash-es'
import { SettingTab } from "./setting-tab"
import { SettingTitle } from "./setting-title"
Expand All @@ -22,6 +21,7 @@ import { SettingRender } from "./setting-render"
import { Separator } from "@/components/ui/separator"
import useSettingStore from "@/stores/setting"
import { useSearchParams } from "next/navigation";
import { toast } from "@/hooks/use-toast"

const flatConfig = config.flatMap(item => item.settings)

Expand All @@ -32,8 +32,9 @@ const formSchema = z.object(flatConfig.reduce((acc, item) => {
};
}, {}))

let isInit = false

export default function Page() {
const [isInitialRender, setIsInitialRender] = useState(false)
const [currentAnchor, setCurrentAnchor] = useState('about')
const [showOutline, setShowOutline] = useState(false)
const settingStore = useSettingStore()
Expand All @@ -54,13 +55,18 @@ export default function Page() {
for (const [key] of Object.entries(form.getValues())) {
const value = await store.get(key)
if (key && value !== undefined) {
console.log(key, value);
form.setValue(key as keyof z.infer<typeof formSchema>, value as never)
const storeKey = `set${upperFirst(key)}` as keyof typeof settingStore
(settingStore[storeKey] as (value: unknown) => void)(value)
}
}
setIsInitialRender(true)
setTimeout(() => {
isInit = true
}, 500);
}

async function onSubmit(values: z.infer<typeof formSchema>) {
async function submitHandler(values: z.infer<typeof formSchema>) {
for (const [key, value] of Object.entries(values)) {
const checkKey = key as keyof typeof settingStore
const checkValue = settingStore[checkKey]
Expand All @@ -70,15 +76,10 @@ export default function Page() {
const storeKey = `set${upperFirst(key)}` as keyof typeof settingStore
(settingStore[storeKey] as (value: unknown) => void)(value)
await store.save()
if (isInitialRender) {
toast({ title: "设置已保存", description: `${flatConfig.find(item => item.key === key)?.title}已更新。`, duration: 1000 })
}
}
}
}

const debounceSubmit = debounce(() => form.handleSubmit(onSubmit)(), 2000)

useEffect(() => {
initFormDefaultValues()
}, [])
Expand All @@ -94,10 +95,24 @@ export default function Page() {
}
}, [parmas])

const debounceToast = useCallback(debounce(() => {
toast({
title: '设置已保存',
variant: 'default',
duration: 1000,
})
}, 1000), [])

useEffect(() => {
if (isInit) {
debounceToast()
}
}, [settingStore])

return <div className="flex">
<SettingTab />
<Form {...form}>
<form onChange={debounceSubmit} id="setting-form" className="space-y-4 p-2 flex-1 h-screen overflow-y-scroll">
<form onChange={() => form.handleSubmit(submitHandler)()} id="setting-form" className="space-y-4 p-2 flex-1 h-screen overflow-y-scroll">
{
config.map(item => {
return (
Expand Down
3 changes: 2 additions & 1 deletion src/lib/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ export async function fetchAiModels() {
method: 'GET',
headers,
};
return (await fetch('https://api.chatanywhere.tech/v1/models', requestOptions)).json()
return await fetch('https://api.chatanywhere.tech/v1/models', requestOptions)
.then(response => response.json())
}

export async function fetchAiStream(text: string, callback: (text: string) => void) {
Expand Down
2 changes: 1 addition & 1 deletion src/stores/setting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const useSettingStore = create<SettingState>((set, get) => ({
Object.entries(get()).forEach(async([key, value]) => {
const res = await store.get(key)
if (typeof value === 'function') return
if (res && key!== 'version') {
if (res !== undefined && key!== 'version') {
set({ [key]: res })
} else {
await store.set(key, value)
Expand Down

0 comments on commit c91dde4

Please sign in to comment.