chore: sync local working copy as of 2026-08-15
The Gitea repo was initialised from an earlier snapshot, so main and the machine this runs on had drifted apart in 153 files before any UI work started. This commit brings the branch up to the local tree as it stood on 2026-08-15 21:31 (from cowork_local.7z), so the redesign that follows shows up as its own reviewable diff instead of being mixed in with the pre-existing divergence. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+50
-57
@@ -103,67 +103,58 @@ class HelpAgentWidget(QWidget):
|
||||
self._apply_state()
|
||||
|
||||
# ---- theming ----------------------------------------------------------
|
||||
def _compute_palette(self) -> Dict[str, str]:
|
||||
"""Chat-body colours that FOLLOW the app's light/dark theme. The header
|
||||
is intentionally NOT themed here (it stays a fixed light bar — see
|
||||
_apply_style), only the conversation area adapts."""
|
||||
from ..theme import resolve_theme
|
||||
dark = resolve_theme(getattr(self.ctx.config, "theme", "system")) == "dark"
|
||||
if dark:
|
||||
return {
|
||||
"panel_bg": "#16202b", "text": "#e3ebf5", "log_bg": "#0f1720",
|
||||
"input_bg": "#1b2733", "border": "#33404d",
|
||||
"user_bg": "#123a52", "user_label": "#58c0ee",
|
||||
"bot_bg": "#232f3b", "bot_label": "#6fe3a4",
|
||||
}
|
||||
return {
|
||||
"panel_bg": "#ffffff", "text": "#14212b", "log_bg": "#f7f9fb",
|
||||
"input_bg": "#ffffff", "border": "#d5d9de",
|
||||
"user_bg": "#dceff8", "user_label": "#0077B6",
|
||||
"bot_bg": "#eef1f4", "bot_label": "#2f7d55",
|
||||
}
|
||||
def _compute_palette(self):
|
||||
"""The app's design tokens for the theme in effect. The whole dock —
|
||||
header included — follows the app theme; a header locked to a light
|
||||
strip stranded a bright bar in the middle of the dark UI."""
|
||||
from ..theme import palette
|
||||
return palette(getattr(self.ctx.config, "theme", "system"))
|
||||
|
||||
def apply_theme(self) -> None:
|
||||
"""Re-style + re-render when the app theme switches (called from
|
||||
MainWindow._apply_theme). Header stays fixed; chat body re-colours."""
|
||||
MainWindow._apply_theme). The whole dock re-colours, icons included —
|
||||
icons are painted bitmaps, so they must be rebuilt, not restyled."""
|
||||
self._pal = self._compute_palette()
|
||||
self._apply_style()
|
||||
muted = self._pal.text_muted
|
||||
self.edge_tab.setIcon(icon("chevron-left", color=muted))
|
||||
self.collapse_btn.setIcon(icon("chevron-right", color=muted))
|
||||
self.min_btn.setIcon(icon("minus", color=muted))
|
||||
self._render()
|
||||
|
||||
def _apply_style(self) -> None:
|
||||
# The HEADER bar is a FIXED light strip in both themes (per request); only
|
||||
# the chat body below follows the app's light/dark palette (self._pal).
|
||||
from ..theme import ACCENT, ACCENT2, GRADIENT
|
||||
"""The dock owns its own style sheet (it floats above the window, so the
|
||||
app-wide sheet does not reach it cleanly) but draws every value from the
|
||||
shared tokens — see theme.py."""
|
||||
p = self._pal
|
||||
r, rl = p.radius, p.radius_lg
|
||||
self.setStyleSheet(f"""
|
||||
/* Clean rounded app-icon badge (like image 2): a fixed light card
|
||||
framing the icon — no QPushButton box. */
|
||||
#helpLauncher {{ background: #e8f2fb; border: 1px solid #d3e3f2;
|
||||
border-radius: 16px; }}
|
||||
#helpLauncher:hover {{ background: #dcedfb; }}
|
||||
#helpCollapseBtn, #helpEdgeTab {{ background: rgba(0,0,0,0.06); border: none;
|
||||
border-radius: 6px; }}
|
||||
#helpCollapseBtn:hover, #helpEdgeTab:hover {{ background: rgba(0,0,0,0.14); }}
|
||||
#helpPanel {{ background: {p['panel_bg']}; border: 1px solid {p['border']};
|
||||
border-radius: 14px; color: {p['text']}; }}
|
||||
/* Faint-blue header bar — LOCKED light, dark title, in both themes.
|
||||
The header AND its child labels set fixed backgrounds so the dark
|
||||
theme never bleeds into the App-Assistant title strip. */
|
||||
#helpHeader {{ background: #e8f2fb; border-bottom: 1px solid #d9e6f2;
|
||||
border-top-left-radius: 14px; border-top-right-radius: 14px; }}
|
||||
#helpHeader QLabel {{ background: transparent; color: #14212b; }}
|
||||
#helpTitle {{ color: #14212b; font-weight: 700; font-size: 13px; background: transparent; }}
|
||||
#helpMinBtn {{ background: transparent; border: none; }}
|
||||
#helpMinBtn:hover {{ background: rgba(0,0,0,0.10); border-radius: 6px; }}
|
||||
#helpLog {{ background: {p['log_bg']}; border: none; color: {p['text']}; padding: 4px 6px; }}
|
||||
#helpInputRow {{ background: {p['panel_bg']}; border-bottom-left-radius: 14px;
|
||||
border-bottom-right-radius: 14px; }}
|
||||
#helpInput {{ border: 1px solid {p['border']}; border-radius: 8px; padding: 5px 8px;
|
||||
background: {p['input_bg']}; color: {p['text']}; }}
|
||||
#helpInput:focus {{ border: 1px solid {ACCENT}; }}
|
||||
#helpSendBtn {{ background: {GRADIENT}; border: none; border-radius: 8px; }}
|
||||
#helpSendBtn:hover {{ background: {ACCENT2}; }}
|
||||
#helpSendBtn:disabled {{ background: #b7c0c9; }}
|
||||
/* The app-icon badge that opens the dock: a plain card, no button box. */
|
||||
#helpLauncher {{ background: {p.surface}; border: 1px solid {p.border};
|
||||
border-radius: {rl}px; }}
|
||||
#helpLauncher:hover {{ background: {p.hover}; }}
|
||||
#helpCollapseBtn, #helpEdgeTab {{ background: {p.surface}; border: none;
|
||||
border-radius: {r}px; }}
|
||||
#helpCollapseBtn:hover, #helpEdgeTab:hover {{ background: {p.hover}; }}
|
||||
#helpPanel {{ background: {p.surface}; border: 1px solid {p.border};
|
||||
border-radius: {rl}px; color: {p.text}; }}
|
||||
#helpHeader {{ background: {p.surface}; border-bottom: 1px solid {p.border};
|
||||
border-top-left-radius: {rl}px; border-top-right-radius: {rl}px; }}
|
||||
#helpHeader QLabel {{ background: transparent; color: {p.text}; }}
|
||||
#helpTitle {{ color: {p.text}; font-weight: 600; font-size: 13px;
|
||||
background: transparent; }}
|
||||
#helpMinBtn {{ background: transparent; border: none; border-radius: {r}px; }}
|
||||
#helpMinBtn:hover {{ background: {p.hover}; }}
|
||||
#helpLog {{ background: {p.sunken}; border: none; color: {p.text};
|
||||
padding: 4px 6px; }}
|
||||
#helpInputRow {{ background: {p.surface};
|
||||
border-bottom-left-radius: {rl}px; border-bottom-right-radius: {rl}px; }}
|
||||
#helpInput {{ border: 1px solid {p.border}; border-radius: {r}px; padding: 5px 8px;
|
||||
background: {p.surface_raised}; color: {p.text}; }}
|
||||
#helpInput:focus {{ border: 1px solid {p.focus_ring}; }}
|
||||
#helpSendBtn {{ background: {p.accent_solid}; border: none; border-radius: {r}px; }}
|
||||
#helpSendBtn:hover {{ background: {p.accent_solid_hover}; }}
|
||||
#helpSendBtn:disabled {{ background: {p.border_strong}; }}
|
||||
""")
|
||||
|
||||
# ---- greeting / labels ------------------------------------------------
|
||||
@@ -177,7 +168,7 @@ class HelpAgentWidget(QWidget):
|
||||
# assistant back (chevron points left = "slide out").
|
||||
self.edge_tab = QPushButton(self)
|
||||
self.edge_tab.setObjectName("helpEdgeTab")
|
||||
self.edge_tab.setIcon(icon("chevron-left", color="#5a6570"))
|
||||
self.edge_tab.setIcon(icon("chevron-left", color=self._pal.text_muted))
|
||||
self.edge_tab.setCursor(Qt.PointingHandCursor)
|
||||
self.edge_tab.setToolTip(tr("help_agent.show_tooltip"))
|
||||
self.edge_tab.clicked.connect(self._show_launcher)
|
||||
@@ -186,7 +177,7 @@ class HelpAgentWidget(QWidget):
|
||||
# A left-side chevron collapses the assistant to the edge…
|
||||
self.collapse_btn = QPushButton(self)
|
||||
self.collapse_btn.setObjectName("helpCollapseBtn")
|
||||
self.collapse_btn.setIcon(icon("chevron-right", color="#5a6570"))
|
||||
self.collapse_btn.setIcon(icon("chevron-right", color=self._pal.text_muted))
|
||||
self.collapse_btn.setCursor(Qt.PointingHandCursor)
|
||||
self.collapse_btn.setToolTip(tr("help_agent.hide_tooltip"))
|
||||
self.collapse_btn.clicked.connect(self._hide_to_edge)
|
||||
@@ -222,7 +213,7 @@ class HelpAgentWidget(QWidget):
|
||||
hb.addWidget(self.title, 1)
|
||||
self.min_btn = QPushButton(header)
|
||||
self.min_btn.setObjectName("helpMinBtn")
|
||||
self.min_btn.setIcon(icon("minus", color="#5a6570"))
|
||||
self.min_btn.setIcon(icon("minus", color=self._pal.text_muted))
|
||||
self.min_btn.setFixedSize(24, 24)
|
||||
self.min_btn.setCursor(Qt.PointingHandCursor)
|
||||
self.min_btn.setToolTip(tr("help_agent.collapse_tooltip"))
|
||||
@@ -318,17 +309,19 @@ class HelpAgentWidget(QWidget):
|
||||
p = self._pal
|
||||
text = (content or "").replace("&", "&").replace("<", "<").replace(">", ">")
|
||||
text = text.replace("\n", "<br>")
|
||||
# bgcolor= is a solid-only HTML attribute, hence accent_wash (pre-blended)
|
||||
# rather than the translucent accent_soft used in style sheets.
|
||||
if who == "user":
|
||||
align, bg, label_color = "right", p["user_bg"], p["user_label"]
|
||||
align, bg, label_color = "right", p.accent_wash, p.accent
|
||||
label = tr("chat.you")
|
||||
else:
|
||||
align, bg, label_color = "left", p["bot_bg"], p["bot_label"]
|
||||
align, bg, label_color = "left", p.surface_raised, p.success
|
||||
label = tr("help_agent.title")
|
||||
return (
|
||||
f'<table width="100%" cellspacing="0" cellpadding="0"><tr>'
|
||||
f'<td align="{align}">'
|
||||
f'<table width="80%" cellspacing="0" cellpadding="7" bgcolor="{bg}"><tr>'
|
||||
f'<td style="color:{p["text"]};">'
|
||||
f'<td style="color:{p.text};">'
|
||||
f'<b style="color:{label_color};">{label}</b><br>{text}'
|
||||
f'</td></tr></table></td></tr></table>'
|
||||
'<div style="line-height:6px;"> </div>' # gap between turns
|
||||
|
||||
Reference in New Issue
Block a user