feat: implement patch and settings store
Signed-off-by: Sebastian <krupinski01@gmail.com>
This commit is contained in:
@@ -78,9 +78,7 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
await servicesStore.list()
|
||||
|
||||
const services = [...servicesStore.servicesEnabled]
|
||||
services.forEach(service => {
|
||||
void loadFoldersForService(service,{ selectInbox: true })
|
||||
})
|
||||
await Promise.all(services.map(service => loadFoldersForService(service)))
|
||||
} catch (error) {
|
||||
console.error('[Mail][Operations] Failed to initialize:', error)
|
||||
} finally {
|
||||
@@ -88,10 +86,7 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadFoldersForService(
|
||||
service: ServiceObject,
|
||||
options: { selectInbox?: boolean } = {},
|
||||
) {
|
||||
async function loadFoldersForService(service: ServiceObject) {
|
||||
|
||||
if (service.identifier === null) {
|
||||
return
|
||||
@@ -102,24 +97,10 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
|
||||
try {
|
||||
// retrieve folders for service
|
||||
const collections = await collectionsStore.collectionsForService(service.provider, service.identifier, true)
|
||||
await collectionsStore.collectionsForService(service.provider, service.identifier, true)
|
||||
|
||||
_setServiceFolderLoaded(service.provider, service.identifier, true)
|
||||
|
||||
if (options.selectInbox && !selectedFolder.value) {
|
||||
const inbox = Object.values(collections).find(
|
||||
folder =>
|
||||
folder.provider === service.provider &&
|
||||
String(folder.service) === String(service.identifier) &&
|
||||
(folder.properties.role === 'inbox' ||
|
||||
String(folder.identifier).toLowerCase() === 'inbox'),
|
||||
)
|
||||
|
||||
if (inbox) {
|
||||
await selectFolder(inbox)
|
||||
}
|
||||
}
|
||||
|
||||
_updateSyncSources()
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : 'Failed to load folders'
|
||||
@@ -323,41 +304,25 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
return service
|
||||
}
|
||||
|
||||
async function selectFolder(folder: CollectionObject) {
|
||||
async function selectFolder(folder: CollectionObject | null) {
|
||||
selectedFolder.value = folder
|
||||
selectedMessage.value = null
|
||||
|
||||
try {
|
||||
await entitiesStore.list([folder.identifier])
|
||||
} catch (error) {
|
||||
console.error('[Mail][Operations] Failed to load messages:', error)
|
||||
if (folder) {
|
||||
try {
|
||||
await entitiesStore.list([folder.identifier])
|
||||
} catch (error) {
|
||||
console.error('[Mail][Operations] Failed to load messages:', error)
|
||||
}
|
||||
}
|
||||
|
||||
_updateSyncSources()
|
||||
}
|
||||
|
||||
function clearSelectedFolder() {
|
||||
selectedFolder.value = null
|
||||
selectedMessage.value = null
|
||||
|
||||
_updateSyncSources()
|
||||
}
|
||||
|
||||
function selectMessage(entity: EntityObject) {
|
||||
function selectMessage(entity: EntityObject | null) {
|
||||
selectedMessage.value = entity
|
||||
}
|
||||
|
||||
function clearSelectedMessage() {
|
||||
selectedMessage.value = null
|
||||
}
|
||||
|
||||
async function reloadSelectedFolder() {
|
||||
// Reload the current folder so the sent message appears in Sent
|
||||
if (selectedFolder.value) {
|
||||
await selectFolder(selectedFolder.value)
|
||||
}
|
||||
}
|
||||
|
||||
async function saveComposerDraft(folder: CollectionObject, message: ComposerMessageInput) {
|
||||
composerSaving.value = true
|
||||
|
||||
@@ -380,6 +345,24 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
}
|
||||
}
|
||||
|
||||
function findFoldersByRole(role: string): CollectionObject[] {
|
||||
const normalizedRole = role.toLowerCase()
|
||||
|
||||
return servicesStore.servicesEnabled.flatMap(service => {
|
||||
if (service.identifier === null) {
|
||||
return []
|
||||
}
|
||||
|
||||
return collectionsStore.collectionsForService(service.provider, service.identifier).filter(
|
||||
folder =>
|
||||
folder.provider === service.provider &&
|
||||
String(folder.service) === String(service.identifier) &&
|
||||
(folder.properties.role === normalizedRole ||
|
||||
String(folder.identifier).toLowerCase() === normalizedRole),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
async function sendComposerMessage(message: ComposerMessageInput) {
|
||||
composerSending.value = true
|
||||
|
||||
@@ -492,7 +475,7 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
const deletedFolder = await collectionsStore.delete(folder.identifier)
|
||||
|
||||
if (_sameCollection(selectedFolder.value, folder)) {
|
||||
clearSelectedFolder()
|
||||
await selectFolder(null)
|
||||
}
|
||||
|
||||
notify(
|
||||
@@ -503,6 +486,81 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
return deletedFolder
|
||||
}
|
||||
|
||||
async function deleteMessages(entityIdentifiers: EntityIdentifier[]) {
|
||||
if (entityIdentifiers.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
const { successes, failures } = await entitiesStore.delete(entityIdentifiers)
|
||||
|
||||
if (failures.length === 0) {
|
||||
notify(
|
||||
successes.length === 1 ? 'Message deleted' : `${successes.length} messages deleted`,
|
||||
'success',
|
||||
)
|
||||
}
|
||||
|
||||
if (failures.length > 0) {
|
||||
notify(
|
||||
successes.length === 0
|
||||
? `Delete failed for ${failures.length === 1 ? '1 message' : `${failures.length} messages`}`
|
||||
: `Deleted ${successes.length} ${successes.length === 1 ? 'message' : 'messages'}. ${failures.length} failed.`,
|
||||
successes.length === 0 ? 'error' : 'warning',
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
const messageText = error instanceof Error ? error.message : 'Failed to delete messages'
|
||||
console.error('[Mail][Operations] Failed to delete messages:', error)
|
||||
notify(messageText, 'error')
|
||||
throw error
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function flagMessages(entityIdentifiers: EntityIdentifier[], flags: Partial<MessageInterface['flags']>, options: { notify?: boolean } = {}) {
|
||||
if (entityIdentifiers.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const shouldNotify = options.notify ?? true
|
||||
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
const patch = entitiesStore.fresh().properties
|
||||
patch.flags = flags
|
||||
|
||||
const { successes, failures } = await entitiesStore.patch(patch, entityIdentifiers)
|
||||
|
||||
if (shouldNotify && successes.length > 0) {
|
||||
notify(
|
||||
successes.length === 1 ? 'Message updated' : `${successes.length} messages updated`,
|
||||
'success',
|
||||
)
|
||||
}
|
||||
|
||||
if (shouldNotify && failures.length > 0) {
|
||||
notify(
|
||||
successes.length === 0
|
||||
? `Update failed for ${failures.length === 1 ? '1 message' : `${failures.length} messages`}`
|
||||
: `Updated ${successes.length} ${successes.length === 1 ? 'message' : 'messages'}. ${failures.length} failed.`,
|
||||
successes.length === 0 ? 'error' : 'warning',
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
const messageText = error instanceof Error ? error.message : 'Failed to update messages'
|
||||
console.error('[Mail][Operations] Failed to update messages:', error)
|
||||
notify(messageText, 'error')
|
||||
throw error
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function moveMessages(target: CollectionObject, entityIdentifiers: EntityIdentifier[]) {
|
||||
const { movableIdentifiers, sourceCollections } = entityIdentifiers.reduce(
|
||||
(accumulator, identifier) => {
|
||||
@@ -575,41 +633,6 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteMessages(entityIdentifiers: EntityIdentifier[]) {
|
||||
if (entityIdentifiers.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
const { successes, failures } = await entitiesStore.delete(entityIdentifiers)
|
||||
|
||||
if (failures.length === 0) {
|
||||
notify(
|
||||
successes.length === 1 ? 'Message deleted' : `${successes.length} messages deleted`,
|
||||
'success',
|
||||
)
|
||||
}
|
||||
|
||||
if (failures.length > 0) {
|
||||
notify(
|
||||
successes.length === 0
|
||||
? `Delete failed for ${failures.length === 1 ? '1 message' : `${failures.length} messages`}`
|
||||
: `Deleted ${successes.length} ${successes.length === 1 ? 'message' : 'messages'}. ${failures.length} failed.`,
|
||||
successes.length === 0 ? 'error' : 'warning',
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
const messageText = error instanceof Error ? error.message : 'Failed to delete messages'
|
||||
console.error('[Mail][Operations] Failed to delete messages:', error)
|
||||
notify(messageText, 'error')
|
||||
throw error
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function notify(message: string, color: 'success' | 'error' | 'info' | 'warning' = 'success') {
|
||||
showSnackbar({ message, color })
|
||||
}
|
||||
@@ -625,7 +648,6 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
|
||||
// State
|
||||
loading,
|
||||
selectedFolder,
|
||||
selectedMessage,
|
||||
composerSaving,
|
||||
composerSending,
|
||||
@@ -641,14 +663,12 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
// Actions
|
||||
retrieveService,
|
||||
selectFolder,
|
||||
clearSelectedFolder,
|
||||
selectMessage,
|
||||
clearSelectedMessage,
|
||||
createFolder,
|
||||
reloadSelectedFolder,
|
||||
saveComposerDraft,
|
||||
sendComposerMessage,
|
||||
resetComposerState,
|
||||
flagMessages,
|
||||
deleteMessages,
|
||||
deleteFolder,
|
||||
moveMessages,
|
||||
@@ -658,6 +678,7 @@ export const useMailStore = defineStore('mailStore', () => {
|
||||
isServiceFolderLoading,
|
||||
hasServiceFoldersLoaded,
|
||||
getServiceFolderError,
|
||||
findFoldersByRole,
|
||||
loadFoldersForService,
|
||||
initialize,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user