feat: show last message time and preview in channel list

Each channel item in the desktop sidebar and the mobile dropdown now
surfaces the timestamp of the last message (HH:MM today / DD.MM older)
and a truncated plain-text preview (up to 60 chars, mentions stripped).
Sidebar clamps preview to 2 lines, dropdown to 1 line. Empty channels
render as a single-line name, unchanged.

- api.py: /api/messages/updates returns last_message_preview +
  last_message_time; new _make_preview helper strips @[name] syntax
  and truncates with ellipsis.
- app.js: new channelLastMessages state populated by the poll loop and
  by the new_message socket event; populateChannelSidebar,
  renderChannelDropdownItems, and updateChannelSidebarBadges build and
  maintain the two-row layout (.channel-item-top + .channel-item-preview).
- style.css: sidebar and dropdown items switch to column flex; new
  .channel-item-top, .channel-last-time, .channel-item-preview rules.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
MarekWo
2026-04-23 07:43:02 +02:00
parent 57a0ca018d
commit daf9c5c0db
3 changed files with 191 additions and 18 deletions
+39 -6
View File
@@ -52,17 +52,49 @@ main {
}
.channel-sidebar-item {
padding: 0.5rem 0.75rem;
padding: 0.45rem 0.75rem;
cursor: pointer;
display: flex;
align-items: center;
gap: 0.5rem;
flex-direction: column;
align-items: stretch;
gap: 0;
border-bottom: 1px solid var(--border-light);
font-size: 0.85rem;
transition: background-color 0.15s;
color: var(--text-primary);
}
/* Top row: name + time + unread badge */
.channel-item-top {
display: flex;
align-items: center;
gap: 0.35rem;
min-width: 0;
}
.channel-last-time {
font-size: 0.72rem;
color: var(--text-muted);
white-space: nowrap;
flex-shrink: 0;
}
.channel-item-preview {
font-size: 0.72rem;
color: var(--text-muted);
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
line-height: 1.3;
margin-top: 0.1rem;
word-break: break-word;
}
.channel-selector-item .channel-item-preview {
-webkit-line-clamp: 1;
}
.channel-sidebar-item:hover {
background-color: var(--bg-hover);
}
@@ -124,11 +156,12 @@ main {
}
.channel-selector-item {
padding: 0.5rem 0.75rem;
padding: 0.45rem 0.75rem;
cursor: pointer;
display: flex;
align-items: center;
gap: 0.5rem;
flex-direction: column;
align-items: stretch;
gap: 0;
border-bottom: 1px solid var(--border-light);
font-size: 0.88rem;
font-weight: 400;