Significant tiptap updates
This commit is contained in:
@@ -48,6 +48,21 @@ export const TaskDetail: Component<TaskDetailProps> = (props) => {
|
||||
}
|
||||
});
|
||||
|
||||
const [trackedMentions, setTrackedMentions] = createSignal<Set<string>>(new Set());
|
||||
|
||||
createEffect(() => {
|
||||
if (props.isOpen && props.task.content) {
|
||||
const html = props.task.content;
|
||||
const mentionRegex = /data-type="mention"[^>]*data-id="([^"]+)"/g;
|
||||
let match;
|
||||
const initial = new Set<string>();
|
||||
while ((match = mentionRegex.exec(html)) !== null) {
|
||||
initial.add(match[1]);
|
||||
}
|
||||
setTrackedMentions(initial);
|
||||
}
|
||||
});
|
||||
|
||||
let debounceTimer: number | undefined;
|
||||
let pendingContent: string | null = null;
|
||||
|
||||
@@ -57,6 +72,39 @@ export const TaskDetail: Component<TaskDetailProps> = (props) => {
|
||||
debounceTimer = setTimeout(() => {
|
||||
if (pendingContent !== null) {
|
||||
updateTask(props.task.id, { content: pendingContent });
|
||||
|
||||
// Sync mentions deletion
|
||||
const mentionRegex = /data-type="mention"[^>]*data-id="([^"]+)"/g;
|
||||
let match;
|
||||
const currentMentions = new Set<string>();
|
||||
while ((match = mentionRegex.exec(pendingContent)) !== null) {
|
||||
currentMentions.add(match[1].toLowerCase());
|
||||
}
|
||||
|
||||
const currentTags = props.task.tags || [];
|
||||
let tagsChanged = false;
|
||||
const newTags = currentTags.filter(t => {
|
||||
const tagLower = t.toLowerCase();
|
||||
const isTracked = [...trackedMentions()].some(tm => tm.toLowerCase() === tagLower);
|
||||
if (isTracked && !currentMentions.has(tagLower)) {
|
||||
tagsChanged = true;
|
||||
// Also remove from tracked
|
||||
setTrackedMentions(prev => {
|
||||
const next = new Set(prev);
|
||||
for (let p of next) {
|
||||
if (p.toLowerCase() === tagLower) next.delete(p);
|
||||
}
|
||||
return next;
|
||||
});
|
||||
return false; // remove from tags
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (tagsChanged) {
|
||||
updateTags(newTags);
|
||||
}
|
||||
|
||||
pendingContent = null;
|
||||
}
|
||||
}, 1000);
|
||||
@@ -353,6 +401,19 @@ export const TaskDetail: Component<TaskDetailProps> = (props) => {
|
||||
content={props.task.content}
|
||||
onUpdate={updateTaskContent}
|
||||
onEditorReady={setEditorInstance}
|
||||
onNoteOpen={(noteId) => {
|
||||
props.onClose();
|
||||
window.dispatchEvent(new CustomEvent('open-note', { detail: { noteId } }));
|
||||
}}
|
||||
onUserMention={(name) => {
|
||||
const tagName = '@' + name;
|
||||
setTrackedMentions(prev => new Set([...prev, tagName]));
|
||||
const currentTags = props.task.tags || [];
|
||||
if (!currentTags.some(t => t.toLowerCase() === tagName.toLowerCase())) {
|
||||
updateTags([...currentTags, tagName]);
|
||||
toast.success(`Added tag ${tagName} to share task.`);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Suspense>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user