v0.3.8 fixed messages summaries
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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": {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
2
build.sh
2
build.sh
@@ -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"
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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>}
|
||||||
|
|||||||
Reference in New Issue
Block a user