diff --git a/frontend/src/components/mail/ConversationListItem.vue b/frontend/src/components/mail/ConversationListItem.vue index 8dcdaed..d7d3901 100644 --- a/frontend/src/components/mail/ConversationListItem.vue +++ b/frontend/src/components/mail/ConversationListItem.vue @@ -5,11 +5,14 @@ // - 줄의 메일이 모두 보내기를 기다리는 메일이면 고르기 · 별을 쓸 수 없다(aria-disabled + 까닭은 title — 메일 줄의 고르기 칸과 같은 결) // - 마지막 메일이 붙잡힌 메일이면 시각 자리가 "보내는 중" · "예약 · …"(청록 굵게 — 메일 목록과 같다) // - 임시보관함의 제목 없는 저장본은 메일 줄처럼 흐린 "(제목 없음)" (리뷰 L5) +// 끌어다 놓기(15단계 — 디자인 원본 ListDrag15): 줄을 메일함 패널로 끌어 옮긴다 — 고른 줄이면 고른 것 모두, 아니면 이 줄만. +// 그 대화에서 이 메일함에 든 메일을 옮기고(붙잡힌 메일은 빼고), 그런 메일뿐인 줄은 끌 수 없다. 줄의 링크가 끌어 가던 메일 주소 대신 우리 끌기 자료만 싣는다 (useMailRowDrag) import { computed } from 'vue' import type { RouteLocationRaw } from 'vue-router' import AppIcon from '@/components/AppIcon.vue' import MailCheckbox from '@/components/mail/MailCheckbox.vue' +import { useMailRowDrag } from '@/composables/useMailDrag' import { MAIL_BULK_TEXT, MAIL_LIST_ROW_TEXT, MAIL_NO_SUBJECT } from '@/shared/constants/mail' import { MAIL_CONVERSATION_LIST_TEXT } from '@/shared/constants/mail-conversation' import { SEND_LATER_TEXT } from '@/shared/constants/mail-send-later' @@ -55,6 +58,8 @@ const props = withDefaults(defineProps(), { const emit = defineEmits() +const drag = useMailRowDrag() + const subject = computed(() => props.row.latest.subject || MAIL_NO_SUBJECT) const countText = computed(() => conversationCountText(props.row)) /** 마지막 메일이 붙잡아 둔 발송이면 "예약 · …" · "보내는 중" (9단계) */ @@ -85,7 +90,10 @@ function onStar() { { 'is-selected': selected, 'is-unread': unread, 'is-checked': checked, 'is-checking': checking }, ]" :data-row-id="row.id" + :draggable="!held" @mousedown="onMouseDown" + @dragstart="(event: DragEvent) => drag.start(event, row.id)" + @dragend="drag.end" >

() /** 펼친 안의 id — 메일 id 는 서버의 불투명한 글이라 그대로 붙인다 */ const panelId = computed(() => `conversation-panel-${props.row.message.id}`) +/** 펼친 줄 머리의 [답장] — 답장할 수 있는 메일이고(row.replyLocation) 그사이 지워지지 않았을 때 (펼친 안 아래 [답장]과 같은 조건) */ +const headReply = computed(() => { + if (!props.expanded || !props.row.replyLocation) return null + const detail = props.detail + if (detail?.status === 'error' && detail.error.code === 'RES_001') return null + return props.row.replyLocation +})