@@ -5,10 +5,9 @@ import { useEntitiesStore } from '@MailManager/stores/entitiesStore'
|
||||
import { useServicesStore } from '@MailManager/stores/servicesStore'
|
||||
import { useMailSync } from '@MailManager/composables/useMailSync'
|
||||
import { useSnackbar } from '@KTXC'
|
||||
import type { CollectionObject } from '@MailManager/models/collection'
|
||||
import type { EntityInterface } from '@MailManager/types/entity'
|
||||
import type { CollectionIdentifier, EntityIdentifier } from '@MailManager/types/common'
|
||||
import type { MessageInterface } from '@MailManager/types/message'
|
||||
import type { ServiceObject } from '@MailManager/models'
|
||||
import type { ServiceObject, CollectionObject, EntityObject } from '@MailManager/models'
|
||||
|
||||
export const useMailStore = defineStore('mailStore', () => {
|
||||
const collectionsStore = useCollectionsStore()
|
||||
@@ -42,11 +41,15 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
|
||||
// ── Selection State ───────────────────────────────────────────────────────
|
||||
const selectedFolder = shallowRef<CollectionObject | null>(null)
|
||||
const selectedMessage = shallowRef<EntityInterface<MessageInterface> | null>(null)
|
||||
const selectedMessage = shallowRef<EntityObject | null>(null)
|
||||
|
||||
// ── Compose State ─────────────────────────────────────────────────────────
|
||||
const composeMode = ref(false)
|
||||
const composeReplyTo = shallowRef<EntityInterface<MessageInterface> | null>(null)
|
||||
const composeReplyTo = shallowRef<EntityObject | null>(null)
|
||||
|
||||
// ── Move State ────────────────────────────────────────────────────────────
|
||||
const moveDialogVisible = ref(false)
|
||||
const moveMessageCandidate = shallowRef<EntityObject | null>(null)
|
||||
|
||||
// ── Computed ──────────────────────────────────────────────────────────────
|
||||
const currentMessages = computed(() => {
|
||||
@@ -205,6 +208,27 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
return serviceFolderErrorState.value[_serviceKey(provider, service)] ?? null
|
||||
}
|
||||
|
||||
function _entityIdentifier(entity: EntityObject): EntityIdentifier {
|
||||
return `${entity.provider}:${String(entity.service)}:${String(entity.collection)}:${String(entity.identifier)}` as EntityIdentifier
|
||||
}
|
||||
|
||||
function _collectionIdentifier(collection: CollectionObject): CollectionIdentifier {
|
||||
return `${collection.provider}:${String(collection.service)}:${String(collection.identifier)}` as CollectionIdentifier
|
||||
}
|
||||
|
||||
function _isSameMessage(left: EntityObject | null, right: EntityObject): boolean {
|
||||
if (!left) {
|
||||
return false
|
||||
}
|
||||
|
||||
return (
|
||||
left.provider === right.provider &&
|
||||
String(left.service) === String(right.service) &&
|
||||
String(left.collection) === String(right.collection) &&
|
||||
String(left.identifier) === String(right.identifier)
|
||||
)
|
||||
}
|
||||
|
||||
// ── Actions ───────────────────────────────────────────────────────────────
|
||||
|
||||
async function selectFolder(folder: CollectionObject) {
|
||||
@@ -227,7 +251,7 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
_updateSyncSources()
|
||||
}
|
||||
|
||||
function selectMessage(message: EntityInterface<MessageInterface>, closeSidebar = false) {
|
||||
function selectMessage(message: EntityObject, closeSidebar = false) {
|
||||
selectedMessage.value = message
|
||||
composeMode.value = false
|
||||
|
||||
@@ -236,12 +260,22 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
}
|
||||
}
|
||||
|
||||
function openCompose(replyTo?: EntityInterface<MessageInterface>) {
|
||||
function openCompose(replyTo?: EntityObject) {
|
||||
composeMode.value = true
|
||||
composeReplyTo.value = replyTo ?? null
|
||||
selectedMessage.value = null
|
||||
}
|
||||
|
||||
function openMoveDialog(message: EntityObject) {
|
||||
moveMessageCandidate.value = message
|
||||
moveDialogVisible.value = true
|
||||
}
|
||||
|
||||
function closeMoveDialog() {
|
||||
moveDialogVisible.value = false
|
||||
moveMessageCandidate.value = null
|
||||
}
|
||||
|
||||
function closeCompose() {
|
||||
composeMode.value = false
|
||||
composeReplyTo.value = null
|
||||
@@ -257,11 +291,64 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteMessage(message: EntityInterface<MessageInterface>) {
|
||||
async function deleteMessage(message: EntityObject) {
|
||||
// TODO: implement delete via entity / collection store
|
||||
console.log('[Mail] Delete message:', message.identifier)
|
||||
}
|
||||
|
||||
async function moveMessage(targetFolder: CollectionObject) {
|
||||
const message = moveMessageCandidate.value
|
||||
|
||||
if (!message) {
|
||||
return
|
||||
}
|
||||
|
||||
const isSameCollection =
|
||||
targetFolder.provider === message.provider &&
|
||||
String(targetFolder.service) === String(message.service) &&
|
||||
String(targetFolder.identifier) === String(message.collection)
|
||||
|
||||
if (isSameCollection) {
|
||||
closeMoveDialog()
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
const sourceIdentifier = _entityIdentifier(message)
|
||||
const response = await entitiesStore.move(_collectionIdentifier(targetFolder), [sourceIdentifier])
|
||||
const result = response[sourceIdentifier]
|
||||
|
||||
if (!result || !result.success) {
|
||||
throw new Error(result && 'error' in result ? result.error : 'Failed to move message')
|
||||
}
|
||||
|
||||
if (_isSameMessage(selectedMessage.value, message)) {
|
||||
selectedMessage.value = null
|
||||
}
|
||||
|
||||
const service = servicesStore.services.find(entry =>
|
||||
entry.provider === message.provider &&
|
||||
String(entry.identifier) === String(message.service),
|
||||
)
|
||||
|
||||
if (service) {
|
||||
void loadFoldersForService(service)
|
||||
}
|
||||
|
||||
notify(`Message moved to "${targetFolder.properties.label || targetFolder.identifier}"`, 'success')
|
||||
closeMoveDialog()
|
||||
} catch (error) {
|
||||
const messageText = error instanceof Error ? error.message : 'Failed to move message'
|
||||
console.error('[Mail] Failed to move message:', error)
|
||||
notify(messageText, 'error')
|
||||
throw error
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function toggleSidebar() {
|
||||
sidebarVisible.value = !sidebarVisible.value
|
||||
}
|
||||
@@ -291,6 +378,8 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
selectedMessage,
|
||||
composeMode,
|
||||
composeReplyTo,
|
||||
moveDialogVisible,
|
||||
moveMessageCandidate,
|
||||
serviceFolderLoadingState,
|
||||
serviceFolderLoadedState,
|
||||
serviceFolderErrorState,
|
||||
@@ -302,9 +391,12 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
selectFolder,
|
||||
selectMessage,
|
||||
openCompose,
|
||||
openMoveDialog,
|
||||
closeMoveDialog,
|
||||
closeCompose,
|
||||
afterSent,
|
||||
deleteMessage,
|
||||
moveMessage,
|
||||
toggleSidebar,
|
||||
openSettings,
|
||||
notify,
|
||||
|
||||
Reference in New Issue
Block a user