mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-09-06 16:07:14 +08:00
refactor: move mail flag logic to backend
This commit is contained in:
@@ -8,7 +8,6 @@ import { useIsMobile } from '../utils/composables'
|
||||
import { processItem } from '../utils/email-parser'
|
||||
import { utcToLocalDate } from '../utils';
|
||||
import { buildReplyModel, buildForwardModel } from '../utils/mail-actions'
|
||||
import { MAIL_FLAGS, hasMailFlag } from '../utils/mail-flags'
|
||||
import MailContentRenderer from "./MailContentRenderer.vue";
|
||||
import AiExtractInfo from "./AiExtractInfo.vue";
|
||||
|
||||
@@ -107,7 +106,7 @@ const data = computed(() => {
|
||||
})
|
||||
|
||||
const isMailUnread = (mail) => {
|
||||
return props.enableMailFlags && hasMailFlag(mail?.flags, MAIL_FLAGS.UNREAD)
|
||||
return props.enableMailFlags && mail?.mail_flags?.unread === true
|
||||
}
|
||||
|
||||
const currentPageHasUnread = computed(() => rawData.value.some(isMailUnread))
|
||||
@@ -117,36 +116,28 @@ const mailFlagFilterOptions = computed(() => [
|
||||
{ label: t('read'), value: 'read' },
|
||||
])
|
||||
|
||||
const setMailsUnread = async (mails, unread) => {
|
||||
const changedMails = mails.filter(mail => isMailUnread(mail) !== unread)
|
||||
if (changedMails.length === 0) return true
|
||||
|
||||
changedMails.forEach(mail => {
|
||||
const flags = Number(mail.flags ?? 0)
|
||||
mail.flags = unread ? flags | MAIL_FLAGS.UNREAD : flags & ~MAIL_FLAGS.UNREAD
|
||||
})
|
||||
const updateUnreadState = async (mails, action) => {
|
||||
if (mails.length === 0) return true
|
||||
try {
|
||||
await props.updateMailFlags(
|
||||
changedMails.map(mail => mail.id),
|
||||
unread ? MAIL_FLAGS.UNREAD : 0,
|
||||
unread ? 0 : MAIL_FLAGS.UNREAD
|
||||
)
|
||||
const response = await props.updateMailFlags(mails.map(mail => mail.id), 'unread', action)
|
||||
const results = response?.results ?? []
|
||||
const resultById = new Map(results.map(result => [result.id, result]))
|
||||
mails.forEach(mail => {
|
||||
const result = resultById.get(mail.id)
|
||||
if (result) mail.mail_flags = result.mail_flags
|
||||
})
|
||||
return true
|
||||
} catch (error) {
|
||||
changedMails.forEach(mail => {
|
||||
const flags = Number(mail.flags ?? 0)
|
||||
mail.flags = unread ? flags & ~MAIL_FLAGS.UNREAD : flags | MAIL_FLAGS.UNREAD
|
||||
})
|
||||
message.error(error.message || "error")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const markMailsRead = async (mails) => setMailsUnread(mails, false)
|
||||
const markMailsRead = async (mails) => updateUnreadState(mails, 'clear')
|
||||
|
||||
const toggleCurrentMailUnread = async () => {
|
||||
if (!curMail.value) return
|
||||
await setMailsUnread([curMail.value], !isMailUnread(curMail.value))
|
||||
await updateUnreadState([curMail.value], 'toggle')
|
||||
}
|
||||
|
||||
const openMail = async (mail) => {
|
||||
|
||||
@@ -8,7 +8,6 @@ import { getDownloadEmlUrl } from '../utils/email-parser';
|
||||
import { blockRemoteContent } from '../utils/remote-content-policy';
|
||||
import { utcToLocalDate } from '../utils';
|
||||
import { useGlobalState } from '../store';
|
||||
import { MAIL_FLAGS, hasMailFlag } from '../utils/mail-flags';
|
||||
|
||||
const { preferShowTextMail, useIframeShowMail, useUTCDate, isDark, autoLoadRemoteImages } = useGlobalState();
|
||||
|
||||
@@ -156,7 +155,7 @@ const handleSaveToS3 = async (filename, blob) => {
|
||||
</n-button>
|
||||
|
||||
<n-button v-if="enableMailFlags" size="small" tertiary type="info" @click="onToggleUnread">
|
||||
{{ hasMailFlag(mail.flags, MAIL_FLAGS.UNREAD) ? t('markRead') : t('markUnread') }}
|
||||
{{ mail.mail_flags?.unread ? t('markRead') : t('markUnread') }}
|
||||
</n-button>
|
||||
|
||||
<n-button v-if="showReply" size="small" tertiary type="info" @click="handleReply">
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
export const MAIL_FLAGS = {
|
||||
UNREAD: 1,
|
||||
}
|
||||
|
||||
export const hasMailFlag = (flags, flag) => {
|
||||
return (Number(flags ?? 0) & flag) !== 0
|
||||
}
|
||||
|
||||
export const getMailFlagFilterQuery = (filter) => {
|
||||
if (filter === 'unread') return '&flag=0&flag_state=set'
|
||||
if (filter === 'read') return '&flag=0&flag_state=unset'
|
||||
return ''
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import { useRoute } from 'vue-router'
|
||||
import { useGlobalState } from '../store'
|
||||
import { api } from '../api'
|
||||
import { useIsMobile } from '../utils/composables'
|
||||
import { getMailFlagFilterQuery } from '../utils/mail-flags'
|
||||
import { FullscreenExitOutlined } from '@vicons/material'
|
||||
|
||||
import AddressBar from './index/AddressBar.vue';
|
||||
@@ -39,8 +38,9 @@ const fetchMailData = async (limit, offset, mailFlagFilter = 'all') => {
|
||||
if (singleMail) return { results: [singleMail], count: 1 };
|
||||
return { results: [], count: 0 };
|
||||
}
|
||||
const readStatusQuery = mailFlagFilter === 'all' ? '' : `&read_status=${mailFlagFilter}`
|
||||
return await api.fetch(
|
||||
`/api/mails?limit=${limit}&offset=${offset}${getMailFlagFilterQuery(mailFlagFilter)}`
|
||||
`/api/mails?limit=${limit}&offset=${offset}${readStatusQuery}`
|
||||
);
|
||||
};
|
||||
|
||||
@@ -48,10 +48,10 @@ const deleteMail = async (curMailId) => {
|
||||
await api.fetch(`/api/mails/${curMailId}`, { method: 'DELETE' });
|
||||
};
|
||||
|
||||
const updateMailFlags = async (ids, add, remove) => {
|
||||
await api.fetch(`/api/mails/flags`, {
|
||||
const updateMailFlags = async (ids, flag, action) => {
|
||||
return await api.fetch(`/api/mails/flags`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({ ids, add, remove })
|
||||
body: JSON.stringify({ ids, flag, action })
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ import AccountSettings from './AccountSettings.vue'
|
||||
import { processItem } from '../../utils/email-parser'
|
||||
import MailContentRenderer from '../../components/MailContentRenderer.vue'
|
||||
import AddressSelect from '../../components/AddressSelect.vue'
|
||||
import { MAIL_FLAGS, hasMailFlag } from '../../utils/mail-flags'
|
||||
|
||||
const { jwt, settings, useSimpleIndex, showAddressCredential, openSettings, loading } = useGlobalState()
|
||||
const message = useMessage()
|
||||
@@ -51,12 +50,13 @@ const fetchMails = async () => {
|
||||
totalCount.value = count > 0 ? count : totalCount.value;
|
||||
const rawMail = results && results.length > 0 ? results[0] : null
|
||||
currentMail.value = rawMail ? await processItem(rawMail) : null
|
||||
if (openSettings.value.enableMailFlags && hasMailFlag(rawMail?.flags, MAIL_FLAGS.UNREAD)) {
|
||||
rawMail.flags = Number(rawMail.flags ?? 0) & ~MAIL_FLAGS.UNREAD
|
||||
await api.fetch(`/api/mails/flags`, {
|
||||
if (openSettings.value.enableMailFlags && rawMail) {
|
||||
const response = await api.fetch(`/api/mails/flags`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({ ids: [rawMail.id], add: 0, remove: MAIL_FLAGS.UNREAD })
|
||||
body: JSON.stringify({ ids: [rawMail.id], flag: 'unread', action: 'clear' })
|
||||
})
|
||||
const updatedMail = response.results?.[0]
|
||||
if (updatedMail) currentMail.value.mail_flags = updatedMail.mail_flags
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch mails:', error)
|
||||
@@ -66,23 +66,18 @@ const fetchMails = async () => {
|
||||
|
||||
const toggleCurrentMailUnread = async () => {
|
||||
if (!currentMail.value || !openSettings.value.enableMailFlags) return
|
||||
const wasUnread = hasMailFlag(currentMail.value.flags, MAIL_FLAGS.UNREAD)
|
||||
currentMail.value.flags = wasUnread
|
||||
? Number(currentMail.value.flags ?? 0) & ~MAIL_FLAGS.UNREAD
|
||||
: Number(currentMail.value.flags ?? 0) | MAIL_FLAGS.UNREAD
|
||||
try {
|
||||
await api.fetch(`/api/mails/flags`, {
|
||||
const response = await api.fetch(`/api/mails/flags`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({
|
||||
ids: [currentMail.value.id],
|
||||
add: wasUnread ? 0 : MAIL_FLAGS.UNREAD,
|
||||
remove: wasUnread ? MAIL_FLAGS.UNREAD : 0,
|
||||
flag: 'unread',
|
||||
action: 'toggle',
|
||||
})
|
||||
})
|
||||
const updatedMail = response.results?.[0]
|
||||
if (updatedMail) currentMail.value.mail_flags = updatedMail.mail_flags
|
||||
} catch (error) {
|
||||
currentMail.value.flags = wasUnread
|
||||
? Number(currentMail.value.flags ?? 0) | MAIL_FLAGS.UNREAD
|
||||
: Number(currentMail.value.flags ?? 0) & ~MAIL_FLAGS.UNREAD
|
||||
message.error(error.message || 'error')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import { useScopedI18n } from '@/i18n/app'
|
||||
import { api } from '../../api'
|
||||
import { useGlobalState } from '../../store'
|
||||
import MailBox from '../../components/MailBox.vue';
|
||||
import { getMailFlagFilterQuery } from '../../utils/mail-flags';
|
||||
|
||||
const message = useMessage()
|
||||
const { openSettings } = useGlobalState()
|
||||
@@ -26,7 +25,7 @@ const fetchMailData = async (limit, offset, mailFlagFilter = 'all') => {
|
||||
`/user_api/mails`
|
||||
+ `?limit=${limit}`
|
||||
+ `&offset=${offset}`
|
||||
+ getMailFlagFilterQuery(mailFlagFilter)
|
||||
+ (mailFlagFilter === 'all' ? '' : `&read_status=${mailFlagFilter}`)
|
||||
+ (addressFilter.value ? `&address=${addressFilter.value}` : '')
|
||||
);
|
||||
}
|
||||
@@ -52,10 +51,10 @@ const deleteMail = async (curMailId) => {
|
||||
await api.fetch(`/user_api/mails/${curMailId}`, { method: 'DELETE' });
|
||||
};
|
||||
|
||||
const updateMailFlags = async (ids, add, remove) => {
|
||||
await api.fetch(`/user_api/mails/flags`, {
|
||||
const updateMailFlags = async (ids, flag, action) => {
|
||||
return await api.fetch(`/user_api/mails/flags`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({ ids, add, remove })
|
||||
body: JSON.stringify({ ids, flag, action })
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user