diff --git a/apps/app-frontend/src/components/ui/skin/EditSkinModal.vue b/apps/app-frontend/src/components/ui/skin/EditSkinModal.vue index 615a06d4e..edafd98d3 100644 --- a/apps/app-frontend/src/components/ui/skin/EditSkinModal.vue +++ b/apps/app-frontend/src/components/ui/skin/EditSkinModal.vue @@ -26,7 +26,7 @@

Texture

-
@@ -85,9 +85,6 @@ - - -
@@ -231,19 +228,35 @@ function show(e: MouseEvent, skin?: Skin) { modal.value?.show(e) } +function showNew(e: MouseEvent, skinTexture: Uint8Array, filename: string) { + mode.value = 'new' + currentSkin.value = null + fileUploadTextureBlob.value = skinTexture + fileName.value = filename + variant.value = 'CLASSIC' + selectedCape.value = undefined + visibleCapeList.value = [] + initVisibleCapeList() + modal.value?.show(e) +} + +function restoreWithNewTexture(skinTexture: Uint8Array, filename: string) { + fileUploadTextureBlob.value = skinTexture + fileName.value = filename + + if (shouldRestoreModal.value) { + setTimeout(() => { + modal.value?.show() + shouldRestoreModal.value = false + }, 0) + } +} + function hide() { modal.value?.hide() setTimeout(() => resetState(), 250) } -async function onTextureSelected(files: FileList|null) { - if (!files?.length) return - const file = files[0] - fileName.value = file.name - const buf = await file.arrayBuffer() - fileUploadTextureBlob.value = new Uint8Array(buf) -} - function selectCape(cape: Cape|undefined) { if (cape && selectedCape.value?.id !== cape.id) { const isInVisibleList = visibleCapeList.value.some(c => c.id === cape.id) @@ -298,17 +311,10 @@ function openSelectCapeModal(e: MouseEvent) { }, 0) } -async function handleDelete() { - try { - if (currentSkin.value?.is_equipped) { - await unequip_skin() - } - await remove_custom_skin(currentSkin.value!) - emit('deleted', currentSkin.value!) - hide() - } catch (err) { - handleError(err) - } +function openUploadSkinModal(e: MouseEvent) { + shouldRestoreModal.value = true + modal.value?.hide() + emit('open-upload-modal', e) } async function save() { @@ -345,9 +351,16 @@ watch(() => props.capes, () => { }, { immediate: true }) const emit = defineEmits<{ - (e:'saved'):void - (e:'deleted', skin: Skin):void + (event: 'saved'): void + (event: 'deleted', skin: Skin): void + (event: 'open-upload-modal', mouseEvent: MouseEvent): void }>() -defineExpose({ show, hide }) +defineExpose({ + show, + showNew, + restoreWithNewTexture, + hide, + shouldRestoreModal +}) diff --git a/apps/app-frontend/src/components/ui/skin/UploadSkinModal.vue b/apps/app-frontend/src/components/ui/skin/UploadSkinModal.vue new file mode 100644 index 000000000..e798031a0 --- /dev/null +++ b/apps/app-frontend/src/components/ui/skin/UploadSkinModal.vue @@ -0,0 +1,101 @@ + + + diff --git a/apps/app-frontend/src/pages/Skins.vue b/apps/app-frontend/src/pages/Skins.vue index c208cbd2d..ad5917bf0 100644 --- a/apps/app-frontend/src/pages/Skins.vue +++ b/apps/app-frontend/src/pages/Skins.vue @@ -9,9 +9,10 @@ import { ConfirmModal } from '@modrinth/ui' import type { Ref } from 'vue'; -import { ref, computed, useTemplateRef, watch, onMounted, onUnmounted, inject, nextTick } from 'vue' +import { ref, computed, useTemplateRef, watch, onMounted, onUnmounted, inject } from 'vue' 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 { get_available_skins, @@ -33,13 +34,13 @@ import type AccountsCard from "@/components/ui/AccountsCard.vue"; const editSkinModal = useTemplateRef('editSkinModal') const selectCapeModal = useTemplateRef('selectCapeModal') +const uploadSkinModal = useTemplateRef('uploadSkinModal') const settings = ref(await getSettings()) const skins = ref([]) const capes = ref([]) const accountsCard = inject('accountsCard') as Ref -const loginInProgress = ref(false); const currentUser = ref(undefined) const currentUserId = ref(undefined) @@ -151,6 +152,33 @@ async function login() { accountsCard.value.setLoginDisabled(false); } +function openUploadSkinModal(e: MouseEvent) { + uploadSkinModal.value?.show(e) +} + +function onSkinFileUploaded(file: File) { + const fakeEvent = new MouseEvent('click') + file.arrayBuffer().then(buf => { + const skinTexture = new Uint8Array(buf) + + if (editSkinModal.value && editSkinModal.value.shouldRestoreModal) { + editSkinModal.value.restoreWithNewTexture(skinTexture, file.name) + } else { + editSkinModal.value?.showNew(fakeEvent, skinTexture, file.name) + } + }) +} + +function onUploadCanceled() { + if (editSkinModal.value && editSkinModal.value.shouldRestoreModal) { + setTimeout(() => { + const fakeEvent = new MouseEvent('click') + editSkinModal.value!.show(fakeEvent) + editSkinModal.value!.shouldRestoreModal = false + }, 0) + } +} + watch( () => selectedSkin.value?.cape_id, () => {} @@ -190,8 +218,10 @@ await Promise.all([loadCapes(), loadSkins(), loadCurrentUser()]) :capes="capes" @saved="onSkinSaved" @deleted="() => loadSkins()" + @open-upload-modal="openUploadSkinModal" /> +