fix(webui): sp6 third review round, a held message line stays steady between polls, only a pane's latest render decides the line, the held preview cuts on whole characters (#1873, lane sp6-threads)
This commit was merged in pull request #1970.
This commit is contained in:
1 parent
02df2a3a25
commit
789e2bcdd4
1 file changed
+20
-10
@@ -224,8 +224,16 @@
|
||||
why = `Nothing is read for this thread while ${name}'s bus is ${how}.`; readable = false; back = true;
|
||||
}
|
||||
else if (i?.threads && !thread) line = `This thread is not in ${name}'s thread list.`;
|
||||
setText(e.line, line); e.line.hidden = !line;
|
||||
// A held message the last render had no composer for stays in the line between polls, so the
|
||||
// status line neither flickers nor is announced again on every read.
|
||||
const withHeld = () => {
|
||||
const cps = [...p.draft.replace(/\s+/g, ' ').trim()];
|
||||
return `${line ? `${line} ` : ''}Your unsent message is kept until this thread can send: “${cps.length > 200 ? `${cps.slice(0, 200).join('')}…` : cps.join('')}”`;
|
||||
};
|
||||
const shown = readable && p.held && p.draft ? withHeld() : line;
|
||||
setText(e.line, shown); e.line.hidden = !shown;
|
||||
if (!readable) {
|
||||
p.held = false;
|
||||
// An unsent message outlives the chat view: it is held on the pane and put back when the
|
||||
// thread reads again.
|
||||
const typed = p.chat && e.body.querySelector('form textarea')?.value;
|
||||
@@ -236,19 +244,21 @@
|
||||
return;
|
||||
}
|
||||
if (!p.chat) { p.chat = window.MosaicChat.pane(p.org); p.first = true; }
|
||||
const first = p.first, chat = p.chat; p.first = false;
|
||||
const first = p.first, chat = p.chat, seq = ++p.seq; p.first = false;
|
||||
void chat.render({ path: `/chat/threads/${p.id}`, container: e.body, canSend: !!list && i?.chatSend === true, navigated: first }).then(() => {
|
||||
if (!p.draft || p.chat !== chat || !p.el.isConnected) return;
|
||||
const field = e.body.querySelector('form textarea');
|
||||
if (!field) {
|
||||
// Only the latest render of this pane decides: an earlier one that a newer render cut short
|
||||
// has no composer yet and must not claim the thread cannot send.
|
||||
if (seq !== p.seq || p.chat !== chat || !p.el.isConnected) return;
|
||||
const field = p.draft ? e.body.querySelector('form textarea') : null;
|
||||
if (p.draft && !field) {
|
||||
// The thread reads but offers no composer: the held message stays visible here, never silently held.
|
||||
const held = p.draft.length > 200 ? `${p.draft.slice(0, 200)}…` : p.draft;
|
||||
setText(e.line, `${line ? `${line} ` : ''}Your unsent message is kept until this thread can send: “${held}”`); e.line.hidden = false;
|
||||
p.held = true; const text = withHeld(); setText(e.line, text); e.line.hidden = false;
|
||||
return;
|
||||
}
|
||||
// Put the held message back only into an empty composer; text typed meanwhile is never overwritten.
|
||||
if (!field.value) { field.value = p.draft; field.dispatchEvent(new Event('input', { bubbles: true })); }
|
||||
if (field.value === p.draft) p.draft = '';
|
||||
if (field && !field.value) { field.value = p.draft; field.dispatchEvent(new Event('input', { bubbles: true })); }
|
||||
if (field && field.value === p.draft) p.draft = '';
|
||||
if (p.held && (field || !p.draft)) { p.held = false; setText(e.line, line); e.line.hidden = !line; }
|
||||
}, () => {});
|
||||
}
|
||||
function paintTabs() {
|
||||
@@ -281,7 +291,7 @@
|
||||
// ---------- panes ----------
|
||||
function makePane(key) {
|
||||
const { org, id } = split(key);
|
||||
const p = { key, org, id, n: ++paneSeq, el: null, chat: null, first: true, title: null, draft: '' };
|
||||
const p = { key, org, id, n: ++paneSeq, el: null, chat: null, first: true, title: null, draft: '', held: false, seq: 0 };
|
||||
const box = mounted.root.querySelector('[data-assist-panes]');
|
||||
box.insertAdjacentHTML('beforeend', paneShell(p));
|
||||
p.el = box.lastElementChild;
|
||||
|
||||
Reference in new issue
Block a user