fix: various improvements
This commit is contained in:
@@ -22,7 +22,7 @@ import { computed, inject, onMounted, onUnmounted, ref, useTemplateRef, watch }
|
||||
import EditSkinModal from '@/components/ui/skin/EditSkinModal.vue'
|
||||
import SelectCapeModal from '@/components/ui/skin/SelectCapeModal.vue'
|
||||
import UploadSkinModal from '@/components/ui/skin/UploadSkinModal.vue'
|
||||
import { handleError } from '@/store/notifications'
|
||||
import { handleError, useNotifications } from '@/store/notifications'
|
||||
import type { Cape, Skin } from '@/helpers/skins.ts'
|
||||
import {
|
||||
normalize_skin_texture,
|
||||
@@ -48,6 +48,8 @@ const editSkinModal = useTemplateRef('editSkinModal')
|
||||
const selectCapeModal = useTemplateRef('selectCapeModal')
|
||||
const uploadSkinModal = useTemplateRef('uploadSkinModal')
|
||||
|
||||
const notifications = useNotifications()
|
||||
|
||||
const settings = ref(await getSettings())
|
||||
const skins = ref<Skin[]>([])
|
||||
const capes = ref<Cape[]>([])
|
||||
@@ -149,7 +151,16 @@ async function changeSkin(newSkin: Skin) {
|
||||
} catch (error) {
|
||||
selectedSkin.value = previousSkin
|
||||
skins.value = previousSkinsList
|
||||
handleError(error)
|
||||
|
||||
if ((error as { message?: string })?.message?.includes('429 Too Many Requests')) {
|
||||
notifications.addNotification({
|
||||
type: 'error',
|
||||
title: 'Slow down!',
|
||||
text: "You're changing your skin too frequently. Mojang's servers have temporarily blocked further requests. Please wait a moment before trying again.",
|
||||
})
|
||||
} else {
|
||||
handleError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +180,16 @@ async function handleCapeSelected(cape: Cape | undefined) {
|
||||
} catch (error) {
|
||||
defaultCape.value = previousDefaultCape
|
||||
capes.value = previousCapesList
|
||||
handleError(error)
|
||||
|
||||
if ((error as { message?: string })?.message?.includes('429 Too Many Requests')) {
|
||||
notifications.addNotification({
|
||||
type: 'error',
|
||||
title: 'Slow down!',
|
||||
text: "You're changing your cape too frequently. Mojang's servers have temporarily blocked further requests. Please wait a moment before trying again.",
|
||||
})
|
||||
} else {
|
||||
handleError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ const props = withDefaults(
|
||||
baseAnimation: 'idle',
|
||||
randomAnimations: ['idle_sub_1', 'idle_sub_2', 'idle_sub_3'],
|
||||
randomAnimationInterval: 8000,
|
||||
transitionDuration: 0.5,
|
||||
transitionDuration: 0.2,
|
||||
}),
|
||||
},
|
||||
)
|
||||
@@ -204,11 +204,14 @@ function initializeAnimations(loadedScene: THREE.Object3D, clips: THREE.Animatio
|
||||
|
||||
clips.forEach((clip) => {
|
||||
const action = mixer.value!.clipAction(clip)
|
||||
|
||||
action.setLoop(THREE.LoopOnce, 1)
|
||||
action.clampWhenFinished = true
|
||||
actions.value[clip.name] = action
|
||||
console.log(`Loaded animation: ${clip.name}`)
|
||||
})
|
||||
|
||||
if (baseAnimation.value && actions.value[baseAnimation.value]) {
|
||||
actions.value[baseAnimation.value].setLoop(THREE.LoopRepeat, Infinity)
|
||||
playAnimation(baseAnimation.value)
|
||||
setupRandomAnimationLoop()
|
||||
} else {
|
||||
@@ -216,7 +219,7 @@ function initializeAnimations(loadedScene: THREE.Object3D, clips: THREE.Animatio
|
||||
|
||||
const firstAnimationName = Object.keys(actions.value)[0]
|
||||
if (firstAnimationName) {
|
||||
console.log(`Playing first available animation: ${firstAnimationName}`)
|
||||
actions.value[firstAnimationName].setLoop(THREE.LoopRepeat, Infinity)
|
||||
playAnimation(firstAnimationName)
|
||||
}
|
||||
}
|
||||
@@ -229,6 +232,12 @@ function playAnimation(name: string) {
|
||||
}
|
||||
|
||||
const action = actions.value[name]
|
||||
|
||||
if (currentAnimation.value === name && action.isRunning() && name !== baseAnimation.value) {
|
||||
console.log(`Animation "${name}" is already running, ignoring request`)
|
||||
return false
|
||||
}
|
||||
|
||||
const transitionDuration = props.animationConfig.transitionDuration || 0.3
|
||||
|
||||
Object.entries(actions.value).forEach(([actionName, actionInstance]) => {
|
||||
@@ -238,12 +247,35 @@ function playAnimation(name: string) {
|
||||
})
|
||||
|
||||
action.reset()
|
||||
action.setLoop(THREE.LoopRepeat, Infinity)
|
||||
|
||||
if (name === baseAnimation.value) {
|
||||
action.setLoop(THREE.LoopRepeat, Infinity)
|
||||
} else {
|
||||
action.setLoop(THREE.LoopOnce, 1)
|
||||
action.clampWhenFinished = true
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const onFinished = (event: any) => {
|
||||
if (event.action === action) {
|
||||
mixer.value?.removeEventListener('finished', onFinished)
|
||||
if (currentAnimation.value === name && baseAnimation.value) {
|
||||
action.fadeOut(transitionDuration)
|
||||
const baseAction = actions.value[baseAnimation.value]
|
||||
baseAction.reset()
|
||||
baseAction.fadeIn(transitionDuration)
|
||||
baseAction.play()
|
||||
currentAnimation.value = baseAnimation.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mixer.value.addEventListener('finished', onFinished)
|
||||
}
|
||||
|
||||
action.fadeIn(transitionDuration)
|
||||
action.play()
|
||||
|
||||
currentAnimation.value = name
|
||||
console.log(`Playing animation: ${name}`)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -265,15 +297,48 @@ function setupRandomAnimationLoop() {
|
||||
}
|
||||
|
||||
function playRandomAnimation(name: string) {
|
||||
if (!playAnimation(name)) return
|
||||
if (!mixer.value || !actions.value[name]) {
|
||||
console.warn(`Animation "${name}" not found!`)
|
||||
return
|
||||
}
|
||||
|
||||
const animationDuration = actions.value[name].getClip().duration * 1000
|
||||
const action = actions.value[name]
|
||||
|
||||
setTimeout(() => {
|
||||
if (currentAnimation.value === name && baseAnimation.value) {
|
||||
playAnimation(baseAnimation.value)
|
||||
if (currentAnimation.value === name && action.isRunning()) {
|
||||
console.log(`Animation "${name}" is already running, ignoring request`)
|
||||
return
|
||||
}
|
||||
|
||||
const transitionDuration = props.animationConfig.transitionDuration || 0.3
|
||||
|
||||
if (baseAnimation.value && actions.value[baseAnimation.value].isRunning()) {
|
||||
actions.value[baseAnimation.value].fadeOut(transitionDuration)
|
||||
}
|
||||
|
||||
action.reset()
|
||||
action.setLoop(THREE.LoopOnce, 1)
|
||||
action.clampWhenFinished = true
|
||||
action.fadeIn(transitionDuration)
|
||||
action.play()
|
||||
|
||||
currentAnimation.value = name
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const onFinished = (event: any) => {
|
||||
if (event.action === action) {
|
||||
mixer.value?.removeEventListener('finished', onFinished)
|
||||
if (currentAnimation.value === name && baseAnimation.value) {
|
||||
action.fadeOut(transitionDuration)
|
||||
const baseAction = actions.value[baseAnimation.value]
|
||||
baseAction.reset()
|
||||
baseAction.fadeIn(transitionDuration)
|
||||
baseAction.play()
|
||||
currentAnimation.value = baseAnimation.value
|
||||
}
|
||||
}
|
||||
}, animationDuration + 500)
|
||||
}
|
||||
|
||||
mixer.value.addEventListener('finished', onFinished)
|
||||
}
|
||||
|
||||
function stopAnimations() {
|
||||
|
||||
Reference in New Issue
Block a user