v0.11.20 UI updates
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jama-backend",
|
||||
"version": "0.11.19",
|
||||
"version": "0.11.20",
|
||||
"description": "TeamChat backend server",
|
||||
"main": "src/index.js",
|
||||
"scripts": {
|
||||
|
||||
2
build.sh
2
build.sh
@@ -13,7 +13,7 @@
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
set -euo pipefail
|
||||
|
||||
VERSION="${1:-0.11.19}"
|
||||
VERSION="${1:-0.11.20}"
|
||||
ACTION="${2:-}"
|
||||
REGISTRY="${REGISTRY:-}"
|
||||
IMAGE_NAME="jama"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jama-frontend",
|
||||
"version": "0.11.19",
|
||||
"version": "0.11.20",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -8,6 +8,12 @@ import { useSocket } from '../contexts/SocketContext.jsx';
|
||||
import './ChatWindow.css';
|
||||
import GroupInfoModal from './GroupInfoModal.jsx';
|
||||
|
||||
// Must match Avatar.jsx and Sidebar.jsx exactly so header colours are consistent with message avatars
|
||||
const AVATAR_COLORS = ['#1a73e8','#ea4335','#34a853','#fa7b17','#a142f4','#00897b','#e91e8c','#0097a7'];
|
||||
function nameToColor(name) {
|
||||
return AVATAR_COLORS[(name || '').charCodeAt(0) % AVATAR_COLORS.length];
|
||||
}
|
||||
|
||||
export default function ChatWindow({ group, onBack, onGroupUpdated, onDirectMessage, onMessageDeleted, onlineUserIds = new Set() }) {
|
||||
const { user: currentUser } = useAuth();
|
||||
const { socket } = useSocket();
|
||||
@@ -237,13 +243,21 @@ export default function ChatWindow({ group, onBack, onGroupUpdated, onDirectMess
|
||||
<img src={group.peer_avatar} alt={group.name} className="group-icon-sm" style={{ objectFit: 'cover', padding: 0 }} />
|
||||
{isOnline && <span className="online-dot" style={{ position: 'absolute', bottom: 1, right: 1 }} />}
|
||||
</div>
|
||||
) : isDirect && !group.is_managed ? (
|
||||
// No custom avatar — use same per-user colour as Avatar.jsx and Sidebar.jsx
|
||||
<div style={{ position: 'relative', flexShrink: 0 }}>
|
||||
<div className="group-icon-sm" style={{ background: nameToColor(group.peer_real_name || group.name), flexShrink: 0 }}>
|
||||
{(group.peer_real_name || group.name)[0]?.toUpperCase()}
|
||||
</div>
|
||||
{isOnline && <span className="online-dot" style={{ position: 'absolute', bottom: 1, right: 1 }} />}
|
||||
</div>
|
||||
) : group.is_managed ? (
|
||||
<div className="group-icon-sm" style={{ background: avatarColors.dm, borderRadius: 8, flexShrink: 0, fontSize: 11, fontWeight: 700 }}>
|
||||
{group.is_multi_group ? 'MG' : 'UG'}
|
||||
</div>
|
||||
) : (
|
||||
<div className="group-icon-sm" style={{ background: group.type === 'public' ? avatarColors.public : avatarColors.dm, flexShrink: 0 }}>
|
||||
{group.type === 'public' ? '#' : isDirect ? (group.peer_real_name || group.name)[0]?.toUpperCase() : group.name[0]?.toUpperCase()}
|
||||
{group.type === 'public' ? '#' : group.name[0]?.toUpperCase()}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ export default function Sidebar({ groups, activeGroupId, onSelectGroup, notifica
|
||||
return (
|
||||
<div className="sidebar">
|
||||
<div className="sidebar-newchat-bar">
|
||||
{!isMobile && !groupMessagesMode && (
|
||||
{!isMobile && (
|
||||
<button className="newchat-btn" onClick={onNewChat}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" width="18" height="18">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 0 1 .865-.501 48.172 48.172 0 0 0 3.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z" />
|
||||
@@ -180,7 +180,7 @@ export default function Sidebar({ groups, activeGroupId, onSelectGroup, notifica
|
||||
)}
|
||||
</div>
|
||||
|
||||
{isMobile && !groupMessagesMode && (
|
||||
{isMobile && (
|
||||
<button className="newchat-fab" onClick={onNewChat} title="New Chat">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" width="24" height="24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 0 1 .865-.501 48.172 48.172 0 0 0 3.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z" />
|
||||
|
||||
@@ -433,6 +433,7 @@ export default function Chat() {
|
||||
onSelectGroup={selectGroup}
|
||||
notifications={notifications}
|
||||
unreadGroups={unreadGroups}
|
||||
onNewChat={() => setModal('newchat')}
|
||||
onProfile={() => setModal('profile')}
|
||||
onUsers={() => setPage('users')}
|
||||
onSettings={() => setModal('settings')}
|
||||
@@ -472,6 +473,7 @@ export default function Chat() {
|
||||
{modal === 'branding' && <BrandingModal onClose={() => setModal(null)} />}
|
||||
{modal === 'help' && <HelpModal onClose={() => setModal(null)} dismissed={helpDismissed} />}
|
||||
{modal === 'about' && <AboutModal onClose={() => setModal(null)} />}
|
||||
{modal === 'newchat' && <NewChatModal onClose={() => setModal(null)} onCreated={(g) => { loadGroups(); setModal(null); setActiveGroupId(g.id); setPage('chat'); }} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user