feat: structured @-mentions (notify+clickable+hover), distinct links, Ctrl-rebalance sliders
- Mentions now insert a span carrying the user id (handles names with spaces): the sanitizer permits <span class="mention" data-user-card="ULID">, comment and chat notifications resolve by id and only fire for users with access, and mentions render as clickable chips with the shared hover user-card. - Messages composer inserts an atomic, non-editable mention chip so the trailing space no longer collapses while typing. - Links inside chat messages and task comments are underlined/accented so they read as clickable. - Atomization: hold Ctrl/Cmd while dragging an effort slider to rebalance the sibling coefficients proportionally (sum stays ~1.00); added a hint. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { api, toast } from '/static/js/api.js';
|
||||
import { subscribe } from '/static/js/ws.js';
|
||||
import { attachMentions } from '/static/js/mention.js';
|
||||
import { attachMentions, mentionHTML } from '/static/js/mention.js';
|
||||
|
||||
const root = document.getElementById('task-root');
|
||||
const errorBox = document.getElementById('error');
|
||||
@@ -58,7 +58,7 @@ async function render() {
|
||||
const comments = await Promise.all((t.comments || []).map(async (c) => `
|
||||
<div class="card" style="padding:12px">
|
||||
<p class="muted" style="margin:0 0 8px">${esc(await userName(c.authorId))} · ${new Date(c.at).toLocaleString()}</p>
|
||||
<div>${c.body}</div>
|
||||
<div class="comment-body">${c.body}</div>
|
||||
</div>`));
|
||||
|
||||
const timeline = await Promise.all((t.timeline || []).slice().reverse().map(async (e) => `
|
||||
@@ -183,9 +183,10 @@ function wireHandlers() {
|
||||
});
|
||||
document.getElementById('comment-form').addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
const body = document.getElementById('comment-body').value;
|
||||
const field = document.getElementById('comment-body');
|
||||
const body = mentionHTML(field.value, field).replace(/\n/g, '<br>');
|
||||
try {
|
||||
await api('POST', `/api/v1/tasks/${taskId}/comments`, { body: '<p>' + esc(body).replace(/\n/g, '<br>') + '</p>' });
|
||||
await api('POST', `/api/v1/tasks/${taskId}/comments`, { body: '<p>' + body + '</p>' });
|
||||
load();
|
||||
} catch (err) { toast(err.message, 'err'); }
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user