refactor: Context 与 Provider 合并 — 消除 contexts/ 目录,一文件一状态单元

- ThemeContext + useTheme → ThemeProvider.tsx(原 hooks/use-theme.ts 删除)
- AppContext + useAppContext → AppProvider.tsx(原 contexts/app-context.ts 删除)
- SettingsContext + useSettings → SettingsProvider.tsx(原 contexts/settings-context.ts 删除)
- HomeContext + useHomeContext → HomeContent.tsx(原 contexts/home-context.ts 删除)
- 删除空的 contexts/ 目录,20+ 导入路径同步更新
- TypeScript 编译通过(npx tsc --noEmit 零错误)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-09 14:02:48 +08:00
parent eb12248a62
commit 53df926973
25 changed files with 248 additions and 291 deletions

View File

@@ -1,6 +1,6 @@
import { useState, useEffect, useCallback } from 'react'; import { useState, useEffect, useCallback } from 'react';
import { useAppContext } from './contexts/app-context'; import { useAppContext } from '@/components/AppProvider';
import { LoginPage } from './pages/login'; import { LoginPage } from './pages/login';
import { SettingsPage } from './pages/settings'; import { SettingsPage } from './pages/settings';
import { on, off, EVENTS } from './utils/event-bus'; import { on, off, EVENTS } from './utils/event-bus';

View File

@@ -1,14 +1,17 @@
// ============================================================ // ============================================================
// AppProvider — 应用状态 Provider 组件 // AppProvider — 全局应用状态 Context + Provider + Hook
//
// 导出:
// AppContext, useAppContext() — Context + Consumer Hook
// AppContextValue — 类型
// AppProvider — Provider 组件
// ============================================================ // ============================================================
import { useState, useMemo, useCallback, useEffect, type ReactNode } from 'react'; import { createContext, useContext, useState, useMemo, useCallback, useEffect, type ReactNode } from 'react';
import type { Platform, Edition } from '@shared/types'; import type { Platform, Edition } from '@shared/types';
import { getPlatform, isDev } from '@/utils/platform'; import { getPlatform, isDev } from '@/utils/platform';
import { safeIpcOn, safeIpcOff } from '@/utils/ipc'; import { safeIpcOn, safeIpcOff } from '@/utils/ipc';
import { AppContext } from '@/contexts/app-context';
import type { AppContextValue } from '@/contexts/app-context';
import type { LoginResponseBody } from '@/services/modules'; import type { LoginResponseBody } from '@/services/modules';
import { setToken, clearToken, initTokenStore } from '@/services/request'; import { setToken, clearToken, initTokenStore } from '@/services/request';
import { emit, EVENTS } from '@/utils/event-bus'; import { emit, EVENTS } from '@/utils/event-bus';
@@ -23,6 +26,39 @@ import {
initRefreshTokenStore, initRefreshTokenStore,
} from '@/services/auth-token'; } from '@/services/auth-token';
// ---------- Context 类型 ----------
export interface AppContextValue {
/** 当前操作系统平台 */
platform: Platform;
/** 产品版本(个人版 / 企业版) */
edition: Edition;
/** 用户是否已登录 */
isLoggedIn: boolean;
/** 当前登录用户信息(未登录时为 null结构与 LoginResponseBody 一致) */
user: LoginResponseBody | null;
/** 登录:保存 Token 并更新登录态auth 为登录接口返回值,异步加密存储) */
login: (auth: LoginResponseBody) => Promise<void>;
/** 退出登录:清除 Token 和用户状态 */
logout: () => void;
/** 是否为开发环境 */
isDevMode: boolean;
}
export const AppContext = createContext<AppContextValue | null>(null);
// ---------- Consumer Hook ----------
export function useAppContext(): AppContextValue {
const ctx = useContext(AppContext);
if (!ctx) {
throw new Error('useAppContext() 必须在 <AppProvider> 内部调用');
}
return ctx;
}
// ---------- Provider 组件 ----------
interface AppProviderProps { interface AppProviderProps {
children: ReactNode; children: ReactNode;
} }

View File

@@ -1,23 +1,99 @@
// ============================================================ // ============================================================
// SettingsProvider — 设置状态 Provider 组件 // SettingsProvider — 设置项集中状态管理 Context + Provider + Hook
// //
// 职责: // 职责:
// - 初始化时从 localStorage 读取已存储的设置项 // - 存储路径的集中管理read/write/clear
// - 提供 SettingsContext 给所有子组件 // - 持久化到 localStorage遵循 ele-heixiu-* 键名规范
// - 写操作同步更新 state + localStorage // - 全局组件通过 useSettings() 消费
// ============================================================ // ============================================================
import { useState, useCallback, type ReactNode } from 'react'; import { createContext, useContext, useState, useCallback, type ReactNode } from 'react';
import {
SettingsContext, // ---------- localStorage 键 ----------
readStoredOutputPath,
writeStoredOutputPath, const OUTPUT_PATH_KEY = 'ele-heixiu-output-path';
clearStoredOutputPath, const TEAM_REPO_PATH_KEY = 'ele-heixiu-team-repo-path';
readStoredTeamRepoPath,
writeStoredTeamRepoPath, // ---------- Context 类型 ----------
clearStoredTeamRepoPath,
} from '@/contexts/settings-context'; export interface SettingsContextValue {
import type { SettingsContextValue } from '@/contexts/settings-context'; /** 大模型产物存储仓库路径 */
outputPath: string;
/** 团队创作存储仓库路径(企业版) */
teamRepoPath: string;
/** 设置产物输出路径 */
setOutputPath: (path: string) => void;
/** 设置团队创作仓库路径 */
setTeamRepoPath: (path: string) => void;
/** 清除产物输出路径 */
clearOutputPath: () => void;
/** 清除团队创作仓库路径 */
clearTeamRepoPath: () => void;
}
export const SettingsContext = createContext<SettingsContextValue | null>(null);
// ---------- 工具函数localStorage 读写)----------
export function readStoredOutputPath(): string {
try {
return localStorage.getItem(OUTPUT_PATH_KEY) || '';
} catch {
return '';
}
}
export function writeStoredOutputPath(path: string): void {
try {
localStorage.setItem(OUTPUT_PATH_KEY, path);
} catch {
/* 静默忽略 */
}
}
export function clearStoredOutputPath(): void {
try {
localStorage.removeItem(OUTPUT_PATH_KEY);
} catch {
/* 静默忽略 */
}
}
export function readStoredTeamRepoPath(): string {
try {
return localStorage.getItem(TEAM_REPO_PATH_KEY) || '';
} catch {
return '';
}
}
export function writeStoredTeamRepoPath(path: string): void {
try {
localStorage.setItem(TEAM_REPO_PATH_KEY, path);
} catch {
/* 静默忽略 */
}
}
export function clearStoredTeamRepoPath(): void {
try {
localStorage.removeItem(TEAM_REPO_PATH_KEY);
} catch {
/* 静默忽略 */
}
}
// ---------- Consumer Hook ----------
export function useSettings(): SettingsContextValue {
const ctx = useContext(SettingsContext);
if (!ctx) {
throw new Error('useSettings() 必须在 <SettingsProvider> 内部调用');
}
return ctx;
}
// ---------- Provider 组件 ----------
interface SettingsProviderProps { interface SettingsProviderProps {
children: ReactNode; children: ReactNode;

View File

@@ -1,5 +1,5 @@
// ============================================================ // ============================================================
// ThemeProvider — 主题 Provider 组件 // ThemeProvider — 主题 Context + Provider + Hook + 工具函数
// //
// 桌面端Electron使用 View Transitions API 驱动主题切换: // 桌面端Electron使用 View Transitions API 驱动主题切换:
// GPU 合成器截取旧/新两帧做一次 cross-fade替代 80+ 个 // GPU 合成器截取旧/新两帧做一次 cross-fade替代 80+ 个
@@ -7,20 +7,70 @@
// 浏览器不支持时回退到 CSS transition 方案。 // 浏览器不支持时回退到 CSS transition 方案。
// ============================================================ // ============================================================
import { useState, useEffect, useLayoutEffect, useCallback, type ReactNode } from 'react'; import { createContext, useContext, useState, useEffect, useLayoutEffect, useCallback, type ReactNode } from 'react';
import { flushSync } from 'react-dom'; import { flushSync } from 'react-dom';
import { ConfigProvider } from 'antd'; import { ConfigProvider } from 'antd';
import zhCN from 'antd/locale/zh_CN'; import zhCN from 'antd/locale/zh_CN';
import { getThemeConfig } from '../theme/antd-theme'; import { getThemeConfig } from '../theme/antd-theme';
import {
ThemeContext, // ---------- Context 类型 ----------
readStoredTheme,
writeStoredTheme, export interface ThemeContextValue {
applyHtmlTheme, isDark: boolean;
STORAGE_KEY, toggleTheme: () => void;
} from '../hooks/use-theme'; setLight: () => void;
import type { ThemeContextValue } from '../hooks/use-theme'; setDark: () => void;
}
export const ThemeContext = createContext<ThemeContextValue | null>(null);
// ---------- localStorage 工具函数 ----------
export const STORAGE_KEY = 'ele-heixiu-theme';
export function readStoredTheme(): boolean {
try {
const stored = localStorage.getItem(STORAGE_KEY);
if (stored === 'dark') return true;
if (stored === 'light') return false;
} catch {
/* 静默忽略 */
}
if (typeof window !== 'undefined' && window.matchMedia) {
return window.matchMedia('(prefers-color-scheme: dark)').matches;
}
return false;
}
export function writeStoredTheme(isDark: boolean): void {
try {
localStorage.setItem(STORAGE_KEY, isDark ? 'dark' : 'light');
} catch {
/* 静默忽略 */
}
}
export function applyHtmlTheme(isDark: boolean): void {
document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');
if (isDark) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
}
// ---------- Consumer Hook ----------
export function useTheme(): ThemeContextValue {
const ctx = useContext(ThemeContext);
if (!ctx) {
throw new Error('useTheme() 必须在 <ThemeProvider> 内部调用');
}
return ctx;
}
// ---------- Provider 组件 ----------
interface ThemeProviderProps { interface ThemeProviderProps {
children: ReactNode; children: ReactNode;

View File

@@ -12,7 +12,7 @@
// ============================================================ // ============================================================
import { useState, useRef, useCallback, useEffect, type ReactNode } from 'react'; import { useState, useRef, useCallback, useEffect, type ReactNode } from 'react';
import { useTheme } from '@/hooks/use-theme'; import { useTheme } from '@/components/ThemeProvider';
// ---------- 类型 ---------- // ---------- 类型 ----------

View File

@@ -6,7 +6,7 @@
import { Modal, Typography } from 'antd'; import { Modal, Typography } from 'antd';
import { FileTextOutlined } from '@ant-design/icons'; import { FileTextOutlined } from '@ant-design/icons';
import { useTheme } from '@/hooks/use-theme'; import { useTheme } from '@/components/ThemeProvider';
// Vite ?raw 导入:将 .txt 内容作为字符串直接内联 // Vite ?raw 导入:将 .txt 内容作为字符串直接内联
import serviceAgreement from '@/assets/legal/用户服务协议.txt?raw'; import serviceAgreement from '@/assets/legal/用户服务协议.txt?raw';

View File

@@ -10,8 +10,8 @@
import {useState, useCallback, useMemo} from 'react'; import {useState, useCallback, useMemo} from 'react';
import {App} from 'antd'; import {App} from 'antd';
import {useAppContext} from '@/contexts/app-context'; import {useAppContext} from '@/components/AppProvider';
import {useTheme} from '@/hooks/use-theme'; import {useTheme} from '@/components/ThemeProvider';
import {emit, EVENTS} from '@/utils/event-bus.ts'; import {emit, EVENTS} from '@/utils/event-bus.ts';
import {NavItem} from './NavItem'; import {NavItem} from './NavItem';
import {AnnouncementDrawer} from './AnnouncementDrawer'; import {AnnouncementDrawer} from './AnnouncementDrawer';

View File

@@ -3,7 +3,7 @@
// 布局图标SVG在上文字在下 // 布局图标SVG在上文字在下
// ============================================================ // ============================================================
import { useTheme } from '@/hooks/use-theme.ts'; import { useTheme } from '@/components/ThemeProvider';
import type { NavItemConfig } from './types'; import type { NavItemConfig } from './types';
interface NavItemProps { interface NavItemProps {

View File

@@ -1,38 +0,0 @@
// ============================================================
// AppContext — 全局应用状态
// ============================================================
import { createContext, useContext } from 'react';
import type { Platform, Edition } from '@shared/types';
import type { LoginResponseBody } from '@/services/modules';
// ---------- Context 类型 ----------
export interface AppContextValue {
/** 当前操作系统平台 */
platform: Platform;
/** 产品版本(个人版 / 企业版) */
edition: Edition;
/** 用户是否已登录 */
isLoggedIn: boolean;
/** 当前登录用户信息(未登录时为 null结构与 LoginResponseBody 一致) */
user: LoginResponseBody | null;
/** 登录:保存 Token 并更新登录态auth 为登录接口返回值,异步加密存储) */
login: (auth: LoginResponseBody) => Promise<void>;
/** 退出登录:清除 Token 和用户状态 */
logout: () => void;
/** 是否为开发环境 */
isDevMode: boolean;
}
export const AppContext = createContext<AppContextValue | null>(null);
// ---------- Consumer Hook ----------
export function useAppContext(): AppContextValue {
const ctx = useContext(AppContext);
if (!ctx) {
throw new Error('useAppContext() 必须在 <AppProvider> 内部调用');
}
return ctx;
}

View File

@@ -1,43 +0,0 @@
// ============================================================
// HomeContext — 首页状态管理
// 管理:选中模型、任务分页、选中任务记录、刷新信号
// ============================================================
import { createContext, useContext } from 'react';
import type { ModelsListResponseBody } from '@/services/modules/models';
import type { TaskInfoItemResponseBody } from '@/services/modules/task';
// ---------- Context 类型 ----------
export interface HomeContextValue {
/** 当前选中的模型 */
selectedModel: ModelsListResponseBody | null;
setSelectedModel: (model: ModelsListResponseBody | null) => void;
/** 任务记录分页 — 当前页码 */
taskPage: number;
/** 任务记录分页 — 每页条数 */
taskPageSize: number;
setTaskPage: (page: number) => void;
setTaskPageSize: (size: number) => void;
/** 当前选中的任务记录(用于右侧预览) */
selectedTask: TaskInfoItemResponseBody | null;
setSelectedTask: (task: TaskInfoItemResponseBody | null) => void;
/** 侧边栏折叠状态 */
isLeftCollapsed: boolean;
toggleLeftCollapsed: () => void;
}
export const HomeContext = createContext<HomeContextValue | null>(null);
// ---------- Consumer Hook ----------
export function useHomeContext(): HomeContextValue {
const ctx = useContext(HomeContext);
if (!ctx) {
throw new Error('useHomeContext() 必须在 <HomeProvider> 内部调用');
}
return ctx;
}

View File

@@ -1,94 +0,0 @@
// ============================================================
// SettingsContext — 设置项集中状态管理(类似 Vue Pinia store
//
// 职责:
// - 存储路径的集中管理read/write/clear
// - 持久化到 localStorage遵循 ele-heixiu-* 键名规范
// - 全局组件通过 useSettings() 消费
// ============================================================
import { createContext, useContext } from 'react';
// ---------- localStorage 键 ----------
const OUTPUT_PATH_KEY = 'ele-heixiu-output-path';
const TEAM_REPO_PATH_KEY = 'ele-heixiu-team-repo-path';
// ---------- Context 类型 ----------
export interface SettingsContextValue {
/** 大模型产物存储仓库路径 */
outputPath: string;
/** 团队创作存储仓库路径(企业版) */
teamRepoPath: string;
/** 设置产物输出路径 */
setOutputPath: (path: string) => void;
/** 设置团队创作仓库路径 */
setTeamRepoPath: (path: string) => void;
/** 清除产物输出路径 */
clearOutputPath: () => void;
/** 清除团队创作仓库路径 */
clearTeamRepoPath: () => void;
}
export const SettingsContext = createContext<SettingsContextValue | null>(null);
// ---------- 工具函数localStorage 读写) ----------
export function readStoredOutputPath(): string {
try {
return localStorage.getItem(OUTPUT_PATH_KEY) || '';
} catch {
return '';
}
}
export function writeStoredOutputPath(path: string): void {
try {
localStorage.setItem(OUTPUT_PATH_KEY, path);
} catch {
/* 静默忽略 */
}
}
export function clearStoredOutputPath(): void {
try {
localStorage.removeItem(OUTPUT_PATH_KEY);
} catch {
/* 静默忽略 */
}
}
export function readStoredTeamRepoPath(): string {
try {
return localStorage.getItem(TEAM_REPO_PATH_KEY) || '';
} catch {
return '';
}
}
export function writeStoredTeamRepoPath(path: string): void {
try {
localStorage.setItem(TEAM_REPO_PATH_KEY, path);
} catch {
/* 静默忽略 */
}
}
export function clearStoredTeamRepoPath(): void {
try {
localStorage.removeItem(TEAM_REPO_PATH_KEY);
} catch {
/* 静默忽略 */
}
}
// ---------- Consumer Hook ----------
export function useSettings(): SettingsContextValue {
const ctx = useContext(SettingsContext);
if (!ctx) {
throw new Error('useSettings() 必须在 <SettingsProvider> 内部调用');
}
return ctx;
}

View File

@@ -13,7 +13,7 @@
// ============================================================ // ============================================================
import {useMemo} from 'react'; import {useMemo} from 'react';
import {useAppContext} from '@/contexts/app-context'; import {useAppContext} from '@/components/AppProvider';
import { import {
TaskAPI, TaskAPI,
ModelAPI, ModelAPI,

View File

@@ -1,61 +0,0 @@
// ============================================================
// useTheme — 亮/暗主题切换 Hook
// ============================================================
import { createContext, useContext } from 'react';
// ---------- Context 类型 ----------
export interface ThemeContextValue {
isDark: boolean;
toggleTheme: () => void;
setLight: () => void;
setDark: () => void;
}
export const ThemeContext = createContext<ThemeContextValue | null>(null);
// ---------- 工具函数 ----------
export const STORAGE_KEY = 'ele-heixiu-theme';
export function readStoredTheme(): boolean {
try {
const stored = localStorage.getItem(STORAGE_KEY);
if (stored === 'dark') return true;
if (stored === 'light') return false;
} catch {
/* 静默忽略 */
}
if (typeof window !== 'undefined' && window.matchMedia) {
return window.matchMedia('(prefers-color-scheme: dark)').matches;
}
return false;
}
export function writeStoredTheme(isDark: boolean): void {
try {
localStorage.setItem(STORAGE_KEY, isDark ? 'dark' : 'light');
} catch {
/* 静默忽略 */
}
}
export function applyHtmlTheme(isDark: boolean): void {
document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');
if (isDark) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
}
// ---------- Consumer Hook ----------
export function useTheme(): ThemeContextValue {
const ctx = useContext(ThemeContext);
if (!ctx) {
throw new Error('useTheme() 必须在 <ThemeProvider> 内部调用');
}
return ctx;
}

View File

@@ -1,13 +1,12 @@
// ============================================================ // ============================================================
// HomeContent — 首页三列正文布局 + HomeProvider // HomeContent — 首页三列正文布局 + HomeProviderContext + Provider + Hook
// 可拖拽调整三栏宽度,所有数据请求在登录后发送 // 可拖拽调整三栏宽度,所有数据请求在登录后发送
// ============================================================ // ============================================================
import { useState, useCallback, useRef, useEffect, useMemo } from 'react'; import { createContext, useContext, useState, useCallback, useRef, useEffect, useMemo } from 'react';
import { theme as antTheme, Empty } from 'antd'; import { theme as antTheme, Empty } from 'antd';
import { HomeContext } from '@/contexts/home-context'; import { useAppContext } from '@/components/AppProvider';
import { useAppContext } from '@/contexts/app-context';
import type { ModelsListResponseBody, TaskInfoItemResponseBody } from '@/services/modules'; import type { ModelsListResponseBody, TaskInfoItemResponseBody } from '@/services/modules';
import { LeftPanel } from './components/LeftPanel'; import { LeftPanel } from './components/LeftPanel';
import { CenterPanel } from './components/CenterPanel'; import { CenterPanel } from './components/CenterPanel';
@@ -17,6 +16,38 @@ import { Typography } from 'antd';
const { Text } = Typography; const { Text } = Typography;
// ---------- Context 类型 ----------
export interface HomeContextValue {
/** 当前选中的模型 */
selectedModel: ModelsListResponseBody | null;
setSelectedModel: (model: ModelsListResponseBody | null) => void;
/** 任务记录分页 — 当前页码 */
taskPage: number;
/** 任务记录分页 — 每页条数 */
taskPageSize: number;
setTaskPage: (page: number) => void;
setTaskPageSize: (size: number) => void;
/** 当前选中的任务记录(用于右侧预览) */
selectedTask: TaskInfoItemResponseBody | null;
setSelectedTask: (task: TaskInfoItemResponseBody | null) => void;
/** 侧边栏折叠状态 */
isLeftCollapsed: boolean;
toggleLeftCollapsed: () => void;
}
export const HomeContext = createContext<HomeContextValue | null>(null);
// ---------- Consumer Hook ----------
export function useHomeContext(): HomeContextValue {
const ctx = useContext(HomeContext);
if (!ctx) {
throw new Error('useHomeContext() 必须在 <HomeContent> 内部调用');
}
return ctx;
}
// ---------- 常量 ---------- // ---------- 常量 ----------
/** 左列最小/默认宽度 */ /** 左列最小/默认宽度 */

View File

@@ -25,8 +25,8 @@ import {
} from '@ant-design/icons'; } from '@ant-design/icons';
import type { UploadFile } from 'antd/es/upload'; import type { UploadFile } from 'antd/es/upload';
import { useHomeContext } from '@/contexts/home-context'; import { useHomeContext } from '@/pages/home/HomeContent';
import { useAppContext } from '@/contexts/app-context'; import { useAppContext } from '@/components/AppProvider';
import { useSubmitTask } from '@/hooks/use-api'; import { useSubmitTask } from '@/hooks/use-api';
import { emit, EVENTS } from '@/utils/event-bus'; import { emit, EVENTS } from '@/utils/event-bus';
import type { ModelsListResponseBody, TaskInfoItemResponseBody } from '@/services/modules'; import type { ModelsListResponseBody, TaskInfoItemResponseBody } from '@/services/modules';

View File

@@ -8,7 +8,7 @@ import { Tabs, Spin, Empty, Tag, Typography, Button, Result, message, theme as a
import { AppstoreOutlined } from '@ant-design/icons'; import { AppstoreOutlined } from '@ant-design/icons';
import { useModelList } from '@/hooks/use-api'; import { useModelList } from '@/hooks/use-api';
import { useHomeContext } from '@/contexts/home-context'; import { useHomeContext } from '@/pages/home/HomeContent';
import { resolveCategoryLabel, MODEL_CATEGORIES } from '@/services/modules'; import { resolveCategoryLabel, MODEL_CATEGORIES } from '@/services/modules';
import type { ModelsListResponseBody, ModelCategoryStringEnum } from '@/services/modules'; import type { ModelsListResponseBody, ModelCategoryStringEnum } from '@/services/modules';

View File

@@ -11,7 +11,7 @@ import {
CloseCircleOutlined, CloseCircleOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import { useHomeContext } from '@/contexts/home-context'; import { useHomeContext } from '@/pages/home/HomeContent';
import { useTaskDetail } from '@/hooks/use-api'; import { useTaskDetail } from '@/hooks/use-api';
import type { TaskStatusString } from '@/services/modules'; import type { TaskStatusString } from '@/services/modules';

View File

@@ -18,9 +18,9 @@ import type { FilterValue, SorterResult } from 'antd/es/table/interface';
import { HistoryOutlined, SearchOutlined, SettingOutlined } from '@ant-design/icons'; import { HistoryOutlined, SearchOutlined, SettingOutlined } from '@ant-design/icons';
import { useTaskList, useModelList } from '@/hooks/use-api'; import { useTaskList, useModelList } from '@/hooks/use-api';
import { useAppContext } from '@/contexts/app-context'; import { useAppContext } from '@/components/AppProvider';
import { useHomeContext } from '@/contexts/home-context'; import { useHomeContext } from '@/pages/home/HomeContent';
import { useTheme } from '@/hooks/use-theme'; import { useTheme } from '@/components/ThemeProvider';
import { on, off, EVENTS } from '@/utils/event-bus'; import { on, off, EVENTS } from '@/utils/event-bus';
import type { import type {
TaskInfoItemResponseBody, TaskInfoItemResponseBody,

View File

@@ -12,7 +12,7 @@ import { useState, useCallback } from 'react';
import { Modal, Input, Button, Typography, App } from 'antd'; import { Modal, Input, Button, Typography, App } from 'antd';
import { LockOutlined, KeyOutlined, SafetyOutlined } from '@ant-design/icons'; import { LockOutlined, KeyOutlined, SafetyOutlined } from '@ant-design/icons';
import { useTheme } from '@/hooks/use-theme.ts'; import { useTheme } from '@/components/ThemeProvider';
import { AuthAPI } from '@/services/modules'; import { AuthAPI } from '@/services/modules';
import { validatePassword, validateConfirmPassword } from '../config/validators'; import { validatePassword, validateConfirmPassword } from '../config/validators';

View File

@@ -18,7 +18,7 @@ import {
KeyOutlined, KeyOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import { useTheme } from '@/hooks/use-theme.ts'; import { useTheme } from '@/components/ThemeProvider';
import { AuthAPI } from '@/services/modules'; import { AuthAPI } from '@/services/modules';
import { import {
validatePhone, validatePhone,

View File

@@ -10,8 +10,8 @@
import { useState, useCallback } from 'react'; import { useState, useCallback } from 'react';
import { Modal, Tabs, Typography, App } from 'antd'; import { Modal, Tabs, Typography, App } from 'antd';
import { useAppContext } from '@/contexts/app-context.ts'; import { useAppContext } from '@/components/AppProvider';
import { useTheme } from '@/hooks/use-theme.ts'; import { useTheme } from '@/components/ThemeProvider';
import { LoginForm } from './components/LoginForm'; import { LoginForm } from './components/LoginForm';
import { RegisterForm } from './components/RegisterForm'; import { RegisterForm } from './components/RegisterForm';
import { ForgotPasswordModal } from './components/ForgotPasswordModal'; import { ForgotPasswordModal } from './components/ForgotPasswordModal';

View File

@@ -14,7 +14,7 @@
import { useCallback } from 'react'; import { useCallback } from 'react';
import { Modal } from 'antd'; import { Modal } from 'antd';
import { SettingOutlined, CloseOutlined } from '@ant-design/icons'; import { SettingOutlined, CloseOutlined } from '@ant-design/icons';
import { useAppContext } from '@/contexts/app-context'; import { useAppContext } from '@/components/AppProvider';
import { isMacOS } from '@/utils/platform'; import { isMacOS } from '@/utils/platform';
import { ThemeSetting } from './blocks/ThemeSetting'; import { ThemeSetting } from './blocks/ThemeSetting';
import { StoragePathSetting } from './blocks/StoragePathSetting'; import { StoragePathSetting } from './blocks/StoragePathSetting';

View File

@@ -9,7 +9,7 @@ import { useState, useCallback } from 'react';
import { Card, Button, Input, Typography, Space, App } from 'antd'; import { Card, Button, Input, Typography, Space, App } from 'antd';
import { FolderOpenOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons'; import { FolderOpenOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
import type { Edition } from '@shared/types'; import type { Edition } from '@shared/types';
import { useSettings } from '@/contexts/settings-context'; import { useSettings } from '@/components/SettingsProvider';
import { hasIpc, safeIpcInvoke } from '@/utils/ipc'; import { hasIpc, safeIpcInvoke } from '@/utils/ipc';
import { BIDIRECTIONAL } from '@shared/constants/ipc-channels'; import { BIDIRECTIONAL } from '@shared/constants/ipc-channels';

View File

@@ -9,7 +9,7 @@ import {
InfoCircleOutlined, InfoCircleOutlined,
EnvironmentOutlined, EnvironmentOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import { useAppContext } from '@/contexts/app-context'; import { useAppContext } from '@/components/AppProvider';
import { getPlatformName } from '@/utils/platform'; import { getPlatformName } from '@/utils/platform';
import { APP_VERSION } from '@shared/constants/version'; import { APP_VERSION } from '@shared/constants/version';
import { getEditionName } from '@shared/constants/app'; import { getEditionName } from '@shared/constants/app';

View File

@@ -4,7 +4,7 @@
import { Card, Segmented, Typography } from 'antd'; import { Card, Segmented, Typography } from 'antd';
import { BulbOutlined, BulbFilled } from '@ant-design/icons'; import { BulbOutlined, BulbFilled } from '@ant-design/icons';
import { useTheme } from '@/hooks/use-theme'; import { useTheme } from '@/components/ThemeProvider';
const { Text } = Typography; const { Text } = Typography;