Commit Graph

24 Commits

Author SHA1 Message Date
Nicolas Varrot
de6976bae8 fix: add missing aria-labels to icon-only buttons for accessibility
- Sidebar close button: aria-label for screen readers
- Sidebar search clear button: aria-label
- ChatMessage raw JSON copy button: aria-label
- Added i18n keys: sidebar.close, sidebar.clearSearch (EN + FR)
2026-02-13 05:42:23 +00:00
Nicolas Varrot
dfbfc375da fix: open external links in new tab with rel=noopener noreferrer
Markdown links pointing to external URLs (http/https) now open in a
new tab with target=_blank and rel='noopener noreferrer' for security.
Internal/relative links are unaffected.
2026-02-13 04:42:39 +00:00
Nicolas Varrot
82d2e37a27 feat: raw JSON viewer toggle on each message
Add a {⁠} button (visible on hover) that toggles a collapsible panel
showing the full raw gateway JSON payload for any message.
Includes copy-to-clipboard, word-wrap, and i18n (EN/FR).
Useful for debugging and understanding the gateway protocol.

Closes feedback #52
2026-02-13 01:41:04 +00:00
Nicolas Varrot
c7cd47b09a feat: strip webhook/hook scaffolding from user messages
Messages from /hooks/agent containing SECURITY NOTICE blocks and
<<<EXTERNAL_UNTRUSTED_CONTENT>>> delimiters are now cleaned up.
Only the actual user content is displayed, with a small webhook
badge indicator showing the message originated from a webhook.

Closes feedback #54
2026-02-13 01:12:04 +00:00
Nicolas Varrot
b60c0ce3c4 fix: migrate all components to theme-aware CSS variables
Replace ~150 hardcoded Tailwind color classes (bg-zinc-*, text-zinc-*,
border-white/*, text-cyan-*, bg-cyan-*) with CSS custom properties
(--pc-*) across all 17 components.

Add @theme block in index.css for Tailwind v4 theme-aware utility
classes (bg-pc-elevated, text-pc-text, border-pc-border, etc.).

Add --pc-hover, --pc-hover-strong, --pc-separator variables per theme
(white/alpha for dark/OLED, black/alpha for light).

Theme switcher (dark/light/OLED) now actually works — all UI elements
respond to theme changes in real-time.

Fixes #55
2026-02-13 00:29:50 +00:00
Nicolas Varrot
25e63f8d18 feat: improved thinking/reasoning indicator with elapsed time counter
When the agent is reasoning with hidden thinking (thinking=low), show a
pulsing 'Reasoning...' indicator with elapsed time instead of generic
bouncing dots. Once text content starts streaming, falls back to the
regular streaming dots.

Closes feedback #40
2026-02-12 23:42:39 +00:00
Nicolas Varrot
da2e4862dd feat: display agent avatar from OpenClaw identity config
Fetch agent identity via agent.identity.get WS method after connect.
Display avatar in message bubbles (replacing Bot icon) and in the
header (replacing the PinchChat logo when an avatar is configured).
Falls back to default icons when no avatar is set.
2026-02-12 23:29:32 +00:00
Nicolas Varrot
9f67c9e5dc fix: metadata viewer popup clipped by overflow-hidden parent
The MetadataViewer popup was rendered inside the message bubble which has
overflow-hidden, causing the popup to be invisible. Fix by using
createPortal to render the popup directly on document.body with fixed
positioning. Also adds click-outside-to-close behavior.

Closes feedback #46
2026-02-12 23:22:05 +00:00
Nicolas Varrot
b4813f091a feat: add message metadata viewer on hover
Small info button appears on hover of each message bubble.
Click to expand a panel showing raw message metadata (id, role,
timestamp, channel, sender info, etc.) from the gateway.
Useful for debugging and understanding message routing.
Collapsed by default, doesn't clutter the UI.

Closes feedback item #39
2026-02-12 23:17:27 +00:00
Nicolas Varrot
53a8655bb1 docs: release v1.14.2 — textarea scrollbar fix 2026-02-12 23:12:04 +00:00
Nicolas Varrot
3ca76ebe26 style: rework user message styling from violet to cyan theme
Replace violet tint with cyan/teal tones to match the existing cyan accent
theme. User messages now use from-cyan-900/20 background gradient and
cyan-400/15 border, with cyan-200 user icon. Subtler and more cohesive
with the dark theme while remaining clearly distinct from assistant messages.

Fixes feedback #44
2026-02-12 23:10:03 +00:00
Nicolas Varrot
792a34bfb9 style: visually differentiate user vs assistant message bubbles
User messages now have a subtle violet tint (border + gradient) to
distinguish them from assistant messages, similar to WhatsApp/Telegram
style. Keeps the dark theme and soft palette.
2026-02-12 22:26:18 +00:00
Nicolas Varrot
4c8faf07e3 fix: prevent autoFormatText from wrapping markdown prose in code fences
The looksLikeCode/isCodeLine heuristics were too aggressive:
- Pattern /^\s*(\/\/|#|\/\*|\*)/ matched markdown bold (**text**) and
  headings (# title) as code comments, causing entire sections to be
  wrapped in code fences and rendered as raw text
- Pattern /^\s*(\/\/|#)/ in isCodeLine caught markdown headers
- Added early bail-out when text contains markdown indicators (**bold**,
  headings, bullet lists) to prevent false positives
- Narrowed comment detection to actual code comments only

Fixes: raw **bold** shown in long assistant messages (reported by Josh)
2026-02-12 17:26:32 +00:00
Nicolas Varrot
581675d00c feat: distinguish system events from user messages
System events (heartbeats, cron triggers, webhooks, channel events)
now render as subtle inline notifications instead of full user bubbles.
Detection based on content patterns ([EVENT], [cron:], [HEARTBEAT], etc.).
2026-02-12 16:49:16 +00:00
Nicolas Varrot
916910f5ce fix: resolve all ESLint errors and add lint step to CI
- Extract credential helpers to src/lib/credentials.ts (fixes react-refresh/only-export-components)
- Extract buildImageSrc to src/lib/image.ts (fixes react-refresh/only-export-components)
- Reorder useCallback declarations in useGateway to fix react-hooks/immutability
- Sync refs via useEffect instead of during render (fixes react-hooks/refs)
- Replace useState initializer effect with lazy initializer functions in LoginScreen
- Add comments to empty catch blocks (fixes no-empty)
- Remove unused variable (fixes @typescript-eslint/no-unused-vars)
- Downgrade react-hooks/set-state-in-effect to warning (valid init/status patterns)
- Add lint step to CI workflow (runs before type-check and build)
2026-02-11 23:37:37 +00:00
Nicolas Varrot
5b2f3a340d feat: add retry/resend button on user messages
Hover over any user message to reveal a retry button (↻) that resends
the message text. Disabled while a response is generating.
Includes EN/FR i18n strings.
2026-02-11 21:56:48 +00:00
Nicolas Varrot
693229c14e refactor: replace any types with proper TypeScript types across gateway client, hooks, and components
- Add GatewayMessage and JsonPayload interfaces to gateway.ts
- Type WebSocket message parsing with GatewayMessage instead of any
- Use ReturnType<typeof setTimeout> for timer refs
- Type chat event payload destructuring explicitly
- Add ChatPayloadMessage interface for extractText()
- Replace any casts in loadSessions/loadHistory with typed assertions
- Add str() helper in ToolCall.tsx for safe unknown→string extraction
- Use Extract<MessageBlock, ...> type guards instead of `as any` casts
- Type CodeBlock children prop properly
2026-02-11 21:17:44 +00:00
Nicolas Varrot
59104b4217 feat: support line breaks in messages (remark-breaks plugin) 2026-02-11 20:22:17 +00:00
Nicolas Varrot
dd5b56e02c feat: add copy-to-clipboard button on assistant messages
Appears on hover over assistant message bubbles. Shows a check icon
with 'Copied!' feedback for 2s after clicking. i18n support (EN/FR).
Does not show on streaming messages or empty messages.
2026-02-11 19:26:06 +00:00
Nicolas Varrot
762a5f2026 feat: inline image display with lightbox
- Add image block type for base64 and URL images
- Parse image/image_url blocks from gateway history
- Render images inline in chat messages (rounded, dark-themed)
- Click-to-zoom lightbox with Escape to close
- Markdown images also use the lightbox component
- Detect base64 images in tool results (e.g. Read tool on image files)
- Support png, jpg, gif, webp formats
2026-02-11 17:18:10 +00:00
Nicolas Varrot
9b3aed4adc feat: add runtime language selector in header (EN/FR toggle)
- Add LanguageSelector component with globe icon + cycle button
- Refactor i18n to support reactive locale switching via useSyncExternalStore
- Locale priority: localStorage > VITE_LOCALE > navigator.language > 'en'
- All components now use useT() hook for reactive re-rendering on locale change
- Persists choice to localStorage (key: pinchchat-locale)
- No page reload needed — instant switch
2026-02-11 16:18:22 +00:00
Nicolas Varrot
b6a989bb51 feat: add copy button on code blocks
Hover over any fenced code block to reveal a floating copy-to-clipboard
button (top-right corner). Provides visual feedback (checkmark) on success.
Uses a custom ReactMarkdown <pre> component wrapper.
2026-02-11 15:46:49 +00:00
Nicolas Varrot
88c393ed50 fix: use i18n locale for timestamp formatting instead of hardcoded fr-FR 2026-02-11 14:31:32 +00:00
Nicolas Varrot
1f8ff9ae0a Initial commit — ClawChat v1.0.0 2026-02-11 00:48:43 +00:00