fix: 修复首次启动公告未弹出并添加侧栏公告入口
Axolotl desktop CI / guardrails (push) Has been cancelled
Axolotl desktop CI / desktop (macos-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (ubuntu-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (windows-latest) (push) Has been cancelled
Axolotl desktop CI / website (push) Has been cancelled
Repository checks / typos (push) Has been cancelled
Repository checks / tombi (push) Has been cancelled
Rust checks / shear (push) Has been cancelled
Sync source to CNB / Sync Git ref (push) Has been cancelled
Axolotl desktop CI / guardrails (push) Has been cancelled
Axolotl desktop CI / desktop (macos-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (ubuntu-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (windows-latest) (push) Has been cancelled
Axolotl desktop CI / website (push) Has been cancelled
Repository checks / typos (push) Has been cancelled
Repository checks / tombi (push) Has been cancelled
Rust checks / shear (push) Has been cancelled
Sync source to CNB / Sync Git ref (push) Has been cancelled
首次启动公告未弹出,原因有二:
- StartupAnnouncementModal 未 defineExpose({ show }),父组件调用
show() 静默失败;
- 展示逻辑在调用 show() 之前就写入了 localStorage 的"已读"标记,
一旦 show 失败便永久不再弹出。
修复:
- 组件补上 defineExpose({ show });
- 展示逻辑改为"确认能拿到组件实例并 show() 成功后再写标记",
组件尚未挂载时于 nextTick 重试。
同时把首页侧栏的"每日小挑战"替换为可点击的"公告"入口
(HomeAnnouncementEntry),点击通过 provide/inject 的
showStartupAnnouncement 打开公告弹窗。
This commit is contained in:
1 parent
bb6b8cb8d2
commit
913e0071dd
4 files changed
+55
-6
No files matched your search
@@ -63,7 +63,7 @@ import { openUrl } from '@tauri-apps/plugin-opener'
|
|||||||
import { type as getOsType } from '@tauri-apps/plugin-os'
|
import { type as getOsType } from '@tauri-apps/plugin-os'
|
||||||
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state'
|
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state'
|
||||||
import { hideAllPoppers } from 'floating-vue'
|
import { hideAllPoppers } from 'floating-vue'
|
||||||
import { computed, onMounted, onUnmounted, provide, ref, watch } from 'vue'
|
import { computed, nextTick, onMounted, onUnmounted, provide, ref, watch } from 'vue'
|
||||||
import { type RouteLocationNormalizedLoaded, RouterView, useRoute, useRouter } from 'vue-router'
|
import { type RouteLocationNormalizedLoaded, RouterView, useRoute, useRouter } from 'vue-router'
|
||||||
|
|
||||||
import InstancePlayerModal from '@/components/instance/InstancePlayerModal.vue'
|
import InstancePlayerModal from '@/components/instance/InstancePlayerModal.vue'
|
||||||
@@ -1271,6 +1271,7 @@ provide(
|
|||||||
)
|
)
|
||||||
provide('previewMinecraftCrashModal', () => minecraftCrashModal.value?.showPreview())
|
provide('previewMinecraftCrashModal', () => minecraftCrashModal.value?.showPreview())
|
||||||
provide('showLauncherPopup', (_request: unknown) => {})
|
provide('showLauncherPopup', (_request: unknown) => {})
|
||||||
|
provide('showStartupAnnouncement', () => startupAnnouncementModal.value?.show())
|
||||||
|
|
||||||
const stateFailed = ref(false)
|
const stateFailed = ref(false)
|
||||||
stateInitialization
|
stateInitialization
|
||||||
@@ -1544,13 +1545,27 @@ const startupAnnouncementModal = ref<InstanceType<typeof StartupAnnouncementModa
|
|||||||
const STARTUP_ANNOUNCEMENT_KEY = 'starlight-startup-announcement-seen-v1'
|
const STARTUP_ANNOUNCEMENT_KEY = 'starlight-startup-announcement-seen-v1'
|
||||||
|
|
||||||
function maybeShowStartupAnnouncement() {
|
function maybeShowStartupAnnouncement() {
|
||||||
|
let alreadySeen = false
|
||||||
|
try {
|
||||||
|
alreadySeen = localStorage.getItem(STARTUP_ANNOUNCEMENT_KEY) !== null
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Failed to read startup announcement flag', error)
|
||||||
|
}
|
||||||
|
if (alreadySeen) return
|
||||||
|
|
||||||
|
const modal = startupAnnouncementModal.value
|
||||||
|
if (!modal) {
|
||||||
|
// The modal component has not mounted yet; try again on the next tick.
|
||||||
|
void nextTick(maybeShowStartupAnnouncement)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
modal.show()
|
||||||
try {
|
try {
|
||||||
if (localStorage.getItem(STARTUP_ANNOUNCEMENT_KEY)) return
|
|
||||||
localStorage.setItem(STARTUP_ANNOUNCEMENT_KEY, '1')
|
localStorage.setItem(STARTUP_ANNOUNCEMENT_KEY, '1')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Failed to read/write startup announcement flag', error)
|
console.warn('Failed to write startup announcement flag', error)
|
||||||
}
|
}
|
||||||
startupAnnouncementModal.value?.show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Drop import system ──────────────────────────────────────────────────
|
// ── Drop import system ──────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { NewspaperIcon, RightArrowIcon } from '@modrinth/assets'
|
||||||
|
import { inject } from 'vue'
|
||||||
|
|
||||||
|
const showAnnouncement = inject<(() => void) | undefined>('showStartupAnnouncement')
|
||||||
|
|
||||||
|
function open() {
|
||||||
|
showAnnouncement?.()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<section
|
||||||
|
class="flex min-w-0 flex-col gap-3 border-0 border-b-[1px] border-solid border-[--brand-gradient-border] p-4"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="group flex w-full cursor-pointer flex-col gap-2 border-0 bg-transparent p-0 text-left"
|
||||||
|
@click="open"
|
||||||
|
>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<NewspaperIcon class="size-4 shrink-0 text-secondary" aria-hidden="true" />
|
||||||
|
<h2 class="m-0 truncate text-lg">公告</h2>
|
||||||
|
<RightArrowIcon
|
||||||
|
class="ml-auto size-4 shrink-0 text-secondary transition-transform group-hover:translate-x-0.5"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p class="m-0 text-sm leading-relaxed text-secondary">点击查看最新公告</p>
|
||||||
|
</button>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
@@ -30,6 +30,8 @@ function hide() {
|
|||||||
function openLink(url: string) {
|
function openLink(url: string) {
|
||||||
void openUrl(url)
|
void openUrl(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defineExpose({ show })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { computed, onUnmounted, ref } from 'vue'
|
|||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
|
||||||
import { getActivePlayerName } from '@/components/home/home-utils'
|
import { getActivePlayerName } from '@/components/home/home-utils'
|
||||||
import HomeDailyChallenge from '@/components/home/HomeDailyChallenge.vue'
|
import HomeAnnouncementEntry from '@/components/home/HomeAnnouncementEntry.vue'
|
||||||
import HomeInstancePickerModal from '@/components/home/HomeInstancePickerModal.vue'
|
import HomeInstancePickerModal from '@/components/home/HomeInstancePickerModal.vue'
|
||||||
import HomeLaunchProgress from '@/components/home/HomeLaunchProgress.vue'
|
import HomeLaunchProgress from '@/components/home/HomeLaunchProgress.vue'
|
||||||
import HomeMinecraftNews from '@/components/home/HomeMinecraftNews.vue'
|
import HomeMinecraftNews from '@/components/home/HomeMinecraftNews.vue'
|
||||||
@@ -202,7 +202,7 @@ onUnmounted(() => {
|
|||||||
>
|
>
|
||||||
<HomeLaunchProgress />
|
<HomeLaunchProgress />
|
||||||
<HomePlayInsights />
|
<HomePlayInsights />
|
||||||
<HomeDailyChallenge />
|
<HomeAnnouncementEntry />
|
||||||
<HomeMinecraftNews />
|
<HomeMinecraftNews />
|
||||||
</div>
|
</div>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
|
|||||||
Reference in new issue
Block a user