Files
spark-store/src/components/AppSidebar.vue
T
xiyidaiwa 81567f8351 refactor(display): 移除字体大小设置,仅保留界面整体缩放
用户实测发现仅调字体到特大/超大时主页面卡片布局遮挡,且字体大小
与界面缩放功能效果高度重叠。故采用方案1:删除字体大小入口,放大
统一由 Electron setZoomFactor 处理(整体等比缩放,不破坏布局)。

- displaySettings.ts:移除 FontSizeOption/FONT_SIZE_OPTIONS/applyFontSize/
  setFontSize/initFontSize 等全部字体相关导出,仅保留界面缩放
- App.vue:移除 initFontSize 导入与调用
- SettingsModal.vue:删除「字体大小」卡片及所有相关逻辑,仅留「界面缩放」
- 还原 8 个组件中当初为字体联动改写的 rem 为原始 px(10/11/12/13/15px),
  消除对 html font-size 的依赖,卡片布局不再因字号变化溢出
2026-08-18 00:15:24 +08:00

217 lines
5.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="flex h-full flex-col gap-6">
<div class="flex-1 space-y-1 overflow-y-auto scrollbar-muted px-1 py-1">
<button
type="button"
class="sidebar-tab"
:class="{ 'sidebar-tab-active': activeTab === 'home' }"
@click="selectTab('home')"
>
<span class="sidebar-tab-icon"><i class="fas fa-star"></i></span>
<span class="sidebar-tab-label">首页推荐</span>
</button>
<button
type="button"
class="sidebar-tab"
:class="{ 'sidebar-tab-active': activeTab === 'all' }"
@click="selectTab('all')"
>
<span class="sidebar-tab-icon"><i class="fas fa-th-large"></i></span>
<span class="sidebar-tab-label">全部应用</span>
<span
class="ml-auto rounded-full bg-slate-100 px-2 py-0.5 text-xs font-semibold text-slate-500 dark:bg-slate-800/70 dark:text-slate-300"
>{{ categoryCounts.all || 0 }}</span
>
</button>
<!-- 排行榜 / 荣耀榜暂时隐藏入口代码保留后续按需恢复 -->
<button
v-if="false"
type="button"
class="sidebar-tab"
:class="{ 'sidebar-tab-active': activeTab === 'ranking' }"
@click="selectTab('ranking')"
>
<span class="sidebar-tab-icon"><i class="fas fa-trophy"></i></span>
<span class="sidebar-tab-label">排行榜</span>
</button>
<button
v-if="false"
type="button"
class="sidebar-tab"
:class="{ 'sidebar-tab-active': activeTab === 'honor' }"
@click="selectTab('honor')"
>
<span class="sidebar-tab-icon"><i class="fas fa-medal"></i></span>
<span class="sidebar-tab-label">荣耀榜</span>
</button>
<div
v-if="sidebarEntries.length > 0"
class="my-3 border-t border-slate-100 dark:border-slate-800"
></div>
<button
v-for="entry in sidebarEntries"
:key="entry.id"
type="button"
class="sidebar-tab"
:class="{ 'sidebar-tab-active': activeTab === entry.id }"
@click="selectTab(entry.id)"
>
<span class="sidebar-tab-icon">
<i v-if="entry.icon" :class="entry.icon"></i>
<i v-else class="fas fa-folder"></i>
</span>
<span class="sidebar-tab-label">{{ entry.name }}</span>
<span
v-if="entryCounts[entry.id]"
class="ml-auto rounded-full bg-slate-100 px-2 py-0.5 text-xs font-semibold text-slate-500 dark:bg-slate-800/70 dark:text-slate-300"
>{{ entryCounts[entry.id] }}</span
>
</button>
</div>
<div class="border-t border-slate-200 pt-4 dark:border-slate-800">
<button
v-if="canManageApps"
type="button"
class="sidebar-tab"
@click="emitSidebarAction('list')"
>
<span class="sidebar-tab-icon"><i class="fas fa-download"></i></span>
<span class="sidebar-tab-label">应用管理</span>
</button>
<button
v-if="canOpenUpdateCenter"
type="button"
class="sidebar-tab"
@click="emitSidebarAction('update')"
>
<span class="sidebar-tab-icon"><i class="fas fa-sync-alt"></i></span>
<span class="sidebar-tab-label">软件更新</span>
</button>
<button
type="button"
class="sidebar-tab"
@click="emitSidebarAction('submit')"
>
<span class="sidebar-tab-icon"><i class="fas fa-upload"></i></span>
<span class="sidebar-tab-label">投稿应用</span>
</button>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from "vue";
import type { SidebarEntry, SparkUser } from "../global/typedefinition";
const props = defineProps<{
activeTab: string;
categoryCounts: Record<string, number>;
themeMode: "light" | "dark" | "auto";
sparkAvailable: boolean;
apmAvailable: boolean;
storeFilter: "spark" | "apm" | "both";
sidebarEntries: SidebarEntry[];
entryCounts: Record<string, number>;
currentUser: SparkUser | null;
}>();
const emit = defineEmits<{
(e: "toggle-theme"): void;
(e: "select-tab", tab: string): void;
(e: "close"): void;
(e: "list"): void;
(e: "update"): void;
(e: "submit"): void;
(e: "request-login"): void;
(e: "open-user-management"): void;
(e: "open-favorites"): void;
(e: "open-forum"): void;
(e: "edit-profile"): void;
(e: "logout"): void;
}>();
const canManageApps = computed(() => {
return (
(props.storeFilter !== "apm" && props.sparkAvailable) ||
(props.storeFilter !== "spark" && props.apmAvailable)
);
});
const canOpenUpdateCenter = canManageApps;
const selectTab = (tab: string) => {
emit("select-tab", tab);
};
const emitSidebarAction = (action: "list" | "update" | "submit") => {
if (action === "list") emit("list");
else if (action === "update") emit("update");
else emit("submit");
};
</script>
<style scoped>
.sidebar-tab {
display: flex;
width: 100%;
align-items: center;
gap: 12px;
border: 1px solid transparent;
border-radius: 12px;
padding: 10px 0.875rem;
text-align: left;
font-size: 0.875rem;
font-weight: 500;
color: #64748b;
transition: all 0.15s ease;
background: transparent;
cursor: pointer;
}
.sidebar-tab:hover {
background: rgba(0, 113, 227, 0.06);
color: #0071e3;
}
.dark .sidebar-tab:hover {
background: rgba(64, 156, 255, 0.1);
color: #409cff;
}
.sidebar-tab-active {
background: rgba(0, 113, 227, 0.1);
color: #0066cc;
border-color: rgba(0, 113, 227, 0.2);
}
.dark .sidebar-tab-active {
background: rgba(64, 156, 255, 0.15);
color: #409cff;
border-color: rgba(64, 156, 255, 0.25);
}
.sidebar-tab-icon {
display: flex;
align-items: center;
justify-content: center;
width: 1.5rem;
height: 1.5rem;
font-size: 0.875rem;
flex-shrink: 0;
}
.sidebar-tab-label {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>