项目文件夹

文件
wehub-resource-sync 2114b14ee0
Sync main into demo / sync (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:35:26 +08:00

226 行
6.3 KiB
TypeScript

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
/**
* App 唯一标识符。
* 新增 App 无需修改此文件 —— manifest.ts 自动发现。
* 运行时验证通过 isValidAppId()(检查 APP_REGISTRY)。
*/
export type AppId = string;
/**
* 已实现组件的 App ID(运行时由 hasAppComponent() 判定)。
*/
export type ImplementedAppId = string;
/** 单个 Activity 实例(Task 栈中的一层) */
export interface ActivityInstance {
/** 全局唯一,如 act_1 */
activityId: string;
appId: AppId;
/** 创建时的路由(用于首次导航) */
initialRoute: string;
/** 启动此 Activity 时的来源 Task(用于 finish 后回到调用方) */
launchedByTaskId?: string;
/** startActivityForResult 时的 Intent 载荷 */
intent?: import('./types/manifest').IntentPayload;
/** OS 分配的 requestCode(仅 intent activity 有) */
requestCode?: number;
/** 调用方 activityId(仅 intent activity 有) */
callerActivityId?: string;
}
/** Task = 一组 Activity 的栈(bottom -> top */
export interface Task {
taskId: string;
rootAppId: AppId;
stack: ActivityInstance[];
/** 最近激活时间(用于 MRU 排序) */
lastActiveAt: number;
/** 激活此 Task 时的前台 TaskId(用于 Task 返回栈:finish 时回到发起方) */
launchedByTaskId?: string;
/** 此 Task 的初始路由是否由外部 openApp(appId, route) 设置。
* true → Back 到底时 finish Task(等同 Android 非 launcher Activity 的 finish
* false/undefined → Back 到底时 moveTaskToBackTask 保活) */
wasExternallyRouted?: boolean;
}
/** 由 tasks 派生的活跃 Intent 记录 */
export interface ActiveIntentEntry {
requestCode: number;
callerAppId: AppId;
targetAppId: AppId;
wasTargetRunning: boolean;
intent: import('./types/manifest').IntentPayload;
resolvedRoute: string;
}
export interface OSState {
tasks: Task[];
activeTaskId: string | null;
/** 派生字段:当前前台 App 的 ID(从 activeTask 栈顶 Activity 推导) */
readonly activeAppId?: AppId | null;
isLauncherVisible: boolean;
isRecentsVisible: boolean;
}
// ============================================================================
// System Shade / Notifications / Quick Settings
// ============================================================================
export type ShadePanelKind = 'notifications' | 'control';
export type PendingIntentToken = string;
export interface OSNotification {
id: string;
appId?: AppId; // optional: system notifications may omit appId
title: string;
body?: string;
timestamp: number; // ms since epoch
read: boolean;
importance?: 'low' | 'default' | 'high';
route?: string; // optional: deep-link into app when tapped
pendingIntent?: PendingIntentToken;
/** When true (default), tapping the notification auto-dismisses it (Android setAutoCancel). */
autoCancel?: boolean;
}
export interface OSNotificationSnapshot {
items: OSNotification[];
unreadCount: number;
}
export interface QuickSettingsState {
wifiEnabled: boolean;
mobileDataEnabled: boolean;
bluetoothEnabled: boolean;
airplaneModeEnabled: boolean;
doNotDisturbEnabled: boolean;
flashlightEnabled: boolean;
batterySaverEnabled: boolean;
rotationLocked: boolean;
locationEnabled: boolean;
nfcEnabled: boolean;
screenCastEnabled: boolean;
autoBrightnessEnabled: boolean;
eyeComfortEnabled: boolean;
darkModeEnabled: boolean;
}
export interface SystemShadeSnapshot {
open: boolean;
kind: ShadePanelKind;
}
// ============================================================================
// File System Types
// ============================================================================
/**
* File/Directory node in the virtual file system
*/
export interface FSNode {
id: string;
name: string;
type: 'file' | 'directory';
parentId: string | null; // null = root directory
path: string; // Full path, e.g., /sdcard/DCIM/Camera/IMG_001.jpg
// Metadata
size: number; // File size in bytes (0 for directories)
mimeType?: string; // MIME type for files
createdAt: number; // Timestamp
modifiedAt: number; // Timestamp
// Storage location marker
storage: 'preset' | 'indexeddb' | 'memory';
// Media-specific properties
thumbnailUri?: string; // Thumbnail for images/videos
width?: number; // Image/video width
height?: number; // Image/video height
duration?: number; // Video/audio duration in seconds
}
/**
* Preset directory configuration
*/
export interface PresetDirectory {
path: string;
displayName?: string; // Display name, e.g., "相机" for /DCIM/Camera
icon?: string;
}
/**
* Preset file configuration
*/
export interface PresetFile {
path: string;
uri: string; // Actual resource path (in public/ or URL)
mimeType: string;
size: number;
width?: number;
height?: number;
duration?: number;
}
/**
* File system configuration
*/
export interface FileSystemConfig {
presetStructure: PresetDirectory[];
presetFiles: PresetFile[];
}
// ============================================================================
// Media Service Types
// ============================================================================
/**
* Media item (photo/video) for gallery
*/
export interface MediaItem {
id: string;
type: 'image' | 'video';
uri: string; // Display URI
thumbnailUri?: string;
name: string;
mimeType: string;
size: number;
width?: number;
height?: number;
duration?: number;
createdAt: number;
path: string; // File system path
}
/**
* Album for grouping media
*/
export interface Album {
id: string;
name: string;
type: 'system' | 'app'; // System album vs app-specific
coverUri?: string;
coverPath?: string; // Path for async loading
count: number;
pathPattern?: string; // Path pattern to match, e.g., "/sdcard/DCIM/Camera"
}
/**
* Media picker options
*/
export interface MediaPickerOptions {
type?: 'image' | 'video' | 'all';
multiple?: boolean;
maxSelect?: number;
albumId?: string;
title?: string;
}
/**
* Media picker result
*/
export interface MediaPickerResult {
selected: MediaItem[];
cancelled: boolean;
}