댓글 읽음과 즐겨찾기 정리

This commit is contained in:
2026-04-07 14:24:16 +09:00
parent 31e266e79e
commit 68481c3ebf
7 changed files with 70 additions and 20 deletions

View File

@@ -11,8 +11,9 @@ const router = useRouter()
const toast = useToast()
const notifications = ref([])
const isLoading = ref(false)
const unreadOnly = ref(false)
const unreadOnly = ref(true)
const isMarkingAllRead = ref(false)
const markingNotificationId = ref('')
const unreadCount = computed(() => notifications.value.filter((item) => !item.isRead).length)
@@ -75,16 +76,30 @@ async function loadInbox() {
async function markOneAsRead(notificationId) {
const target = notifications.value.find((item) => item.id === notificationId)
if (!target || target.isRead) return
const original = notifications.value.map((item) => ({ ...item }))
target.isRead = true
if (unreadOnly.value) {
notifications.value = notifications.value.filter((item) => item.id !== notificationId)
}
emitUnreadCount(unreadCount.value)
try {
await api.markCommentInboxRead({ notificationIds: [notificationId] })
} catch (error) {
target.isRead = false
notifications.value = original
emitUnreadCount(unreadCount.value)
}
}
async function markNotificationButton(notificationId) {
if (!notificationId || markingNotificationId.value) return
markingNotificationId.value = notificationId
try {
await markOneAsRead(notificationId)
} finally {
markingNotificationId.value = ''
}
}
async function markAllAsRead() {
if (!unreadCount.value) return
isMarkingAllRead.value = true
@@ -181,7 +196,15 @@ watch(unreadOnly, loadInbox)
<div class="commentInboxCard__title">{{ notificationTitle(notification) }}</div>
<div class="commentInboxCard__status">
<span v-if="!notification.isRead" class="commentInboxCard__dot" aria-label="안 읽음"></span>
<span class="commentInboxCard__badge">{{ notification.notificationType === 'comment_reply' ? '답글' : '댓글' }}</span>
<button
v-if="!notification.isRead"
class="commentInboxCard__badge"
type="button"
:disabled="!!markingNotificationId"
@click.stop="markNotificationButton(notification.id)"
>
{{ markingNotificationId === notification.id ? '처리 중...' : '읽음 처리' }}
</button>
</div>
</div>
<div class="commentInboxCard__thread">
@@ -373,13 +396,21 @@ watch(unreadOnly, loadInbox)
.commentInboxCard__badge {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 28px;
padding: 0 12px;
border-radius: 999px;
border: 1px solid color-mix(in srgb, var(--theme-accent) 22%, var(--theme-border));
background: color-mix(in srgb, var(--theme-accent) 18%, var(--theme-surface-soft));
color: var(--theme-text);
font-size: 12px;
font-weight: 800;
cursor: pointer;
}
.commentInboxCard__badge:disabled {
cursor: default;
opacity: 0.7;
}
.commentInboxCard__thread {

View File

@@ -143,6 +143,7 @@ const canDuplicate = computed(() => !!auth.user && hasSavedTierList.value)
const canSwitchToViewerMode = computed(() => isOwnTierList.value && hasSavedTierList.value && !previewMode.value)
const canSwitchToEditMode = computed(() => isOwnTierList.value && hasSavedTierList.value && previewMode.value)
const duplicateActionLabel = computed(() => (isOwnTierList.value ? '복사본 만들기' : '내 티어표로 복사'))
const favoriteActionLabel = computed(() => (isFavorited.value ? '즐겨찾기 해제하기' : '즐겨찾기에 추가하기'))
const canOpenAuthorProfile = computed(() => !!ownerId.value && hasSavedTierList.value)
const copiedFromLabel = computed(() => {
if (!sourceTierListId.value) return ''
@@ -1502,6 +1503,9 @@ onUnmounted(() => {
<button v-if="hasSavedTierList" class="btn btn--ghost viewerSidebar__button" type="button" @click="copyShareUrl">
공유하기
</button>
<button v-if="canFavorite" class="btn btn--save viewerSidebar__button" type="button" :disabled="isFavoriteBusy" @click="toggleFavorite">
{{ favoriteActionLabel }}
</button>
<button v-if="canDuplicate" class="btn btn--save viewerSidebar__button" type="button" @click="duplicateCurrentTierList">
{{ duplicateActionLabel }}
</button>
@@ -1944,10 +1948,10 @@ onUnmounted(() => {
</div>
<div v-if="canFavorite" class="editorSidebar__section">
<button class="editorSidebar__favorite" :disabled="isFavoriteBusy" @click="toggleFavorite">
<span> 즐겨찾기</span>
<span>{{ favoriteCount }}</span>
<button class="btn btn--save editorSidebar__button editorSidebar__favoriteButton" :disabled="isFavoriteBusy" @click="toggleFavorite">
{{ favoriteActionLabel }}
</button>
<div class="editorSidebar__favoriteMeta">현재 {{ favoriteCount }}명이 티어표를 즐겨찾기했어요.</div>
</div>
<div v-if="canEdit && customItems.length" class="editorSidebar__section">
@@ -2996,19 +3000,15 @@ onUnmounted(() => {
color: var(--theme-text-soft);
word-break: break-word;
}
.editorSidebar__favorite {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
.editorSidebar__favoriteButton {
width: 100%;
padding: 11px 12px;
border-radius: 14px;
border: 1px solid var(--theme-border);
background: var(--theme-pill-bg);
color: var(--theme-text);
font-weight: 800;
cursor: pointer;
}
.editorSidebar__favoriteMeta {
margin-top: 10px;
color: var(--theme-text-muted);
font-size: 13px;
line-height: 1.5;
}
.editorSidebar__section--footer {
padding-top: 12px;