From 3f6678ac2f3fc2275d72c473351344153112903d Mon Sep 17 00:00:00 2001 From: Ap_Tx <110907771+ApTx2012@users.noreply.github.com> Date: Sat, 10 Oct 2026 21:32:11 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E7=A7=BB=E6=A4=8D=E8=BF=9C?= =?UTF-8?q?=E7=A8=8B=E5=85=AC=E5=91=8A=E4=B8=AD=E5=BF=83=20(#9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 从 Axolotl 搬 RemoteAnnouncements.vue,顶栏加公告铃铛。远程拉取先禁用,等接口。 --- apps/app-frontend/src/App.vue | 2 + .../src/components/ui/AppActionBar.vue | 47 ++- .../src/components/ui/RemoteAnnouncements.vue | 388 ++++++++++++++++++ .../src/helpers/remote-announcements.ts | 3 + .../app-frontend/src/locales/en-US/index.json | 30 ++ .../app-frontend/src/locales/zh-CN/index.json | 5 +- packages/ui/src/composables/index.ts | 1 + 7 files changed, 474 insertions(+), 2 deletions(-) create mode 100644 apps/app-frontend/src/components/ui/RemoteAnnouncements.vue diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue index 521a733..d0418bf 100644 --- a/apps/app-frontend/src/App.vue +++ b/apps/app-frontend/src/App.vue @@ -95,6 +95,7 @@ import NavRail from '@/components/ui/NavRail.vue' import OnboardingOverlay from '@/components/ui/onboarding/OnboardingOverlay.vue' import QuickInstanceSwitcher from '@/components/ui/QuickInstanceSwitcher.vue' import SkinSiteSessionFrame from '@/components/ui/SkinSiteSessionFrame.vue' +import RemoteAnnouncements from '@/components/ui/RemoteAnnouncements.vue' import StartupAnnouncementModal from '@/components/ui/StartupAnnouncementModal.vue' import SplashScreen from '@/components/ui/SplashScreen.vue' import WindowControls from '@/components/ui/WindowControls.vue' @@ -2227,6 +2228,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload) +
+ + + import { BellIcon, + NewspaperIcon, DownloadIcon, DropdownIcon, OnlineIndicatorIcon, @@ -211,7 +229,7 @@ import { } from '@modrinth/ui' import { convertFileSrc } from '@tauri-apps/api/core' import { Dropdown } from 'floating-vue' -import { computed, onBeforeUnmount, ref, watch } from 'vue' +import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue' import { useRoute, useRouter } from 'vue-router' import AppUpdateButton from '@/components/ui/app-update-button/index.vue' @@ -222,6 +240,10 @@ import { get_many as getInstances } from '@/helpers/instance' import { get_all as getRunningProcesses, kill as killProcess } from '@/helpers/process' import type { LoadingBar } from '@/helpers/state' import { progress_bars_list } from '@/helpers/state' +import { + OPEN_REMOTE_ANNOUNCEMENT_CENTER_EVENT, + REMOTE_ANNOUNCEMENTS_UPDATED_EVENT, +} from '@/helpers/remote-announcements' import type { GameInstance } from '@/helpers/types' import { downloadBarTypes, injectDownloadManager } from '@/providers/download-manager' @@ -231,6 +253,25 @@ const popupNotificationManager = injectPopupNotificationManager() const downloadManager = injectDownloadManager() const { formatMessage } = useVIntl() +const announcementUnreadCount = ref(0) + +function openAnnouncementCenter() { + window.dispatchEvent(new CustomEvent(OPEN_REMOTE_ANNOUNCEMENT_CENTER_EVENT)) +} + +function updateAnnouncementCount(event: Event) { + const detail = (event as CustomEvent<{ unreadKeys?: string[] }>).detail + announcementUnreadCount.value = detail?.unreadKeys?.length ?? 0 +} + +onMounted(() => { + window.addEventListener(REMOTE_ANNOUNCEMENTS_UPDATED_EVENT, updateAnnouncementCount) +}) + +onBeforeUnmount(() => { + window.removeEventListener(REMOTE_ANNOUNCEMENTS_UPDATED_EVENT, updateAnnouncementCount) +}) + type NotificationHistoryItem = { key: string createdAt?: number @@ -370,6 +411,10 @@ const messages = defineMessages({ id: 'app.action-bar.notifications', defaultMessage: 'Notifications', }, + announcements: { + id: 'app.action-bar.announcements', + defaultMessage: 'Announcements', + }, clearNotifications: { id: 'app.action-bar.notifications.clear', defaultMessage: 'Clear all', diff --git a/apps/app-frontend/src/components/ui/RemoteAnnouncements.vue b/apps/app-frontend/src/components/ui/RemoteAnnouncements.vue new file mode 100644 index 0000000..4e23f3c --- /dev/null +++ b/apps/app-frontend/src/components/ui/RemoteAnnouncements.vue @@ -0,0 +1,388 @@ + + + diff --git a/apps/app-frontend/src/helpers/remote-announcements.ts b/apps/app-frontend/src/helpers/remote-announcements.ts index a8b2a24..92f7bfe 100644 --- a/apps/app-frontend/src/helpers/remote-announcements.ts +++ b/apps/app-frontend/src/helpers/remote-announcements.ts @@ -64,3 +64,6 @@ export function isAnnouncementActive(item: RemoteAnnouncement, now = Date.now()) export function announcementKey(item: RemoteAnnouncement) { return item.id + ':' + item.published_at } + +export const REMOTE_ANNOUNCEMENTS_UPDATED_EVENT = 'starlight:remote-announcements-updated' +export const OPEN_REMOTE_ANNOUNCEMENT_CENTER_EVENT = 'starlight:open-remote-announcement-center' diff --git a/apps/app-frontend/src/locales/en-US/index.json b/apps/app-frontend/src/locales/en-US/index.json index ec78130..76e7dec 100644 --- a/apps/app-frontend/src/locales/en-US/index.json +++ b/apps/app-frontend/src/locales/en-US/index.json @@ -11431,5 +11431,35 @@ }, "app.anniversary.banner": { "message": "Happy {ordinal} Anniversary, Starlight!" + }, + "app.action-bar.announcements": { + "message": "Announcements" + }, + "app.remote-announcements.center-title": { + "message": "Announcements" + }, + "app.remote-announcements.empty": { + "message": "No announcements" + }, + "app.remote-announcements.view": { + "message": "View announcement" + }, + "app.remote-announcements.unread": { + "message": "Unread" + }, + "app.remote-announcements.read-all": { + "message": "Mark all announcements as read" + }, + "app.remote-announcements.preview-title": { + "message": "Announcement style preview" + }, + "app.remote-announcements.preview-summary": { + "message": "This is a local preview notification. Select View announcement to see the full Markdown content." + }, + "app.remote-announcements.preview-content": { + "message": "## Announcement preview\n\nThis is **sample content**, not a published announcement.\n\n- Supports headings, lists, and links\n- Close buttons are always available\n\n> Previewing does not change real announcement read status.\n\n| Type | Display |\n| --- | --- |\n| Modal | Full Markdown content |\n| Popup | Summary, then full content |\n\n[Visit the website](https://skin.starlight.cool/)" + }, + "app.remote-announcements.preview-action": { + "message": "Visit website" } } diff --git a/apps/app-frontend/src/locales/zh-CN/index.json b/apps/app-frontend/src/locales/zh-CN/index.json index 8760bfe..2065faa 100644 --- a/apps/app-frontend/src/locales/zh-CN/index.json +++ b/apps/app-frontend/src/locales/zh-CN/index.json @@ -11351,5 +11351,8 @@ "app.settings.synced-options.game-settings.value-off": { "message": "关闭" }, "app.settings.synced-options.game-settings.value-on": { "message": "开启" }, "app.settings.synced-options.game-settings.value-unset": { "message": "选择一个值" }, - "app.anniversary.banner": { "message": "Starlight {ordinal} 周年快乐!" } + "app.anniversary.banner": { "message": "Starlight {ordinal} 周年快乐!" }, + "app.action-bar.announcements": { "message": "公告" }, + "app.remote-announcements.center-title": { "message": "公告" }, + "app.remote-announcements.empty": { "message": "暂无公告" } } diff --git a/packages/ui/src/composables/index.ts b/packages/ui/src/composables/index.ts index 8a74269..f66970b 100644 --- a/packages/ui/src/composables/index.ts +++ b/packages/ui/src/composables/index.ts @@ -8,6 +8,7 @@ export * from './format-number' export * from './how-ago' export * from './i18n' export * from './i18n-debug' +export * from './modal-stack' export * from './page-leave-safety' export * from './scroll-indicator' export type { ArmorPreviewConfig } from './skin-rendering/armor-preview-types' From 1b6534ad8c49744d9c2b60bb0133bc294456e1b9 Mon Sep 17 00:00:00 2001 From: Ap_Tx <3045929398@qq.com> Date: Sat, 10 Oct 2026 21:53:05 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20changelog=20=E8=AF=84=E8=AE=BA=20wor?= =?UTF-8?q?kflow=20=E8=A1=A5=20pull-requests=20write=20=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/changelog-comment.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/changelog-comment.yml b/.github/workflows/changelog-comment.yml index 33dd202..fcba466 100644 --- a/.github/workflows/changelog-comment.yml +++ b/.github/workflows/changelog-comment.yml @@ -12,7 +12,7 @@ on: permissions: issues: write - pull-requests: read + pull-requests: write jobs: comment: @@ -21,7 +21,7 @@ jobs: permissions: issues: write - pull-requests: read + pull-requests: write contents: read steps: From c54acd2e369e718e62b7754c8b45352ded77679d Mon Sep 17 00:00:00 2001 From: Ap_Tx <110907771+ApTx2012@users.noreply.github.com> Date: Sat, 10 Oct 2026 21:54:50 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=E8=A1=A5=E9=BD=90=E7=9B=94=E7=94=B2?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E7=9A=84=E4=B8=AD=E6=96=87=E7=BF=BB=E8=AF=91?= =?UTF-8?q?=20(#11)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 皮肤编辑器盔甲面板的 46 条文案此前只有英文,补上 packages/ui 的中英对照。 --- packages/ui/src/locales/en-US/index.json | 140 ++++++++++++++++++++++- packages/ui/src/locales/zh-CN/index.json | 140 ++++++++++++++++++++++- 2 files changed, 278 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/locales/en-US/index.json b/packages/ui/src/locales/en-US/index.json index 948c00a..6634624 100644 --- a/packages/ui/src/locales/en-US/index.json +++ b/packages/ui/src/locales/en-US/index.json @@ -4723,5 +4723,143 @@ }, "version.supplementary-resources.type": { "defaultMessage": "Type" - } + }, + "skin.preview.armor.equip-material": { + "defaultMessage": "{material} {slot}" + }, + "skin.preview.armor.material": { + "defaultMessage": "Armor material" + }, + "skin.preview.armor.material.chainmail": { + "defaultMessage": "Chainmail" + }, + "skin.preview.armor.material.copper": { + "defaultMessage": "Copper" + }, + "skin.preview.armor.material.diamond": { + "defaultMessage": "Diamond" + }, + "skin.preview.armor.material.gold": { + "defaultMessage": "Gold" + }, + "skin.preview.armor.material.iron": { + "defaultMessage": "Iron" + }, + "skin.preview.armor.material.leather": { + "defaultMessage": "Leather" + }, + "skin.preview.armor.material.netherite": { + "defaultMessage": "Netherite" + }, + "skin.preview.armor.material.turtle": { + "defaultMessage": "Turtle Shell" + }, + "skin.preview.armor.open": { + "defaultMessage": "Armor and trims" + }, + "skin.preview.armor.piece": { + "defaultMessage": "Armor piece" + }, + "skin.preview.armor.remove-piece": { + "defaultMessage": "Remove {slot}" + }, + "skin.preview.armor.remove-trim": { + "defaultMessage": "No armor trim" + }, + "skin.preview.armor.slot-state": { + "defaultMessage": "{slot}: {state}" + }, + "skin.preview.armor.slot.boots": { + "defaultMessage": "Boots" + }, + "skin.preview.armor.slot.chestplate": { + "defaultMessage": "Chestplate" + }, + "skin.preview.armor.slot.helmet": { + "defaultMessage": "Helmet" + }, + "skin.preview.armor.slot.leggings": { + "defaultMessage": "Leggings" + }, + "skin.preview.armor.trim-material": { + "defaultMessage": "Trim material" + }, + "skin.preview.armor.trim-material.amethyst": { + "defaultMessage": "Amethyst" + }, + "skin.preview.armor.trim-material.emerald": { + "defaultMessage": "Emerald" + }, + "skin.preview.armor.trim-material.lapis": { + "defaultMessage": "Lapis Lazuli" + }, + "skin.preview.armor.trim-material.quartz": { + "defaultMessage": "Quartz" + }, + "skin.preview.armor.trim-material.redstone": { + "defaultMessage": "Redstone" + }, + "skin.preview.armor.trim-material.resin": { + "defaultMessage": "Resin Brick" + }, + "skin.preview.armor.trim-pattern": { + "defaultMessage": "Trim pattern" + }, + "skin.preview.armor.trim.bolt": { + "defaultMessage": "Bolt Armor Trim" + }, + "skin.preview.armor.trim.coast": { + "defaultMessage": "Coast Armor Trim" + }, + "skin.preview.armor.trim.dune": { + "defaultMessage": "Dune Armor Trim" + }, + "skin.preview.armor.trim.eye": { + "defaultMessage": "Eye Armor Trim" + }, + "skin.preview.armor.trim.flow": { + "defaultMessage": "Flow Armor Trim" + }, + "skin.preview.armor.trim.host": { + "defaultMessage": "Host Armor Trim" + }, + "skin.preview.armor.trim.raiser": { + "defaultMessage": "Raiser Armor Trim" + }, + "skin.preview.armor.trim.rib": { + "defaultMessage": "Rib Armor Trim" + }, + "skin.preview.armor.trim.sentry": { + "defaultMessage": "Sentry Armor Trim" + }, + "skin.preview.armor.trim.shaper": { + "defaultMessage": "Shaper Armor Trim" + }, + "skin.preview.armor.trim.silence": { + "defaultMessage": "Silence Armor Trim" + }, + "skin.preview.armor.trim.snout": { + "defaultMessage": "Snout Armor Trim" + }, + "skin.preview.armor.trim.spire": { + "defaultMessage": "Spire Armor Trim" + }, + "skin.preview.armor.trim.tide": { + "defaultMessage": "Tide Armor Trim" + }, + "skin.preview.armor.trim.vex": { + "defaultMessage": "Vex Armor Trim" + }, + "skin.preview.armor.trim.ward": { + "defaultMessage": "Ward Armor Trim" + }, + "skin.preview.armor.trim.wayfinder": { + "defaultMessage": "Wayfinder Armor Trim" + }, + "skin.preview.armor.trim.wild": { + "defaultMessage": "Wild Armor Trim" + }, + "skin.preview.armor.unequipped": { + "defaultMessage": "Unequipped" + } } diff --git a/packages/ui/src/locales/zh-CN/index.json b/packages/ui/src/locales/zh-CN/index.json index cada412..80ae032 100644 --- a/packages/ui/src/locales/zh-CN/index.json +++ b/packages/ui/src/locales/zh-CN/index.json @@ -4744,5 +4744,143 @@ }, "image-viewer.previous": { "defaultMessage": "上一张图像" - } + }, + "skin.preview.armor.equip-material": { + "message": "为{slot}装备{material}" + }, + "skin.preview.armor.material": { + "message": "盔甲材质" + }, + "skin.preview.armor.material.chainmail": { + "message": "锁链" + }, + "skin.preview.armor.material.copper": { + "message": "铜" + }, + "skin.preview.armor.material.diamond": { + "message": "钻石" + }, + "skin.preview.armor.material.gold": { + "message": "金" + }, + "skin.preview.armor.material.iron": { + "message": "铁" + }, + "skin.preview.armor.material.leather": { + "message": "皮革" + }, + "skin.preview.armor.material.netherite": { + "message": "下界合金" + }, + "skin.preview.armor.material.turtle": { + "message": "海龟壳" + }, + "skin.preview.armor.open": { + "message": "盔甲与纹饰" + }, + "skin.preview.armor.piece": { + "message": "盔甲部位" + }, + "skin.preview.armor.remove-piece": { + "message": "脱下{slot}" + }, + "skin.preview.armor.remove-trim": { + "message": "无盔甲纹饰" + }, + "skin.preview.armor.slot-state": { + "message": "{slot}:{state}" + }, + "skin.preview.armor.slot.boots": { + "message": "靴子" + }, + "skin.preview.armor.slot.chestplate": { + "message": "胸甲" + }, + "skin.preview.armor.slot.helmet": { + "message": "头盔" + }, + "skin.preview.armor.slot.leggings": { + "message": "护腿" + }, + "skin.preview.armor.trim-material": { + "message": "纹饰材料" + }, + "skin.preview.armor.trim-material.amethyst": { + "message": "紫水晶" + }, + "skin.preview.armor.trim-material.emerald": { + "message": "绿宝石" + }, + "skin.preview.armor.trim-material.lapis": { + "message": "青金石" + }, + "skin.preview.armor.trim-material.quartz": { + "message": "下界石英" + }, + "skin.preview.armor.trim-material.redstone": { + "message": "红石" + }, + "skin.preview.armor.trim-material.resin": { + "message": "树脂砖" + }, + "skin.preview.armor.trim-pattern": { + "message": "纹饰图案" + }, + "skin.preview.armor.trim.bolt": { + "message": "镶铆盔甲纹饰" + }, + "skin.preview.armor.trim.coast": { + "message": "海岸盔甲纹饰" + }, + "skin.preview.armor.trim.dune": { + "message": "沙丘盔甲纹饰" + }, + "skin.preview.armor.trim.eye": { + "message": "眼眸盔甲纹饰" + }, + "skin.preview.armor.trim.flow": { + "message": "涡流盔甲纹饰" + }, + "skin.preview.armor.trim.host": { + "message": "雇主盔甲纹饰" + }, + "skin.preview.armor.trim.raiser": { + "message": "牧民盔甲纹饰" + }, + "skin.preview.armor.trim.rib": { + "message": "肋骨盔甲纹饰" + }, + "skin.preview.armor.trim.sentry": { + "message": "哨兵盔甲纹饰" + }, + "skin.preview.armor.trim.shaper": { + "message": "塑造盔甲纹饰" + }, + "skin.preview.armor.trim.silence": { + "message": "幽静盔甲纹饰" + }, + "skin.preview.armor.trim.snout": { + "message": "猪鼻盔甲纹饰" + }, + "skin.preview.armor.trim.spire": { + "message": "尖塔盔甲纹饰" + }, + "skin.preview.armor.trim.tide": { + "message": "潮汐盔甲纹饰" + }, + "skin.preview.armor.trim.vex": { + "message": "恼鬼盔甲纹饰" + }, + "skin.preview.armor.trim.ward": { + "message": "监守盔甲纹饰" + }, + "skin.preview.armor.trim.wayfinder": { + "message": "向导盔甲纹饰" + }, + "skin.preview.armor.trim.wild": { + "message": "荒野盔甲纹饰" + }, + "skin.preview.armor.unequipped": { + "message": "未装备" + } }