mirror of
https://github.com/Crazyco-xyz/48hr.email.git
synced 2026-01-09 19:29:34 +01:00
[Feat]: Show total and historical email count in UI
Enhances user interface by displaying both the current number of emails and the largest UID seen, offering better visibility into historical mailbox activity. Updates backend logic and view templates to support this change, and improves maintainability by centralizing count formatting.
This commit is contained in:
parent
1cf35f76f0
commit
83a4fac4ab
8 changed files with 43 additions and 3 deletions
|
|
@ -71,7 +71,7 @@ User=user
|
|||
Group=user
|
||||
|
||||
WorkingDirectory=/opt/48hr-email
|
||||
ExecStart=npm run prod
|
||||
ExecStart=npm run start
|
||||
|
||||
Restart=on-failure
|
||||
TimeoutStartSec=0
|
||||
|
|
|
|||
3
app.js
3
app.js
|
|
@ -56,6 +56,9 @@ imapService.on(ImapService.EVENT_ERROR, error => {
|
|||
|
||||
app.set('mailProcessingService', mailProcessingService)
|
||||
|
||||
app.locals.imapService = imapService
|
||||
app.locals.mailProcessingService = mailProcessingService
|
||||
|
||||
debug('Starting IMAP connection and message loading')
|
||||
imapService.connectAndLoadMessages().catch(error => {
|
||||
debug('Failed to connect to IMAP:', error.message)
|
||||
|
|
|
|||
|
|
@ -150,6 +150,17 @@ class Helper {
|
|||
return result
|
||||
}
|
||||
}
|
||||
|
||||
async getLargestUid(imapService) {
|
||||
return await imapService.getLargestUid();
|
||||
}
|
||||
|
||||
countElementBuilder(count = 0, largestUid = 0) {
|
||||
const handling = `<label title="Historically managed ${largestUid} email${largestUid === 1 ? '' : 's'}">
|
||||
<h4 style="display: inline;"><u><i>${count}</i></u> mail${count === 1 ? '' : 's'}</h4>
|
||||
</label>`
|
||||
return handling
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Helper
|
||||
|
|
@ -421,8 +421,18 @@ class ImapService extends EventEmitter {
|
|||
]
|
||||
return this.connection.search(searchCriteria, fetchOptions)
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the largest UID from all messages in the mailbox.
|
||||
*/
|
||||
async getLargestUid() {
|
||||
const uids = await this._getAllUids();
|
||||
return uids.length > 0 ? Math.max(...uids) : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Consumers should use these constants:
|
||||
ImapService.EVENT_NEW_MAIL = 'mail'
|
||||
ImapService.EVENT_DELETED_MAIL = 'mailDeleted'
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ router.get('/:address/:errorCode', async(req, res, next) => {
|
|||
}
|
||||
debug(`Error page requested: ${req.params.errorCode} for ${req.params.address}`)
|
||||
const count = await mailProcessingService.getCount()
|
||||
const largestUid = await req.app.locals.imapService.getLargestUid()
|
||||
const totalcount = helper.countElementBuilder(count, largestUid)
|
||||
const errorCode = parseInt(req.params.errorCode) || 404
|
||||
const message = req.query.message || (req.session && req.session.errorMessage) || 'An error occurred'
|
||||
|
||||
|
|
@ -26,6 +28,7 @@ router.get('/:address/:errorCode', async(req, res, next) => {
|
|||
purgeTime: purgeTime,
|
||||
address: req.params.address,
|
||||
count: count,
|
||||
totalcount: totalcount,
|
||||
message: message,
|
||||
status: errorCode,
|
||||
branding: config.http.branding
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ const helper = new(Helper)
|
|||
|
||||
const purgeTime = helper.purgeTimeElemetBuilder()
|
||||
|
||||
|
||||
const sanitizeAddress = param('address').customSanitizer(
|
||||
(value, { req }) => {
|
||||
return req.params.address
|
||||
|
|
@ -25,12 +26,15 @@ router.get('^/:address([^@/]+@[^@/]+)', sanitizeAddress, async(req, res, next) =
|
|||
}
|
||||
debug(`Inbox request for ${req.params.address}`)
|
||||
const count = await mailProcessingService.getCount()
|
||||
const largestUid = await req.app.locals.imapService.getLargestUid()
|
||||
const totalcount = helper.countElementBuilder(count, largestUid)
|
||||
debug(`Rendering inbox with ${count} total mails`)
|
||||
res.render('inbox', {
|
||||
title: `${config.http.branding[0]} | ` + req.params.address,
|
||||
purgeTime: purgeTime,
|
||||
address: req.params.address,
|
||||
count: count,
|
||||
totalcount: totalcount,
|
||||
mailSummaries: mailProcessingService.getMailSummaries(req.params.address),
|
||||
branding: config.http.branding,
|
||||
})
|
||||
|
|
@ -49,6 +53,8 @@ router.get(
|
|||
const mailProcessingService = req.app.get('mailProcessingService')
|
||||
debug(`Viewing email ${req.params.uid} for ${req.params.address}`)
|
||||
const count = await mailProcessingService.getCount()
|
||||
const largestUid = await req.app.locals.imapService.getLargestUid()
|
||||
const totalcount = helper.countElementBuilder(count, largestUid)
|
||||
const mail = await mailProcessingService.getOneFullMail(
|
||||
req.params.address,
|
||||
req.params.uid
|
||||
|
|
@ -67,6 +73,7 @@ router.get(
|
|||
purgeTime: purgeTime,
|
||||
address: req.params.address,
|
||||
count: count,
|
||||
totalcount: totalcount,
|
||||
mail,
|
||||
uid: req.params.uid,
|
||||
branding: config.http.branding,
|
||||
|
|
@ -194,6 +201,8 @@ router.get(
|
|||
debug(`Fetching raw email ${req.params.uid} for ${req.params.address}`)
|
||||
const uid = parseInt(req.params.uid, 10)
|
||||
const count = await mailProcessingService.getCount()
|
||||
const largestUid = await req.app.locals.imapService.getLargestUid()
|
||||
const totalcount = helper.countElementBuilder(count, largestUid)
|
||||
|
||||
// Validate UID is a valid integer
|
||||
if (isNaN(uid) || uid <= 0) {
|
||||
|
|
@ -214,7 +223,8 @@ router.get(
|
|||
debug(`Rendering raw email view for UID ${req.params.uid}`)
|
||||
res.render('raw', {
|
||||
title: req.params.uid + " | raw | " + req.params.address,
|
||||
mail
|
||||
mail,
|
||||
totalcount: totalcount
|
||||
})
|
||||
} else {
|
||||
debug(`Raw email ${uid} not found for ${req.params.address}`)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ router.get('/', async(req, res, next) => {
|
|||
}
|
||||
debug('Login page requested')
|
||||
const count = await mailProcessingService.getCount()
|
||||
const largestUid = await req.app.locals.imapService.getLargestUid()
|
||||
const totalcount = helper.countElementBuilder(count, largestUid)
|
||||
debug(`Rendering login page with ${count} total mails`)
|
||||
res.render('login', {
|
||||
title: `${config.http.branding[0]} | Your temporary Inbox`,
|
||||
|
|
@ -25,6 +27,7 @@ router.get('/', async(req, res, next) => {
|
|||
purgeTime: purgeTime,
|
||||
domains: helper.getDomains(),
|
||||
count: count,
|
||||
totalcount: totalcount,
|
||||
branding: config.http.branding,
|
||||
example: config.email.examples.account,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
{% block footer %}
|
||||
<section class="container footer">
|
||||
<hr>
|
||||
<h4>{{ branding[0] }} offered by <a href="{{ branding[2] }}" style="text-decoration:underline" target="_blank">{{ branding[1] }}</a> | All Emails will be deleted after {{ purgeTime | raw }} | Currently handling <u><i>{{ count }}</i></u> Emails</h4>
|
||||
<h4>{{ branding[0] }} offered by <a href="{{ branding[2] }}" style="text-decoration:underline" target="_blank">{{ branding[1] }}</a> | All Emails will be deleted after {{ purgeTime | raw }} | Currently handling {{ totalcount | raw }}</h4>
|
||||
<h4 class="container footer-two"> This project is <a href="https://github.com/crazyco-xyz/48hr.email" style="text-decoration:underline" target="_blank">open-source ♥</a></h4>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue