This commit is contained in:
1 parent
26a29714b2
commit
0af663ac8c
4 files changed
+10450
-10366
No files matched your search
@@ -294,6 +294,9 @@ async function buildPlayer(entry: {
|
||||
export function requestSkinSitePlayers(): Promise<SkinSitePlayer[]> {
|
||||
if (playersRequest) return playersRequest
|
||||
if (status.value !== 'signed-in' || !user.value) {
|
||||
// Keep the status meaningful so the UI does not spin forever: an
|
||||
// unauthenticated request means "not loaded yet", not "loading".
|
||||
playersStatus.value = 'idle'
|
||||
return Promise.reject(new Error('请先登录 StarLight 皮肤站。'))
|
||||
}
|
||||
|
||||
@@ -319,6 +322,16 @@ export function requestSkinSitePlayers(): Promise<SkinSitePlayer[]> {
|
||||
return playersRequest
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop any in-flight or cached player request and fetch again. Used by views
|
||||
* that need to recover after a failed load (e.g. signing in from the skin
|
||||
* page while the first attempt raced the session check).
|
||||
*/
|
||||
export function reloadSkinSitePlayers(): Promise<SkinSitePlayer[]> {
|
||||
playersRequest = null
|
||||
return requestSkinSitePlayers()
|
||||
}
|
||||
|
||||
export function selectSkinSitePlayer(playerId: string | null) {
|
||||
if (playerId === null) {
|
||||
selectedPlayerId.value = null
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -39,6 +39,7 @@ import SkinListSkeleton from '@/components/ui/skin/SkinListSkeleton.vue'
|
||||
import VirtualSkinSectionList from '@/components/ui/skin/VirtualSkinSectionList.vue'
|
||||
import {
|
||||
openSkinSiteLogin,
|
||||
reloadSkinSitePlayers,
|
||||
requestSkinSitePlayers,
|
||||
requestSkinSiteSkinUpdate,
|
||||
selectedSkinSitePlayerId,
|
||||
@@ -214,6 +215,18 @@ const messages = defineMessages({
|
||||
id: 'app.skins.skin-site-account.empty-description',
|
||||
defaultMessage: 'This skin site account does not have an available player profile yet.',
|
||||
},
|
||||
errorSkinSitePlayersTitle: {
|
||||
id: 'app.skins.skin-site-account.error-title',
|
||||
defaultMessage: 'Could not load your players',
|
||||
},
|
||||
errorSkinSitePlayersDescription: {
|
||||
id: 'app.skins.skin-site-account.error-description',
|
||||
defaultMessage: 'Check your connection and try again.',
|
||||
},
|
||||
retryButton: {
|
||||
id: 'app.skins.skin-site-account.retry',
|
||||
defaultMessage: 'Retry',
|
||||
},
|
||||
offlineCompatibility: {
|
||||
id: 'app.skins.offline-account.compatibility',
|
||||
defaultMessage:
|
||||
@@ -982,6 +995,37 @@ watch(
|
||||
},
|
||||
)
|
||||
|
||||
// Load the player list whenever the session becomes available or the view is
|
||||
// opened while the list never started loading. Without this the skin page can
|
||||
// sit on "loading" forever when the first request raced the session check.
|
||||
function ensureSkinSitePlayersLoaded() {
|
||||
if (!skinSiteUser.value) return
|
||||
if (skinSitePlayersStatus.value === 'checking') return
|
||||
if (skinSitePlayersStatus.value === 'ready' && skinSitePlayers.value.length) return
|
||||
if (skinSitePlayersStatus.value === 'error') return
|
||||
void reloadSkinSitePlayers().catch((error) => {
|
||||
console.warn('Failed to load skin site players:', error)
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [skinSiteUser.value?.uuid, skinSiteStatus.value] as const,
|
||||
([uuid, sessionStatus]) => {
|
||||
if (uuid && sessionStatus === 'signed-in') ensureSkinSitePlayersLoaded()
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
watch(skinSitePlayersStatus, (value) => {
|
||||
if (value === 'idle' && skinSiteUser.value) ensureSkinSitePlayersLoaded()
|
||||
})
|
||||
|
||||
function retrySkinSitePlayers() {
|
||||
void reloadSkinSitePlayers().catch((error) => {
|
||||
console.warn('Failed to reload skin site players:', error)
|
||||
})
|
||||
}
|
||||
|
||||
function getBakedSkinTextures(skin: Skin): RenderResult | undefined {
|
||||
const key = `${skin.texture_key}+${skin.variant}+${skin.cape_id ?? 'no-cape'}`
|
||||
return skinBlobUrlMap.get(key)
|
||||
@@ -1436,22 +1480,26 @@ await loadSkins()
|
||||
<h1 class="text-3xl font-extrabold m-0">
|
||||
{{
|
||||
formatMessage(
|
||||
skinSiteUser
|
||||
? skinSitePlayersStatus === 'checking' || skinSitePlayersStatus === 'idle'
|
||||
!skinSiteUser
|
||||
? messages.signInTitle
|
||||
: skinSitePlayersStatus === 'error'
|
||||
? messages.errorSkinSitePlayersTitle
|
||||
: skinSitePlayersStatus === 'checking' || skinSitePlayersStatus === 'idle'
|
||||
? messages.loadingSkinSitePlayersTitle
|
||||
: messages.noSkinSitePlayersTitle
|
||||
: messages.signInTitle,
|
||||
: messages.noSkinSitePlayersTitle,
|
||||
)
|
||||
}}
|
||||
</h1>
|
||||
<p class="text-lg m-0">
|
||||
{{
|
||||
formatMessage(
|
||||
skinSiteUser
|
||||
? skinSitePlayersStatus === 'checking' || skinSitePlayersStatus === 'idle'
|
||||
!skinSiteUser
|
||||
? messages.signInDescription
|
||||
: skinSitePlayersStatus === 'error'
|
||||
? messages.errorSkinSitePlayersDescription
|
||||
: skinSitePlayersStatus === 'checking' || skinSitePlayersStatus === 'idle'
|
||||
? messages.loadingSkinSitePlayersDescription
|
||||
: messages.noSkinSitePlayersDescription
|
||||
: messages.signInDescription,
|
||||
: messages.noSkinSitePlayersDescription,
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
@@ -1462,6 +1510,11 @@ await loadSkins()
|
||||
"
|
||||
class="h-8 w-8 animate-spin text-brand"
|
||||
/>
|
||||
<ButtonStyled v-if="skinSiteUser && skinSitePlayersStatus === 'error'" color="brand">
|
||||
<button @click="retrySkinSitePlayers">
|
||||
{{ formatMessage(messages.retryButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-if="!offline && !skinSiteUser" color="brand">
|
||||
<button @click="loginToSkinSite">
|
||||
<LogInIcon />
|
||||
|
||||
Reference in new issue
Block a user