feat: complete hosted mod sync and launcher interface updates
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
Add pack sync markers, tagged mod updates, parallel progress, JWT downloads and retry recovery. Include pending onboarding, about scene, compatibility data pack and download fixes.
This commit is contained in:
1 parent
5d473ebfbc
commit
bc904065c3
63 files changed
+3516
-1059
No files matched your search
@@ -5,7 +5,6 @@ import { getVersion } from '@tauri-apps/api/app'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { defineAsyncComponent, inject, nextTick, onScopeDispose, ref, shallowRef } from 'vue'
|
||||
|
||||
import ColorMineAvatar from '@/components/ui/easteregg/color-mine/ColorMineAvatar.vue'
|
||||
import EasterEggContributorsModal from '@/components/ui/easteregg/EasterEggContributorsModal.vue'
|
||||
import EasterEggGameModal from '@/components/ui/easteregg/EasterEggGameModal.vue'
|
||||
import { AxolotlBrandConfig } from '@/config'
|
||||
@@ -17,7 +16,7 @@ import { type AboutMemberExperience, getAboutMemberExperience } from './about-me
|
||||
const { formatMessage } = useVIntl()
|
||||
const version = await getVersion()
|
||||
const experienceHost = ref<HTMLElement>()
|
||||
const activeMemberExperience = shallowRef<AboutMemberExperience>()
|
||||
const activeMemberExperience = shallowRef<Extract<AboutMemberExperience, { kind: 'scene' }>>()
|
||||
const pressingMemberName = ref<string>()
|
||||
let longPressTimer: number | undefined
|
||||
let pressStart = { x: 0, y: 0 }
|
||||
@@ -41,9 +40,13 @@ function startMemberLongPress(member: TeamMember, event: PointerEvent) {
|
||||
pressStart = { x: event.clientX, y: event.clientY }
|
||||
pressingMemberName.value = member.name
|
||||
longPressTimer = window.setTimeout(async () => {
|
||||
activeMemberExperience.value = experience
|
||||
suppressNextMemberClick = true
|
||||
cancelMemberLongPress()
|
||||
if (experience.kind === 'color-mine') {
|
||||
openColorMine()
|
||||
return
|
||||
}
|
||||
activeMemberExperience.value = experience
|
||||
await nextTick()
|
||||
experienceHost.value?.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
||||
}, experience.longPressDuration)
|
||||
@@ -300,56 +303,37 @@ const messages = defineMessages({
|
||||
{{ formatMessage(messages.developmentTeam) }}
|
||||
</h3>
|
||||
<div class="grid gap-3 sm:grid-cols-2">
|
||||
<template v-for="member in teamMembers" :key="member.name">
|
||||
<div
|
||||
v-if="member.name === 'Disy920'"
|
||||
class="flex min-w-0 items-center gap-3 rounded-xl bg-surface-4 p-3 transition-colors hover:bg-surface-5"
|
||||
>
|
||||
<ColorMineAvatar
|
||||
:src="member.avatarUrl"
|
||||
:name="member.name"
|
||||
:href="member.url"
|
||||
@activate="openColorMine"
|
||||
/>
|
||||
<a
|
||||
:href="member.url"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="flex min-w-0 flex-1 items-center gap-3"
|
||||
>
|
||||
<span class="min-w-0 flex-1 truncate font-semibold text-contrast">{{
|
||||
member.name
|
||||
}}</span>
|
||||
<ExternalIcon v-if="member.url" class="size-4 shrink-0 text-secondary" />
|
||||
</a>
|
||||
</div>
|
||||
<a
|
||||
v-else
|
||||
:href="member.url ?? undefined"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="flex min-w-0 items-center gap-3 rounded-xl bg-surface-4 p-3 transition-colors hover:bg-surface-5"
|
||||
@pointerdown="startMemberLongPress(member, $event)"
|
||||
@pointermove="moveMemberLongPress"
|
||||
@pointerup="cancelMemberLongPress"
|
||||
@pointerleave="cancelMemberLongPress"
|
||||
@click="handleMemberClick"
|
||||
@contextmenu="handleMemberContextMenu(member, $event)"
|
||||
>
|
||||
<Avatar
|
||||
:src="member.avatarUrl"
|
||||
:alt="member.name"
|
||||
size="2.5rem"
|
||||
circle
|
||||
no-shadow
|
||||
loading="lazy"
|
||||
/>
|
||||
<span class="min-w-0 flex-1 truncate font-semibold text-contrast">
|
||||
{{ member.name }}
|
||||
</span>
|
||||
<ExternalIcon v-if="member.url" class="size-4 shrink-0 text-secondary" />
|
||||
</a>
|
||||
</template>
|
||||
<a
|
||||
v-for="member in teamMembers"
|
||||
:key="member.name"
|
||||
:href="member.url ?? undefined"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="flex min-w-0 items-center gap-3 rounded-xl bg-surface-4 p-3 transition-colors hover:bg-surface-5"
|
||||
:class="{ 'member-card-holding': pressingMemberName === member.name }"
|
||||
@pointerdown="startMemberLongPress(member, $event)"
|
||||
@pointermove="moveMemberLongPress"
|
||||
@pointerup="cancelMemberLongPress"
|
||||
@pointercancel="cancelMemberLongPress"
|
||||
@pointerleave="cancelMemberLongPress"
|
||||
@blur="cancelMemberLongPress"
|
||||
@click="handleMemberClick"
|
||||
@contextmenu="handleMemberContextMenu(member, $event)"
|
||||
@dragstart.prevent
|
||||
>
|
||||
<Avatar
|
||||
:src="member.avatarUrl"
|
||||
:alt="member.name"
|
||||
size="2.5rem"
|
||||
circle
|
||||
no-shadow
|
||||
loading="lazy"
|
||||
/>
|
||||
<span class="min-w-0 flex-1 truncate font-semibold text-contrast">
|
||||
{{ member.name }}
|
||||
</span>
|
||||
<ExternalIcon v-if="member.url" class="size-4 shrink-0 text-secondary" />
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
<details class="group pt-4 about-settings-details">
|
||||
@@ -417,6 +401,11 @@ const messages = defineMessages({
|
||||
padding: var(--gap-lg);
|
||||
}
|
||||
|
||||
.member-card-holding {
|
||||
outline: 2px solid var(--color-brand);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.about-page :deep(.rounded-xl.bg-surface-4) {
|
||||
border: 1px solid
|
||||
var(--settings-card-border, color-mix(in srgb, var(--surface-4) 72%, transparent));
|
||||
|
||||
@@ -1,21 +1,31 @@
|
||||
|
||||
import type { Component } from 'vue'
|
||||
|
||||
import AboutEasterEgg from '../AboutEasterEgg.vue'
|
||||
|
||||
export type AboutMemberExperience = {
|
||||
component: Component
|
||||
longPressDuration: number
|
||||
}
|
||||
export type AboutMemberExperience =
|
||||
| {
|
||||
kind: 'scene'
|
||||
component: Component
|
||||
longPressDuration: number
|
||||
}
|
||||
| {
|
||||
kind: 'color-mine'
|
||||
longPressDuration: number
|
||||
}
|
||||
|
||||
// 长按「关于」页成员名字触发的彩蛋体验。
|
||||
// 长按「关于」页成员卡片触发的彩蛋体验。
|
||||
// 下界之星合成彩蛋(AboutEasterEgg.vue),由长按成员名 / 暗号 / Konami 秘技触发。
|
||||
// 若要为特定成员挂载自定义彩蛋,在这里新增条目即可。
|
||||
const memberExperiences: Record<string, AboutMemberExperience> = {
|
||||
'easter-egg': {
|
||||
kind: 'scene',
|
||||
component: AboutEasterEgg,
|
||||
longPressDuration: 800,
|
||||
},
|
||||
'color-mine': {
|
||||
kind: 'color-mine',
|
||||
longPressDuration: 800,
|
||||
},
|
||||
}
|
||||
|
||||
export function getAboutMemberExperience(experience: unknown): AboutMemberExperience | undefined {
|
||||
|
||||
Reference in new issue
Block a user