Skip to content

feat: add auto-start and minimize to tray feature#1301

Open
g-k-s-03 wants to merge 10 commits into
AOSSIE-Org:mainfrom
g-k-s-03:feature/auto-start-minimize-tray
Open

feat: add auto-start and minimize to tray feature#1301
g-k-s-03 wants to merge 10 commits into
AOSSIE-Org:mainfrom
g-k-s-03:feature/auto-start-minimize-tray

Conversation

@g-k-s-03

@g-k-s-03 g-k-s-03 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Fixes #817
This PR implements two system integration features:

  1. Auto Start — uses tauri-plugin-autostart to register the app
    with the system startup manager. User can enable/disable via
    a toggle in Settings → General. When launched at boot, the app
    starts minimized to the system tray.

  2. Minimize to Tray — closing the window now hides the app to the
    system tray instead of exiting. A tray icon with a context menu
    (Show / Quit) allows the user to restore the window or fully
    exit the app.

Tested on Windows. The tauri-plugin-autostart plugin handles
macOS and Linux platform support internally.

Also fixed a duplicate core:tray:default entry in
capabilities/migrated.json.

Screenshot 2026-06-02 045312 Screenshot 2026-06-02 045409 Screenshot 2026-06-02 045420 Screenshot 2026-06-08 100109

Summary by CodeRabbit

  • New Features

    • App now hides to the system tray instead of quitting; tray supports show and quit actions
    • New "Launch at startup" toggle added to System settings; app can start minimized
  • Documentation

    • API docs clarified: POST /images/toggle-favourite now notes it toggles an image’s favorite status
  • Chores

    • Added autostart and tray support dependencies
  • Tests

    • Updated tests and mocks to await and verify the startup toggle behavior

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Looking for one thing? Review this PR in Change Stack to search files, summaries, diffs, and code without losing your place.

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds autostart and minimize-to-tray behavior to the Tauri desktop app: dependency and capability updates, tray UI and autostart commands, a Settings UI toggle with tests/mocks, and a small OpenAPI operation description addition.

Changes

Application Behavior Settings

Layer / File(s) Summary
Tauri dependencies and capabilities
frontend/src-tauri/Cargo.toml, frontend/src-tauri/capabilities/migrated.json
Add tray-icon feature to tauri, add tauri-plugin-autostart = "2", and include "autostart:default" capability while adjusting tray capability ordering.
Window lifecycle, tray UI, and autostart commands
frontend/src-tauri/src/main.rs
Intercept CloseRequested to hide the window; add enable_autostart, disable_autostart, is_autostart_enabled Tauri commands; configure autostart plugin with --minimized; hide main window on minimized startup; build tray with Show/Quit and left-click handlers; register new invokes.
Frontend autostart toggle UI
frontend/src/pages/SettingsPage/components/SystemSettingsCard.tsx, frontend/src/pages/SettingsPage/Settings.tsx
New SystemSettingsCard component queries initial autostart status, renders an accessible switch-style toggle, invokes enable/disable commands, and is integrated into Settings page general tab.
Tests and mocks
frontend/jest.setup.ts, frontend/src/pages/__tests__/*
Jest Tauri invoke mock now switches by command; Settings tests updated to await the autostart switch and use accessible-name queries and async setup.
Backend formatting & OpenAPI
backend/app/database/images.py, backend/app/routes/images.py, docs/backend/backend_python/openapi.json
Minor SQL/formatting edits in images DB and routes, and add description field to POST /images/toggle-favourite in OpenAPI spec.

Sequence Diagram

sequenceDiagram
  participant Frontend as Frontend React
  participant TauriCmds as Tauri Commands main.rs
  participant Autolaunch as Autolaunch Plugin
  participant Tray as System Tray
  participant Window as Main Window
  participant App as Tauri App Process

  Frontend->>TauriCmds: is_autostart_enabled
  TauriCmds->>Autolaunch: is_enabled
  Autolaunch-->>TauriCmds: bool
  TauriCmds-->>Frontend: result bool or error string

  Frontend->>TauriCmds: enable_autostart or disable_autostart
  TauriCmds->>Autolaunch: enable or disable
  Autolaunch-->>TauriCmds: success or error
  TauriCmds-->>Frontend: result unit or error string

  Note over Window: CloseRequested is intercepted and window is hidden
  Tray->>Window: Show action triggers show and focus
  Tray->>App: Quit action triggers process tree kill and app exit
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • AOSSIE-Org/PictoPy#515: Changes to Tauri invoke handler that may conflict with new autostart command registrations.
  • AOSSIE-Org/PictoPy#606: Settings page restructuring; this PR adds SystemSettingsCard into the general tab.

Suggested labels

Python, TypeScript/JavaScript, Rust, Documentation, Linter

Suggested reviewers

  • rohan-pandeyy

Poem

🐇 In the tray I tuck my ears at night,
then wake at boot in morning light.
A toggle flips, a window hides,
yet softly in the background bides.
Hop-hop, new settings feel just right.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add auto-start and minimize to tray feature' directly and specifically describes the main changes in the pull request: adding auto-start functionality and minimize-to-tray behavior.
Linked Issues check ✅ Passed The PR implements all core requirements from issue #817: auto-start with tauri-plugin-autostart integration and platform support [#817], minimize-to-tray with system tray context menu [#817], and Settings UI toggle for user control [#817].
Out of Scope Changes check ✅ Passed Changes are focused on feature implementation with minor supporting updates: duplicated tray capability removal (in-scope housekeeping), test updates for new UI components, Jest mock updates for new Tauri commands, and formatting of existing backend functions.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added enhancement New feature or request frontend labels Jun 1, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/backend/backend_python/openapi.json`:
- Line 896: The OpenAPI description uses American spelling "favorite" but the
endpoint and schema use British spelling; update the description string for the
"/toggle-favourite" operation to use "favourite" (e.g., "Toggle the favourite
status of an image.") and check the related schema name ToggleFavouriteRequest
and any other description fields for the same consistency to ensure all
user-facing docs use "favourite".

In `@frontend/src-tauri/src/main.rs`:
- Line 243: The .icon call uses app.default_window_icon().unwrap().clone() which
can panic; instead convert the Option to a Result and propagate the error from
the setup closure. Replace the unwrap usage in the .icon invocation (around
default_window_icon) with a safe conversion (e.g., call .ok_or / ok_or_else to
produce an error value and use ? to return it) so setup returns Err when no
default icon is present rather than panicking.
- Around line 242-273: The tray left-click handler (inside TrayIconBuilder
.on_tray_icon_event using TrayIconEvent::Click and MouseButton::Left) will
conflict with Tauri v2's default menu_on_left_click behavior; update the
TrayIconBuilder chain to call .menu_on_left_click(false) so left-click only
triggers your restore logic (show/set_focus in the on_tray_icon_event) and the
context menu remains on right-click.

In `@frontend/src/pages/SettingsPage/components/SystemSettingsCard.tsx`:
- Around line 17-25: The handler handleToggle can fire multiple invoke(...)
calls concurrently causing out-of-order resolution and stale UI; add a local
pending boolean state (e.g., isToggling) and short-circuit if isToggling is
true, set isToggling = true before calling invoke and set it false in finally,
disable the switch control while isToggling is true, compute the intended new
value from the current autostart at the moment of click (const next =
!autostart) and only call setAutostart(next) after a successful invoke (and
consider reading the confirmed value from the response if available) to ensure
the toggle reflects the last user action; update both occurrences of
handleToggle (lines shown) accordingly.
- Around line 6-70: Add a React Testing Library test suite for
SystemSettingsCard that mocks the invoke bridge to cover mount-time fetch,
toggle success, and error paths: mock invoke('is_autostart_enabled') to return
true/false and assert initial switch state and loading behavior (verify disabled
while loading and role="switch" aria-checked updates), mock invoke for
'enable_autostart'/'disable_autostart' to resolve and assert the UI flips state
when the button is clicked, and mock invoke to reject to assert the error path
leaves state unchanged and optionally logs; use render, waitFor (or findBy*),
and fireEvent/click to drive the component and restore/reset mocks between tests
so the mount effect and handleToggle flows are fully covered.
- Around line 33-64: The switch control in SystemSettingsCard is missing an
accessible name and description; add IDs for the visible label ("Launch at
startup") and its helper text then reference them from the button via
aria-labelledby and aria-describedby (keeping existing role="switch",
aria-checked={autostart}, disabled={loading}, and onClick={handleToggle});
ensure the IDs are unique within the component and used where the label and
helper text are rendered so assistive tech announces both the name and the
description.
- Around line 11-14: The current promise chain calling
invoke<boolean>('is_autostart_enabled') swallows errors and unconditionally
calls setAutostart(false) on failure; instead preserve an explicit unknown/error
state and keep the control disabled until a successful read. Change the state
used by SystemSettingsCard (the state set by setAutostart) to allow a tri-state
(true | false | null or an explicit error flag), update the promise catch to set
the state to null/error rather than false, ensure setLoading still flips off in
finally, and update any toggle/handler logic to no-op or stay disabled when
autostart is null so the UI does not falsely show disabled and avoid calling
enable_autostart when the real status is unknown; locate this logic around the
invoke call and the setAutostart usage (and the toggle handler) to implement the
change.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7e50fbb4-03f3-49a1-8b39-a72d45b0ef81

📥 Commits

Reviewing files that changed from the base of the PR and between ffd438a and f689f4d.

⛔ Files ignored due to path filters (2)
  • frontend/package-lock.json is excluded by !**/package-lock.json
  • frontend/src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • docs/backend/backend_python/openapi.json
  • frontend/src-tauri/Cargo.toml
  • frontend/src-tauri/capabilities/migrated.json
  • frontend/src-tauri/src/main.rs
  • frontend/src/pages/SettingsPage/Settings.tsx
  • frontend/src/pages/SettingsPage/components/SystemSettingsCard.tsx

Comment thread docs/backend/backend_python/openapi.json
Comment thread frontend/src-tauri/src/main.rs
Comment thread frontend/src-tauri/src/main.rs Outdated
Comment thread frontend/src/pages/SettingsPage/components/SystemSettingsCard.tsx
Comment thread frontend/src/pages/SettingsPage/components/SystemSettingsCard.tsx Outdated
Comment thread frontend/src/pages/SettingsPage/components/SystemSettingsCard.tsx
Comment thread frontend/src/pages/SettingsPage/components/SystemSettingsCard.tsx
@rohan-pandeyy

Copy link
Copy Markdown
Member

@g-k-s-03 please fix the lint errors and address the frontend failures

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/src/pages/__tests__/PageSanity.test.tsx (1)

30-30: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove or update the outdated sync-render comment.

This comment now conflicts with the async findByRole wait and is misleading during future test maintenance.

As per coding guidelines, "Verify that documentation and comments are free of spelling mistakes".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/pages/__tests__/PageSanity.test.tsx` at line 30, The trailing
comment "Settings is expected to render synchronously." in the
PageSanity.test.tsx test block is now misleading because the test uses async
utilities (findByRole); remove or replace that comment with a short, accurate
note referencing the async behavior (e.g., "Settings renders asynchronously;
using findByRole to await render") so future maintainers see the correct
expectation; update the comment next to the closing of the test block that
currently reads the outdated text and ensure spelling matches project
guidelines.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/pages/__tests__/SettingsPage.test.tsx`:
- Around line 7-12: The test currently only asserts presence of the "launch at
startup" switch; update setupTest / the test suite for Settings to also simulate
user interaction with that switch (use the user returned from setupTest to click
the switch found by role 'switch' name /launch at startup/i), then assert the
expected outcome: either that the autostart IPC/command was invoked (mock and
expect the handler/spied method was called, e.g., mock the autostart toggle IPC
or module used by Settings) or that the switch's checked state (aria-checked or
component state) toggled accordingly; add this behavior assertion in the same
test (and mirror similar assertions for tests between lines 14-118) so the test
verifies the actual autostart toggle effect rather than only presence.

---

Outside diff comments:
In `@frontend/src/pages/__tests__/PageSanity.test.tsx`:
- Line 30: The trailing comment "Settings is expected to render synchronously."
in the PageSanity.test.tsx test block is now misleading because the test uses
async utilities (findByRole); remove or replace that comment with a short,
accurate note referencing the async behavior (e.g., "Settings renders
asynchronously; using findByRole to await render") so future maintainers see the
correct expectation; update the comment next to the closing of the test block
that currently reads the outdated text and ensure spelling matches project
guidelines.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5d0677f5-b7a1-4ab4-a6b6-73f3d0291a34

📥 Commits

Reviewing files that changed from the base of the PR and between dcffffb and b413c55.

📒 Files selected for processing (3)
  • frontend/jest.setup.ts
  • frontend/src/pages/__tests__/PageSanity.test.tsx
  • frontend/src/pages/__tests__/SettingsPage.test.tsx

Comment thread frontend/src/pages/__tests__/SettingsPage.test.tsx
@g-k-s-03

g-k-s-03 commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

@rohan-pandeyy done, please review

@g-k-s-03

g-k-s-03 commented Jun 6, 2026

Copy link
Copy Markdown
Contributor Author

@rohan-pandeyy done, addressed the spelling inconsistency.

@g-k-s-03

g-k-s-03 commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

@rohan-pandeyy Implemented the close-to-tray toggle as discussed
in the Saturday meeting.
New behavior:

  • Close to tray toggle ON :- clicking X hides window to tray,
    backend keeps running in background
  • Close to tray toggle OFF :- clicking X kills backend processes
    and exits completely (original behavior restored)
    This gives users full control over close behavior, similar to
    how Spotify handles it.
    Screenshots attached.

@rohan-pandeyy

Copy link
Copy Markdown
Member

@g-k-s-03, can you test the implementation in production? You'll need to run the build-and-release.yml workflow in your fork branch and test both "Auto start" and "Minimize to tray" options.

For information regarding how to correctly get a build in your fork branch, you can follow this message: #1295 (comment)

@g-k-s-03 g-k-s-03 requested a review from rohan-pandeyy June 8, 2026 04:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request frontend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feat: Implement Application Behavior Settings

2 participants