Changeset 0.19.0.1 (#82)
This commit is contained in:
@@ -272,16 +272,84 @@ const UI = {
|
||||
);
|
||||
}
|
||||
|
||||
if (chats.length === 0 && query) {
|
||||
const projects = App.projects || [];
|
||||
|
||||
if (chats.length === 0 && projects.length === 0 && query) {
|
||||
el.innerHTML = `<div class="sidebar-search-empty">No chats matching "${esc(query)}"</div>`;
|
||||
return;
|
||||
}
|
||||
if (chats.length === 0) {
|
||||
if (chats.length === 0 && projects.length === 0) {
|
||||
el.innerHTML = '<div class="sidebar-empty">No conversations yet</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Group by time
|
||||
let html = '';
|
||||
|
||||
// ── Chat item renderer ──────────────────
|
||||
const renderChatItem = (c) => {
|
||||
const time = _relativeTime(c.updatedAt);
|
||||
return `
|
||||
<div class="chat-item ${c.id === App.currentChatId ? 'active' : ''}"
|
||||
onclick="selectChat('${c.id}')"
|
||||
oncontextmenu="showChatContextMenu(event,'${c.id}')"
|
||||
draggable="true"
|
||||
ondragstart="onChatDragStart(event,'${c.id}')"
|
||||
ondragend="onChatDragEnd(event)">
|
||||
<span class="chat-item-title" ondblclick="startRenameChat('${c.id}');event.stopPropagation();" title="Double-click to rename">${esc(c.title)}</span>
|
||||
<span class="chat-item-time">${time}</span>
|
||||
<button class="chat-item-delete" onclick="deleteChat('${c.id}');event.stopPropagation();" title="Delete">✕</button>
|
||||
</div>`;
|
||||
};
|
||||
|
||||
// ── Project groups ──────────────────────
|
||||
if (projects.length > 0) {
|
||||
projects.forEach(proj => {
|
||||
const projChats = chats.filter(c => c.projectId === proj.id);
|
||||
if (projChats.length === 0 && query) return; // hide empty projects during search
|
||||
const isCollapsed = App.collapsedProjects[proj.id];
|
||||
const colorDot = proj.color
|
||||
? `<span class="project-dot" style="background:${esc(proj.color)}"></span>`
|
||||
: '<span class="project-dot"></span>';
|
||||
const arrow = isCollapsed ? '▸' : '▾';
|
||||
|
||||
html += `<div class="project-group"
|
||||
ondragover="onProjectDragOver(event)"
|
||||
ondragleave="onProjectDragLeave(event)"
|
||||
ondrop="onProjectDrop(event,'${proj.id}')">
|
||||
<div class="project-header" onclick="toggleProjectCollapse('${proj.id}')">
|
||||
<span class="project-arrow">${arrow}</span>
|
||||
${colorDot}
|
||||
<span class="project-name">${esc(proj.name)}</span>
|
||||
<span class="project-count">${projChats.length}</span>
|
||||
<button class="project-menu-btn" onclick="event.stopPropagation();showProjectMenu(event,'${proj.id}')" title="Project options">⋯</button>
|
||||
</div>`;
|
||||
|
||||
if (!isCollapsed) {
|
||||
if (projChats.length === 0) {
|
||||
html += '<div class="project-empty">Drop chats here</div>';
|
||||
} else {
|
||||
projChats.forEach(c => { html += renderChatItem(c); });
|
||||
}
|
||||
}
|
||||
html += '</div>';
|
||||
});
|
||||
}
|
||||
|
||||
// ── Recent (unassigned) chats ───────────
|
||||
const recentChats = chats.filter(c => !c.projectId);
|
||||
|
||||
if (recentChats.length > 0 || projects.length > 0) {
|
||||
// Only show "Recent" label if there are also projects
|
||||
if (projects.length > 0) {
|
||||
html += `<div class="recent-section"
|
||||
ondragover="onProjectDragOver(event)"
|
||||
ondragleave="onProjectDragLeave(event)"
|
||||
ondrop="onRecentDrop(event)">
|
||||
<div class="chat-group-label" style="padding-top:8px">Recent</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
// Group recent by time
|
||||
const now = new Date();
|
||||
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
||||
const yesterday = new Date(today - 86400000);
|
||||
@@ -289,7 +357,7 @@ const UI = {
|
||||
|
||||
const groups = { today: [], yesterday: [], week: [], older: [] };
|
||||
|
||||
chats.forEach(c => {
|
||||
recentChats.forEach(c => {
|
||||
const d = new Date(c.updatedAt);
|
||||
if (d >= today) groups.today.push(c);
|
||||
else if (d >= yesterday) groups.yesterday.push(c);
|
||||
@@ -297,20 +365,16 @@ const UI = {
|
||||
else groups.older.push(c);
|
||||
});
|
||||
|
||||
let html = '';
|
||||
const renderGroup = (label, chats) => {
|
||||
if (chats.length === 0) return;
|
||||
html += `<div class="chat-group-label">${label}</div>`;
|
||||
chats.forEach(c => {
|
||||
const time = _relativeTime(c.updatedAt);
|
||||
html += `
|
||||
<div class="chat-item ${c.id === App.currentChatId ? 'active' : ''}"
|
||||
onclick="selectChat('${c.id}')">
|
||||
<span class="chat-item-title" ondblclick="startRenameChat('${c.id}');event.stopPropagation();" title="Double-click to rename">${esc(c.title)}</span>
|
||||
<span class="chat-item-time">${time}</span>
|
||||
<button class="chat-item-delete" onclick="deleteChat('${c.id}');event.stopPropagation();" title="Delete">✕</button>
|
||||
</div>`;
|
||||
});
|
||||
const renderGroup = (label, items) => {
|
||||
if (items.length === 0) return;
|
||||
// Only show time labels when there are no projects (preserve original look)
|
||||
// or when inside the Recent section
|
||||
if (projects.length > 0) {
|
||||
html += `<div class="chat-group-label chat-time-label">${label}</div>`;
|
||||
} else {
|
||||
html += `<div class="chat-group-label">${label}</div>`;
|
||||
}
|
||||
items.forEach(c => { html += renderChatItem(c); });
|
||||
};
|
||||
|
||||
renderGroup('Today', groups.today);
|
||||
@@ -318,6 +382,13 @@ const UI = {
|
||||
renderGroup('Previous 7 days', groups.week);
|
||||
renderGroup('Older', groups.older);
|
||||
|
||||
if (projects.length > 0 && recentChats.length > 0) {
|
||||
html += '</div>'; // close recent-section
|
||||
} else if (projects.length > 0 && recentChats.length === 0) {
|
||||
// Close the recent-section div we opened
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
el.innerHTML = html;
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user