diff --git a/.env.example b/.env.example index e108673..6ad10fd 100644 --- a/.env.example +++ b/.env.example @@ -10,7 +10,7 @@ PROJECT_NAME=jama # Image version to run (set by build.sh, or use 'latest') -JAMA_VERSION=0.9.5 +JAMA_VERSION=0.9.6 # App port — the host port Docker maps to the container PORT=3000 diff --git a/backend/package.json b/backend/package.json index bb89739..b1c6ad9 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "jama-backend", - "version": "0.9.5", + "version": "0.9.6", "description": "TeamChat backend server", "main": "src/index.js", "scripts": { diff --git a/build.sh b/build.sh index 0923ca7..c4475d7 100644 --- a/build.sh +++ b/build.sh @@ -13,7 +13,7 @@ # ───────────────────────────────────────────────────────────── set -euo pipefail -VERSION="${1:-0.9.5}" +VERSION="${1:-0.9.6}" ACTION="${2:-}" REGISTRY="${REGISTRY:-}" IMAGE_NAME="jama" diff --git a/frontend/package.json b/frontend/package.json index 5f39ee6..791ce19 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "jama-frontend", - "version": "0.9.5", + "version": "0.9.6", "private": true, "scripts": { "dev": "vite", diff --git a/frontend/src/components/ChatWindow.jsx b/frontend/src/components/ChatWindow.jsx index 7a2a90f..928f605 100644 --- a/frontend/src/components/ChatWindow.jsx +++ b/frontend/src/components/ChatWindow.jsx @@ -19,6 +19,7 @@ export default function ChatWindow({ group, onBack, onGroupUpdated, onDirectMess const [typing, setTyping] = useState([]); const [iconGroupInfo, setIconGroupInfo] = useState(''); const [showInfo, setShowInfo] = useState(false); + const [replyTo, setReplyTo] = useState(null); const [isMobile, setIsMobile] = useState(window.innerWidth < 768); const messagesEndRef = useRef(null); @@ -143,10 +144,16 @@ export default function ChatWindow({ group, onBack, onGroupUpdated, onDirectMess } }; - const handleSend = async ({ content, imageUrl, replyToId }) => { - if ((!content?.trim() && !imageUrl) || !group) return; + const handleSend = async ({ content, imageFile, linkPreview, emojiOnly }) => { + if ((!content?.trim() && !imageFile) || !group) return; + const replyToId = replyTo?.id || null; + setReplyTo(null); try { - await api.sendMessage({ groupId: group.id, content: content?.trim() || '', imageUrl, replyToId }); + if (imageFile) { + await api.uploadImage(group.id, imageFile, { replyToId, content: content?.trim() || '' }); + } else { + await api.sendMessage(group.id, { content: content.trim(), replyToId, linkPreview, emojiOnly }); + } } catch (e) { toast(e.message || 'Failed to send', 'error'); } @@ -169,7 +176,7 @@ export default function ChatWindow({ group, onBack, onGroupUpdated, onDirectMess }; const handleReply = (msg) => { - window.dispatchEvent(new CustomEvent('jama:reply', { detail: msg })); + setReplyTo(msg); }; const handleDirectMessage = (dmGroup) => { @@ -199,6 +206,7 @@ export default function ChatWindow({ group, onBack, onGroupUpdated, onDirectMess const isOnline = isDirect && group.peer_id && (onlineUserIds instanceof Set ? onlineUserIds.has(Number(group.peer_id)) : false); return ( + <>
{/* Header */}
@@ -292,8 +300,9 @@ export default function ChatWindow({ group, onBack, onGroupUpdated, onDirectMess This channel is read-only
) : ( - + setReplyTo(null)} onTyping={() => {}} /> )} +
{showInfo && ( setShowInfo(false)} /> )} - + ); }