mirror of
https://gitee.com/spark-store-project/spark-store
synced 2026-09-20 21:50:11 +08:00
- 标签优先显示策略 initTagPriorityStrategy 提到 App.vue onMounted 统一调用, 消除组件挂载顺序导致先读内存默认 auto 的竞态窗口(AppDetailModal 移除重复调用) - InstalledAppsModal 过滤逻辑合并为单次遍历(保留 hasOrigin 双来源语义) - 统计 apm/spark/total 改为基于 searchFilteredApps 单次遍历 - canOpenDetail 补充业务含义注释与可读性变量 - 将 App.vue 重构的 9 个 composable 纳入版本管理 - 验证:vue-tsc 0 / eslint 0 / dpkg-buildpackage 打包 spark-store_5.2.1.24-test 成功
168 lines
6.2 KiB
TypeScript
168 lines
6.2 KiB
TypeScript
/**
|
||
* useAppState —— 跨 composable 共享的全局原始响应式状态(单例)。
|
||
*
|
||
* 设计说明(避免循环依赖与重复实例化):
|
||
* App.vue 原文件中的逻辑被拆分到多个 composable(useCatalog / useRanking /
|
||
* useAppDetail / useInstalledApps / useFavorites / useAccountSync / useDownloads)。
|
||
* 这些 composable 之间存在大量共享状态(apps / currentApp / installedApps /
|
||
* favorite* / 各类弹窗开关等)。若各自持有会出现多实例与状态不同步,并引发循环依赖。
|
||
*
|
||
* 故把"贯穿整个应用生命周期的全局原始状态"集中在本模块以单例形式导出,
|
||
* 所有 composable 与 App.vue 均从本模块取用同一份 ref 实例。
|
||
* 这与现有 global/authState.ts、global/storeConfig.ts 的单例风格一致。
|
||
*
|
||
* 本模块**只持有状态与极少量纯派生 computed**,不含任何业务逻辑/副作用,
|
||
* 确保拆分前后运行时行为完全一致(7 维度审计:功能/状态一致)。
|
||
*
|
||
* 注意:currentApp / currentAppSparkInstalled / currentAppApmInstalled 同时在
|
||
* storeConfig 中导出(供其它模块直接引用)。本模块从 storeConfig 再导出以保持单一实例。
|
||
*/
|
||
import { ref, computed } from "vue";
|
||
import type { Ref } from "vue";
|
||
import type {
|
||
App,
|
||
AppJson,
|
||
CategoryInfo,
|
||
SidebarEntry,
|
||
HomeLink,
|
||
FavoriteFolder,
|
||
FavoriteItem,
|
||
InstalledAppInfo,
|
||
ResolvedFavoriteItem,
|
||
SystemInfo,
|
||
DownloadedAppRecord,
|
||
SyncedAppListItem,
|
||
AppReview,
|
||
ReviewUserProfile,
|
||
DownloadItem,
|
||
} from "../global/typedefinition";
|
||
|
||
// ===== 目录数据 =====
|
||
export const apps: Ref<App[]> = ref([]);
|
||
export const categories: Ref<Record<string, CategoryInfo>> = ref({});
|
||
export const tabCategories: Ref<Record<string, Record<string, CategoryInfo>>> =
|
||
ref({});
|
||
export const tabApps: Ref<Record<string, App[]>> = ref({});
|
||
export const loadingTabs = ref<Set<string>>(new Set());
|
||
export const homeListUrls = ref<
|
||
Record<string, { spark?: string; apm?: string }>
|
||
>({});
|
||
export const sidebarEntries: Ref<SidebarEntry[]> = ref([]);
|
||
export const sparkAvailable = ref(false);
|
||
export const apmAvailable = ref(false);
|
||
export const storeFilter = ref<"spark" | "apm" | "both">("both");
|
||
export const initialCatalogLoaded = ref(false);
|
||
export const loading = ref(true);
|
||
|
||
// ===== 首页 / 排行 =====
|
||
export const homeLinks = ref<HomeLink[]>([]);
|
||
export const homeLoading = ref(false);
|
||
export const homeError = ref("");
|
||
export const apmRanking = ref<App[]>([]);
|
||
export const sparkRanking = ref<App[]>([]);
|
||
export const rankingLoading = ref(false);
|
||
|
||
// ===== 导航 =====
|
||
export type MainView = "default" | "favorites";
|
||
export const currentView = ref<MainView>("default");
|
||
export const activeTab = ref("home");
|
||
export const selectedCategory = ref("all");
|
||
export const searchQuery = ref("");
|
||
export const isSidebarOpen = ref(false);
|
||
|
||
// ===== 详情弹窗 =====
|
||
export {
|
||
currentApp,
|
||
currentAppSparkInstalled,
|
||
currentAppApmInstalled,
|
||
} from "../global/storeConfig";
|
||
export const showModal = ref(false);
|
||
export const showPreview = ref(false);
|
||
export const currentScreenIndex = ref(0);
|
||
export const screenshots = ref<string[]>([]);
|
||
|
||
// ===== 已安装应用 =====
|
||
export const showInstalledModal = ref(false);
|
||
export const installedApps = ref<App[]>([]);
|
||
export const installedLoading = ref(false);
|
||
export const installedError = ref("");
|
||
export const installedWarning = ref("");
|
||
export const installedRefreshGeneration = ref(0);
|
||
export const installedSyncPromptShown = ref(false);
|
||
|
||
// ===== 收藏夹 =====
|
||
export const favoriteFolders = ref<FavoriteFolder[]>([]);
|
||
export const activeFavoriteFolderId = ref<number | null>(null);
|
||
export const favoriteItems = ref<FavoriteItem[]>([]);
|
||
export const favoriteItemsByFolder = ref<Record<number, FavoriteItem[]>>({});
|
||
export const showFavoriteSelector = ref(false);
|
||
export const favoriteTargetApp = ref<App | null>(null);
|
||
export const favoriteSelectorDraftFolderIds = ref<Array<
|
||
number | "default"
|
||
> | null>(null);
|
||
export const favoriteLoading = ref(false);
|
||
export const favoriteError = ref("");
|
||
export const favoriteRequestGeneration = ref(0);
|
||
|
||
// ===== 账号 / 下载历史 / 云端同步 / 恢复 =====
|
||
export const showUserManagementModal = ref(false);
|
||
export const downloadedApps = ref<DownloadedAppRecord[]>([]);
|
||
export const downloadedLoading = ref(false);
|
||
export const downloadedError = ref("");
|
||
export const downloadedRequestGeneration = ref(0);
|
||
export const syncLoading = ref(false);
|
||
export const syncStatusMessage = ref("");
|
||
export const syncRequestGeneration = ref(0);
|
||
export const syncCandidateApps = ref<App[]>([]);
|
||
export const restoreLoading = ref(false);
|
||
export const restoreError = ref("");
|
||
export const showRestoreModal = ref(false);
|
||
export const restoreItems = ref<SyncedAppListItem[]>([]);
|
||
export const restoreRequestGeneration = ref(0);
|
||
export const showLoginModal = ref(false);
|
||
export const loginLoading = ref(false);
|
||
export const loginError = ref("");
|
||
export const showLoginPrompt = ref(false);
|
||
export const loginPromptMessage = ref("请登录星火账号后继续操作。");
|
||
export const showLoginPromptMessage = loginPromptMessage;
|
||
export const showReviewUserProfileModal = ref(false);
|
||
export const selectedReviewUserProfile = ref<ReviewUserProfile | null>(null);
|
||
export const systemInfo = ref<SystemInfo>({ distro: "unknown" });
|
||
|
||
// ===== 下载队列 =====
|
||
export { downloads } from "../global/downloadStatus";
|
||
export const showDownloadDetailModal = ref(false);
|
||
export const currentDownload: Ref<DownloadItem | null> = ref(null);
|
||
|
||
// ===== 其它弹窗 / 卸载 / 更新中心编排 =====
|
||
export const showUninstallModal = ref(false);
|
||
export const uninstallTargetApp: Ref<App | null> = ref(null);
|
||
export const showAboutModal = ref(false);
|
||
export const showSettingsModal = ref(false);
|
||
export const showApmInstallDialog = ref(false);
|
||
|
||
// 可用来源 computed(供 storeFilter 相关判断复用)
|
||
export const availableSources = computed(() => ({
|
||
spark: sparkAvailable.value,
|
||
apm: apmAvailable.value,
|
||
}));
|
||
|
||
// 运算符别名(仅导出类型引用,避免重复定义)
|
||
export type {
|
||
App,
|
||
AppJson,
|
||
CategoryInfo,
|
||
SidebarEntry,
|
||
HomeLink,
|
||
FavoriteFolder,
|
||
FavoriteItem,
|
||
InstalledAppInfo,
|
||
ResolvedFavoriteItem,
|
||
SystemInfo,
|
||
DownloadedAppRecord,
|
||
SyncedAppListItem,
|
||
AppReview,
|
||
ReviewUserProfile,
|
||
DownloadItem,
|
||
};
|