Merge pull request #12 from ApTx2012/feat/ui
Sync source to CNB / Sync Git ref (push) Skipped
Axolotl desktop CI / guardrails (push) Canceled after 0s
Axolotl desktop CI / desktop (macos-latest) (push) Canceled after 0s
Axolotl desktop CI / desktop (ubuntu-latest) (push) Canceled after 0s
Axolotl desktop CI / desktop (windows-latest) (push) Canceled after 0s
Axolotl desktop CI / website (push) Canceled after 0s
Repository checks / typos (push) Canceled after 0s
Repository checks / tombi (push) Canceled after 0s
Rust checks / shear (push) Canceled after 0s

feat: 接入皮肤站公告 API
This commit is contained in:
Ax_Tps authored and GitHub committed 2026-10-11 06:13:00 +08:00
commit b776b99f26
3 files changed
+208 -12

No files matched your search

@@ -8,12 +8,14 @@ import {
useVIntl,
} from '@modrinth/ui'
import { renderString } from '@modrinth/utils'
import { fetch as tauriFetch } from '@tauri-apps/plugin-http'
import { openUrl } from '@tauri-apps/plugin-opener'
import { computed, nextTick, onMounted, onUnmounted, reactive, ref, watch } from 'vue'
import {
announcementKey,
isAnnouncementActive,
mapBroadcastAnnouncements,
OPEN_REMOTE_ANNOUNCEMENT_CENTER_EVENT,
parseAnnouncements,
REMOTE_ANNOUNCEMENTS_UPDATED_EVENT,
@@ -21,6 +23,12 @@ import {
safeAnnouncementUrl,
} from '@/helpers/remote-announcements'
import {
requestSkinSiteDownloadToken,
skinSiteStatus,
waitForSkinSiteSession,
} from '@/composables/skin-site-session.ts'
const props = defineProps<{ ready: boolean; previewOnly?: boolean }>()
const { formatMessage } = useVIntl()
const { hasModal } = useModalStack()
@@ -61,7 +69,7 @@ const queuedThisSession = new Set<string>()
const startupNotified = new Set<string>()
let items: RemoteAnnouncement[] = []
let pending: RemoteAnnouncement[] = []
let cacheKey = ''
let cacheKey = 'starlight-remote-announcements-cache-v1'
let cacheLoaded = false
let disposed = false
let interval: ReturnType<typeof setInterval> | undefined
@@ -202,11 +210,35 @@ function loadCache() {
// Ignore malformed or expired cache payloads
}
}
function saveCache(next: RemoteAnnouncement[]) {
if (!cacheKey) return
try {
localStorage.setItem(cacheKey, JSON.stringify({ savedAt: Date.now(), items: next }))
} catch {
// localStorage may be unavailable (private mode / quota)
}
}
async function refresh() {
// Remote fetching is disabled until Starlight has its own announcements API.
// We still load any previously cached items so the center has content to show.
if (disposed) return
loadCache()
if (skinSiteStatus.value !== 'signed-in') return
try {
await waitForSkinSiteSession()
const token = await requestSkinSiteDownloadToken()
const response = await tauriFetch('https://skin.starlight.cool/starlight/skin/broadcast/all', {
method: 'GET',
headers: { Authorization: `Bearer ${token}` },
})
if (!response.ok) return
const data = await response.json()
const parsed = mapBroadcastAnnouncements((data as { payload?: unknown } | null)?.payload)
if (parsed && !disposed) {
sync(parsed, true)
saveCache(parsed)
}
} catch {
// Remote fetch failed; previously cached items remain displayed
}
}
async function openLink(value: unknown) {
const url = safeAnnouncementUrl(value)