From d4e841a28c8a10fb218e7c53c1aa5252a8cba4a7 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Thu, 9 Jul 2026 04:57:47 +0000 Subject: [PATCH] feat: redesign mobile app with tactile UI --- .../mobile/android/app/capacitor.build.gradle | 2 +- apps/mobile/android/capacitor.settings.gradle | 3 + apps/mobile/package.json | 3 +- .../src/components/app-shell/AppShell.tsx | 47 +- .../src/components/bottom-nav/BottomNav.tsx | 16 +- .../screens/ActivityScreen/ActivityScreen.tsx | 21 +- .../src/screens/AskScreen/ChatScreen.tsx | 39 +- .../src/screens/FilesScreen/FilesScreen.tsx | 34 +- .../screens/SettingsScreen/SettingsScreen.tsx | 29 +- .../screens/TerminalScreen/TerminalScreen.tsx | 16 +- apps/mobile/src/styles/globals.css | 422 +++++++++++++----- package-lock.json | 10 + 12 files changed, 451 insertions(+), 191 deletions(-) diff --git a/apps/mobile/android/app/capacitor.build.gradle b/apps/mobile/android/app/capacitor.build.gradle index bbfb44f..23c73a9 100644 --- a/apps/mobile/android/app/capacitor.build.gradle +++ b/apps/mobile/android/app/capacitor.build.gradle @@ -9,7 +9,7 @@ android { apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" dependencies { - + implementation project(':capacitor-haptics') } diff --git a/apps/mobile/android/capacitor.settings.gradle b/apps/mobile/android/capacitor.settings.gradle index a8bab35..30260dc 100644 --- a/apps/mobile/android/capacitor.settings.gradle +++ b/apps/mobile/android/capacitor.settings.gradle @@ -1,3 +1,6 @@ // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN include ':capacitor-android' project(':capacitor-android').projectDir = new File('../../../node_modules/@capacitor/android/capacitor') + +include ':capacitor-haptics' +project(':capacitor-haptics').projectDir = new File('../../../node_modules/@capacitor/haptics/android') diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 10a4fd8..2d8c424 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -20,7 +20,8 @@ "react": "^19.0.0", "react-dom": "^19.0.0", "@capacitor/android": "^7.4.0", - "@capacitor/core": "^7.4.0" + "@capacitor/core": "^7.4.0", + "@capacitor/haptics": "^7.0.2" }, "devDependencies": { "@types/react": "^19.0.2", diff --git a/apps/mobile/src/components/app-shell/AppShell.tsx b/apps/mobile/src/components/app-shell/AppShell.tsx index 6636eee..7ec2bec 100644 --- a/apps/mobile/src/components/app-shell/AppShell.tsx +++ b/apps/mobile/src/components/app-shell/AppShell.tsx @@ -1,4 +1,5 @@ -import { useEffect, useState, type ReactNode } from 'react'; +import { useEffect, useMemo, useState, type ReactNode } from 'react'; +import { Flame, Gem, Heart, Wifi, WifiOff } from 'lucide-react'; import { useCompanion } from '../../api/CompanionContext.js'; import type { ScreenId } from '../../app/navigation.js'; import { BottomNav } from '../bottom-nav/BottomNav.js'; @@ -9,6 +10,14 @@ type AppShellProps = { onNavigate: (screen: ScreenId) => void; }; +const screenTitles: Record = { + chat: { title: 'Quest', kicker: 'Hermes training path' }, + files: { title: 'Backpack', kicker: 'Workspace loot' }, + terminal: { title: 'Power move', kicker: 'Run a command' }, + activity: { title: 'League', kicker: 'Companion stats' }, + settings: { title: 'Nest', kicker: 'Connection setup' }, +}; + export function AppShell({ activeScreen, children, onNavigate }: AppShellProps) { const { client } = useCompanion(); const [online, setOnline] = useState(false); @@ -30,20 +39,32 @@ export function AppShell({ activeScreen, children, onNavigate }: AppShellProps) }; }, [client]); + const title = useMemo(() => screenTitles[activeScreen], [activeScreen]); + return ( -
-
-
-

Hermes Mobile

-

Agent command center

+
+
+
+ +
+

{title.kicker}

+

{title.title}

+
+
+ 7 + 550 + 3 +
+
+ +
+ {online ? : } + {online ? 'Companion online — ready for quests' : 'Companion offline — check Settings'}
-
- - {online ? 'Online' : 'Offline'} -
-
-
{children}
- + +
{children}
+ +
); } diff --git a/apps/mobile/src/components/bottom-nav/BottomNav.tsx b/apps/mobile/src/components/bottom-nav/BottomNav.tsx index 9fc65b9..07d34a2 100644 --- a/apps/mobile/src/components/bottom-nav/BottomNav.tsx +++ b/apps/mobile/src/components/bottom-nav/BottomNav.tsx @@ -1,3 +1,4 @@ +import { Haptics, ImpactStyle } from '@capacitor/haptics'; import type { ScreenId } from '../../app/navigation.js'; import { navItems } from '../../app/navigation.js'; @@ -6,6 +7,14 @@ type BottomNavProps = { onNavigate: (screen: ScreenId) => void; }; +async function tap(): Promise { + try { + await Haptics.impact({ style: ImpactStyle.Light }); + } catch { + // Browser preview / unsupported devices: ignore. + } +} + export function BottomNav({ activeScreen, onNavigate }: BottomNavProps) { return (