Initial commit

This commit is contained in:
2026-03-08 01:34:54 +08:00
commit 1f104f73c8
441 changed files with 64911 additions and 0 deletions

9
shared/types/api.ts Normal file
View File

@@ -0,0 +1,9 @@
export type ApiErrorDTO = {
code: string
message: string
details?: unknown
}
export type ApiResponse<T> =
| { success: true; data: T }
| { success: false; error: ApiErrorDTO }

22
shared/types/file.ts Normal file
View File

@@ -0,0 +1,22 @@
export type FileKind = 'file' | 'dir'
export interface FileItemDTO {
name: string
type: FileKind
size: number
modified: string
path: string
}
export interface FileContentDTO {
content: string
metadata: {
size: number
modified: string
}
}
export type PathExistsDTO = {
exists: boolean
type: FileKind | null
}

9
shared/types/index.ts Normal file
View File

@@ -0,0 +1,9 @@
export * from './file.js'
export * from './module.js'
export * from './tab.js'
export * from './time.js'
export * from './todo.js'
export * from './pydemos.js'
export * from './recycle-bin.js'
export * from './settings.js'
export * from './api.js'

34
shared/types/module.ts Normal file
View File

@@ -0,0 +1,34 @@
import type { LucideIcon } from 'lucide-react'
import type { FileItemDTO as FileItem } from './file.js'
export type {
HttpMethod,
EndpointConfig,
EndpointDefinition,
ModuleEndpoints,
ModuleApiConfig,
ModuleDefinition,
ApiModuleConfig,
} from '../modules/types.js'
export type Brand<T, TBrand extends string> = T & { __brand: TBrand }
export type ModuleId = Brand<string, 'ModuleId'>
import type { ModuleDefinition, ModuleEndpoints } from '../modules/types.js'
export interface FrontendModuleConfig<
TEndpoints extends ModuleEndpoints = ModuleEndpoints
> extends Omit<ModuleDefinition<string, TEndpoints>, 'icon' | 'basePath'> {
basePath?: string
icon: LucideIcon
component: React.ComponentType
}
export interface InternalModuleConfig extends FrontendModuleConfig {
tabId: string
fileItem: FileItem
}
export const createModuleId = (id: string): ModuleId => {
return id as ModuleId
}

11
shared/types/pydemos.ts Normal file
View File

@@ -0,0 +1,11 @@
export interface PyDemoItem {
name: string
path: string
created: string
fileCount: number
}
export interface PyDemoMonth {
month: number
demos: PyDemoItem[]
}

View File

@@ -0,0 +1,14 @@
import type { FileKind } from './file.js'
export interface RecycleBinItemDTO {
name: string
originalName: string
type: FileKind
deletedDate: string
path: string
}
export interface RecycleBinGroupDTO {
date: string
items: RecycleBinItemDTO[]
}

7
shared/types/settings.ts Normal file
View File

@@ -0,0 +1,7 @@
export type ThemeMode = 'light' | 'dark'
export interface SettingsDTO {
theme?: 'light' | 'dark'
wallpaperOpacity?: number
markdownFontSize?: number
}

1
shared/types/tab.ts Normal file
View File

@@ -0,0 +1 @@
export type TabType = 'markdown' | 'todo' | 'settings' | 'search' | 'recycle-bin' | 'weread' | 'time-tracking' | 'pydemos' | 'remote' | 'remote-desktop' | 'remote-git' | 'other'

101
shared/types/time.ts Normal file
View File

@@ -0,0 +1,101 @@
export type { TabType } from './tab.js'
export interface TimePeriod {
start: string
end: string
}
export interface TabRecord {
tabId: string
filePath: string | null
fileName: string
tabType: import('./tab.js').TabType
duration: number
focusedPeriods: TimePeriod[]
}
export interface TimingSession {
id: string
startTime: string
endTime?: string
duration: number
status: 'active' | 'paused' | 'ended'
tabRecords: TabRecord[]
}
export interface TabSummary {
fileName: string
tabType: import('./tab.js').TabType
totalDuration: number
focusCount: number
}
export interface DayTimeData {
date: string
totalDuration: number
sessions: TimingSession[]
tabSummary: Record<string, TabSummary>
lastUpdated: string
}
export interface DaySummary {
totalDuration: number
sessions: number
topTabs: Array<{ fileName: string; duration: number }>
}
export interface MonthTimeData {
year: number
month: number
days: Record<string, DaySummary>
monthlyTotal: number
averageDaily: number
activeDays: number
lastUpdated: string
}
export interface YearTimeData {
year: number
months: Record<string, { totalDuration: number; activeDays: number }>
yearlyTotal: number
averageMonthly: number
averageDaily: number
totalActiveDays: number
}
export interface CurrentTimerState {
isRunning: boolean
isPaused: boolean
currentSession: {
id: string
startTime: string
duration: number
currentTab: {
tabId: string
fileName: string
tabType: import('./tab.js').TabType
} | null
} | null
todayDuration: number
}
export interface TimeStats {
totalDuration: number
activeDays: number
averageDaily: number
longestDay: { date: string; duration: number } | null
longestSession: { date: string; duration: number } | null
topTabs: Array<{ fileName: string; duration: number; percentage: number }>
tabTypeDistribution: Array<{ tabType: import('./tab.js').TabType; duration: number; percentage: number }>
}
export interface TimeTrackingEvent {
type: 'tab-switch' | 'tab-open' | 'tab-close' | 'window-focus' | 'window-blur' | 'app-quit' | 'heartbeat'
timestamp: string
tabInfo?: {
tabId: string
filePath: string | null
fileName: string
tabType: import('./tab.js').TabType
}
}

10
shared/types/todo.ts Normal file
View File

@@ -0,0 +1,10 @@
export interface TodoItem {
id: string
content: string
completed: boolean
}
export interface DayTodo {
date: string
items: TodoItem[]
}