refactor: split stores and use events
Signed-off-by: Sebastian <krupinski01@gmail.com>
This commit is contained in:
@@ -38,34 +38,26 @@ const LONG_PRESS_MS = 450
|
||||
|
||||
const selectedIdSet = computed(() => new Set(props.selectionList))
|
||||
|
||||
const isOpened = (message: EntityObject): boolean => {
|
||||
if (!props.selectedMessage) return false
|
||||
return (
|
||||
message.provider === props.selectedMessage.provider &&
|
||||
message.service === props.selectedMessage.service &&
|
||||
message.collection === props.selectedMessage.collection &&
|
||||
message.identifier === props.selectedMessage.identifier
|
||||
)
|
||||
}
|
||||
|
||||
const isSelected = (message: EntityObject): boolean => {
|
||||
return selectedIdSet.value.has(
|
||||
`${message.provider}:${String(message.service)}:${String(message.collection)}:${String(message.identifier)}` as EntityIdentifier,
|
||||
)
|
||||
}
|
||||
|
||||
// Check if message is unread
|
||||
const isUnread = (message: EntityObject): boolean => {
|
||||
return !message.properties.flags?.read
|
||||
}
|
||||
|
||||
// Check if message is flagged
|
||||
const isFlagged = (message: EntityObject): boolean => {
|
||||
return message.properties.flags?.flagged || false
|
||||
}
|
||||
|
||||
const currentMessages = computed(() => props.messages ?? [])
|
||||
|
||||
const getMessageTimestamp = (message: EntityObject): string | null => {
|
||||
return message.properties.received
|
||||
|| message.properties.sent
|
||||
|| message.modified
|
||||
|| message.created
|
||||
|| null
|
||||
}
|
||||
|
||||
const getMessageTimeValue = (message: EntityObject): number => {
|
||||
const timestamp = getMessageTimestamp(message)
|
||||
if (!timestamp) {
|
||||
return 0
|
||||
}
|
||||
|
||||
const timeValue = new Date(timestamp).getTime()
|
||||
return Number.isNaN(timeValue) ? 0 : timeValue
|
||||
}
|
||||
|
||||
const selectionCount = computed(() => props.selectionList.length)
|
||||
|
||||
const hasSelection = computed(() => selectionCount.value > 0)
|
||||
@@ -74,11 +66,45 @@ const allCurrentMessagesSelected = computed(() => {
|
||||
return currentMessages.value.length > 0 && currentMessages.value.every(message => isSelected(message))
|
||||
})
|
||||
|
||||
// Sorted messages (newest first)
|
||||
const sortedMessages = computed(() => {
|
||||
return [...currentMessages.value].sort((a, b) => {
|
||||
const dateA = getMessageTimeValue(a)
|
||||
const dateB = getMessageTimeValue(b)
|
||||
return dateB - dateA
|
||||
})
|
||||
})
|
||||
|
||||
// Read/Unread counts from collection properties
|
||||
const unreadCount = computed(() => {
|
||||
return props.selectedCollection?.properties.unread ?? 0
|
||||
})
|
||||
|
||||
const totalCount = computed(() => {
|
||||
return props.selectedCollection?.properties.total ?? 0
|
||||
})
|
||||
|
||||
// True only when the collection explicitly provides total/unread counts
|
||||
const hasCountData = computed(() => {
|
||||
return props.selectedCollection?.properties.total != null
|
||||
})
|
||||
|
||||
const isOpened = (message: EntityObject): boolean => {
|
||||
if (!props.selectedMessage) return false
|
||||
return (message.identifier === props.selectedMessage.identifier)
|
||||
}
|
||||
|
||||
const isSelected = (message: EntityObject): boolean => {
|
||||
return selectedIdSet.value.has(message.identifier)
|
||||
}
|
||||
|
||||
// Format date for display
|
||||
const formatDate = (date: Date | string | null | undefined): string => {
|
||||
if (!date) return ''
|
||||
|
||||
const messageDate = new Date(date)
|
||||
if (Number.isNaN(messageDate.getTime())) return ''
|
||||
|
||||
const now = new Date()
|
||||
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
|
||||
const yesterday = new Date(today)
|
||||
@@ -121,11 +147,24 @@ const truncate = (text: string | null | undefined, length: number = 100): string
|
||||
return text.length > length ? text.substring(0, length) + '...' : text
|
||||
}
|
||||
|
||||
const isSelectionControlClick = (event: MouseEvent | KeyboardEvent): boolean => {
|
||||
return event.target instanceof Element && event.target.closest('.message-selection-checkbox') !== null
|
||||
}
|
||||
|
||||
const handleSelectionToggle = (message: EntityObject) => {
|
||||
emit('toggleSelection', message)
|
||||
}
|
||||
|
||||
const handleMessageMouseClick = (event: MouseEvent | KeyboardEvent, message: EntityObject) => {
|
||||
if (isSelectionControlClick(event)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (suppressNextClick.value) {
|
||||
suppressNextClick.value = false
|
||||
return
|
||||
}
|
||||
|
||||
if (event.shiftKey && !props.selectionMode) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
@@ -138,11 +177,6 @@ const handleMessageMouseClick = (event: MouseEvent | KeyboardEvent, message: Ent
|
||||
return
|
||||
}
|
||||
|
||||
if (suppressNextClick.value) {
|
||||
suppressNextClick.value = false
|
||||
return
|
||||
}
|
||||
|
||||
if (props.selectionMode) {
|
||||
emit('toggleSelection', message)
|
||||
return
|
||||
@@ -152,6 +186,10 @@ const handleMessageMouseClick = (event: MouseEvent | KeyboardEvent, message: Ent
|
||||
}
|
||||
|
||||
const handleMessageMouseDown = (event: MouseEvent, message: EntityObject) => {
|
||||
if (isSelectionControlClick(event)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!event.shiftKey || props.selectionMode) {
|
||||
return
|
||||
}
|
||||
@@ -200,29 +238,6 @@ onBeforeUnmount(() => {
|
||||
const handleSelectAllToggle = (value: boolean | null) => {
|
||||
emit('toggleSelectAll', value === true)
|
||||
}
|
||||
|
||||
// Sorted messages (newest first)
|
||||
const sortedMessages = computed(() => {
|
||||
return [...currentMessages.value].sort((a, b) => {
|
||||
const dateA = a.properties.date ? new Date(a.properties.date).getTime() : 0
|
||||
const dateB = b.properties.date ? new Date(b.properties.date).getTime() : 0
|
||||
return dateB - dateA
|
||||
})
|
||||
})
|
||||
|
||||
// Read/Unread counts from collection properties
|
||||
const unreadCount = computed(() => {
|
||||
return props.selectedCollection?.properties.unread ?? 0
|
||||
})
|
||||
|
||||
const totalCount = computed(() => {
|
||||
return props.selectedCollection?.properties.total ?? 0
|
||||
})
|
||||
|
||||
// True only when the collection explicitly provides total/unread counts
|
||||
const hasCountData = computed(() => {
|
||||
return props.selectedCollection?.properties.total != null
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -282,7 +297,6 @@ const hasCountData = computed(() => {
|
||||
size="small"
|
||||
icon="mdi-close"
|
||||
variant="text"
|
||||
:disabled="!hasSelection"
|
||||
@click="emit('clearSelection')"
|
||||
>
|
||||
<v-icon>mdi-close</v-icon>
|
||||
@@ -320,13 +334,13 @@ const hasCountData = computed(() => {
|
||||
>
|
||||
<template v-slot:default="{ item: message }">
|
||||
<v-list-item
|
||||
:key="`${message.provider}:${message.service}:${message.collection}:${message.identifier}`"
|
||||
:key="message.identifier"
|
||||
class="message-item"
|
||||
:class="{
|
||||
'opened': isOpened(message),
|
||||
'selected': isSelected(message),
|
||||
'selection-mode': selectionMode,
|
||||
'unread': isUnread(message)
|
||||
'unread': !message.properties.isRead
|
||||
}"
|
||||
@mousedown="handleMessageMouseDown($event, message)"
|
||||
@click="handleMessageMouseClick($event, message)"
|
||||
@@ -360,7 +374,7 @@ const hasCountData = computed(() => {
|
||||
{{ message.properties.from?.label || message.properties.from?.address || 'Unknown Sender' }}
|
||||
</span>
|
||||
<span class="text-caption text-medium-emphasis ml-2">
|
||||
{{ formatDate(message.properties.date) }}
|
||||
{{ formatDate(getMessageTimestamp(message)) }}
|
||||
</span>
|
||||
</v-list-item-title>
|
||||
|
||||
@@ -369,13 +383,13 @@ const hasCountData = computed(() => {
|
||||
</v-list-item-subtitle>
|
||||
|
||||
<v-list-item-subtitle class="text-caption text-truncate">
|
||||
{{ truncate(message.properties.snippet, 80) }}
|
||||
{{ '' }}
|
||||
</v-list-item-subtitle>
|
||||
|
||||
<template v-slot:append>
|
||||
<div class="d-flex flex-column align-center">
|
||||
<v-icon
|
||||
v-if="isFlagged(message)"
|
||||
v-if="message.properties.isFlagged"
|
||||
size="small"
|
||||
color="warning"
|
||||
class="mb-1"
|
||||
@@ -383,7 +397,7 @@ const hasCountData = computed(() => {
|
||||
mdi-star
|
||||
</v-icon>
|
||||
<v-icon
|
||||
v-if="message.properties.attachments && message.properties.attachments.length > 0"
|
||||
v-if="message.properties.hasAttachments"
|
||||
size="small"
|
||||
color="grey"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user