diff --git a/app/frontend/src/App.css b/app/frontend/src/App.css index ab7dcd1..26b3263 100644 --- a/app/frontend/src/App.css +++ b/app/frontend/src/App.css @@ -2004,6 +2004,201 @@ html[data-theme="dark"] .m3-segment-item:hover:not(.active):not(.disabled) { color: var(--md-sys-color-on-surface-variant); } +.history-item-delete { + background: transparent; + border: none; + color: var(--md-sys-color-outline); + cursor: pointer; + padding: 4px; + border-radius: 4px; + display: flex; + align-items: center; + justify-content: center; + transition: transform var(--md-transition-duration) var(--md-transition-easing); +} + +.gallery-item:hover .gallery-thumb { + transform: scale(1.05); +} + +.gallery-select-badge { + position: absolute; + top: 8px; + right: 8px; + width: 26px; + height: 26px; + border-radius: 50%; + display: grid; + place-items: center; + color: var(--md-sys-color-on-primary); + background: var(--md-sys-color-primary); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.28); +} + +.app-dialog-backdrop { + position: fixed; + inset: 0; + z-index: 1000; + display: flex; + align-items: center; + justify-content: center; + padding: 24px; + background: rgba(8, 12, 24, 0.64); + backdrop-filter: blur(4px) saturate(0.86); +} + +.app-dialog { + width: min(460px, 100%); + background: color-mix(in srgb, var(--md-sys-color-surface) 96%, white 4%); + color: var(--md-sys-color-on-surface); + border: 1px solid color-mix(in srgb, var(--md-sys-color-outline) 55%, transparent); + border-radius: var(--md-shape-corner-large); + box-shadow: + 0 22px 60px rgba(0, 0, 0, 0.42), + 0 0 0 1px rgba(255, 255, 255, 0.08) inset; + padding: 24px; +} + +.app-dialog-title { + font-size: 1.15rem; + font-weight: 800; + margin: 0 0 10px 0; +} + +.app-dialog-message { + font-size: 0.92rem; + line-height: 1.45; + color: var(--md-sys-color-on-surface-variant); + margin: 0; + white-space: pre-wrap; +} + +.app-dialog-actions { + display: flex; + justify-content: flex-end; + gap: 10px; + margin-top: 22px; + flex-wrap: wrap; +} + +.gallery-empty { + text-align: center; + padding: 36px; + color: var(--md-sys-color-on-surface-variant); + font-size: 0.85rem; + opacity: 0.8; +} + +/* Animations */ +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +@keyframes pulse { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.55; transform: scale(1.06); } +} + +/* Sidebar specs classes */ +.sidebar-specs-header { + display: flex; + align-items: center; + gap: 6px; + margin-bottom: 6px; + font-weight: 600; + color: var(--md-sys-color-on-background); +} + +.sidebar-specs-item { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + opacity: 0.85; + margin-bottom: 2px; + color: var(--md-sys-color-on-background); +} + +.sidebar-specs-os { + color: var(--md-sys-color-primary); + font-weight: 600; + margin-top: 4px; +} + +/* Chat History Sidebar styling */ +.chat-history-sidebar { + width: 240px; + flex-shrink: 0; + display: flex; + flex-direction: column; + background: var(--md-sys-color-surface-variant); + opacity: 0.95; + border: 1px solid var(--border-color); + border-radius: var(--md-shape-corner-large); + padding: 16px; + height: 100%; + overflow: hidden; + box-shadow: var(--glass-shadow); + transition: all 0.3s ease; +} + +.history-items-list { + display: flex; + flex-direction: column; + gap: 8px; + margin-top: 14px; + overflow-y: auto; + flex: 1; +} + +.history-item { + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px 12px; + border-radius: var(--md-shape-corner-medium); + cursor: pointer; + background: transparent; + transition: background-color 0.2s ease, border-color 0.2s ease; + border: 1px solid transparent; +} + +.history-item:hover { + background: rgba(120, 120, 120, 0.1); +} + +.history-item.active { + background: var(--md-sys-color-secondary-container); + color: var(--md-sys-color-on-secondary-container); + border-color: var(--md-sys-color-outline-variant); +} + +.history-item-info { + display: flex; + flex-direction: column; + min-width: 0; + flex: 1; +} + +.history-item-title { + font-size: 0.85rem; + font-weight: 600; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + color: var(--md-sys-color-on-surface); +} + +.history-item-meta { + font-size: 0.68rem; + opacity: 0.7; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + margin-top: 2px; + color: var(--md-sys-color-on-surface-variant); +} + .history-item-delete { background: transparent; border: none; @@ -2023,3 +2218,80 @@ html[data-theme="dark"] .m3-segment-item:hover:not(.active):not(.disabled) { color: var(--md-sys-color-error); background: rgba(239, 68, 68, 0.1); } + +/* Chat Thinking Block (Reasoning Process) */ +.chat-thinking-container { + margin-bottom: 8px; + border-radius: 8px; + border: 1px dashed rgba(255, 255, 255, 0.15); + background: rgba(255, 255, 255, 0.03); + overflow: hidden; + max-width: 100%; +} + +.chat-thinking-header { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + padding: 8px 12px; + background: rgba(255, 255, 255, 0.05); + border: none; + color: var(--md-sys-color-on-surface-variant); + font-size: 0.8rem; + font-weight: 500; + cursor: pointer; + text-align: left; + transition: background 0.2s; + outline: none; +} + +.chat-thinking-header:hover { + background: rgba(255, 255, 255, 0.08); +} + +.chat-thinking-title { + display: flex; + align-items: center; + gap: 6px; + opacity: 0.8; +} + +.chat-thinking-content { + padding: 10px 12px; + font-size: 0.8rem; + line-height: 1.5; + color: var(--md-sys-color-on-surface-variant); + opacity: 0.75; + border-top: 1px dashed rgba(255, 255, 255, 0.1); + white-space: pre-wrap; + font-family: var(--font-family-monospace, monospace); + background: rgba(0, 0, 0, 0.1); + max-height: 200px; + overflow-y: auto; +} + +/* DeepThink button animations and interactions */ +.chat-composer-deepthink-btn:hover { + background: rgba(99, 102, 241, 0.08) !important; + color: var(--md-sys-color-primary) !important; + border-color: color-mix(in srgb, var(--md-sys-color-primary) 50%, transparent) !important; +} + +.chat-composer-deepthink-btn.active:hover { + background: rgba(99, 102, 241, 0.22) !important; +} + +@keyframes spin-slow { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.rotate-anim { + animation: spin-slow 8s linear infinite; +} + diff --git a/app/frontend/src/App.jsx b/app/frontend/src/App.jsx index 36775bd..ad5a78e 100644 --- a/app/frontend/src/App.jsx +++ b/app/frontend/src/App.jsx @@ -118,14 +118,19 @@ function App() { const saved = localStorage.getItem("textSettings"); if (saved) { try { - return JSON.parse(saved); + const parsed = JSON.parse(saved); + return { + enableThinking: true, + ...parsed + }; } catch (_) {} } return { contextSize: 0, temperature: 0.7, systemPrompt: "You are a helpful local AI assistant.", - threads: 4 + threads: 4, + enableThinking: true }; }); diff --git a/app/frontend/src/components/ModelManager.jsx b/app/frontend/src/components/ModelManager.jsx index 3eadc55..5ef227b 100644 --- a/app/frontend/src/components/ModelManager.jsx +++ b/app/frontend/src/components/ModelManager.jsx @@ -25,7 +25,6 @@ import { } from "../services/api"; const MODEL_FILTERS = [ - { id: "potato", label: "Potato PC" }, { id: "vision", label: "Vision" }, { id: "uncensored", label: "Uncensored" }, ]; diff --git a/app/frontend/src/components/Settings.jsx b/app/frontend/src/components/Settings.jsx index 92108f8..090ca83 100644 --- a/app/frontend/src/components/Settings.jsx +++ b/app/frontend/src/components/Settings.jsx @@ -523,6 +523,30 @@ function Settings({ + {/* Show Thinking Process toggle */} +