feat: Mobile UX Polish v2 — context bar, session titles, composer, image preview (#28)

* feat: mobile UX polish — context bar, session titles, composer spacing, image preview

- Context bar: slim 3px bar with tap-to-reveal inline label (auto-hides 3s)
- Session titles: auto-friendly names (agent:main:main → Main Chat, heartbeat prompts → Main Chat)
- Title truncated to 20 chars with word boundary breaks, max-width 45vw
- Composer: tighter toolbar padding/gaps, model selector compact on mobile
- Attachment ✕ button always visible on mobile (hover-only on desktop)
- Tap-to-preview fullscreen image overlay (portaled to body)
- Message spacing: tighter gaps between messages on mobile
- User bubbles: compact padding on mobile
- Dashboard NowCard: friendly agent names
- Tasks widget: hides empty columns on mobile, wrapped in useMemo
- Logo tip: only shows on mobile
- PWA icons optimized + apple-touch-icon added

* fix: onboarding SSR hydration + allow empty gateway token

- onboarding-tour.tsx: added mounted state guard, return null during SSR
  prevents Joyride from accessing localStorage/DOM server-side
- use-onboarding-tour.ts: lazy localStorage read via useEffect
  eliminates server/client state divergence on hydration
- gateway.ts: remove hard requirement for token/password
  allows connecting to gateways without auth (e.g. nanobot on port 18790)
  device identity signature handles authentication instead
- gateway-setup-wizard.tsx: mark token as optional, add nanobot port hint

Reported-by: @absol_89 (Tharshan)

* fix: remove pull-to-refresh (buggy on mobile) + gateway save timeout 5s→15s

- Remove pull-to-refresh from dashboard and chat message list
- Increase gateway config save timeout from 5s to 15s
- Show 'Config saved. Reconnecting...' instead of timeout error
- Remove onPullOffsetChange prop from chat-screen
- Add onRefresh prop to chat-message-list for manual refresh
- Add mobile viewport detection for responsive padding
- Clean up unused streaming state variables

* feat: mobile agent hub sheet + tab bar improvements + chat header polish

- Add slide-up mobile sheet for agent view panel (replaces desktop sidebar)
- Tab bar: swipe-up gesture to reveal when hidden by keyboard
- Chat header: agent model + connection status display
- Chat empty state: responsive padding for mobile
- Orchestrator avatar: accept className prop
- Onboarding tour steps: minor cleanup

* chore: fix all 40 pre-existing TypeScript errors (0 remaining)

- Remove unused imports/variables across 15 files (TS6133/TS6192)
- Fix update-notifier type narrowing for 'done' state (TS2367)
- Fix route type assignments with string casts for /chat/main (TS2322)
- Fix gateway.ts global declaration syntax (TS2488)
- Remove invalid tooltipClose Joyride style property (TS2353)
- Remove stale skills-screen 'featured' tab comparison (TS2367)
- Remove unused @ts-expect-error in vite.config.ts (TS2578)
- Clean up dead code: getMessageTimestamp, normalizeStatusPayload, etc.

No functionality changes. All fixes verified with npx tsc --noEmit.

* fix: auto-refresh model list cache every 30s

Previously, configured models were cached forever in memory, requiring
a server restart to pick up new models added to openclaw.json config.

Now uses a 30s TTL so model list updates are reflected automatically.
Exports invalidateCache() for manual refresh if needed.

* feat: show all user-configured models in model switcher

Models defined in openclaw.json config but not auto-discovered by the
gateway's models.list RPC now appear in the model switcher. This ensures
newly added models (like claude-sonnet-4-6) show up without waiting for
gateway discovery.

Also exports getConfiguredModelsFromConfig() for direct config reads.

* fix: new chat creates unique thread ID instead of routing to main

* feat: telegram-style slash command autocomplete in chat composer

* feat(dashboard): add WidgetShell component + wiggle/shimmer CSS

- WidgetShell: unified iOS-style widget container with size variants
  (small/medium/large), glass background, press states, edit mode jiggle,
  loading skeleton, and error state
- WIDGET_SIZE_SPAN export for use in widget-grid CSS grid layout
- Added animate-shimmer utility (skeleton loading)
- Added animate-wiggle keyframe (iOS jiggle edit mode)
- tsc --noEmit: 0 errors

---------

Co-authored-by: Aurora <aurora@MacBookPro.lan>
This commit is contained in:
Eric
2026-02-17 22:50:47 -05:00
committed by GitHub
parent ce1aca3a21
commit a9772d200c
47 changed files with 1609 additions and 834 deletions

View File

@@ -10,7 +10,7 @@ import tailwindcss from '@tailwindcss/vite'
import { defineConfig, loadEnv } from 'vite'
import viteTsConfigPaths from 'vite-tsconfig-paths'
const config = defineConfig(({ mode, isSsrBuild }) => {
const config = defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '')
const gatewayUrl = env.CLAWDBOT_GATEWAY_URL?.trim() || 'ws://127.0.0.1:18789'
@@ -95,7 +95,6 @@ const config = defineConfig(({ mode, isSsrBuild }) => {
name: 'client-process-env',
enforce: 'pre',
transform(code, _id) {
// @ts-expect-error environment exists on plugin context in Vite 6
const envName = this.environment?.name
if (envName !== 'client') return null
if (!code.includes('process.env') && !code.includes('process.platform')) return null