diff --git a/app/src/components/PopupDialog.tsx b/app/src/components/PopupDialog.tsx index 1325585..b8eef39 100644 --- a/app/src/components/PopupDialog.tsx +++ b/app/src/components/PopupDialog.tsx @@ -15,6 +15,7 @@ export type PopupDialogProps = { title: string; description?: string; name: string; + placeholder?: string; defaultValue?: string; onValueChange?: (value: string) => string; onSubmit?: (value: string) => Promise; @@ -44,6 +45,7 @@ function PopupDialog({ title, description, name, + placeholder, defaultValue, onValueChange, onSubmit, @@ -71,6 +73,7 @@ function PopupDialog({ ); }} value={value} + placeholder={placeholder} /> diff --git a/app/src/components/app/AppProvider.tsx b/app/src/components/app/AppProvider.tsx index ac5effa..405e78f 100644 --- a/app/src/components/app/AppProvider.tsx +++ b/app/src/components/app/AppProvider.tsx @@ -35,7 +35,7 @@ function AppProvider() { if (!obj) return; item.free = obj.type === nonBilling; - item.auth = item.free && !obj.anonymous; + item.auth = !item.free || !obj.anonymous; }); resetJsArray(supportModels, loadPreferenceModels(market)); diff --git a/app/src/resources/i18n/cn.json b/app/src/resources/i18n/cn.json index 3143184..9e94f9e 100644 --- a/app/src/resources/i18n/cn.json +++ b/app/src/resources/i18n/cn.json @@ -422,6 +422,7 @@ "update": "更新", "migrate": "提交", "sync": "同步上游", + "sync-site": "上游地址", "sync-tip": "同步上游模型市场", "sync-placeholder": "请输入上游 Chat Nio 的 API 地址,如:https://api.chatnio.net", "sync-items": "共发现 {{length}} 个模型,已有模型 {{exist}} 个(不会覆盖),新增模型 {{new}} 个,本站点渠道已支持模型 {{support}} 个", diff --git a/app/src/resources/i18n/en.json b/app/src/resources/i18n/en.json index 248d1ea..bd760f2 100644 --- a/app/src/resources/i18n/en.json +++ b/app/src/resources/i18n/en.json @@ -488,7 +488,8 @@ "sync-placeholder": "Please enter the API address of the upstream Chat Nio, for example: https://api.chatnio.net", "sync-items": "A total of {{length}} models have been found, {{exist}} models have been found (will not be overwritten), {{new}} models have been added, {{support}} models have been supported in this site channel", "sync-all": "Sync all ({{length}})", - "sync-self": "Sync supported models ({{length}})" + "sync-self": "Sync supported models ({{length}})", + "sync-site": "Upstream address" }, "model-chart-tip": "Token usage", "subscription": "Subscription Management", diff --git a/app/src/resources/i18n/ja.json b/app/src/resources/i18n/ja.json index b7a4818..5f58ee6 100644 --- a/app/src/resources/i18n/ja.json +++ b/app/src/resources/i18n/ja.json @@ -488,7 +488,8 @@ "sync-placeholder": "アップストリームのChat NioのAPIアドレスを入力してください。例: https://api.chatnio.net", "sync-items": "合計{{length}}個のモデルが見つかりました。{{exist}}個のモデルが見つかりました(上書きされません)。{{new}}個のモデルが追加されました。{{support}}個のモデルがこのサイトチャンネルでサポートされています", "sync-all": "すべて同期({{length}})", - "sync-self": "サポートされているモデルを同期({{ length }})" + "sync-self": "サポートされているモデルを同期({{ length }})", + "sync-site": "アップストリームアドレス" }, "model-chart-tip": "トークンの使用状況", "subscription": "サブスクリプション管理", diff --git a/app/src/resources/i18n/ru.json b/app/src/resources/i18n/ru.json index b5ac69c..92fb687 100644 --- a/app/src/resources/i18n/ru.json +++ b/app/src/resources/i18n/ru.json @@ -488,7 +488,8 @@ "sync-placeholder": "Введите API-адрес вышестоящего Chat Nio, например: https://api.chatnio.net", "sync-items": "Всего было найдено {{length}} моделей, {{exist}} моделей было найдено (не будет перезаписано), {{new}} моделей было добавлено, {{support}} моделей было поддержано в этом канале сайта", "sync-all": "Синхронизировать все ({{length}})", - "sync-self": "Синхронизация поддерживаемых моделей ({{length}})" + "sync-self": "Синхронизация поддерживаемых моделей ({{length}})", + "sync-site": "Адрес выше по потоку" }, "model-chart-tip": "Использование токенов", "subscription": "Управление подписками", diff --git a/app/src/routes/admin/Market.tsx b/app/src/routes/admin/Market.tsx index b52ece7..fa84733 100644 --- a/app/src/routes/admin/Market.tsx +++ b/app/src/routes/admin/Market.tsx @@ -8,9 +8,15 @@ import { useTranslation } from "react-i18next"; import { Dispatch, useMemo, useReducer, useState } from "react"; import { Model as RawModel } from "@/api/types.ts"; import { supportModels } from "@/conf"; -import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd"; import { Input } from "@/components/ui/input.tsx"; -import { GripVertical, HelpCircle, Loader2, Plus, Trash2 } from "lucide-react"; +import { + ChevronDown, + ChevronUp, + HelpCircle, + Loader2, + Plus, + Trash2, +} from "lucide-react"; import { generateRandomChar, isUrl } from "@/utils/base.ts"; import Require from "@/components/Require.tsx"; import { Textarea } from "@/components/ui/textarea.tsx"; @@ -26,6 +32,7 @@ import { Combobox } from "@/components/ui/combo-box.tsx"; import { channelModels } from "@/admin/channel.ts"; import { cn } from "@/components/ui/lib/utils.ts"; import { marketEvent } from "@/events/market.ts"; +import PopupDialog from "@/components/PopupDialog.tsx"; type Model = RawModel & { seed?: string; @@ -169,6 +176,18 @@ function reducer(state: MarketForm, action: any): MarketForm { const [removed] = state.splice(from, 1); state.splice(to, 0, removed); return [...state]; + case "upward": + if (action.payload.idx === 0) return state; + const upward = state[action.payload.idx]; + state[action.payload.idx] = state[action.payload.idx - 1]; + state[action.payload.idx - 1] = upward; + return [...state]; + case "downward": + if (action.payload.idx === state.length - 1) return state; + const downward = state[action.payload.idx]; + state[action.payload.idx] = state[action.payload.idx + 1]; + state[action.payload.idx + 1] = downward; + return [...state]; default: throw new Error(); } @@ -339,8 +358,19 @@ function Market() { }, [form, index]); }; + const [popupOpen, setPopupOpen] = useState(false); + return (
+ + @@ -348,209 +378,172 @@ function Market() { {loading && } - { - const { destination, source } = result; - if ( - !destination || - destination.index === source.index || - destination.index === -1 - ) - return; - - const from = source.index; - const to = destination.index; - - dispatch({ type: "replace", payload: { from, to } }); - }} - > - - {(provided) => ( -
- {form.map((model, index) => ( - - {(provided) => ( -
- -
-
- - - {t("admin.market.model-name")} - - { - dispatch({ - type: "update-name", - payload: { - idx: index, - name: e.target.value, - }, - }); - }} - /> -
-
- - - {t("admin.market.model-id")} - - { - dispatch({ - type: "update-id", - payload: { idx: index, id }, - }); - }} - className={`model-combobox`} - list={channelModels} - placeholder={t( - "admin.market.model-id-placeholder", - )} - /> -
-
- {t("admin.market.model-description")} -