Update AirFlow branding and settings UI
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 4m32s

This commit is contained in:
zyc 2026-05-28 13:58:30 +08:00
parent a7b61c05f5
commit c3f616dc22
42 changed files with 1403 additions and 1256 deletions

File diff suppressed because one or more lines are too long

View File

@ -53,7 +53,7 @@ Comedy_humor/
## 使用方式
本技能包作为 ToonFlow 导演 AI 的叙事手法参考,在故事创作流程中自动加载,指导:
本技能包作为 AirFlow 导演 AI 的叙事手法参考,在故事创作流程中自动加载,指导:
1. **叙事规划** — 确定喜剧内核、笑点节奏曲线、场景喜感与音效时机
2. **分镜表生成** — 根据叙事规划输出具体的景别、运镜、时长与转场方案

View File

@ -53,7 +53,7 @@ Hot_blooded_action/
## 使用方式
本技能包作为 ToonFlow 导演 AI 的叙事手法参考,在故事创作流程中自动加载,指导:
本技能包作为 AirFlow 导演 AI 的叙事手法参考,在故事创作流程中自动加载,指导:
1. **叙事规划** — 确定热血内核、燃点节奏曲线、场景情绪与音乐爆发时机
2. **分镜表生成** — 根据叙事规划输出具体的景别、运镜、时长与转场方案

View File

@ -54,7 +54,7 @@ Mystery_thriller/
## 使用方式
本技能包作为 ToonFlow 导演 AI 的叙事手法参考,在故事创作流程中自动加载,指导:
本技能包作为 AirFlow 导演 AI 的叙事手法参考,在故事创作流程中自动加载,指导:
1. **叙事规划** — 确定悬念内核、信息释放节奏、场景氛围与音效方向
2. **分镜表生成** — 根据叙事规划输出具体的景别、运镜、时长与转场方案

View File

@ -53,7 +53,7 @@ Scifi_post_apocalypse/
## 使用方式
本技能包作为 ToonFlow 导演 AI 的叙事手法参考,在故事创作流程中自动加载,指导:
本技能包作为 AirFlow 导演 AI 的叙事手法参考,在故事创作流程中自动加载,指导:
1. **叙事规划** — 确定末世内核、生存节奏曲线、场景废墟氛围与音效方向
2. **分镜表生成** — 根据叙事规划输出具体的景别、运镜、时长与转场方案

View File

@ -54,7 +54,7 @@ Sweet_romance_novel/
## 使用方式
本技能包作为 ToonFlow 导演 AI 的叙事手法参考,在故事创作流程中自动加载,指导:
本技能包作为 AirFlow 导演 AI 的叙事手法参考,在故事创作流程中自动加载,指导:
1. **叙事规划** — 确定情感内核、节奏曲线、场景情绪与音乐方向
2. **分镜表生成** — 根据叙事规划输出具体的景别、运镜、时长与转场方案

View File

@ -53,7 +53,7 @@ Urban_workplace_drama/
## 使用方式
本技能包作为 ToonFlow 导演 AI 的叙事手法参考,在故事创作流程中自动加载,指导:
本技能包作为 AirFlow 导演 AI 的叙事手法参考,在故事创作流程中自动加载,指导:
1. **叙事规划** — 确定职场内核、博弈节奏曲线、场景权力关系与音效方向
2. **分镜表生成** — 根据叙事规划输出具体的景别、运镜、时长与转场方案

View File

@ -53,7 +53,7 @@ Xianxia_fantasy/
## 使用方式
本技能包作为 ToonFlow 导演 AI 的叙事手法参考,在故事创作流程中自动加载,指导:
本技能包作为 AirFlow 导演 AI 的叙事手法参考,在故事创作流程中自动加载,指导:
1. **叙事规划** — 确定仙侠内核、宿命节奏曲线、场景意境与音乐方向
2. **分镜表生成** — 根据叙事规划输出具体的景别、运镜、时长与转场方案

View File

@ -1,5 +1,5 @@
/**
* Toonflow AI供应商模板 - AtlasCloud MASS
* AirFlow AI供应商模板 - AtlasCloud MASS
* @version 0.8
*
*
@ -136,7 +136,7 @@ const vendor: VendorConfig = {
version: "1.0",
author: "AtlasCloud",
name: "AtlasCloud MASS",
description: "AtlasCloud 全模态平台接入 Toonflow。默认按官方文档填写文本、图片、视频与任务轮询路径。",
description: "AtlasCloud 全模态平台接入 AirFlow。默认按官方文档填写文本、图片、视频与任务轮询路径。",
inputs: [
{ key: "apiKey", label: "API密钥", type: "password", required: true, placeholder: "AtlasCloud API Key" },
{ key: "chatBaseUrl", label: "文本基地址", type: "url", required: true, placeholder: "https://api.atlascloud.ai/v1", disabled: true },

View File

@ -1,5 +1,5 @@
/**
* Toonflow AI供应商模板 - DeepSeek
* AirFlow AI供应商模板 - DeepSeek
* @version 2.0
*/
@ -128,7 +128,7 @@ declare const exports: {
const vendor: VendorConfig = {
id: "deepseek",
version: "2.0",
author: "Toonflow",
author: "AirFlow",
name: "DeepSeek",
description:
"DeepSeek 官方接口适配,支持 V4 系列模型与思考模式(思维链输出)。\n\n[前往平台](https://platform.deepseek.com/)",

View File

@ -1,5 +1,5 @@
/**
* Toonflow AI供应商模板
* AirFlow AI供应商模板
* @version 2.0
*/
@ -159,7 +159,7 @@ declare const exports: {
const vendor: VendorConfig = {
id: "grsai",
version: "2.1",
author: "Toonflow",
author: "AirFlow",
name: "Grsai",
description:
"Grsai AI平台适配支持文生图、图生图、文生视频、Gemini兼容文本模型 \n [前往中转平台](https://tf.grsai.ai/zh)",

View File

@ -1,5 +1,5 @@
/**
* Toonflow AI供应商模板 - AI
* AirFlow AI供应商模板 - AI
* @version 2.0
*/
@ -134,7 +134,7 @@ declare const exports: {
const vendor: VendorConfig = {
id: "klingai",
version: "2.0",
author: "Toonflow",
author: "AirFlow",
name: "可灵AI",
description:
"可灵AI视频生成\n\n支持可灵全系列视频模型包括 kling-video-o1、kling-v3-omni、kling-v3、kling-v2-6、kling-v2-5-turbo、kling-v2-1、kling-v2-master、kling-v1-6、kling-v1-5、kling-v1 等。\n\n需要在[可灵AI开放平台](https://klingai.com)\n\n获取 Access Key 和 Secret Key。",

View File

@ -1,5 +1,5 @@
/**
* Toonflow AI供应商模板 - MiniMax(AI)
* AirFlow AI供应商模板 - MiniMax(AI)
* @version 2.0
*/
@ -135,7 +135,7 @@ declare const exports: {
const vendor: VendorConfig = {
id: "minimax",
version: "2.1",
author: "Toonflow",
author: "AirFlow",
name: "MiniMax(海螺AI)",
description: "MiniMax官方接口适配支持M系列推理文本模型、文生图/图生图、视频生成(文生视频、图生视频、首尾帧生成)能力 \n [前往平台](https://minimaxi.com/)",
inputs: [

6
data/vendor/null.ts vendored
View File

@ -1,5 +1,5 @@
/**
* Toonflow AI供应商模板
* AirFlow AI供应商模板
* @version 2.0
*/
@ -134,7 +134,7 @@ declare const exports: {
const vendor: VendorConfig = {
id: "null",
version: "2.0",
author: "Toonflow",
author: "AirFlow",
name: "空模板",
description: "## 开发模板您可以使用此模板进行Vibe Coding",
inputs: [
@ -196,7 +196,7 @@ export {};
* ============================================================
*
*
* Toonflow AI AI
* AirFlow AI AI
* curl API
*
*

View File

@ -1,5 +1,5 @@
/**
* Toonflow AI供应商模板
* AirFlow AI供应商模板
* @version 2.0
*/
// ============================================================
@ -113,7 +113,7 @@ declare const exports: {
const vendor: VendorConfig = {
id: "openai",
version: "2.0",
author: "Toonflow",
author: "AirFlow",
name: "OpenAI标准接口",
description: "OpenAI标准格式接口可修改请求地址并手动添加模型。",
icon: "",

View File

@ -1,5 +1,5 @@
/**
* Toonflow官方中转平台
* AirFlow官方中转平台
* @version 2.0
*/
@ -134,10 +134,10 @@ declare const exports: {
const vendor: VendorConfig = {
id: "toonflow",
version: "2.0",
author: "Toonflow",
name: "Toonflow官方中转平台",
author: "AirFlow",
name: "AirFlow官方中转平台",
description:
"## Toonflow官方中转平台\n\nToonflow官方中转平台提供**文本、图像、视频、音频**等多模态生成能力的中转服务,支持接入多个大模型供应商,方便用户统一管理和调用不同供应商的生成能力。\n\n🔗 [前往中转平台](https://api.toonflow.net/)\n\n如果这个项目对你有帮助可以考虑支持一下我们的开发工作 ☕",
"## AirFlow官方中转平台\n\nAirFlow官方中转平台提供**文本、图像、视频、音频**等多模态生成能力的中转服务,支持接入多个大模型供应商,方便用户统一管理和调用不同供应商的生成能力。\n\n🔗 [前往中转平台](https://api.toonflow.net/)\n\n如果这个项目对你有帮助可以考虑支持一下我们的开发工作 ☕",
icon: "",
inputs: [{ key: "apiKey", label: "API密钥", type: "password", required: true }],
inputValues: {

View File

@ -1,5 +1,5 @@
/**
* Toonflow AI供应商模板 - ()
* AirFlow AI供应商模板 - ()
* @version 2.0
*/

View File

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="ToonFlow logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="AirFlow logo">
<defs>
<linearGradient id="tf-stem" x1="24" y1="24" x2="96" y2="98" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#64e1d3"/>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
appId: net.toonflow.www
productName: ToonFlow
productName: AirFlow
copyright: Copyright © 2026
directories:

View File

@ -1,7 +1,7 @@
{
"name": "toonflow",
"version": "1.1.7",
"description": "Toonflow 是一款 AI 短剧漫剧工具,能够利用 AI 技术将小说自动转化为剧本,并结合 AI 生成的图片和视频,实现高效的短剧创作。",
"description": "AirFlow 是一款 AI 短剧漫剧工具,能够利用 AI 技术将小说自动转化为剧本,并结合 AI 生成的图片和视频,实现高效的短剧创作。",
"author": "HBAI-Ltd <ltlctools@outlook.com>",
"license": "Apache-2.0",
"homepage": "https://github.com/HBAI-Ltd/Toonflow-app#readme",

File diff suppressed because one or more lines are too long

View File

@ -30,7 +30,7 @@ export default router.post(
const ending = await u.oss.getFileUrl("/ending.mp4", "assets");
data.push({
id: 0,
name: "Toonflow片尾",
name: "AirFlow片尾",
filePath: ending,
type: "clip",
});

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Toonflow</title>
<title>AirFlow</title>
</head>
<body>
<div id="app"></div>

View File

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="ToonFlow logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="AirFlow logo">
<defs>
<linearGradient id="tf-stem" x1="24" y1="24" x2="96" y2="98" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#64e1d3"/>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="ToonFlow logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="AirFlow logo">
<defs>
<linearGradient id="tf-stem" x1="24" y1="24" x2="96" y2="98" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#64e1d3"/>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -4,7 +4,7 @@
<!-- 欢迎首页 -->
<template v-if="currentStep === 0">
<div class="welcomePage">
<img src="@/assets/logo.png" alt="ToonFlow Logo" class="welcomeLogo" />
<img src="@/assets/logo.png" alt="AirFlow Logo" class="welcomeLogo" />
<h1 class="welcomeTitle">{{ $t("hello.welcomeTitle") }}</h1>
<p class="welcomeDesc">{{ $t("hello.welcomeDesc") }}</p>
<t-button theme="primary" size="large" @click="currentStep = 1">{{ $t("hello.startConfig") }}</t-button>

View File

@ -2,9 +2,9 @@
<div class="about">
<t-card bordered :style="{ width: '100%' }" class="logoCard">
<div class="f">
<img src="@/assets/logo.png" alt="ToonFlow Logo" class="logo" @click="onLogoClick" />
<img src="@/assets/logo.png" alt="AirFlow Logo" class="logo" @click="onLogoClick" />
<div class="appName">
<div class="name">ToonFlow</div>
<div class="name">AirFlow</div>
<div class="data">{{ $t("settings.about.slogan") }}</div>
<div class="version">
<t-tag theme="primary" shape="round" size="small" style="padding: 10px">v{{ version }}</t-tag>
@ -212,7 +212,7 @@ const updateSource = ref<UpdateSource>("toonflow");
const updateSources = ref([
{
value: "toonflow" as UpdateSource,
label: "ToonFlow",
label: "AirFlow",
iconType: "image" as const,
iconSrc: toonflowLogo,
iconClass: "toonflow",
@ -288,7 +288,7 @@ function checkUpdate() {
function getUpdateSourceLabel(source: UpdateSource) {
const sourceMap = {
toonflow: "ToonFlow",
toonflow: "AirFlow",
github: "GitHub",
atomgit: "AtomGit",
gitee: "Gitee",

View File

@ -1,53 +1,73 @@
<template>
<div class="otherConfig">
<t-form label-align="top">
<t-form-item name="chapterReg">
<template #label>
<span>{{ $t("settings.other.chapterRegex") }}</span>
<t-button style="margin-left: 15px" @click="setDefaultReg" size="small">{{ $t("settings.other.restoreDefault") }}</t-button>
</template>
<t-textarea v-model="otherSetting.chapterReg" :placeholder="$t('settings.other.regexPlaceholder')" style="width: 400px" />
</t-form-item>
<t-form-item :label="$t('settings.other.requestTimeout')" name="axiosTimeOut">
<section class="settingBlock wide">
<div class="blockHeader">
<span class="blockTitle">{{ $t("settings.other.chapterRegex") }}</span>
<t-button variant="outline" size="small" @click="setDefaultReg">
<template #icon><t-icon name="refresh" /></template>
{{ $t("settings.other.restoreDefault") }}
</t-button>
</div>
<t-textarea
v-model="otherSetting.chapterReg"
class="regexInput"
:autosize="{ minRows: 4, maxRows: 6 }"
:placeholder="$t('settings.other.regexPlaceholder')" />
</section>
<div class="settingsGrid">
<section class="settingBlock">
<span class="fieldLabel">{{ $t("settings.other.requestTimeout") }}</span>
<t-input-number
class="numberInput"
auto-width
:suffix="$t('settings.other.seconds')"
:min="10"
v-model="axiosTimeOutInSeconds"
:allowInputOverLimit="false"
:placeholder="$t('settings.other.inputSeconds')" />
</t-form-item>
<t-form-item :label="$t('settings.other.agentCanvasScalingMethod')">
<t-radio-group variant="default-filled" v-model="canvasWheelEvent">
<t-radio-button value="zoom">{{ $t("settings.other.zoom") }}</t-radio-button>
<t-radio-button value="scroll">{{ $t("settings.other.scroll") }}</t-radio-button>
</t-radio-group>
</t-form-item>
<t-form-item :label="$t('settings.other.isInteracting')">
<t-radio-group variant="default-filled" v-model="otherSetting.interacting">
<t-radio-button :value="false">{{ $t("settings.other.closeIsInteracting") }}</t-radio-button>
<t-radio-button :value="true">{{ $t("settings.other.openIsInteracting") }}</t-radio-button>
</t-radio-group>
</t-form-item>
<t-form-item :label="$t('settings.other.assetConcurrency')" name="assetsBatchGenereateSize">
</section>
<section class="settingBlock">
<span class="fieldLabel">{{ $t("settings.other.assetConcurrency") }}</span>
<t-input-number
class="numberInput"
auto-width
:suffix="$t('settings.other.count')"
:min="1"
v-model="otherSetting.assetsBatchGenereateSize"
:allowInputOverLimit="false"
:placeholder="$t('settings.other.inputCount')" />
</t-form-item>
<t-form-item :label="$t('settings.other.scriptEpisodeLength')" name="scriptEpisodeLength">
</section>
<section class="settingBlock">
<span class="fieldLabel">{{ $t("settings.other.scriptEpisodeLength") }}</span>
<t-input-number
class="numberInput"
auto-width
:suffix="$t('settings.other.chars')"
:min="100"
v-model="otherSetting.scriptEpisodeLength"
:allowInputOverLimit="false"
:placeholder="$t('settings.other.inputChars')" />
</t-form-item>
</t-form>
</section>
<section class="settingBlock">
<span class="fieldLabel">{{ $t("settings.other.agentCanvasScalingMethod") }}</span>
<t-radio-group variant="default-filled" v-model="canvasWheelEvent">
<t-radio-button value="zoom">{{ $t("settings.other.zoom") }}</t-radio-button>
<t-radio-button value="scroll">{{ $t("settings.other.scroll") }}</t-radio-button>
</t-radio-group>
</section>
<section class="settingBlock">
<span class="fieldLabel">{{ $t("settings.other.isInteracting") }}</span>
<t-radio-group variant="default-filled" v-model="otherSetting.interacting">
<t-radio-button :value="false">{{ $t("settings.other.closeIsInteracting") }}</t-radio-button>
<t-radio-button :value="true">{{ $t("settings.other.openIsInteracting") }}</t-radio-button>
</t-radio-group>
</section>
</div>
</div>
</template>
@ -77,5 +97,84 @@ function setDefaultReg() {
<style lang="scss" scoped>
.otherConfig {
width: 100%;
display: flex;
flex-direction: column;
gap: 14px;
padding-bottom: 4px;
}
.settingsGrid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 14px;
}
.settingBlock {
min-width: 0;
min-height: 104px;
padding: 16px;
border: 1px solid rgba(185, 188, 210, 0.14);
border-radius: var(--air-radius-md);
background:
linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.02)),
rgba(17, 21, 37, 0.72);
&.wide {
min-height: 0;
}
}
.blockHeader {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 12px;
}
.blockTitle,
.fieldLabel {
display: block;
color: var(--air-text-primary);
font-size: 13px;
font-weight: 750;
line-height: 1.35;
}
.fieldLabel {
margin-bottom: 12px;
}
.regexInput {
width: 100%;
}
.numberInput {
min-width: 152px;
}
:deep(.t-radio-group) {
max-width: 100%;
}
:deep(.t-radio-button) {
min-width: 64px;
}
:deep(.t-input-number) {
width: 152px;
}
:deep(.t-textarea__inner) {
width: 100%;
min-height: 112px;
font-family: var(--air-font-number);
line-height: 1.58;
}
@media (max-width: 760px) {
.settingsGrid {
grid-template-columns: 1fr;
}
}
</style>

View File

@ -276,7 +276,7 @@
</t-radio-group>
<div class="linkAdd" v-if="addMode == 'linkAdd'">
<t-alert theme="warning" style="margin-bottom: 20px">
请填写 TypeScript 代码文件的链接.ts 文件不要填 API 地址或其他无关链接 确认后 Toonflow 会自动加载该代码请确保链接来源可信
请填写 TypeScript 代码文件的链接.ts 文件不要填 API 地址或其他无关链接 确认后 AirFlow 会自动加载该代码请确保链接来源可信
</t-alert>
<t-input v-model="link" :placeholder="$t('settings.vendor.linkAddPlaceholder')"></t-input>
<div style="margin-top: 10px; text-align: right; width: 100%">

View File

@ -1,12 +1,10 @@
<template>
<t-dialog :header="$t('settings.title')" :footer="false" placement="center" width="1200px" v-model:visible="showSetting">
<t-dialog class="airSettingDialog" :header="$t('settings.title')" :footer="false" placement="center" width="1200px" v-model:visible="showSetting">
<div class="settingPanel">
<t-menu class="settingMenu" v-model:value="activeMenu" :style="{ height: '70vh' }">
<t-menu class="settingMenu" v-model:value="activeMenu">
<t-menu-item v-for="item in menuItems" :key="item.key" :value="item.key">
<template #icon>
<t-badge :count="needUpdate && item.key === 'about' ? 1 : 0" dot>
<component :is="item.icon" class="icon" />
</t-badge>
</template>
{{ $t(item.label) }}
</t-menu-item>
@ -23,7 +21,6 @@
<promptManage v-if="activeMenu === 'promptManage'" />
<otherConfig v-if="activeMenu === 'otherConfig'" />
<dbConfig v-if="activeMenu === 'dbConfig'" />
<about v-if="activeMenu === 'about'" />
<logoutConfig v-if="activeMenu === 'logoutConfig'" />
<memoryConfig v-if="activeMenu === 'memoryConfig'" />
<fileManagement v-if="activeMenu === 'fileManagement'" />
@ -38,7 +35,7 @@
<script setup lang="ts">
import settingStore from "@/stores/setting";
const { showSetting, activeMenu, needUpdate } = storeToRefs(settingStore());
const { showSetting, activeMenu } = storeToRefs(settingStore());
import uiConfig from "./components/uiConfig.vue";
import languageConfig from "./components/languageConfig.vue";
@ -47,7 +44,6 @@ import loginConfig from "./components/loginConfig.vue";
import agentConfog from "./components/agentConfog.vue";
import dbConfig from "./components/dbConfig.vue";
import otherConfig from "./components/otherConfig.vue";
import about from "./components/about.vue";
import logoutConfig from "./components/logoutConfig.vue";
import vendorConfig from "./components/vendorConfig.vue";
import memoryConfig from "./components/memoryConfig.vue";
@ -72,86 +68,172 @@ const menuItems = [
{ key: "otherConfig", label: "settings.menu.otherConfig", icon: "i-application-menu" },
{ key: "requestConfig", label: "settings.menu.requestConfig", icon: "i-api" },
{ key: "devConfig", label: "settings.menu.devConfig", icon: "i-flask" },
{ key: "about", label: "settings.menu.about", icon: "i-info" },
{ key: "logoutConfig", label: "settings.menu.logoutConfig", icon: "i-logout" },
];
const currentMenuItem = computed(() => menuItems.find((item) => item.key === activeMenu.value));
watchEffect(() => {
if (!currentMenuItem.value) activeMenu.value = "ui";
});
</script>
<style lang="scss" scoped>
.settingPanel {
display: flex;
gap: 16px;
height: 70vh;
gap: 18px;
height: min(70vh, 640px);
overflow: hidden;
color: var(--air-text-primary);
.settingMenu {
width: 220px;
min-width: 220px;
padding: 8px;
width: 236px;
min-width: 236px;
height: 100%;
padding: 10px;
border: 1px solid var(--air-border-soft);
border-radius: var(--air-radius-md);
background: rgba(255, 255, 255, 0.035);
background:
linear-gradient(180deg, rgba(17, 21, 37, 0.96), rgba(8, 11, 24, 0.92)),
var(--air-bg-shell);
flex-shrink: 0;
overflow-y: auto;
.icon {
font-size: 18px;
margin-right: 8px;
width: 18px;
height: 18px;
margin-right: 10px;
color: inherit;
}
}
.settingRight {
display: flex;
flex-direction: column;
flex: 1;
min-width: 0;
padding: 2px 4px 0;
height: 70vh;
overflow-y: auto;
height: 100%;
padding: 0;
overflow: hidden;
.sectionTitle {
height: 44px;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 1px solid rgba(185, 188, 210, 0.14);
flex: 0 0 auto;
height: 42px;
margin-bottom: 14px;
padding: 0 2px 12px;
border-bottom: 1px solid rgba(185, 188, 210, 0.13);
color: var(--air-text-primary);
font-family: var(--air-font-display);
font-size: 18px;
font-weight: 650;
line-height: 32px;
font-size: 19px;
font-weight: 750;
line-height: 30px;
}
.settingContent {
width: 100%;
height: calc(70vh - 60px);
padding-right: 6px;
flex: 1;
min-height: 0;
padding: 2px 12px 4px 0;
overflow-y: auto;
}
}
}
:deep(.airSettingDialog) {
.t-dialog {
border: 1px solid rgba(185, 188, 210, 0.18);
border-radius: var(--air-radius-xl);
background:
radial-gradient(circle at 34% 0%, rgba(101, 217, 203, 0.08), transparent 28%),
linear-gradient(180deg, rgba(13, 17, 33, 0.98), rgba(7, 10, 22, 0.98));
box-shadow: var(--air-shadow-lg);
overflow: hidden;
}
.t-dialog__header {
padding: 24px 32px 18px;
border-bottom: 1px solid rgba(185, 188, 210, 0.12);
}
.t-dialog__header-content {
color: var(--air-text-primary);
font-family: var(--air-font-display);
font-size: 16px;
font-weight: 750;
}
.t-dialog__close {
top: 22px;
right: 28px;
color: var(--air-text-secondary);
}
.t-dialog__body {
padding: 16px 32px 30px;
}
}
:deep(.t-menu) {
padding: 0;
background: transparent !important;
}
:deep(.t-menu__item) {
min-height: 40px;
margin-bottom: 4px;
min-height: 42px;
margin-bottom: 5px;
padding: 0 14px;
border: 1px solid transparent;
border-radius: var(--air-field-radius);
color: var(--air-text-secondary);
transition:
background-color 0.16s var(--air-ease-out),
border-color 0.16s var(--air-ease-out),
color 0.16s var(--air-ease-out);
}
:deep(.t-menu__item:hover) {
background: rgba(101, 217, 203, 0.08);
color: var(--air-text-primary);
}
:deep(.t-menu__content) {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 13px;
font-weight: 650;
}
:deep(.t-is-active) {
.t-badge {
color: var(--td-brand-color) !important;
border-color: rgba(101, 217, 203, 0.18);
background: linear-gradient(90deg, rgba(101, 217, 203, 0.2), rgba(101, 217, 203, 0.08));
color: var(--air-accent-teal) !important;
box-shadow: inset 2px 0 0 var(--air-accent-teal);
}
:deep(.t-form__label) {
color: var(--air-text-secondary);
font-size: 12px;
font-weight: 700;
}
:deep(.t-form__item) {
margin-bottom: 18px;
}
:deep(.t-input),
:deep(.t-textarea__inner),
:deep(.t-input-number) {
border-color: var(--air-field-border) !important;
background: var(--air-field-bg) !important;
}
:deep(.t-input:hover),
:deep(.t-textarea__inner:hover),
:deep(.t-input-number:hover) {
border-color: var(--air-field-border-hover) !important;
}
@media (max-width: 900px) {
.settingPanel {
flex-direction: column;
height: 76vh;
.settingMenu {
width: 100%;
@ -162,7 +244,7 @@ const currentMenuItem = computed(() => menuItems.find((item) => item.key === act
}
.settingRight {
height: calc(70vh - 230px);
height: calc(76vh - 230px);
}
}
}

View File

@ -1,7 +1,7 @@
<template>
<div class="titleBar">
<div class="titleBar-title">
<span class="titleBar-text">ToonFlow</span>
<span class="titleBar-text">AirFlow</span>
</div>
<div class="titleBar-controls">
<div class="titleBar-btn" @click="handleMinimize">

View File

@ -1,5 +1,5 @@
/**
* Toonflow AI供应商模板
* AirFlow AI供应商模板
* @version 2.0
*/
@ -134,7 +134,7 @@ declare const exports: {
const vendor: VendorConfig = {
id: "bull",
version: "2.0",
author: "Toonflow",
author: "AirFlow",
name: "空模板",
description: "## OpenAI标准格式接口可修改请求地址并手动添加模型。",
inputs: [
@ -196,7 +196,7 @@ export {};
* ============================================================
*
*
* Toonflow AI AI
* AirFlow AI AI
* curl API
*
*

View File

@ -43,7 +43,7 @@
}
},
"settings": {
"title": "ToonFlow Settings",
"title": "AirFlow Settings",
"menu": {
"language": "Language",
"vendorConfig": "Model Providers",
@ -181,7 +181,7 @@
"linkAdd": "confirm"
},
"agent": {
"bannerDesc": "Use the official Toonflow relay site for one-click configuration. Ready out-of-the-box, no manual setup needed.",
"bannerDesc": "Use the official AirFlow relay site for one-click configuration. Ready out-of-the-box, no manual setup needed.",
"visitWebsite": "Visit Website",
"fillKey": "Enter KEY",
"oneClickFill": "One-Click Fill",
@ -191,19 +191,19 @@
"confirm": "Confirm",
"cancel": "Cancel",
"selectModel": "Select Model",
"fillKeyHeader": "Enter official KEY from Toonflow platform",
"fillKeyHeader": "Enter official KEY from AirFlow platform",
"keyPlaceholder": "Please enter KEY",
"save": "Save",
"msg": {
"notAvailable": "This feature is not yet available. Stay tuned!",
"configSuccess": "Configured successfully",
"updateConfigFailed": "Failed to update config: ",
"keyValid": "KEY is valid. Successfully connected to the Toonflow platform",
"keyValid": "KEY is valid. Successfully connected to the AirFlow platform",
"keyInvalid": "KEY is invalid. Please check and re-enter: ",
"enterKey": "Please enter KEY",
"saveFailed": "Save failed: ",
"getAgentListFailed": "Failed to fetch Agent config list: ",
"toonflowNotFound": "Toonflow official transfer station does not exist"
"toonflowNotFound": "AirFlow official transfer station does not exist"
},
"temperature": "temperature"
},
@ -318,7 +318,7 @@
"skill": {
"scanSkills": "Scan Skills",
"addSkill": "Add Skill",
"importFromHub": "Import from Toonflow-Hub",
"importFromHub": "Import from AirFlow-Hub",
"filterType": "Type",
"filterAttribution": "Attribution",
"searchPlaceholder": "Search skill by name",
@ -338,7 +338,7 @@
"embedding": "Embed",
"edit": "Edit",
"delete": "Delete",
"importFromHubDialog": "Import from Toonflow-Hub",
"importFromHubDialog": "Import from AirFlow-Hub",
"shareLink": "Share Link",
"editSkillTitle": "Edit Skill - ",
"addSkillTitle": "Add Skill",
@ -512,9 +512,9 @@
"warning": "The following are developer tools, please operate with caution!",
"openDevtool": "Open",
"devtoolsDoc": "Document address",
"devtoolsDesc": "After being turned on, a .devtools folder will be created in the Toonflow installation directory. Please ensure that Toonflow has write permissions (run as administrator).",
"devtoolsDesc": "After being turned on, a .devtools folder will be created in the AirFlow installation directory. Please ensure that AirFlow has write permissions (run as administrator).",
"devtoolsDesc2": "Run npx {'@'}ai-sdk/devtools in this directory to enable telemetry debugging",
"openDevtoolFailed": "Failed to open developer tools, please make sure Toonflow desktop is installed",
"openDevtoolFailed": "Failed to open developer tools, please make sure AirFlow desktop is installed",
"notInElectron": "For WEB environment, please open the browser console manually",
"msg": {
"localStorageKeyRequired": "Please enter a localStorage key",
@ -798,7 +798,7 @@
"selectAssets": "Select Assets",
"noAssets": "No related assets",
"selectAssetsTitle": "Select Related Assets",
"welcomeMsg": "Hello! I am the Toonflow AI Assistant. Would you like me to start generating a script?",
"welcomeMsg": "Hello! I am the AirFlow AI Assistant. Would you like me to start generating a script?",
"start": "Start",
"memoryType": {
"message": "Message Memory",
@ -1564,7 +1564,7 @@
"prompt": "prompt word"
},
"hello": {
"welcomeTitle": "Welcome to ToonFlow",
"welcomeTitle": "Welcome to AirFlow",
"welcomeDesc": "AI-driven comic creation workflow platform, let us spend a minute to complete the initial configuration.",
"startConfig": "Start configuration",
"skip": "Skip boot",

View File

@ -43,7 +43,7 @@
}
},
"settings": {
"title": "ToonFlow 設定",
"title": "AirFlow 設定",
"menu": {
"language": "言語設定",
"vendorConfig": "モデルサービス",
@ -180,7 +180,7 @@
"linkAdd": "確認する"
},
"agent": {
"bannerDesc": "Toonflow公式中継サイトを使用すると、設定をワンクリックで入力でき、手動設定なしですぐに使用できます。",
"bannerDesc": "AirFlow公式中継サイトを使用すると、設定をワンクリックで入力でき、手動設定なしですぐに使用できます。",
"visitWebsite": "サイトへ移動",
"fillKey": "KEYを入力",
"oneClickFill": "ワンクリック入力",
@ -190,14 +190,14 @@
"confirm": "確定",
"cancel": "キャンセル",
"selectModel": "モデルを選択",
"fillKeyHeader": "Toonflowプラットフォームの公式KEYを入力",
"fillKeyHeader": "AirFlowプラットフォームの公式KEYを入力",
"keyPlaceholder": "KEYを入力してください",
"save": "保存",
"msg": {
"notAvailable": "この機能は現在準備中です。ご期待ください",
"configSuccess": "設定に成功しました",
"updateConfigFailed": "設定の更新に失敗しました:",
"keyValid": "KEYが有効です。Toonflowプラットフォームに接続しました",
"keyValid": "KEYが有効です。AirFlowプラットフォームに接続しました",
"keyInvalid": "KEYが無効です。確認して再入力してください",
"enterKey": "KEYを入力してください",
"saveFailed": "保存に失敗しました:",
@ -408,9 +408,9 @@
"warning": "以下は開発者ツールです。注意して操作してください。",
"openDevtool": "開ける",
"devtoolsDoc": "書類のアドレス",
"devtoolsDesc": "オンにすると、Toonflow のインストール ディレクトリに .devtools フォルダーが作成されます。 Toonflow に書き込み権限があることを確認してください (管理者として実行)。",
"devtoolsDesc": "オンにすると、AirFlow のインストール ディレクトリに .devtools フォルダーが作成されます。 AirFlow に書き込み権限があることを確認してください (管理者として実行)。",
"devtoolsDesc2": "このディレクトリで npx {'@'}ai-sdk/devtools を実行して、テレメトリのデバッグを有効にします",
"openDevtoolFailed": "開発者ツールを開けませんでした。Toonflow デスクトップがインストールされていることを確認してください",
"openDevtoolFailed": "開発者ツールを開けませんでした。AirFlow デスクトップがインストールされていることを確認してください",
"notInElectron": "WEB環境の場合はブラウザコンソールを手動で開いてください"
}
},
@ -673,7 +673,7 @@
"selectAssets": "アセットを選択",
"noAssets": "関連アセットがありません",
"selectAssetsTitle": "関連アセットの選択",
"welcomeMsg": "こんにちは!Toonflow アシスタントです。シナリオの生成を開始しましょうか?",
"welcomeMsg": "こんにちは!AirFlow アシスタントです。シナリオの生成を開始しましょうか?",
"start": "開始",
"memoryType": {
"message": "メッセージメモリ",

View File

@ -43,7 +43,7 @@
}
},
"settings": {
"title": "Настройки ToonFlow",
"title": "Настройки AirFlow",
"menu": {
"language": "Язык",
"vendorConfig": "Поставщики моделей",
@ -180,7 +180,7 @@
"linkAdd": "подтверждать"
},
"agent": {
"bannerDesc": "Используйте официальный прокси-сервер Toonflow для конфигурации в один клик. Готово к использованию без ручной настройки.",
"bannerDesc": "Используйте официальный прокси-сервер AirFlow для конфигурации в один клик. Готово к использованию без ручной настройки.",
"visitWebsite": "Перейти на сайт",
"fillKey": "Введите KEY",
"oneClickFill": "Вставить в 1 клик",
@ -190,14 +190,14 @@
"confirm": "ОК",
"cancel": "Отмена",
"selectModel": "Выберите модель",
"fillKeyHeader": "Введите официальный KEY платформы Toonflow",
"fillKeyHeader": "Введите официальный KEY платформы AirFlow",
"keyPlaceholder": "Пожалуйста, введите KEY",
"save": "Сохранить",
"msg": {
"notAvailable": "Эта функция пока недоступна. Следите за обновлениями!",
"configSuccess": "Успешно настроено",
"updateConfigFailed": "Ошибка обновления конфигурации: ",
"keyValid": "KEY действителен. Успешное подключение к платформе Toonflow",
"keyValid": "KEY действителен. Успешное подключение к платформе AirFlow",
"keyInvalid": "KEY недействителен. Пожалуйста, проверьте и введите снова: ",
"enterKey": "Пожалуйста, введите KEY",
"saveFailed": "Ошибка сохранения: ",
@ -408,9 +408,9 @@
"warning": "Ниже приведены инструменты разработчика, будьте осторожны!",
"openDevtool": "Открыть",
"devtoolsDoc": "Адрес документа",
"devtoolsDesc": "После включения в каталоге установки Toonflow будет создана папка .devtools. Убедитесь, что у Toonflow есть права на запись (запуск от имени администратора).",
"devtoolsDesc": "После включения в каталоге установки AirFlow будет создана папка .devtools. Убедитесь, что у AirFlow есть права на запись (запуск от имени администратора).",
"devtoolsDesc2": "Запустите npx {'@'}ai-sdk/devtools в этом каталоге, чтобы включить отладку телеметрии.",
"openDevtoolFailed": "Не удалось открыть инструменты разработчика. Убедитесь, что установлен рабочий стол Toonflow.",
"openDevtoolFailed": "Не удалось открыть инструменты разработчика. Убедитесь, что установлен рабочий стол AirFlow.",
"notInElectron": "Для веб-среды откройте консоль браузера вручную."
}
},
@ -673,7 +673,7 @@
"selectAssets": "Выбрать ассеты",
"noAssets": "Нет связанных ассетов",
"selectAssetsTitle": "Выбор связанных ассетов",
"welcomeMsg": "Привет! Я ИИ-ассистент Toonflow. Хотите, чтобы я начал генерировать сценарий?",
"welcomeMsg": "Привет! Я ИИ-ассистент AirFlow. Хотите, чтобы я начал генерировать сценарий?",
"start": "Начать",
"memoryType": {
"message": "Память сообщений",
@ -1424,7 +1424,7 @@
"prompt": "подсказать слово"
},
"hello": {
"welcomeTitle": "Добро пожаловать в ToonFlow",
"welcomeTitle": "Добро пожаловать в AirFlow",
"welcomeDesc": "Платформа рабочего процесса создания комиксов, управляемая искусственным интеллектом, давайте потратим минуту, чтобы завершить первоначальную настройку.",
"startConfig": "Начать настройку",
"skip": "Пропустить загрузку",

View File

@ -43,7 +43,7 @@
}
},
"settings": {
"title": "การตั้งค่า ToonFlow",
"title": "การตั้งค่า AirFlow",
"menu": {
"language": "ตั้งค่าภาษา",
"vendorConfig": "บริการโมเดล",
@ -180,7 +180,7 @@
"linkAdd": "ยืนยัน"
},
"agent": {
"bannerDesc": "ใช้เซิร์ฟเวอร์ตัวกลางอย่างเป็นทางการของ Toonflow รองรับการกรอกการตั้งค่าในคลิกเดียว พร้อมใช้งานทันทีโดยไม่ต้องตั้งค่าด้วยตนเอง",
"bannerDesc": "ใช้เซิร์ฟเวอร์ตัวกลางอย่างเป็นทางการของ AirFlow รองรับการกรอกการตั้งค่าในคลิกเดียว พร้อมใช้งานทันทีโดยไม่ต้องตั้งค่าด้วยตนเอง",
"visitWebsite": "เข้าสู่เว็บไซต์",
"fillKey": "กรอก KEY",
"oneClickFill": "กรอกในคลิกเดียว",
@ -190,19 +190,19 @@
"confirm": "ยืนยัน",
"cancel": "ยกเลิก",
"selectModel": "เลือกโมเดล",
"fillKeyHeader": "กรอก KEY อย่างเป็นทางการจากแพลตฟอร์ม Toonflow",
"fillKeyHeader": "กรอก KEY อย่างเป็นทางการจากแพลตฟอร์ม AirFlow",
"keyPlaceholder": "โปรดกรอก KEY",
"save": "บันทึก",
"msg": {
"notAvailable": "ฟีเจอร์นี้ยังไม่เปิดให้บริการ โปรดติดตามเร็วๆ นี้",
"configSuccess": "ตั้งค่าสำเร็จ",
"updateConfigFailed": "อัปเดตการตั้งค่าล้มเหลว:",
"keyValid": "KEY ถูกต้อง เชื่อมต่อกับแพลตฟอร์ม Toonflow สำเร็จแล้ว",
"keyValid": "KEY ถูกต้อง เชื่อมต่อกับแพลตฟอร์ม AirFlow สำเร็จแล้ว",
"keyInvalid": "KEY ไม่ถูกต้อง โปรดตรวจสอบและกรอกใหม่อีกครั้ง:",
"enterKey": "โปรดกรอก KEY",
"saveFailed": "บันทึกล้มเหลว:",
"getAgentListFailed": "ดึงรายการการตั้งค่า Agent ล้มเหลว:",
"toonflowNotFound": "ไม่มีสถานีรับส่งอย่างเป็นทางการของ Toonflow"
"toonflowNotFound": "ไม่มีสถานีรับส่งอย่างเป็นทางการของ AirFlow"
},
"temperature": "อุณหภูมิ"
},
@ -409,9 +409,9 @@
"warning": "ต่อไปนี้เป็นเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ โปรดดำเนินการด้วยความระมัดระวัง!",
"openDevtool": "เปิด",
"devtoolsDoc": "ที่อยู่เอกสาร",
"devtoolsDesc": "หลังจากเปิดใช้งานแล้ว โฟลเดอร์ .devtools จะถูกสร้างขึ้นในไดเร็กทอรีการติดตั้ง Toonflow โปรดตรวจสอบให้แน่ใจว่า Toonflow มีสิทธิ์ในการเขียน (ทำงานในฐานะผู้ดูแลระบบ)",
"devtoolsDesc": "หลังจากเปิดใช้งานแล้ว โฟลเดอร์ .devtools จะถูกสร้างขึ้นในไดเร็กทอรีการติดตั้ง AirFlow โปรดตรวจสอบให้แน่ใจว่า AirFlow มีสิทธิ์ในการเขียน (ทำงานในฐานะผู้ดูแลระบบ)",
"devtoolsDesc2": "เรียกใช้ npx {'@'}ai-sdk/devtools ในไดเรกทอรีนี้เพื่อเปิดใช้งานการแก้ไขจุดบกพร่องการวัดและส่งข้อมูลทางไกล",
"openDevtoolFailed": "ไม่สามารถเปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ได้ โปรดตรวจสอบให้แน่ใจว่าได้ติดตั้ง Toonflow desktop แล้ว",
"openDevtoolFailed": "ไม่สามารถเปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ได้ โปรดตรวจสอบให้แน่ใจว่าได้ติดตั้ง AirFlow desktop แล้ว",
"notInElectron": "สำหรับสภาพแวดล้อมแบบเว็บ โปรดเปิดคอนโซลเบราว์เซอร์ด้วยตนเอง"
}
},
@ -674,7 +674,7 @@
"selectAssets": "เลือกสินทรัพย์",
"noAssets": "ยังไม่ได้เชื่อมโยงสินทรัพย์",
"selectAssetsTitle": "เลือกสินทรัพย์ที่เกี่ยวข้อง",
"welcomeMsg": "สวัสดี! ฉันคือผู้ช่วยอัจฉริยะ Toonflow ต้องการให้ฉันเริ่มสร้างบทภาพยนตร์ให้คุณเลยไหม?",
"welcomeMsg": "สวัสดี! ฉันคือผู้ช่วยอัจฉริยะ AirFlow ต้องการให้ฉันเริ่มสร้างบทภาพยนตร์ให้คุณเลยไหม?",
"start": "เริ่มต้น",
"memoryType": {
"message": "หน่วยความจำข้อความ",
@ -1412,7 +1412,7 @@
"prompt": "คำพูดที่รวดเร็ว"
},
"hello": {
"welcomeTitle": "ยินดีต้อนรับสู่ ToonFlow",
"welcomeTitle": "ยินดีต้อนรับสู่ AirFlow",
"welcomeDesc": "แพลตฟอร์มเวิร์กโฟลว์การสร้างการ์ตูนที่ขับเคลื่อนด้วย AI ให้เราใช้เวลาสักครู่เพื่อกำหนดค่าเริ่มต้นให้เสร็จสิ้น",
"startConfig": "เริ่มการกำหนดค่า",
"skip": "ข้ามการบูต",

View File

@ -42,7 +42,7 @@
}
},
"settings": {
"title": "Cài đặt ToonFlow",
"title": "Cài đặt AirFlow",
"menu": {
"language": "Cài đặt ngôn ngữ",
"vendorConfig": "Dịch vụ mô hình",
@ -179,7 +179,7 @@
"linkAdd": "xác nhận"
},
"agent": {
"bannerDesc": "Sử dụng máy chủ trung gian chính thức của Toonflow, hỗ trợ điền cấu hình bằng 1 cú nhấp chuột, sẵn sàng sử dụng ngay mà không cần thiết lập thủ công.",
"bannerDesc": "Sử dụng máy chủ trung gian chính thức của AirFlow, hỗ trợ điền cấu hình bằng 1 cú nhấp chuột, sẵn sàng sử dụng ngay mà không cần thiết lập thủ công.",
"visitWebsite": "Truy cập trang web",
"fillKey": "Điền KEY",
"oneClickFill": "Điền bằng 1 cú nhấp chuột",
@ -189,19 +189,19 @@
"confirm": "Xác nhận",
"cancel": "Hủy",
"selectModel": "Chọn mô hình",
"fillKeyHeader": "Điền KEY chính thức của nền tảng Toonflow",
"fillKeyHeader": "Điền KEY chính thức của nền tảng AirFlow",
"keyPlaceholder": "Vui lòng nhập KEY",
"save": "Lưu",
"msg": {
"notAvailable": "Tính năng này hiện chưa khả dụng, vui lòng chờ",
"configSuccess": "Cấu hình thành công",
"updateConfigFailed": "Cập nhật cấu hình thất bại:",
"keyValid": "KEY hợp lệ, kết nối với nền tảng Toonflow thành công",
"keyValid": "KEY hợp lệ, kết nối với nền tảng AirFlow thành công",
"keyInvalid": "KEY không hợp lệ, vui lòng kiểm tra và nhập lại:",
"enterKey": "Vui lòng nhập KEY",
"saveFailed": "Lưu thất bại:",
"getAgentListFailed": "Lấy danh sách cấu hình Agent thất bại:",
"toonflowNotFound": "Trạm trung chuyển chính thức của Toonflow không tồn tại"
"toonflowNotFound": "Trạm trung chuyển chính thức của AirFlow không tồn tại"
},
"temperature": "nhiệt độ"
},
@ -399,9 +399,9 @@
"warning": "Sau đây là các công cụ dành cho nhà phát triển, vui lòng sử dụng thận trọng!",
"openDevtool": "Mở",
"devtoolsDoc": "Địa chỉ tài liệu",
"devtoolsDesc": "Sau khi bật lên sẽ tạo một thư mục .devtools trong thư mục cài đặt Toonflow. Hãy đảm bảo rằng Toonflow có quyền ghi (chạy với tư cách quản trị viên).",
"devtoolsDesc": "Sau khi bật lên sẽ tạo một thư mục .devtools trong thư mục cài đặt AirFlow. Hãy đảm bảo rằng AirFlow có quyền ghi (chạy với tư cách quản trị viên).",
"devtoolsDesc2": "Chạy npx {'@'}ai-sdk/devtools trong thư mục này để bật gỡ lỗi đo từ xa",
"openDevtoolFailed": "Không mở được công cụ dành cho nhà phát triển, vui lòng đảm bảo đã cài đặt Toonflow desktop",
"openDevtoolFailed": "Không mở được công cụ dành cho nhà phát triển, vui lòng đảm bảo đã cài đặt AirFlow desktop",
"notInElectron": "Đối với môi trường WEB, vui lòng mở bảng điều khiển trình duyệt theo cách thủ công"
}
},
@ -664,7 +664,7 @@
"selectAssets": "Chọn tài nguyên",
"noAssets": "Chưa liên kết tài nguyên",
"selectAssetsTitle": "Chọn tài nguyên liên kết",
"welcomeMsg": "Xin chào! Tôi là trợ lý thông minh Toonflow, bạn có muốn tôi bắt đầu tạo kịch bản cho bạn không?",
"welcomeMsg": "Xin chào! Tôi là trợ lý thông minh AirFlow, bạn có muốn tôi bắt đầu tạo kịch bản cho bạn không?",
"start": "Bắt đầu",
"memoryType": {
"message": "Bộ nhớ tin nhắn",
@ -1416,7 +1416,7 @@
"prompt": "lời nhắc"
},
"hello": {
"welcomeTitle": "Chào mừng đến với ToonFlow",
"welcomeTitle": "Chào mừng đến với AirFlow",
"welcomeDesc": "Nền tảng quy trình tạo truyện tranh do AI điều khiển, chúng ta hãy dành một phút để hoàn thành cấu hình ban đầu.",
"startConfig": "Bắt đầu cấu hình",
"skip": "Bỏ qua khởi động",

View File

@ -53,7 +53,7 @@
}
},
"settings": {
"title": "ToonFlow设置",
"title": "AirFlow设置",
"modelMap": {
"imageModel": "图像模型",
"videoModel": "视频模型",
@ -262,7 +262,7 @@
"linkAdd": "确认"
},
"agent": {
"bannerDesc": "使用 Toonflow 官方中转站点,支持一键填入配置,开箱即用,无需手动配置。",
"bannerDesc": "使用 AirFlow 官方中转站点,支持一键填入配置,开箱即用,无需手动配置。",
"visitWebsite": "进入网站",
"fillKey": "填入KEY",
"oneClickFill": "一键填入",
@ -272,19 +272,19 @@
"confirm": "确认",
"cancel": "取消",
"selectModel": "选择模型",
"fillKeyHeader": "填入Toonflow平台的官方KEY",
"fillKeyHeader": "填入AirFlow平台的官方KEY",
"keyPlaceholder": "请输入 KEY",
"save": "保存",
"msg": {
"notAvailable": "该功能暂未开放,敬请期待",
"configSuccess": "配置成功",
"updateConfigFailed": "更新配置失败:",
"keyValid": "KEY有效已成功连接Toonflow平台",
"keyValid": "KEY有效已成功连接AirFlow平台",
"keyInvalid": "KEY无效请检查后重新输入",
"enterKey": "请输入 KEY",
"saveFailed": "保存失败:",
"getAgentListFailed": "获取Agent配置列表失败",
"toonflowNotFound": "Toonflow官方中转站不存在"
"toonflowNotFound": "AirFlow官方中转站不存在"
},
"temperature": "温度"
},
@ -410,7 +410,7 @@
"skill": {
"scanSkills": "扫描Skills",
"addSkill": "新增 Skill",
"importFromHub": "Toonflow-Hub 导入",
"importFromHub": "AirFlow-Hub 导入",
"filterType": "类型",
"filterAttribution": "归属",
"searchPlaceholder": "按名称搜索 skill",
@ -430,7 +430,7 @@
"embedding": "向量化",
"edit": "编辑",
"delete": "删除",
"importFromHubDialog": "从 Toonflow-Hub 导入",
"importFromHubDialog": "从 AirFlow-Hub 导入",
"shareLink": "分享链接",
"editSkillTitle": "编辑 Skill-",
"addSkillTitle": "新增 Skill",
@ -604,9 +604,9 @@
"warning": "以下为开发者工具,谨慎操作!",
"openDevtool": "打开",
"devtoolsDoc": "文档地址",
"devtoolsDesc": "开启后会在Toonflow安装目录创建.devtools文件夹请确保Toonflow有写入权限管理员身份运行。",
"devtoolsDesc": "开启后会在AirFlow安装目录创建.devtools文件夹请确保AirFlow有写入权限管理员身份运行。",
"devtoolsDesc2": "在该目录运行 npx {'@'}ai-sdk/devtools 开启遥测调试",
"openDevtoolFailed": "打开开发者工具失败,请确保已安装Toonflow桌面端",
"openDevtoolFailed": "打开开发者工具失败,请确保已安装AirFlow桌面端",
"notInElectron": "WEB环境请手动打开浏览器控制台",
"msg": {
"localStorageKeyRequired": "请输入 localStorage 的 key",
@ -893,7 +893,7 @@
"selectAssets": "选择资产",
"noAssets": "暂未关联资产",
"selectAssetsTitle": "选择关联资产",
"welcomeMsg": "你好!我是 Toonflow 智能助手,需要我开始为您生成剧本吗?",
"welcomeMsg": "你好!我是 AirFlow 智能助手,需要我开始为您生成剧本吗?",
"start": "开始",
"memoryType": {
"message": "消息记忆",
@ -1681,7 +1681,7 @@
"workbench.production.node.storyboard.deleteNode": "删除",
"workbench.production.node.storyboard.confirmDeleteBody": "确认是否删除该分镜",
"hello": {
"welcomeTitle": "欢迎使用 ToonFlow",
"welcomeTitle": "欢迎使用 AirFlow",
"welcomeDesc": "AI 驱动的漫画创作工作流平台,让我们花一分钟完成初始配置。",
"startConfig": "开始配置",
"skip": "跳过引导",

View File

@ -51,7 +51,7 @@
}
},
"settings": {
"title": "ToonFlow 設定",
"title": "AirFlow 設定",
"menu": {
"language": "語言設定",
"vendorConfig": "模型服務",
@ -188,7 +188,7 @@
"linkAdd": "確認"
},
"agent": {
"bannerDesc": "使用 Toonflow 官方中繼網站,支援一鍵帶入設定,開箱即用,無需手動設定。",
"bannerDesc": "使用 AirFlow 官方中繼網站,支援一鍵帶入設定,開箱即用,無需手動設定。",
"visitWebsite": "進入網站",
"fillKey": "填入 KEY",
"oneClickFill": "一鍵帶入",
@ -198,14 +198,14 @@
"confirm": "確認",
"cancel": "取消",
"selectModel": "選擇模型",
"fillKeyHeader": "填入 Toonflow 平台的官方 KEY",
"fillKeyHeader": "填入 AirFlow 平台的官方 KEY",
"keyPlaceholder": "請輸入 KEY",
"save": "儲存",
"msg": {
"notAvailable": "該功能暫未開放,敬請期待",
"configSuccess": "設定成功",
"updateConfigFailed": "更新設定失敗:",
"keyValid": "KEY 有效,已成功連接 Toonflow 平台",
"keyValid": "KEY 有效,已成功連接 AirFlow 平台",
"keyInvalid": "KEY 無效,請檢查後重新輸入:",
"enterKey": "請輸入 KEY",
"saveFailed": "儲存失敗:",
@ -413,8 +413,8 @@
"warning": "以下為開發者工具,謹慎操作!",
"openDevtool": "打開",
"devtoolsDoc": "文件地址",
"devtoolsDesc": "開啟後會在Toonflow安裝目錄建立.devtools資料夾請確保Toonflow有寫入權限管理員身分執行。",
"openDevtoolFailed": "開啟開發者工具失敗,請確保已安裝Toonflow桌面端",
"devtoolsDesc": "開啟後會在AirFlow安裝目錄建立.devtools資料夾請確保AirFlow有寫入權限管理員身分執行。",
"openDevtoolFailed": "開啟開發者工具失敗,請確保已安裝AirFlow桌面端",
"notInElectron": "WEB環境請手動開啟瀏覽器控制台"
}
},
@ -677,7 +677,7 @@
"selectAssets": "選擇資產",
"noAssets": "暫未關聯資產",
"selectAssetsTitle": "選擇關聯資產",
"welcomeMsg": "你好!我是 Toonflow 智慧助手,需要我開始為您生成劇本嗎?",
"welcomeMsg": "你好!我是 AirFlow 智慧助手,需要我開始為您生成劇本嗎?",
"start": "開始",
"memoryType": {
"message": "訊息記憶",
@ -1407,7 +1407,7 @@
"prompt": "提示詞"
},
"hello": {
"welcomeTitle": "歡迎使用 ToonFlow",
"welcomeTitle": "歡迎使用 AirFlow",
"welcomeDesc": "AI 驅動的漫畫創作工作流程平台,讓我們花一分鐘完成初始設定。",
"startConfig": "開始配置",
"skip": "跳過引導",

View File

@ -9,11 +9,11 @@
</t-dialog>
<main class="loginStage">
<section class="brandPane" aria-label="ToonFlow Studio">
<section class="brandPane" aria-label="AirFlow Studio">
<header class="brandHeader">
<img src="@/assets/logo.svg" alt="ToonFlow Logo" class="brandLogo" />
<img src="@/assets/logo.svg" alt="AirFlow Logo" class="brandLogo" />
<div>
<h1>ToonFlow Studio</h1>
<h1>AirFlow Studio</h1>
<p>智能短剧创作平台</p>
</div>
</header>

View File

@ -21,9 +21,7 @@
<div class="footItem fc ac">
<t-tooltip :content="$t('workbench.menu.settings')" placement="right" destroyOnClose :showArrow="false">
<div class="item c" @click="showSetting = true">
<t-badge :count="needUpdate ? 1 : 0" dot>
<i-setting-one class="icon" />
</t-badge>
</div>
</t-tooltip>
</div>
@ -111,26 +109,8 @@ async function checkVersion() {
});
if (data.needUpdate) {
needUpdate.value = true;
const { activeMenu: settingActiveMenu } = storeToRefs(settingStore());
const notifyInstance = NotifyPlugin.success({
NotifyPlugin.success({
title: $t("version.newVersion") as string,
content: () =>
h(
"div",
{ style: "text-align: right; padding-top: 4px;" },
h(
"span",
{
style: "color: #ed7b2f; font-size: 12px; cursor: pointer;",
onClick: () => {
settingActiveMenu.value = "about";
showSetting.value = true;
NotifyPlugin.close(notifyInstance);
},
},
$t("skillScan.openSettings"),
),
),
closeBtn: true,
placement: "bottom-right",
});