diff --git a/CLAUDE.md b/CLAUDE.md index 082c57c..198faf8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -104,7 +104,7 @@ Na serwerze .249 nginx na porcie 80 przekierowuje na HTTPS. Flask/Gunicorn na po git push origin master && git push inpi master # 2. STAGING: Wdrożenie i test -ssh maciejpi@10.22.68.248 "cd /var/www/nordabiznes && sudo -u www-data git pull && sudo systemctl restart nordabiznes" +ssh maciejpi@10.22.68.248 "cd /var/www/nordabiznes && sudo -u www-data git pull && sudo systemctl reload nordabiznes" # ⚠️ OBOWIĄZKOWO: Test manualny nowej funkcjonalności na staging! # 3. PROD: Pull zmiany (DOPIERO PO WERYFIKACJI STAGING!) @@ -114,7 +114,7 @@ ssh maciejpi@10.22.68.249 "cd /var/www/nordabiznes && sudo -u www-data git pull" ssh maciejpi@10.22.68.249 "cd /var/www/nordabiznes && /var/www/nordabiznes/venv/bin/python3 scripts/run_migration.py database/migrations/XXX_nazwa.sql" # 5. PROD: Restart + weryfikacja -ssh maciejpi@10.22.68.249 "sudo systemctl restart nordabiznes" +ssh maciejpi@10.22.68.249 "sudo systemctl reload nordabiznes" curl -sI https://nordabiznes.pl/health | head -3 ``` @@ -158,7 +158,7 @@ ssh maciejpi@10.22.68.249 "source .env && python3 skrypt.py" ### Deployment - Przed wdrożeniem: `python -m py_compile app.py` - SSH: `ssh maciejpi@10.22.68.249` (ZAWSZE jako maciejpi!) -- Ścieżka: `/var/www/nordabiznes` | Restart: `sudo systemctl restart nordabiznes` +- Ścieżka: `/var/www/nordabiznes` | Restart: `sudo systemctl reload nordabiznes` - **ZAWSZE** aktualizuj `release_notes` w app.py ### Szablony Jinja2 - WAŻNE! diff --git a/static/js/conversations.js b/static/js/conversations.js index e684365..ce5255b 100644 --- a/static/js/conversations.js +++ b/static/js/conversations.js @@ -1275,28 +1275,51 @@ return; } var convId = state.currentConversationId; + var savedReplyTo = state.replyToMessage; + var savedFiles = state.attachedFiles.slice(); + + // OPTIMISTIC UI: clear editor and show message IMMEDIATELY + state.quill.setText(''); + state.attachedFiles = []; + state.replyToMessage = null; + var replyPreview = document.getElementById('replyPreview'); + if (replyPreview) replyPreview.style.display = 'none'; + Composer.renderAttachments(); + + // Show optimistic message in DOM instantly + var tempId = 'temp-' + Date.now(); + var optimisticMsg = { + id: tempId, + conversation_id: convId, + content: html, + sender_id: window.__CURRENT_USER__ ? window.__CURRENT_USER__.id : null, + sender: window.__CURRENT_USER__ || {}, + created_at: new Date().toISOString(), + _optimistic: true + }; + ChatView.appendMessage(optimisticMsg); try { var fd = new FormData(); if (html && text) fd.append('content', html); - if (state.replyToMessage) fd.append('reply_to_id', state.replyToMessage.id); + if (savedReplyTo) fd.append('reply_to_id', savedReplyTo.id); - state.attachedFiles.forEach(function (file) { + savedFiles.forEach(function (file) { fd.append('files', file); }); var result = await api('/api/conversations/' + convId + '/messages', 'POST', fd); - // Clear editor - state.quill.setText(''); - state.attachedFiles = []; - state.replyToMessage = null; - var replyPreview = document.getElementById('replyPreview'); - if (replyPreview) replyPreview.style.display = 'none'; - Composer.renderAttachments(); - - // Append the sent message (dedup check inside appendMessage) - ChatView.appendMessage(result); + // Replace temp ID with real ID in state so polling dedup works + var msgs = state.messages[convId]; + if (msgs) { + for (var i = msgs.length - 1; i >= 0; i--) { + if (msgs[i].id === tempId) { + msgs[i] = result; + break; + } + } + } // Update conversation in list ConversationList.updateConversation(convId, {