diff --git a/infiplot-app b/infiplot-app index ed03716..c00a8c6 160000 --- a/infiplot-app +++ b/infiplot-app @@ -1 +1 @@ -Subproject commit ed037160b04dba976b7980e65522390ee616714e +Subproject commit c00a8c6ff6461d9f786c18704cf42edcf2973173 diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index fc339f8..332f01e 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,4 +1,11 @@ -import type { Locale } from "@infiplot/types"; +import type { + CreationOptions, + CustomStoryDraft, + Locale, + MobileDrama, + ModelConfigMap, + ModelRole, +} from "@infiplot/types"; const DEFAULT_LOCALE: Locale = "zh-CN"; const SUPPORTED_LOCALES = new Set(["en", "ja", "zh-CN"]); @@ -10,3 +17,112 @@ export function normalizeLocale(locale: string | undefined): Locale { return DEFAULT_LOCALE; } + +export const mobileDramaFeed: readonly MobileDrama[] = [ + { + id: "midnight-library", + creator: "阿眠", + title: "午夜图书馆", + hook: "她每翻开一本借阅过期的书,都会听见另一个自己留下的求救声。", + episode: "第 07 集 · 门后的雨", + tags: ["悬疑", "都市奇谈", "强反转"], + palette: ["#1d1028", "#6f42c1", "#f3d77b"], + likes: "23.8w", + comments: "1.2w", + }, + { + id: "orbit-summer", + creator: "Nora", + title: "环形夏天", + hook: "坠落的卫星停在海边旧球场上,十七岁的告白因此被循环了 99 次。", + episode: "第 03 集 · 球场上空", + tags: ["青春", "科幻恋爱", "高甜"], + palette: ["#092635", "#1b9aaa", "#ffcf70"], + likes: "15.6w", + comments: "8420", + }, + { + id: "jade-office", + creator: "南风剧场", + title: "玉京事务所", + hook: "新人社畜入职第一天,发现老板的客户全是从古画里走出来的人。", + episode: "第 11 集 · 画中债", + tags: ["国风", "职场爽剧", "单元案"], + palette: ["#10231d", "#39a875", "#f4eee0"], + likes: "31.4w", + comments: "2.7w", + }, +]; + +export const creationOptions: CreationOptions = { + templates: ["甜宠校园", "悬疑反转", "国风奇谈", "末日群像"], + ratios: ["9:16", "3:4", "1:1"], + rhythms: ["快节奏", "电影感", "日常流"], +}; + +export const defaultStoryDraft: CustomStoryDraft = { + worldSetting: "旧城区的地下影院每晚零点自动放映,还没拍出来的明天。", + styleGuide: "霓虹雨夜、颗粒胶片、人物近景强情绪、冷暖撞色。", +}; + +export const defaultModelConfig: ModelConfigMap = { + text: { + provider: "openai", + baseUrl: "https://api.openai.com/v1", + apiKey: "", + model: "gpt-4.1", + }, + image: { + provider: "openai-compatible", + baseUrl: "https://api.example.com/v1", + apiKey: "", + model: "flux-kontext", + }, + vision: { + provider: "openai", + baseUrl: "https://api.openai.com/v1", + apiKey: "", + model: "gpt-4.1-mini", + }, + tts: { + provider: "stepfun", + baseUrl: "https://api.stepfun.com/v1", + apiKey: "", + model: "step-tts-mini", + }, +}; + +export function normalizeModelConfig(value: unknown): ModelConfigMap { + const source = value && typeof value === "object" ? (value as Partial) : {}; + const result = cloneModelConfig(defaultModelConfig); + + for (const role of Object.keys(defaultModelConfig) as ModelRole[]) { + const candidate = source[role]; + if (!candidate || typeof candidate !== "object") continue; + + result[role] = { + provider: + typeof candidate.provider === "string" + ? candidate.provider.trim() + : defaultModelConfig[role].provider, + baseUrl: + typeof candidate.baseUrl === "string" + ? candidate.baseUrl.trim() + : defaultModelConfig[role].baseUrl, + apiKey: typeof candidate.apiKey === "string" ? candidate.apiKey.trim() : "", + model: + typeof candidate.model === "string" ? candidate.model.trim() : defaultModelConfig[role].model, + }; + } + + return result; +} + +export function cloneModelConfig(config: ModelConfigMap): ModelConfigMap { + return { + text: { ...config.text }, + image: { ...config.image }, + vision: { ...config.vision }, + tts: { ...config.tts }, + }; +} diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 5d54b28..0c1be14 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -31,3 +31,37 @@ export interface SceneResponse { imageUrl?: string; audioUrl?: string; } + +export interface MobileDrama { + id: string; + creator: string; + title: string; + hook: string; + episode: string; + tags: string[]; + palette: readonly [string, string, string]; + likes: string; + comments: string; +} + +export interface CreationOptions { + templates: readonly string[]; + ratios: readonly string[]; + rhythms: readonly string[]; +} + +export interface CustomStoryDraft { + worldSetting: string; + styleGuide: string; +} + +export type ModelRole = "text" | "image" | "vision" | "tts"; + +export interface ModelConfig { + provider: string; + baseUrl: string; + apiKey: string; + model: string; +} + +export type ModelConfigMap = Record; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7fcaabf..f47586e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,12 @@ importers: '@expo/ui': specifier: ~56.0.18 version: 56.0.18(@babel/core@7.29.7)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(expo@56.0.12)(react-dom@19.2.3(react@19.2.3))(react-native-reanimated@4.3.1(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3) + '@infiplot/core': + specifier: workspace:* + version: link:../packages/core + '@infiplot/types': + specifier: workspace:* + version: link:../packages/types expo: specifier: ~56.0.12 version: 56.0.12(@babel/core@7.29.7)(@expo/dom-webview@56.0.5)(@expo/metro-runtime@56.0.15)(expo-router@56.2.11)(react-dom@19.2.3(react@19.2.3))(react-native-web@0.21.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-native-worklets@0.8.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3)(typescript@6.0.3)