mirror of
https://gitee.com/spark-store-project/spark-store
synced 2026-09-22 22:50:11 +08:00
refactor: 基于 upstream/Erotica 重新整合本地功能(来源选择/合并详情/计数/窗口/首页)
将本地在 upstream !408(已安装应用合并+统计)之上的后续改动重新整合到最新 upstream/Erotica: - 已安装应用:卸载/打开按 APM/Spark 来源选择;计数总数=APM+Spark 包数(双来源计为独立包) - 查看详情:已安装页复用所有应用页合并详情视图(单来源优先已装类型,双来源自动模式) - 窗口:恢复阈值改为 1600x900,过大回退默认尺寸并居中,不自动最大化 - 首页推荐:致谢卡片移至其他内容下方,加大标题/卡片/致谢间距 - 隐藏排行榜/荣耀榜侧栏入口(代码保留,v-if=false) - 新增 scripts/test-build.sh 测试打包脚本(版本末段+1 加 -test)并更新 AGENTS.md 冲突文件(index.ts/App.vue/InstalledAppsModal.vue)均取本地完整实现(为上游版本的超集)。
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
<template>
|
||||
<div class="flex h-full min-h-0 flex-col gap-3">
|
||||
<!-- 两个榜单并排,每个榜单内容在容器内滚动 -->
|
||||
<div class="grid min-h-0 flex-1 gap-6 lg:grid-cols-2">
|
||||
<!-- 贡献荣耀榜 -->
|
||||
<section class="flex min-h-0 flex-col">
|
||||
<h2
|
||||
class="mb-2 shrink-0 text-sm font-bold text-slate-800 dark:text-slate-200"
|
||||
>
|
||||
贡献荣耀榜
|
||||
</h2>
|
||||
<div
|
||||
class="grid grid-rows-1 min-h-0 flex-1 gap-4"
|
||||
:class="gridCols"
|
||||
>
|
||||
<div v-if="showSpark" class="flex min-h-0 flex-col">
|
||||
<SourceLabel origin="spark" />
|
||||
<div
|
||||
class="scrollbar-muted min-h-0 flex-1 space-y-1.5 overflow-y-auto pr-1"
|
||||
>
|
||||
<RankingContributorRow
|
||||
v-for="(item, i) in contributeSpark"
|
||||
:key="item.name"
|
||||
:rank="i + 1"
|
||||
:name="item.name"
|
||||
:count="item.count"
|
||||
label="上榜应用"
|
||||
/>
|
||||
<EmptyState
|
||||
v-if="contributeSpark.length === 0"
|
||||
:loading="appsLoading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showApm" class="flex min-h-0 flex-col">
|
||||
<SourceLabel origin="apm" />
|
||||
<div
|
||||
class="scrollbar-muted min-h-0 flex-1 space-y-1.5 overflow-y-auto pr-1"
|
||||
>
|
||||
<RankingContributorRow
|
||||
v-for="(item, i) in contributeApm"
|
||||
:key="item.name"
|
||||
:rank="i + 1"
|
||||
:name="item.name"
|
||||
:count="item.count"
|
||||
label="上榜应用"
|
||||
/>
|
||||
<EmptyState
|
||||
v-if="contributeApm.length === 0"
|
||||
:loading="appsLoading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 更新荣耀榜 -->
|
||||
<section class="flex min-h-0 flex-col">
|
||||
<h2
|
||||
class="mb-2 shrink-0 text-sm font-bold text-slate-800 dark:text-slate-200"
|
||||
>
|
||||
更新荣耀榜
|
||||
</h2>
|
||||
<div
|
||||
class="grid grid-rows-1 min-h-0 flex-1 gap-4"
|
||||
:class="gridCols"
|
||||
>
|
||||
<div v-if="showSpark" class="flex min-h-0 flex-col">
|
||||
<SourceLabel origin="spark" />
|
||||
<div
|
||||
class="scrollbar-muted min-h-0 flex-1 space-y-1.5 overflow-y-auto pr-1"
|
||||
>
|
||||
<RankingContributorRow
|
||||
v-for="(item, i) in updateContributeSpark"
|
||||
:key="item.name"
|
||||
:rank="i + 1"
|
||||
:name="item.name"
|
||||
:count="item.count"
|
||||
label="近期更新"
|
||||
/>
|
||||
<EmptyState
|
||||
v-if="updateContributeSpark.length === 0"
|
||||
:loading="appsLoading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showApm" class="flex min-h-0 flex-col">
|
||||
<SourceLabel origin="apm" />
|
||||
<div
|
||||
class="scrollbar-muted min-h-0 flex-1 space-y-1.5 overflow-y-auto pr-1"
|
||||
>
|
||||
<RankingContributorRow
|
||||
v-for="(item, i) in updateContributeApm"
|
||||
:key="item.name"
|
||||
:rank="i + 1"
|
||||
:name="item.name"
|
||||
:count="item.count"
|
||||
label="近期更新"
|
||||
/>
|
||||
<EmptyState
|
||||
v-if="updateContributeApm.length === 0"
|
||||
:loading="appsLoading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import type { App } from "../global/typedefinition";
|
||||
import { aggregateContributors, topUpdatedContributors } from "../modules/ranking";
|
||||
import SourceLabel from "./SourceLabel.vue";
|
||||
import RankingContributorRow from "./RankingContributorRow.vue";
|
||||
import EmptyState from "./RankingEmptyState.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
apps: App[];
|
||||
storeFilter?: "spark" | "apm" | "both";
|
||||
}>();
|
||||
|
||||
const TOP = 10;
|
||||
|
||||
const showSpark = computed(() => props.storeFilter !== "apm");
|
||||
const showApm = computed(() => props.storeFilter !== "spark");
|
||||
const gridCols = computed(() =>
|
||||
showSpark.value && showApm.value
|
||||
? "grid-cols-1 sm:grid-cols-2"
|
||||
: "grid-cols-1",
|
||||
);
|
||||
const appsLoading = computed(() => props.apps.length === 0);
|
||||
|
||||
const contributeSpark = computed(() =>
|
||||
aggregateContributors(props.apps, "spark", TOP),
|
||||
);
|
||||
const contributeApm = computed(() =>
|
||||
aggregateContributors(props.apps, "apm", TOP),
|
||||
);
|
||||
const updateContributeSpark = computed(() =>
|
||||
topUpdatedContributors(props.apps, "spark"),
|
||||
);
|
||||
const updateContributeApm = computed(() =>
|
||||
topUpdatedContributors(props.apps, "apm"),
|
||||
);
|
||||
</script>
|
||||
Reference in New Issue
Block a user