v0.3.8 fixed messages summaries

This commit is contained in:
2026-03-10 00:14:50 -04:00
parent 27bee43f89
commit 78dc7d5cb3
6 changed files with 19 additions and 9 deletions

View File

@@ -7,7 +7,7 @@ TZ=UTC
# Copy this file to .env and customize # Copy this file to .env and customize
# Image version to run (set by build.sh, or use 'latest') # Image version to run (set by build.sh, or use 'latest')
JAMA_VERSION=0.3.7 JAMA_VERSION=0.3.8
# Default admin credentials (used on FIRST RUN only) # Default admin credentials (used on FIRST RUN only)
ADMIN_NAME=Admin User ADMIN_NAME=Admin User

View File

@@ -1,6 +1,6 @@
{ {
"name": "jama-backend", "name": "jama-backend",
"version": "0.3.7", "version": "0.3.8",
"description": "TeamChat backend server", "description": "TeamChat backend server",
"main": "src/index.js", "main": "src/index.js",
"scripts": { "scripts": {

View File

@@ -51,7 +51,8 @@ router.get('/', authMiddleware, (req, res) => {
SELECT g.*, SELECT g.*,
(SELECT COUNT(*) FROM messages m WHERE m.group_id = g.id AND m.is_deleted = 0) as message_count, (SELECT COUNT(*) FROM messages m WHERE m.group_id = g.id AND m.is_deleted = 0) as message_count,
(SELECT m.content FROM messages m WHERE m.group_id = g.id AND m.is_deleted = 0 ORDER BY m.created_at DESC LIMIT 1) as last_message, (SELECT m.content FROM messages m WHERE m.group_id = g.id AND m.is_deleted = 0 ORDER BY m.created_at DESC LIMIT 1) as last_message,
(SELECT m.created_at FROM messages m WHERE m.group_id = g.id AND m.is_deleted = 0 ORDER BY m.created_at DESC LIMIT 1) as last_message_at (SELECT m.created_at FROM messages m WHERE m.group_id = g.id AND m.is_deleted = 0 ORDER BY m.created_at DESC LIMIT 1) as last_message_at,
(SELECT m.user_id FROM messages m WHERE m.group_id = g.id AND m.is_deleted = 0 ORDER BY m.created_at DESC LIMIT 1) as last_message_user_id
FROM groups g FROM groups g
WHERE g.type = 'public' WHERE g.type = 'public'
ORDER BY g.is_default DESC, g.name ASC ORDER BY g.is_default DESC, g.name ASC
@@ -63,7 +64,8 @@ router.get('/', authMiddleware, (req, res) => {
u.name as owner_name, u.name as owner_name,
(SELECT COUNT(*) FROM messages m WHERE m.group_id = g.id AND m.is_deleted = 0) as message_count, (SELECT COUNT(*) FROM messages m WHERE m.group_id = g.id AND m.is_deleted = 0) as message_count,
(SELECT m.content FROM messages m WHERE m.group_id = g.id AND m.is_deleted = 0 ORDER BY m.created_at DESC LIMIT 1) as last_message, (SELECT m.content FROM messages m WHERE m.group_id = g.id AND m.is_deleted = 0 ORDER BY m.created_at DESC LIMIT 1) as last_message,
(SELECT m.created_at FROM messages m WHERE m.group_id = g.id AND m.is_deleted = 0 ORDER BY m.created_at DESC LIMIT 1) as last_message_at (SELECT m.created_at FROM messages m WHERE m.group_id = g.id AND m.is_deleted = 0 ORDER BY m.created_at DESC LIMIT 1) as last_message_at,
(SELECT m.user_id FROM messages m WHERE m.group_id = g.id AND m.is_deleted = 0 ORDER BY m.created_at DESC LIMIT 1) as last_message_user_id
FROM groups g FROM groups g
JOIN group_members gm ON g.id = gm.group_id AND gm.user_id = ? JOIN group_members gm ON g.id = gm.group_id AND gm.user_id = ?
LEFT JOIN users u ON g.owner_id = u.id LEFT JOIN users u ON g.owner_id = u.id
@@ -88,7 +90,10 @@ router.get('/', authMiddleware, (req, res) => {
const otherUserId = g.direct_peer1_id === userId ? g.direct_peer2_id : g.direct_peer1_id; const otherUserId = g.direct_peer1_id === userId ? g.direct_peer2_id : g.direct_peer1_id;
if (otherUserId) { if (otherUserId) {
const other = db.prepare('SELECT display_name, name FROM users WHERE id = ?').get(otherUserId); const other = db.prepare('SELECT display_name, name FROM users WHERE id = ?').get(otherUserId);
if (other) g.name = other.display_name || other.name; if (other) {
g.peer_real_name = other.name; // always the real name for sidebar title
g.name = other.display_name || other.name; // display name for chat header
}
} }
} }
return g; return g;

View File

@@ -13,7 +13,7 @@
# ───────────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────────
set -euo pipefail set -euo pipefail
VERSION="${1:-0.3.7}" VERSION="${1:-0.3.8}"
ACTION="${2:-}" ACTION="${2:-}"
REGISTRY="${REGISTRY:-}" REGISTRY="${REGISTRY:-}"
IMAGE_NAME="jama" IMAGE_NAME="jama"

View File

@@ -1,6 +1,6 @@
{ {
"name": "jama-frontend", "name": "jama-frontend",
"version": "0.3.7", "version": "0.3.8",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -99,14 +99,19 @@ export default function Sidebar({ groups, activeGroupId, onSelectGroup, notifica
</div> </div>
<div className="group-info flex-1 overflow-hidden"> <div className="group-info flex-1 overflow-hidden">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<span className={`group-name truncate ${hasUnread ? 'unread-name' : ''}`}>{group.name}</span> <span className={`group-name truncate ${hasUnread ? 'unread-name' : ''}`}>{group.is_direct && group.peer_real_name ? group.peer_real_name : group.name}</span>
{group.last_message_at && ( {group.last_message_at && (
<span className="group-time">{formatTime(group.last_message_at)}</span> <span className="group-time">{formatTime(group.last_message_at)}</span>
)} )}
</div> </div>
<div className="flex items-center justify-between gap-2"> <div className="flex items-center justify-between gap-2">
<span className="group-last-msg truncate"> <span className="group-last-msg truncate">
{(group.last_message || '').replace(/@\[([^\]]+)\]/g, '@$1') || (group.is_readonly ? '📢 Read-only' : 'No messages yet')} {(() => {
const preview = (group.last_message || '').replace(/@\[([^\]]+)\]/g, '@$1');
if (!preview) return group.is_readonly ? '📢 Read-only' : 'No messages yet';
const isOwn = group.last_message_user_id && user && group.last_message_user_id === user.id;
return isOwn ? <><strong style={{fontWeight:600}}>You:</strong> {preview}</> : preview;
})()}
</span> </span>
{notifs > 0 && <span className="badge shrink-0">{notifs}</span>} {notifs > 0 && <span className="badge shrink-0">{notifs}</span>}
{hasUnread && notifs === 0 && <span className="badge badge-unread shrink-0">{unreadCount}</span>} {hasUnread && notifs === 0 && <span className="badge badge-unread shrink-0">{unreadCount}</span>}