webmail tweaks

- padding on small attachment download button.
- don't remember "show html" but always display text first.
- propagate modseq to message when flags/keywords change, so "show internals" shows the update.
This commit is contained in:
Mechiel Lukkien 2023-08-10 10:56:04 +02:00
parent f48a53726e
commit c24bb063e5
No known key found for this signature in database
2 changed files with 23 additions and 23 deletions

View File

@ -2208,7 +2208,8 @@ const newMsgitemView = (mi, msglistView, othermb) => {
const e = dom.span(dom._class('msgitemmailbox'), name === othermb.Name ? [] : attr.title(othermb.Name), name); const e = dom.span(dom._class('msgitemmailbox'), name === othermb.Name ? [] : attr.title(othermb.Name), name);
mailboxtag.push(e); mailboxtag.push(e);
} }
const updateFlags = (mask, flags, keywords) => { const updateFlags = (modseq, mask, flags, keywords) => {
msgitemView.messageitem.Message.ModSeq = modseq;
const maskobj = mask; const maskobj = mask;
const flagsobj = flags; const flagsobj = flags;
const mobj = msgitemView.messageitem.Message; const mobj = msgitemView.messageitem.Message;
@ -2412,7 +2413,6 @@ const newMsgView = (miv, msglistView, listMailboxes, possibleLabels, messageLoad
return; return;
} }
loadHTML(); loadHTML();
settingsPut({ ...settings, showHTML: true });
activeBtn(htmlbtn); activeBtn(htmlbtn);
}; };
const cmdShowHTMLExternal = async () => { const cmdShowHTMLExternal = async () => {
@ -2420,7 +2420,6 @@ const newMsgView = (miv, msglistView, listMailboxes, possibleLabels, messageLoad
return; return;
} }
loadHTMLexternal(); loadHTMLexternal();
settingsPut({ ...settings, showHTML: true });
activeBtn(htmlextbtn); activeBtn(htmlextbtn);
}; };
const cmdShowHTMLCycle = async () => { const cmdShowHTMLCycle = async () => {
@ -2591,10 +2590,10 @@ const newMsgView = (miv, msglistView, listMailboxes, possibleLabels, messageLoad
const eye = '👁'; const eye = '👁';
const dl = '⤓'; // \u2913, actually ⭳ \u2b73 would be better, but in fewer fonts (at least macos) const dl = '⤓'; // \u2913, actually ⭳ \u2b73 would be better, but in fewer fonts (at least macos)
const dlurl = 'msg/' + m.ID + '/download/' + [0].concat(a.Path || []).join('.'); const dlurl = 'msg/' + m.ID + '/download/' + [0].concat(a.Path || []).join('.');
const viewbtn = dom.clickbutton(eye, viewable ? ' ' + name : [], attr.title('View this file. Size: ' + size), style({ lineHeight: '1.5' }), function click() { const viewbtn = dom.clickbutton(eye, viewable ? ' ' + name : style({ padding: '0px 0.25em' }), attr.title('View this file. Size: ' + size), style({ lineHeight: '1.5' }), function click() {
view(a); view(a);
}); });
const dlbtn = dom.a(dom._class('button'), attr.download(''), attr.href(dlurl), dl, viewable ? [] : ' ' + name, attr.title('Download this file. Size: ' + size), style({ lineHeight: '1.5' })); const dlbtn = dom.a(dom._class('button'), attr.download(''), attr.href(dlurl), dl, viewable ? style({ padding: '0px 0.25em' }) : ' ' + name, attr.title('Download this file. Size: ' + size), style({ lineHeight: '1.5' }));
if (viewable) { if (viewable) {
return [dom.span(dom._class('btngroup'), viewbtn, dlbtn), ' ']; return [dom.span(dom._class('btngroup'), viewbtn, dlbtn), ' '];
} }
@ -2625,7 +2624,8 @@ const newMsgView = (miv, msglistView, listMailboxes, possibleLabels, messageLoad
messageitem: mi, messageitem: mi,
key: keyHandler(shortcuts), key: keyHandler(shortcuts),
aborter: { abort: () => { } }, aborter: { abort: () => { } },
updateKeywords: (keywords) => { updateKeywords: (modseq, keywords) => {
mi.Message.ModSeq = modseq;
mi.Message.Keywords = keywords; mi.Message.Keywords = keywords;
loadMsgheaderView(msgheaderElem, miv.messageitem, refineKeyword); loadMsgheaderView(msgheaderElem, miv.messageitem, refineKeyword);
}, },
@ -2846,7 +2846,7 @@ const newMsglistView = (msgElem, listMailboxes, setLocationHash, otherMailbox, p
}; };
const mlv = { const mlv = {
root: dom.div(), root: dom.div(),
updateFlags: (mailboxID, uid, mask, flags, keywords) => { updateFlags: (mailboxID, uid, modseq, mask, flags, keywords) => {
// todo optimize: keep mapping of uid to msgitemView for performance. instead of using Array.find // todo optimize: keep mapping of uid to msgitemView for performance. instead of using Array.find
const miv = msgitemViews.find(miv => miv.messageitem.Message.MailboxID === mailboxID && miv.messageitem.Message.UID === uid); const miv = msgitemViews.find(miv => miv.messageitem.Message.MailboxID === mailboxID && miv.messageitem.Message.UID === uid);
if (!miv) { if (!miv) {
@ -2854,9 +2854,9 @@ const newMsglistView = (msgElem, listMailboxes, setLocationHash, otherMailbox, p
log('could not find msgitemView for uid', uid); log('could not find msgitemView for uid', uid);
return; return;
} }
miv.updateFlags(mask, flags, keywords); miv.updateFlags(modseq, mask, flags, keywords);
if (msgView && msgView.messageitem.Message.ID === miv.messageitem.Message.ID) { if (msgView && msgView.messageitem.Message.ID === miv.messageitem.Message.ID) {
msgView.updateKeywords(keywords); msgView.updateKeywords(modseq, keywords);
} }
}, },
addMessageItems: (messageItems) => { addMessageItems: (messageItems) => {
@ -4662,7 +4662,7 @@ const init = async () => {
} }
else if (tag === 'ChangeMsgFlags') { else if (tag === 'ChangeMsgFlags') {
const c = api.parser.ChangeMsgFlags(x); const c = api.parser.ChangeMsgFlags(x);
msglistView.updateFlags(c.MailboxID, c.UID, c.Mask, c.Flags, c.Keywords || []); msglistView.updateFlags(c.MailboxID, c.UID, c.ModSeq, c.Mask, c.Flags, c.Keywords || []);
} }
else if (tag === 'ChangeMailboxRemove') { else if (tag === 'ChangeMailboxRemove') {
const c = api.parser.ChangeMailboxRemove(x); const c = api.parser.ChangeMailboxRemove(x);

View File

@ -1553,7 +1553,7 @@ interface MsgitemView {
root: HTMLElement // MsglistView toggles active/focus classes on the root element. root: HTMLElement // MsglistView toggles active/focus classes on the root element.
messageitem: api.MessageItem messageitem: api.MessageItem
// Called when flags/keywords change for a message. // Called when flags/keywords change for a message.
updateFlags: (mask: api.Flags, flags: api.Flags, keywords: string[]) => void updateFlags: (modseq: number, mask: api.Flags, flags: api.Flags, keywords: string[]) => void
// Must be called when MsgitemView is no longer needed. Typically through // Must be called when MsgitemView is no longer needed. Typically through
// msglistView.clear(). This cleans up the timer that updates the message age. // msglistView.clear(). This cleans up the timer that updates the message age.
@ -1605,7 +1605,8 @@ const newMsgitemView = (mi: api.MessageItem, msglistView: MsglistView, othermb:
mailboxtag.push(e) mailboxtag.push(e)
} }
const updateFlags = (mask: api.Flags, flags: api.Flags, keywords: string[]) => { const updateFlags = (modseq: number, mask: api.Flags, flags: api.Flags, keywords: string[]) => {
msgitemView.messageitem.Message.ModSeq = modseq
const maskobj = mask as unknown as {[key: string]: boolean} const maskobj = mask as unknown as {[key: string]: boolean}
const flagsobj = flags as unknown as {[key: string]: boolean} const flagsobj = flags as unknown as {[key: string]: boolean}
const mobj = msgitemView.messageitem.Message as unknown as {[key: string]: boolean} const mobj = msgitemView.messageitem.Message as unknown as {[key: string]: boolean}
@ -1740,7 +1741,7 @@ interface MsgView {
root: HTMLElement root: HTMLElement
messageitem: api.MessageItem messageitem: api.MessageItem
// Called when keywords for a message have changed, to rerender them. // Called when keywords for a message have changed, to rerender them.
updateKeywords: (keywords: string[]) => void updateKeywords: (modseq: number, keywords: string[]) => void
// Abort loading the message. // Abort loading the message.
aborter: { abort: () => void } aborter: { abort: () => void }
key: (key: string, e: KeyboardEvent) => Promise<void> key: (key: string, e: KeyboardEvent) => Promise<void>
@ -1863,7 +1864,6 @@ const newMsgView = (miv: MsgitemView, msglistView: MsglistView, listMailboxes: l
return return
} }
loadHTML() loadHTML()
settingsPut({...settings, showHTML: true})
activeBtn(htmlbtn) activeBtn(htmlbtn)
} }
const cmdShowHTMLExternal = async () => { const cmdShowHTMLExternal = async () => {
@ -1871,7 +1871,6 @@ const newMsgView = (miv: MsgitemView, msglistView: MsglistView, listMailboxes: l
return return
} }
loadHTMLexternal() loadHTMLexternal()
settingsPut({...settings, showHTML: true})
activeBtn(htmlextbtn) activeBtn(htmlextbtn)
} }
const cmdShowHTMLCycle = async () => { const cmdShowHTMLCycle = async () => {
@ -2181,10 +2180,10 @@ const newMsgView = (miv: MsgitemView, msglistView: MsglistView, listMailboxes: l
const eye = '👁' const eye = '👁'
const dl = '⤓' // \u2913, actually ⭳ \u2b73 would be better, but in fewer fonts (at least macos) const dl = '⤓' // \u2913, actually ⭳ \u2b73 would be better, but in fewer fonts (at least macos)
const dlurl = 'msg/'+m.ID+'/download/'+[0].concat(a.Path || []).join('.') const dlurl = 'msg/'+m.ID+'/download/'+[0].concat(a.Path || []).join('.')
const viewbtn = dom.clickbutton(eye, viewable ? ' '+name : [], attr.title('View this file. Size: '+size), style({lineHeight: '1.5'}), function click() { const viewbtn = dom.clickbutton(eye, viewable ? ' '+name : style({padding: '0px 0.25em'}), attr.title('View this file. Size: '+size), style({lineHeight: '1.5'}), function click() {
view(a) view(a)
}) })
const dlbtn = dom.a(dom._class('button'), attr.download(''), attr.href(dlurl), dl, viewable ? [] : ' '+name, attr.title('Download this file. Size: '+size), style({lineHeight: '1.5'})) const dlbtn = dom.a(dom._class('button'), attr.download(''), attr.href(dlurl), dl, viewable ? style({padding: '0px 0.25em'}) : ' '+name, attr.title('Download this file. Size: '+size), style({lineHeight: '1.5'}))
if (viewable) { if (viewable) {
return [dom.span(dom._class('btngroup'), viewbtn, dlbtn), ' '] return [dom.span(dom._class('btngroup'), viewbtn, dlbtn), ' ']
} }
@ -2239,7 +2238,8 @@ const newMsgView = (miv: MsgitemView, msglistView: MsglistView, listMailboxes: l
messageitem: mi, messageitem: mi,
key: keyHandler(shortcuts), key: keyHandler(shortcuts),
aborter: { abort: () => {} }, aborter: { abort: () => {} },
updateKeywords: (keywords: string[]) => { updateKeywords: (modseq: number, keywords: string[]) => {
mi.Message.ModSeq = modseq
mi.Message.Keywords = keywords mi.Message.Keywords = keywords
loadMsgheaderView(msgheaderElem, miv.messageitem, refineKeyword) loadMsgheaderView(msgheaderElem, miv.messageitem, refineKeyword)
}, },
@ -2357,7 +2357,7 @@ const newMsgView = (miv: MsgitemView, msglistView: MsglistView, listMailboxes: l
// different mailbox/search query is opened. // different mailbox/search query is opened.
interface MsglistView { interface MsglistView {
root: HTMLElement root: HTMLElement
updateFlags: (mailboxID: number, uid: number, mask: api.Flags, flags: api.Flags, keywords: string[]) => void updateFlags: (mailboxID: number, uid: number, modseq: number, mask: api.Flags, flags: api.Flags, keywords: string[]) => void
addMessageItems: (messageItems: api.MessageItem[]) => void addMessageItems: (messageItems: api.MessageItem[]) => void
removeUIDs: (mailboxID: number, uids: number[]) => void removeUIDs: (mailboxID: number, uids: number[]) => void
activeMessageID: () => number // For single message selected, otherwise returns 0. activeMessageID: () => number // For single message selected, otherwise returns 0.
@ -2553,7 +2553,7 @@ const newMsglistView = (msgElem: HTMLElement, listMailboxes: listMailboxes, setL
const mlv: MsglistView = { const mlv: MsglistView = {
root: dom.div(), root: dom.div(),
updateFlags: (mailboxID: number, uid: number, mask: api.Flags, flags: api.Flags, keywords: string[]) => { updateFlags: (mailboxID: number, uid: number, modseq: number, mask: api.Flags, flags: api.Flags, keywords: string[]) => {
// todo optimize: keep mapping of uid to msgitemView for performance. instead of using Array.find // todo optimize: keep mapping of uid to msgitemView for performance. instead of using Array.find
const miv = msgitemViews.find(miv => miv.messageitem.Message.MailboxID === mailboxID && miv.messageitem.Message.UID === uid) const miv = msgitemViews.find(miv => miv.messageitem.Message.MailboxID === mailboxID && miv.messageitem.Message.UID === uid)
if (!miv) { if (!miv) {
@ -2561,9 +2561,9 @@ const newMsglistView = (msgElem: HTMLElement, listMailboxes: listMailboxes, setL
log('could not find msgitemView for uid', uid) log('could not find msgitemView for uid', uid)
return return
} }
miv.updateFlags(mask, flags, keywords) miv.updateFlags(modseq, mask, flags, keywords)
if (msgView && msgView.messageitem.Message.ID === miv.messageitem.Message.ID) { if (msgView && msgView.messageitem.Message.ID === miv.messageitem.Message.ID) {
msgView.updateKeywords(keywords) msgView.updateKeywords(modseq, keywords)
} }
}, },
@ -4966,7 +4966,7 @@ const init = async () => {
msglistView.removeUIDs(c.MailboxID, c.UIDs || []) msglistView.removeUIDs(c.MailboxID, c.UIDs || [])
} else if (tag === 'ChangeMsgFlags') { } else if (tag === 'ChangeMsgFlags') {
const c = api.parser.ChangeMsgFlags(x) const c = api.parser.ChangeMsgFlags(x)
msglistView.updateFlags(c.MailboxID, c.UID, c.Mask, c.Flags, c.Keywords || []) msglistView.updateFlags(c.MailboxID, c.UID, c.ModSeq, c.Mask, c.Flags, c.Keywords || [])
} else if (tag === 'ChangeMailboxRemove') { } else if (tag === 'ChangeMailboxRemove') {
const c = api.parser.ChangeMailboxRemove(x) const c = api.parser.ChangeMailboxRemove(x)
mailboxlistView.removeMailbox(c.MailboxID) mailboxlistView.removeMailbox(c.MailboxID)