로딩 문구와 제목 보정

This commit is contained in:
2026-04-07 16:36:44 +09:00
parent 4fbd4a2845
commit 110242f8e9
7 changed files with 79 additions and 11 deletions

View File

@@ -125,13 +125,19 @@ const effectiveAuthorName = computed(() => {
return (authorAccountName.value || '').trim() || 'unknown'
})
const autoGeneratedTitle = ref(createAutoTierListTitle())
const effectiveTitle = computed(() => {
const saveTitle = computed(() => {
const customTitle = (title.value || '').trim()
if (customTitle) return customTitle
if (persistedTierListId.value) return persistedTierListId.value
if (tierListId.value && tierListId.value !== 'new') return tierListId.value
return autoGeneratedTitle.value
})
const displayTitle = computed(() => {
const customTitle = (title.value || '').trim()
if (customTitle) return customTitle
const topicName = (templateName.value || '').trim()
if (topicName) return `${topicName} 티어표`
if (isEditorLoading.value) return ''
return '제목 없는 티어표'
})
const displayThumbnailUrl = computed(() => thumbnailPreviewUrl.value || (thumbnailSrc.value ? resolveItemSrc({ src: thumbnailSrc.value }) : ''))
const untitledWarning = computed(
() =>
@@ -916,7 +922,7 @@ async function downloadImage() {
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = `${effectiveTitle.value.trim()}.png`
a.download = `${(displayTitle.value || 'tier-maker').trim()}.png`
document.body.appendChild(a)
a.click()
a.remove()
@@ -980,7 +986,7 @@ async function uploadPendingThumbnail() {
}
function buildPayload(existingId) {
const finalTitle = effectiveTitle.value
const finalTitle = saveTitle.value
return {
id: existingId || undefined,
topicId: templateId.value,
@@ -1267,6 +1273,7 @@ function resetEditorStateForRoute() {
groups.value = normalizeLoadedGroups([], columns.value)
pool.value = []
itemsById.value = {}
templateName.value = ''
title.value = ''
persistedTierListId.value = ''
thumbnailSrc.value = ''
@@ -1416,7 +1423,7 @@ watch(
() => {
loadEditorState()
},
{ immediate: true }
{ immediate: true, flush: 'sync' }
)
onMounted(() => {

View File

@@ -20,7 +20,7 @@ const error = ref('')
const brokenThumbnailIds = ref({})
const isTopicLoading = ref(false)
const isListView = computed(() => route.query.view === 'list')
const topicTitle = computed(() => topicName.value || (isTopicLoading.value ? '주제 불러오는 중...' : ''))
const topicTitle = computed(() => topicName.value || '')
const publicTierLists = computed(() => tierLists.value.filter((tierList) => !tierList.isFeatured))
function fmt(ts) {
@@ -88,6 +88,9 @@ watch(
[topicId, query],
() => {
topicName.value = ''
featuredTierLists.value = []
tierLists.value = []
brokenThumbnailIds.value = {}
error.value = ''
loadTierLists()
},
@@ -100,8 +103,16 @@ watch(
<section class="pageHead">
<div class="pageHead__main">
<div class="pageHead__eyebrow">Collection</div>
<h2 class="pageHead__title">{{ topicTitle }}</h2>
<div class="pageHead__desc"> 주제의 공개 티어표를 같은 카드 레이아웃으로 살펴보고 이어서 티어표를 만들 있어요.</div>
<template v-if="isTopicLoading && !topicTitle">
<div class="topicHeadSkeleton" aria-hidden="true">
<div class="topicHeadSkeleton__line topicHeadSkeleton__line--title"></div>
<div class="topicHeadSkeleton__line topicHeadSkeleton__line--desc"></div>
</div>
</template>
<template v-else>
<h2 class="pageHead__title">{{ topicTitle }}</h2>
<div class="pageHead__desc"> 주제의 공개 티어표를 같은 카드 레이아웃으로 살펴보고 이어서 티어표를 만들 있어요.</div>
</template>
</div>
</section>
@@ -194,6 +205,39 @@ watch(
</template>
<style scoped>
.topicHeadSkeleton {
display: grid;
gap: 10px;
}
.topicHeadSkeleton__line {
position: relative;
overflow: hidden;
border-radius: 999px;
background: color-mix(in srgb, var(--theme-surface-soft-2) 88%, transparent);
}
.topicHeadSkeleton__line::after {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.08) 48%, transparent 100%);
transform: translateX(-100%);
animation: topicHeadSkeletonShimmer 1.4s ease-in-out infinite;
}
.topicHeadSkeleton__line--title {
width: min(280px, 72%);
height: 34px;
}
.topicHeadSkeleton__line--desc {
width: min(560px, 94%);
height: 14px;
}
@keyframes topicHeadSkeletonShimmer {
100% {
transform: translateX(100%);
}
}
.panel {
background: transparent;
border-radius: 0;