Skip to content

feat: 014 — new focus from tray - #12

Merged
archae0pteryx merged 2 commits into
mainfrom
feat/014-new-focus-tray
May 2, 2026
Merged

feat: 014 — new focus from tray#12
archae0pteryx merged 2 commits into
mainfrom
feat/014-new-focus-tray

Conversation

@archae0pteryx

@archae0pteryx archae0pteryx commented May 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds "+ New Focus" item at top of tray NSMenu (above focus list, separated by a divider)
  • Clicking opens a dedicated 320×180 new-focus WebviewWindow (decorations: false, transparent: true, visible: false at launch)
  • Second click while window is already open brings it to front without creating a duplicate
  • Form submits via existing create_focus Tauri command; window hides on success
  • Escape key or Cancel button hides without creating

Implementation notes

  • new-focus.html / src/new-focus.tsx — separate Vite entry point so main overlay bundle stays lean
  • NewFocusWindow — always-visible form (no toggle button), resets state on submit/cancel
  • Vite rollupOptions.input for multi-page production build
  • @types/node added (devDep) for path.resolve in vite config
  • capabilities/default.json: new-focus window added to windows list

Test plan

  • task check green (CI)
  • Open tray → "+ New Focus" appears at top
  • Click it → small form window opens
  • Fill title, submit → focus created, pig spawns within 1s, window closes
  • Empty title → inline error, no close
  • Cancel or Escape → window hides, nothing created
  • Click "+ New Focus" while window open → window brought to front, not duplicated

Closes #7

Summary by CodeRabbit

  • New Features

    • Added a compact "New Focus" window (small, fixed size, transparent) to create focus items with title and optional description.
    • Accessible from the system tray via a "+ New Focus" menu item; window opens and gains focus when selected.
    • Press Escape to close the window and clear input/error state.
  • Chores

    • Build updated to include the new window entry and entry point.
  • Dependencies

    • Added a dev dependency for type support.

@coderabbitai

coderabbitai Bot commented May 2, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8c0c025f-d5ea-46ff-871c-2b1a5ac7273f

📥 Commits

Reviewing files that changed from the base of the PR and between a4463b6 and b871032.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (9)
  • new-focus.html
  • package.json
  • src-tauri/capabilities/default.json
  • src-tauri/src/app/tray.rs
  • src-tauri/tauri.conf.json
  • src/components/NewFocusWindow.tsx
  • src/hooks/useNewFocusWindow.ts
  • src/new-focus.tsx
  • vite.config.ts

📝 Walkthrough

Walkthrough

Adds a dedicated "New Focus" Tauri webview and UI, a tray menu item to open it, a React entry point and hook for the form, and build/config updates to include the new HTML entry. The window is hidden by default and shown/focused from the tray.

Changes

New Focus Window Feature

Layer / File(s) Summary
Window & Capability Configuration
src-tauri/tauri.conf.json, src-tauri/capabilities/default.json
New Tauri window label: "new-focus" added to app.windows (loads new-focus.html, 320×180, non-resizable, transparent, visible: false). capabilities/default.json windows array expanded to include "new-focus".
Build System Setup
vite.config.ts, new-focus.html, package.json
Vite rollup input registers new-focus.html as a second entry (newFocus). Added minimal new-focus.html with #root and module script to /src/new-focus.tsx. @types/node added to devDependencies.
Frontend Entry & Wiring
src/new-focus.tsx, src/components/NewFocusWindow.tsx, src/hooks/useNewFocusWindow.ts
New React entry src/new-focus.tsx mounts NewFocusApp. NewFocusWindow presentational component added (controlled props: title, description, submitting, error, handlers). useNewFocusWindow hook implements state, submit/cancel handlers, Escape key behavior, calls focusWriter.createFocus, and hides the window via getCurrentWindow().hide().
Tray Menu Integration
src-tauri/src/app/tray.rs
Tray menu prepends a "+ New Focus" item (NEW_FOCUS_ID) and separator. Menu event handler handles NEW_FOCUS_ID by finding the new-focus webview and calling show() and set_focus().

Sequence Diagram

sequenceDiagram
    actor User
    participant Tray as Tray Menu
    participant Backend as Tauri Backend
    participant Window as New Focus Webview
    participant UI as NewFocusWindow (React)
    participant Cmd as create_focus Command

    User->>Tray: Click "+ New Focus"
    Tray->>Backend: emit menu event NEW_FOCUS_ID
    Backend->>Window: show() and set_focus()
    Window->>UI: mount / render form
    User->>UI: enter title & description
    User->>UI: submit
    UI->>UI: validate title non-empty
    alt valid
        UI->>Cmd: invoke("create_focus",{title,description})
        Cmd->>Backend: create focus
        Cmd-->>UI: success
        UI->>Window: hide()
    else invalid
        UI->>UI: set error state
    end
    alt cancel or Escape
        User->>UI: cancel / press Escape
        UI->>Window: hide()
    end
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

Poem

🐰
A tiny window pops from the tray,
A field to name a focus today,
Tap create, watch a piglet hop—
The window hides, the new plan's on top,
Hooray for small things in a big array!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: 014 — new focus from tray' clearly summarizes the main change: adding a 'New Focus' feature accessible from the tray menu, matching the core objective of implementing tray menu action that opens a dedicated window.
Linked Issues check ✅ Passed The PR implementation fulfills all coding requirements from issue #7: tray menu item added [tray.rs], new-focus window configured [tauri.conf.json, capabilities], NewFocusWindow component created [NewFocusWindow.tsx], separate entry point established [new-focus.tsx, new-focus.html, vite.config.ts], and create_focus command reused without duplication.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the new-focus feature: HTML/TSX entry points, Tauri window configuration, tray menu action, React component, build configuration, and dependencies—no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/014-new-focus-tray

Review rate limit: 8/10 reviews remaining, refill in 9 minutes and 19 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/NewFocusWindow.tsx`:
- Around line 1-82: NewFocusWindow currently performs Tauri I/O and window
lifecycle (invoke, getCurrentWindow, hideWindow, useEffect keyboard handler and
handleSubmit), which violates the view-only components rule; refactor by moving
all Tauri calls and stateful lifecycle into src/new-focus.tsx (or a new hook
useNewFocusWindow) and keep NewFocusWindow purely presentational: remove invoke,
getCurrentWindow, hideWindow, useEffect, handleSubmit and instead accept props
like title, description, setTitle, setDescription, submitting, error, onSubmit,
and onCancel (or an onCreate callback receiving {title,description} and an
onHide/onCancel callback) so the parent/hook handles create_focus invocation and
window hide/show logic and passes callbacks into the NewFocusWindow component.
- Around line 35-38: The code in NewFocusWindow.tsx currently sends description:
description.trim() || null to the invoke("create_focus", ...) call which
serializes null and breaks Rust deserialization for CreateFocusInput (expects a
String with serde(default)); change the payload to send an empty string instead
by removing the "|| null" so description is always a string (use
description.trim() only) when calling invoke("create_focus", ...).

In `@vite.config.ts`:
- Around line 12-19: The Vite ESM config currently uses __dirname in
build.rollupOptions.input (where resolve(..., "index.html") and resolve(...,
"new-focus.html") are called) but __dirname is not defined in ESM; add an
ESM-safe directory helper at the top of the config using import.meta.url and
fileURLToPath to derive a dirname (or compute a baseDir via
path.dirname(fileURLToPath(import.meta.url))), then use that derived dirname
when calling resolve for the "index.html" and "new-focus.html" entries so the
paths resolve correctly in ESM.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2ea711e4-1fd5-4636-9798-43fe0ce032a2

📥 Commits

Reviewing files that changed from the base of the PR and between 14f42a1 and a4463b6.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (8)
  • new-focus.html
  • package.json
  • src-tauri/capabilities/default.json
  • src-tauri/src/app/tray.rs
  • src-tauri/tauri.conf.json
  • src/components/NewFocusWindow.tsx
  • src/new-focus.tsx
  • vite.config.ts

Comment thread src/components/NewFocusWindow.tsx Outdated
Comment thread src/components/NewFocusWindow.tsx Outdated
Comment thread vite.config.ts
Add "+ New Focus" tray menu item that opens a small dedicated webview
window (320×180, no decorations, transparent). Clicking the item shows
and focuses the window; a second click brings it to front without
creating a duplicate. Submitting creates the focus via create_focus and
hides the window; Escape/Cancel also hides.

- new-focus.html + src/new-focus.tsx: separate entry point so the main
  overlay bundle stays lean
- NewFocusWindow: always-visible form, resets on submit/cancel
- vite multi-page build via rollupOptions.input
- @types/node added for path.resolve in vite config
- capabilities/default.json: new-focus window added to windows list
- vite.config.ts: use fileURLToPath(import.meta.url) for ESM-safe __dirname
- NewFocusWindow: extract Tauri I/O into useNewFocusWindow hook; component
  is now purely presentational (props-only, no invoke/window calls)
- new-focus.tsx: wire useNewFocusWindow hook + NewFocusWindow component
- description sent as empty string (not null) via focusWriter.createFocus
@archae0pteryx
archae0pteryx force-pushed the feat/014-new-focus-tray branch from a4463b6 to b871032 Compare May 2, 2026 22:12
@archae0pteryx
archae0pteryx merged commit d54f751 into main May 2, 2026
1 of 2 checks passed
@archae0pteryx
archae0pteryx deleted the feat/014-new-focus-tray branch May 2, 2026 22:13
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.

014 — New Focus from tray

1 participant