feat:移除了弹窗,服务器添加sls

This commit is contained in:
AxTps committed 2026-09-08 22:39:45 +08:00
commit 6a295f9a7a
4082 files changed
+1322534

No files matched your search

@@ -0,0 +1,182 @@
<script setup lang="ts">
import { ExternalIcon } from '@modrinth/assets'
import { Admonition, BulletDivider, ButtonStyled, defineMessages, useVIntl } from '@modrinth/ui'
import { openUrl } from '@tauri-apps/plugin-opener'
import { computed } from 'vue'
import {
ANNOUNCEMENT_CHANGE_TYPES,
type AnnouncementChangeType,
getLocalizedAnnouncementText,
type LauncherAnnouncement,
} from '@/announcements/catalog'
import i18n from '@/i18n.config'
const props = withDefaults(
defineProps<{
announcement?: LauncherAnnouncement
version?: string | null
externalUrl?: string
showHeader?: boolean
}>(),
{
announcement: undefined,
version: null,
externalUrl: undefined,
showHeader: true,
},
)
const { formatMessage } = useVIntl()
const messages = defineMessages({
unknownTitle: {
id: 'app.update-announcement.unknown-title',
defaultMessage: 'Axolotl Launcher was updated',
},
unknownBody: {
id: 'app.update-announcement.unknown-body',
defaultMessage:
'This version does not have a bundled announcement yet. Visit the website for the full changelog.',
},
version: {
id: 'app.update-announcement.version',
defaultMessage: 'Version {version}',
},
openChangelog: {
id: 'app.update-announcement.open-changelog',
defaultMessage: 'Open full changelog',
},
notes: {
id: 'app.update-announcement.notes',
defaultMessage: 'Notes',
},
added: {
id: 'app.update-announcement.category.added',
defaultMessage: 'Added',
},
changed: {
id: 'app.update-announcement.category.changed',
defaultMessage: 'Changed',
},
deprecated: {
id: 'app.update-announcement.category.deprecated',
defaultMessage: 'Deprecated',
},
removed: {
id: 'app.update-announcement.category.removed',
defaultMessage: 'Removed',
},
fixed: {
id: 'app.update-announcement.category.fixed',
defaultMessage: 'Fixed',
},
security: {
id: 'app.update-announcement.category.security',
defaultMessage: 'Security',
},
})
const categoryClasses: Record<AnnouncementChangeType, string> = {
added: 'bg-brand-green',
changed: 'bg-brand-blue',
deprecated: 'bg-brand-orange',
removed: 'bg-brand-red',
fixed: 'bg-brand-purple',
security: 'bg-brand-orange',
}
const locale = computed(() => i18n.global.locale.value)
const title = computed(() =>
props.announcement
? getLocalizedAnnouncementText(props.announcement.title, locale.value)
: formatMessage(messages.unknownTitle),
)
const versionLabel = computed(() =>
formatMessage(messages.version, { version: props.announcement?.version ?? props.version ?? '—' }),
)
const categoryRows = computed(() =>
ANNOUNCEMENT_CHANGE_TYPES.flatMap((type) => {
const changes = props.announcement?.changes[type]
if (!changes?.length) return []
return [
{
type,
label: formatMessage(messages[type]),
className: categoryClasses[type],
changes: changes.map((change) => getLocalizedAnnouncementText(change, locale.value)),
},
]
}),
)
async function openChangelog() {
if (props.externalUrl) await openUrl(props.externalUrl)
}
</script>
<template>
<div class="flex min-w-0 flex-col gap-5 text-primary">
<header v-if="showHeader" class="flex min-w-0 flex-col gap-2">
<h2 class="m-0 break-words text-xl font-semibold text-contrast">{{ title }}</h2>
<div class="flex flex-wrap items-center gap-2 text-sm text-secondary">
<span>{{ versionLabel }}</span>
<BulletDivider v-if="announcement?.publishedAt" />
<time v-if="announcement?.publishedAt" :datetime="announcement.publishedAt">
{{ announcement.publishedAt }}
</time>
</div>
</header>
<div v-if="categoryRows.length" class="flex flex-col">
<section
v-for="(category, index) in categoryRows"
:key="category.type"
class="announcement-category grid grid-cols-1 gap-2 py-4 sm:grid-cols-[7rem_minmax(0,1fr)] sm:gap-5"
:class="{ 'border-t-0 pt-0': index === 0 }"
>
<h3 class="m-0 flex items-center gap-2 text-sm font-semibold text-secondary">
<span
class="size-2 shrink-0 rounded-full"
:class="category.className"
aria-hidden="true"
/>
{{ category.label }}
</h3>
<ul class="m-0 flex list-disc flex-col gap-2 pl-5 leading-relaxed text-primary">
<li v-for="change in category.changes" :key="change">{{ change }}</li>
</ul>
</section>
</div>
<Admonition v-else type="info" :body="formatMessage(messages.unknownBody)" />
<div v-if="announcement?.notes" class="announcement-notes">
<h3 class="m-0 mb-2 text-sm font-semibold text-secondary">
{{ formatMessage(messages.notes) }}
</h3>
<p class="m-0 leading-relaxed text-primary">
{{ getLocalizedAnnouncementText(announcement.notes, locale) }}
</p>
</div>
<ButtonStyled v-if="externalUrl" color="brand" type="outlined" class="self-start">
<button type="button" @click="openChangelog">
<ExternalIcon />
{{ formatMessage(messages.openChangelog) }}
</button>
</ButtonStyled>
</div>
</template>
<style scoped>
.announcement-category {
border-top: 1px solid
var(--settings-divider, color-mix(in srgb, var(--surface-4) 55%, transparent));
}
.announcement-notes {
padding-top: var(--gap-md);
border-top: 1px solid
var(--settings-divider, color-mix(in srgb, var(--surface-4) 55%, transparent));
}
</style>
@@ -0,0 +1,142 @@
<script setup lang="ts">
import { CalendarIcon, HistoryIcon } from '@modrinth/assets'
import { Accordion, defineMessages, TagItem, useVIntl } from '@modrinth/ui'
import { computed } from 'vue'
import {
getAnnouncementByVersion,
getAnnouncements,
getLocalizedAnnouncementText,
} from '@/announcements/catalog'
import { AxolotlBrandConfig } from '@/config'
import i18n from '@/i18n.config'
import UpdateAnnouncementContent from './UpdateAnnouncementContent.vue'
const props = defineProps<{
currentVersion: string
}>()
const { formatMessage } = useVIntl()
const messages = defineMessages({
title: {
id: 'app.settings.updates.announcements.title',
defaultMessage: 'Update announcements',
},
description: {
id: 'app.settings.updates.announcements.description',
defaultMessage: 'See what changed in this version and browse previous releases.',
},
history: {
id: 'app.settings.updates.announcements.history',
defaultMessage: 'Version history',
},
empty: {
id: 'app.settings.updates.announcements.empty',
defaultMessage: 'No bundled update announcements are available.',
},
})
const locale = computed(() => i18n.global.locale.value)
const launcherAnnouncements = getAnnouncements()
const currentAnnouncement = computed(() => getAnnouncementByVersion(props.currentVersion))
const historyAnnouncements = computed(() =>
launcherAnnouncements.filter((announcement) => announcement.id !== currentAnnouncement.value?.id),
)
</script>
<template>
<section class="update-announcement-history">
<div class="flex min-w-0 flex-col gap-1">
<h2 class="m-0 text-lg font-semibold text-contrast">
{{ formatMessage(messages.title) }}
</h2>
<p class="m-0 leading-relaxed text-secondary">
{{ formatMessage(messages.description) }}
</p>
</div>
<div class="min-w-0">
<UpdateAnnouncementContent
:announcement="currentAnnouncement"
:version="currentVersion"
:external-url="currentAnnouncement?.externalUrl ?? AxolotlBrandConfig.website"
/>
</div>
<div class="flex min-w-0 flex-col gap-3">
<h3 class="m-0 flex items-center gap-2 text-base font-semibold text-contrast">
<HistoryIcon aria-hidden="true" class="size-4 text-secondary" />
{{ formatMessage(messages.history) }}
</h3>
<p v-if="historyAnnouncements.length === 0" class="m-0 text-sm text-secondary">
{{ formatMessage(messages.empty) }}
</p>
<div v-else class="flex min-w-0 flex-col gap-2">
<Accordion
v-for="announcement in historyAnnouncements"
:key="announcement.id"
class="update-announcement-history-item hover:border-surface-4 focus-within:border-surface-4"
button-class="group flex w-full cursor-pointer items-center gap-3 border-0 bg-transparent px-4 py-3 text-left"
>
<template #title>
<div class="flex min-w-0 flex-1 items-center gap-3">
<div class="flex min-w-0 flex-1 flex-col gap-1">
<span
class="truncate font-semibold text-primary transition-colors group-hover:text-contrast"
>
{{ getLocalizedAnnouncementText(announcement.title, locale) }}
</span>
<div class="flex flex-wrap items-center gap-x-2 gap-y-1 text-sm text-secondary">
<TagItem class="px-1.5 py-0.5 text-xs">v{{ announcement.version }}</TagItem>
<span class="flex items-center gap-1">
<CalendarIcon aria-hidden="true" class="size-3.5" />
<time :datetime="announcement.publishedAt">{{ announcement.publishedAt }}</time>
</span>
</div>
</div>
</div>
</template>
<div class="update-announcement-history-item-content">
<UpdateAnnouncementContent
:announcement="announcement"
:show-header="false"
:external-url="announcement.externalUrl"
/>
</div>
</Accordion>
</div>
</div>
</section>
</template>
<style scoped>
.update-announcement-history {
display: flex;
min-width: 0;
flex-direction: column;
gap: var(--gap-xl);
padding: var(--gap-xl);
border: 1px solid
var(--settings-card-border, color-mix(in srgb, var(--surface-4) 72%, transparent));
border-radius: var(--radius-md);
background: var(--surface-2);
}
.update-announcement-history-item {
min-width: 0;
overflow: hidden;
border: 1px solid
var(--settings-card-border, color-mix(in srgb, var(--surface-4) 72%, transparent));
border-radius: var(--radius-sm);
background: var(--surface-3);
transition: border-color 120ms ease;
}
.update-announcement-history-item-content {
padding: var(--gap-lg);
border-top: 1px solid
var(--settings-divider, color-mix(in srgb, var(--surface-4) 55%, transparent));
}
</style>