Skip to content

feat(desktop): add Electron desktop shell with sidebar, webview & macOS traffic light supportDesktop dev#454

Open
coder-zkl1988 wants to merge 30 commits into
HKUDS:devfrom
coder-zkl1988:desktop-dev
Open

feat(desktop): add Electron desktop shell with sidebar, webview & macOS traffic light supportDesktop dev#454
coder-zkl1988 wants to merge 30 commits into
HKUDS:devfrom
coder-zkl1988:desktop-dev

Conversation

@coder-zkl1988

Copy link
Copy Markdown

Description

Adds a complete Electron desktop shell (electron/) for DeepTutor, enabling a native macOS experience with embedded webview, window controls, and system tray support.

The shell architecture:

  • Electron main process (electron/src/main/) – manages the Python backend lifecycle, window creation (hidden-inset title bar on macOS), IPC handlers, system tray, and auto-updater
  • Preload script (electron/src/preload/) – exposes a safe window.electron API via contextBridge
  • Shell UI (electron/shell/index.html) – renders a sidebar navigation alongside an embedded webview; injects __DEEPTUTOR_DESKTOP__ / __DEEPTUTOR_PLATFORM__ flags so the web app can detect it's running inside the Electron environment

Frontend changes to support the desktop shell:

  • SidebarShell – redesigned to support desktop-specific behavior: WebkitAppRegion: drag area at the top, macOS traffic light spacer with configurable offset, collapsible sidebar with expand icon at consistent height
  • Electron detection – switched from broken user-agent checks (Electron string is stripped from webview UA) to reading the __DEEPTUTOR_DESKTOP__ flag injected by the shell
  • Layout alignment(utility)/layout.tsx and UtilitySidebar updated to pass children through SidebarShell matching the WorkspaceSidebar pattern, removing duplicate <main> elements that caused layout conflicts
  • Content area – removed width: 100% inline style overrides and the shell's dom-ready CSS injection that broke flex-1 layout sizing

Dev workflow: electron/scripts/dev.mjs starts the Next.js dev server, waits for readiness, then launches Electron via electron-vite dev.

Related Issues

  • Related to desktop shell architecture

Module(s) Affected

  • web (Frontend)
  • Other: electron (Desktop shell)

Checklist

  • I have read and followed the contribution guidelines.
  • My code follows the project's coding standards.
  • I have run pre-commit run --all-files and fixed any issues.
  • I have added relevant tests for my changes.
  • I have updated the documentation (if necessary).
  • My changes do not introduce any new security vulnerabilities.

Additional Notes

Commits in this branch:

Commit Description
c8c508d fix: use webpack in dev mode to fix RSC payload fetch failures
aafcd2b fix(desktop): fix sidebar layout for Electron shell
b594b51 fix: restore original DeepTutor logo and branding

To launch the desktop app in development:

cd electron && npm run dev

Known limitation: Next.js 16 defaults to Turbopack which mis-detects the workspace root when ~/pnpm-lock.yaml exists, causing RSC payload fetch failures during client-side navigation. The web/package.json dev script uses --webpack as a workaround. A proper Turbopack fix would involve setting turbopack.root in next.config.js.

克隆(宗可龙) and others added 30 commits May 6, 2026 16:32
Add Electron desktop application with:
- electron-vite build configuration
- electron-builder packaging (macOS dmg, Windows exe, Linux AppImage)
- TypeScript configs for main, preload, and renderer
- Dependencies: electron-log, electron-store, electron-updater, keytar

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Remove unused Menu and nativeImage imports from index.ts
- Add URL validation to shell:openExternal (only http/https allowed)
- Add TODO comment for backend:getStatus hardcoded values
- Replace console.error with log.error in keytar.ts
- Add try/catch error handling for settings handlers

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add prebuild step to build Next.js before electron-vite
- Add postbuild script to copy Next.js output to renderer
- Configure electron-vite to work with pre-built Next.js app
- Create placeholder renderer entry for electron-vite compatibility
…upport

- Add frameless window with frame: false
- Add custom TitleBar component with traffic lights (macOS) and window controls (Windows)
- Update SidebarShell to support desktop mode with transparent background
- Add -webkit-app-region drag/no-drag for proper titlebar interaction
- Main content area has rounded left edge for glass effect on desktop
…yout

- Remove separate TitleBar component
- Add macOS traffic lights (close/minimize/maximize) in sidebar header
- Sidebar transparent with glass effect on desktop
- Main content area with rounded left corners
- Collapsible sidebar with resize handle
- Nexu-style color scheme and hover states
Next.js 16 defaults to Turbopack for `next dev`, but with Node.js v24
and multiple lockfiles in parent directories, Turbopack mis-detects the
workspace root (picks up ~/pnpm-lock.yaml), causing RSC payload fetch
failures (TypeError: Failed to fetch) during client-side navigation.
This made sidebar tab clicks appear unresponsive.

Add --webpack flag to the dev script to use webpack instead, which does
not have this workspace root detection issue.
- Fix Electron detection in webview: shell now injects __DEEPTUTOR_DESKTOP__
  and __DEEPTUTOR_PLATFORM__ flags via dom-ready, SidebarShell reads them
  instead of broken UA/window.electron checks
- Fix utility layout: pass children through UtilitySidebar → SidebarShell
  (align with WorkspaceSidebar pattern), remove duplicate <main>
- Fix content area width: remove overriding width:100% inline style,
  remove shell's dom-ready CSS injection that broke flex-1 layout
- Add traffic light spacer: 80px drag region at top of sidebar on macOS,
  expand icon keeps same vertical position when collapsed
- Add 30px gap between logo area and navigation tabs
- Remove custom traffic light buttons (redundant with native macOS ones)
- Generate 1024x1024 PNG icon with light background (#fafafa) and logo at 82%
- Replace placeholder SVG with owl-themed DeepTutor brand icon
- Set BrowserWindow icon and macOS dock icon in main process
- Add explicit icon paths in electron-builder.yml for all platforms
…plify draft delete

- Remove shell's .window-drag-bar overlay that blocked clicks on webview content
  (SidebarShell already handles drag regions via WebkitAppRegion)
- Add double-click to maximize/restore on traffic light spacer area
  (shell injects __DEEPTUTOR_MAXIMIZE__ bridge via console-message)
- Replace two-click draft delete with window.confirm() tip dialog
  on Co-Writer home page for clearer UX
- Keep desktop-dev changes: workspace prop, children passthrough in sidebar
- Accept upstream/dev additions: AdminLink, LogoutButton in footerSlot
- Accept upstream/dev changes: NEXT_PUBLIC_AUTH_ENABLED in .env.local
- Keep desktop-dev additions: desktop mode config in .env.local
- onDeleteSession → onDelete to match SessionList's interface
- onRenameSession → onRename to match SessionList's interface
- Fixes Runtime TypeError: onDelete is not a function
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant