fix: rename PRIVATE->PRIVACY, implement info popup overlay for privacy mode

This commit is contained in:
gramps
2026-07-14 13:36:01 -07:00
parent ac58531e8b
commit 8e800b57d1
+29 -18
View File
@@ -103,7 +103,10 @@ body { font-family: var(--font-body); background: var(--bg-primary); color: var(
.badge.admin:hover { border-color:var(--accent-dim); color:var(--accent); } .badge.admin:hover { border-color:var(--accent-dim); color:var(--accent); }
.info-icon { display:inline-flex; align-items:center; justify-content:center; width:18px; height:18px; border-radius:50%; border:1px solid var(--border); color:var(--text-muted); font-size:11px; cursor:pointer; user-select:none; transition:all 0.15s; } .info-icon { display:inline-flex; align-items:center; justify-content:center; width:18px; height:18px; border-radius:50%; border:1px solid var(--border); color:var(--text-muted); font-size:11px; cursor:pointer; user-select:none; transition:all 0.15s; }
.info-icon:hover { border-color:var(--accent-dim); color:var(--accent); } .info-icon:hover { border-color:var(--accent-dim); color:var(--accent); }
.info-popup { position:absolute; top:100%; right:0; margin-top:6px; width:320px; background:var(--bg-secondary); border:1px solid var(--border); border-radius:10px; padding:14px 16px; font-size:12px; line-height:1.6; color:var(--text-primary); z-index:100; box-shadow:0 8px 24px rgba(0,0,0,0.4); } .info-popup-overlay { position:fixed; inset:0; background:rgba(0,0,0,0.6); z-index:1000; display:flex; align-items:center; justify-content:center; }
.info-popup-modal { background:var(--bg-secondary); border:1px solid var(--border); border-radius:12px; padding:24px; max-width:400px; width:90%; font-size:13px; line-height:1.7; color:var(--text-primary); position:relative; box-shadow:0 8px 32px rgba(0,0,0,0.5); }
.info-popup-close { position:absolute; top:8px; right:12px; background:none; border:none; color:var(--text-muted); font-size:22px; cursor:pointer; line-height:1; }
.info-popup-close:hover { color:var(--text-primary); }
.role-label .msg-time { color:var(--text-muted); font-weight:400; font-size:10px; margin-left:6px; } .role-label .msg-time { color:var(--text-muted); font-weight:400; font-size:10px; margin-left:6px; }
.status-dot.offline { background:var(--danger); } .status-dot.offline { background:var(--danger); }
.status-dot.warning { background:var(--warning); } .status-dot.warning { background:var(--warning); }
@@ -405,20 +408,23 @@ body { font-family: var(--font-body); background: var(--bg-primary); color: var(
<button class="badge on" id="searchBadge" onclick="toggleSearch()" title="Toggle auto web search">SEARCH</button> <button class="badge on" id="searchBadge" onclick="toggleSearch()" title="Toggle auto web search">SEARCH</button>
<button class="badge on" id="profileBadge" onclick="toggleProfile()" title="Toggle profile injection">PROFILE</button> <button class="badge on" id="profileBadge" onclick="toggleProfile()" title="Toggle profile injection">PROFILE</button>
<button class="badge on" id="directionBadge" onclick="toggleDirection()" title="Toggle message ordering">NEW</button> <button class="badge on" id="directionBadge" onclick="toggleDirection()" title="Toggle message ordering">NEW</button>
<button class="badge off" id="privateBadge" onclick="togglePrivate()" title="Toggle private chat mode (no persistence, no external queries)">PRIVATE OFF</button> <button class="badge off" id="privateBadge" onclick="togglePrivate()" title="Toggle privacy mode (no persistence, no external queries)">PRIVACY OFF</button>
<span class="info-icon" id="privateInfo" onclick="togglePrivateInfo(event)" title="What is Private Chat?">&#9432;</span> <span class="info-icon" id="privateInfo" onclick="togglePrivateInfo(event)" title="What is Privacy Mode?">&#9432;</span>
<div class="info-popup" id="privateInfoPopup" style="display:none"> <div class="info-popup-overlay" id="privateInfoOverlay" style="display:none" onclick="togglePrivateInfo(event)">
<strong>&#128274; Private Chat</strong><br><br> <div class="info-popup-modal" onclick="event.stopPropagation()">
When enabled:<br> <button class="info-popup-close" onclick="togglePrivateInfo(event)">&times;</button>
&bull; Nothing is saved to the database<br> <strong>&#128274; Privacy Mode</strong><br><br>
&bull; No memory or RAG context is injected<br> <b>When enabled:</b><br>
&bull; Web search is disabled (no external queries)<br> &bull; Nothing is saved to the database<br>
&bull; Messages are not auto-ingested as facts<br> &bull; No memory or RAG context is injected<br>
&bull; No conversation history is kept after refresh<br><br> &bull; Web search is disabled (no external queries)<br>
When disabled:<br> &bull; Messages are not auto-ingested as facts<br>
&bull; All conversations are persisted to disk<br> &bull; No conversation history is kept after refresh<br><br>
&bull; Queries may be stored for training purposes<br> <b>When disabled:</b><br>
&bull; Web search uses external services (SearXNG) &bull; All conversations are persisted to disk (encrypted at rest)<br>
&bull; Queries may be stored for context and memory<br>
&bull; Web search available (SearXNG)
</div>
</div> </div>
<button class="badge admin" id="authActionBtn" onclick="handleAuthAction()" title="Unlock admin">ADMIN</button> <button class="badge admin" id="authActionBtn" onclick="handleAuthAction()" title="Unlock admin">ADMIN</button>
</div> </div>
@@ -910,17 +916,22 @@ function togglePrivate() {
privateEnabled = !privateEnabled; privateEnabled = !privateEnabled;
const badge = document.getElementById('privateBadge'); const badge = document.getElementById('privateBadge');
badge.className = 'badge ' + (privateEnabled ? 'on' : 'off'); badge.className = 'badge ' + (privateEnabled ? 'on' : 'off');
badge.textContent = privateEnabled ? 'PRIVATE' : 'PRIVATE OFF'; badge.textContent = privateEnabled ? 'PRIVACY' : 'PRIVACY OFF';
const searchBtn = document.getElementById('searchBtn'); const searchBtn = document.getElementById('searchBtn');
if (privateEnabled) { if (privateEnabled) {
if (searchBtn) searchBtn.disabled = true; if (searchBtn) searchBtn.disabled = true;
showToast('Private chat: nothing stored, no external queries'); showToast('Privacy: nothing stored, no external queries');
} else { } else {
if (searchBtn && !isStreaming) searchBtn.disabled = false; if (searchBtn && !isStreaming) searchBtn.disabled = false;
showToast('Public mode: conversations are persisted to disk'); showToast('Standard mode: conversations persisted (encrypted at rest)');
} }
} }
function togglePrivateInfo(e) {
const overlay = document.getElementById('privateInfoOverlay');
overlay.style.display = overlay.style.display === 'none' ? 'flex' : 'none';
}
function updateProfileUI() { function updateProfileUI() {
const badge = document.getElementById('profileBadge'); const badge = document.getElementById('profileBadge');
const toggle = document.getElementById('profileToggle'); const toggle = document.getElementById('profileToggle');