Skip to content

added icon, toast sonner and also new window opening#4

Merged
anirudhisonline merged 3 commits into
mainfrom
custom-window-toast-icons
May 6, 2026
Merged

added icon, toast sonner and also new window opening#4
anirudhisonline merged 3 commits into
mainfrom
custom-window-toast-icons

Conversation

@anirudhisonline
Copy link
Copy Markdown
Contributor

@anirudhisonline anirudhisonline commented May 5, 2026

Summary by CodeRabbit

  • New Features

    • Open/manage folders in separate app windows via an Open Folder action
    • Draggable app header showing project/folder name with Windows window controls
    • Toast notifications for game outcomes, resets, and theme changes
    • Integrated in-app toaster for consistent notifications
    • App icon and background resources added for Android
  • Style

    • Root layout adjusted to fill viewport and prevent page scrolling

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: afe2d44c-928f-4c82-ab6e-b8f98b0f788a

📥 Commits

Reviewing files that changed from the base of the PR and between 6f47397 and b850e68.

📒 Files selected for processing (1)
  • src/routes/+page.svelte

📝 Walkthrough

Walkthrough

Adds UI-driven folder-opening via Tauri dialogs and WebviewWindow(s), integrates Sonner toasts across the app (theme changes, game events, folder actions), registers the Tauri dialog plugin and related capability permissions, and introduces an /app route and app shell that reads a path search param for folder display.

Changes

Folder Webview + Toast Integration

Layer / File(s) Summary
Dependencies & Native Plugins
package.json, src-tauri/Cargo.toml
Adds @tauri-apps/plugin-dialog and runed to JS deps, svelte-sonner to devDeps; adds tauri-plugin-dialog and urlencoding to Tauri Cargo dependencies.
Tauri Capabilities / Permissions
src-tauri/capabilities/default.json, src-tauri/capabilities/folder-windows.json
Adds dialog:allow-open and core:webview:allow-create-webview-window to default permissions; introduces folder-windows capability scoped to folder-* with window, dialog, webview-create, and OS permissions.
Tauri Plugin Registration
src-tauri/src/lib.rs
Registers the dialog plugin via .plugin(tauri_plugin_dialog::init()) in the tauri::Builder chain.
Frontend: Toast Infrastructure
src/lib/components/ui/sonner/sonner.svelte, src/lib/components/ui/sonner/index.js
Adds a Sonner wrapper component that binds theme from mode-watcher, provides themed icons, forwards props, and exports Toaster.
Root Layout Integration & Styles
src/routes/+layout.svelte, src/routes/layout.css
Renders <Toaster /> in root layout and adds html, body { overflow: hidden; height: 100%; }.
Theme Toggle Feedback
src/lib/components/themetoggle.svelte
Theme dropdown items now call setMode/resetMode then show a toast describing the chosen mode.
Folder Open Flow (Frontend)
src/routes/+page.svelte
Adds openFolder() that uses Tauri dialog to pick a directory, encodes the path, creates a WebviewWindow at /app?path=<encoded>, and shows success/error toasts; wires Open Folder button to it; also adds toasts for game outcomes and reset.
App Shell & Folder Display
src/routes/app/+layout.svelte, src/routes/app/+page.svelte
Adds an app layout with draggable header and optional Windows controls; derives folderPath and folderName from path search param and renders them on the app page.
Assets & Misc
src-tauri/icons/android/..., .gitignore
Adds Android adaptive icon XML files and adds shhh.md to .gitignore.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant Frontend as Frontend UI
    participant FileDialog as Tauri File Dialog
    participant WindowAPI as WebviewWindow API
    participant AppWindow as /app Webview
    participant Toast as Toast System

    User->>Frontend: Click "Open Folder"
    Frontend->>FileDialog: openDialog({ directory: true })
    FileDialog-->>Frontend: returns folderPath
    Frontend->>WindowAPI: new WebviewWindow("/app?path=<encoded>")
    WindowAPI->>AppWindow: create & load /app with path param
    AppWindow->>AppWindow: read search param, render folderName/path
    Frontend->>Toast: show success/error toasts for actions/events
    Toast->>User: displays notification
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • takerestdev/takerest#3: Modifies Tauri native setup and capability permissions—related to the plugin/capability updates here.
  • takerestdev/takerest#2: Touches theme UI and top-level layout integrations—related to Sonner/toast and layout changes.

Poem

🐰 I hopped a folder open with a cheerful tap,
Toasts chimed greetings while I set the map,
Windows opened wide and paths unfurled,
Icons danced, themes twinkled, folders twirled,
A little rabbit cheers the multi-window world!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title partially captures the main changes (toast notifications and new window opening) but is grammatically awkward and lacks clarity about the primary objective. Consider revising the title to be more concise and grammatically correct, such as 'Add toast notifications, window dialog support, and app icons' or similar.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch custom-window-toast-icons

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (5)
src-tauri/icons/android/values/ic_launcher_background.xml (1)

3-3: ⚡ Quick win

Consider using a brand color instead of pure white for better visibility.

Pure white (#fff) as the launcher icon background may reduce visibility on launchers with light themes, making the icon harder to locate. Android's adaptive icon guidelines recommend using brand colors to improve recognition and ensure the icon stands out across different launcher backgrounds.

🤖 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 `@src-tauri/icons/android/values/ic_launcher_background.xml` at line 3, Replace
the pure white background color for the launcher by updating the color resource
named "ic_launcher_background" to a branded color (e.g., your primary brand hex
or a reference like `@color/brand_primary`) so the adaptive launcher icon stands
out on light themes; locate the <color name="ic_launcher_background"> entry and
change "#fff" to your chosen brand hex (or a color resource reference) and
verify contrast across light/dark launchers.
src/routes/layout.css (1)

10-13: ⚡ Quick win

Scope the scroll lock to the custom window route.

Lines 10-13 live in the app-wide stylesheet imported by src/routes/+layout.svelte, so this disables document scrolling for every route, not just the new folder window. If the intent is only to hide root scrollbars in /app, move overflow: hidden behind a route-scoped layout or wrapper instead of making it global.

🤖 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 `@src/routes/layout.css` around lines 10 - 13, The global rule targeting html,
body with overflow: hidden is applied app-wide; restrict the scroll lock to only
the custom window route by removing or changing the html, body { overflow:
hidden } rule and instead placing overflow: hidden on a route-scoped wrapper
(e.g., the custom window container element or the route's +layout component)
that wraps the /app window. Update the selector in the route-scoped layout or
the custom window component (the wrapper class/ID used to render that route) so
only that element disables scrolling, leaving the global html/body styles
untouched.
src/routes/+page.svelte (1)

10-10: ⚡ Quick win

Unused import: invoke is imported but never used.

The invoke function from @tauri-apps/api/core is not referenced anywhere in this file. Since the openFolder() function creates windows directly via WebviewWindow rather than invoking the Rust command, this import can be removed.

🧹 Proposed fix
-  import { invoke } from "@tauri-apps/api/core";
🤖 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 `@src/routes/`+page.svelte at line 10, Remove the unused import of invoke from
"@tauri-apps/api/core" since it is never referenced; locate the import statement
(import { invoke } from "@tauri-apps/api/core") at the top of the file and
delete it—leave the openFolder() function and WebviewWindow usage unchanged.
src/routes/app/+layout.svelte (2)

35-36: 💤 Low value

Consider using $derived for reactive path values.

$state(params.path) captures the initial value and won't update if params.path changes. If the query param could change during the component's lifetime, these should be derived:

♻️ Proposed fix
-    let folderPath = $state(params.path);
-    let folderName = $state(folderPath.split(/[\\/]/).filter(Boolean).pop() ?? "Project");
+    let folderPath = $derived(params.path);
+    let folderName = $derived(folderPath.split(/[\\/]/).filter(Boolean).pop() ?? "Project");
🤖 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 `@src/routes/app/`+layout.svelte around lines 35 - 36, The current code uses
let folderPath = $state(params.path) and let folderName =
$state(folderPath.split(/[\\/]/).filter(Boolean).pop() ?? "Project"), which
reads a snapshot and won't update when params.path changes; replace these with
derived stores so folderPath and folderName react to updates: create a derived
store from state(params.path) (using $derived or derived(state, ...)) for
folderPath, then derive folderName from that derived folderPath (splitting and
defaulting to "Project") so both update automatically when params.path changes.

21-23: ⚡ Quick win

Unused function: isWindowsPlatform is defined but never called.

This function duplicates the logic already performed in onMount. Consider removing it.

🧹 Proposed fix
-    async function isWindowsPlatform(params) {
-        return (await platform()) === "windows";
-    }
🤖 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 `@src/routes/app/`+layout.svelte around lines 21 - 23, The function
isWindowsPlatform is unused and duplicates logic already in the onMount block;
remove the isWindowsPlatform function declaration to eliminate dead code (or
alternatively replace the inline platform check in onMount with a call to
isWindowsPlatform if you prefer DRY, referencing the function name
isWindowsPlatform and the onMount usage) — update imports/usages accordingly and
run tests/lint to ensure no remaining references.
🤖 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 `@src-tauri/capabilities/folder-windows.json`:
- Around line 6-17: The folder-window capabilities JSON currently grants
privileged APIs that the folder route (+page.svelte) does not use; remove the
unnecessary entries "dialog:allow-open" and
"core:webview:allow-create-webview-window" from the permissions array in
folder-windows.json (keep core:default, core:window/* and other non-privileged
entries), and verify no other privileged APIs remain so only the main window
retains dialog/Webview permissions.

In `@src-tauri/src/lib.rs`:
- Around line 21-22: The current manual encoding using path.replace(' ', "%20")
only handles spaces and breaks on special characters; replace that logic by
using the urlencoding crate to percent-encode the full path (use
urlencoding::encode on the path variable) and then use the returned encoded
string when building the url variable (the encoded/local variables in this code
snippet are encoded and url). Ensure you call to_string() or otherwise convert
the encoded result into a String before passing it to format! so the final url
is fully percent-encoded.

In `@src/routes/`+page.svelte:
- Around line 69-74: Replace the console-only error handling in the window
creation path with user-facing notifications: in the win.once("tauri://error",
...) handler and in the catch block that logs "Failed to open window:", invoke
the app's toast/notification API or dispatch a Svelte store update to show a
concise, user-friendly error toast (include a short message and optional
sanitized error detail for support). Ensure you reference the same win.once
handler and the catch block around the window-opening call so both async error
events and thrown exceptions surface a visible toast to the user.

---

Nitpick comments:
In `@src-tauri/icons/android/values/ic_launcher_background.xml`:
- Line 3: Replace the pure white background color for the launcher by updating
the color resource named "ic_launcher_background" to a branded color (e.g., your
primary brand hex or a reference like `@color/brand_primary`) so the adaptive
launcher icon stands out on light themes; locate the <color
name="ic_launcher_background"> entry and change "#fff" to your chosen brand hex
(or a color resource reference) and verify contrast across light/dark launchers.

In `@src/routes/`+page.svelte:
- Line 10: Remove the unused import of invoke from "@tauri-apps/api/core" since
it is never referenced; locate the import statement (import { invoke } from
"@tauri-apps/api/core") at the top of the file and delete it—leave the
openFolder() function and WebviewWindow usage unchanged.

In `@src/routes/app/`+layout.svelte:
- Around line 35-36: The current code uses let folderPath = $state(params.path)
and let folderName = $state(folderPath.split(/[\\/]/).filter(Boolean).pop() ??
"Project"), which reads a snapshot and won't update when params.path changes;
replace these with derived stores so folderPath and folderName react to updates:
create a derived store from state(params.path) (using $derived or derived(state,
...)) for folderPath, then derive folderName from that derived folderPath
(splitting and defaulting to "Project") so both update automatically when
params.path changes.
- Around line 21-23: The function isWindowsPlatform is unused and duplicates
logic already in the onMount block; remove the isWindowsPlatform function
declaration to eliminate dead code (or alternatively replace the inline platform
check in onMount with a call to isWindowsPlatform if you prefer DRY, referencing
the function name isWindowsPlatform and the onMount usage) — update
imports/usages accordingly and run tests/lint to ensure no remaining references.

In `@src/routes/layout.css`:
- Around line 10-13: The global rule targeting html, body with overflow: hidden
is applied app-wide; restrict the scroll lock to only the custom window route by
removing or changing the html, body { overflow: hidden } rule and instead
placing overflow: hidden on a route-scoped wrapper (e.g., the custom window
container element or the route's +layout component) that wraps the /app window.
Update the selector in the route-scoped layout or the custom window component
(the wrapper class/ID used to render that route) so only that element disables
scrolling, leaving the global html/body styles untouched.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 13e1f442-abf3-403d-b542-c9232535bd36

📥 Commits

Reviewing files that changed from the base of the PR and between 35d29cb and 2b3a8fb.

⛔ Files ignored due to path filters (55)
  • app-icon.png is excluded by !**/*.png
  • bun.lock is excluded by !**/*.lock
  • src-tauri/Cargo.lock is excluded by !**/*.lock
  • src-tauri/icons/128x128.png is excluded by !**/*.png
  • src-tauri/icons/128x128@2x.png is excluded by !**/*.png
  • src-tauri/icons/32x32.png is excluded by !**/*.png
  • src-tauri/icons/64x64.png is excluded by !**/*.png
  • src-tauri/icons/Square107x107Logo.png is excluded by !**/*.png
  • src-tauri/icons/Square142x142Logo.png is excluded by !**/*.png
  • src-tauri/icons/Square150x150Logo.png is excluded by !**/*.png
  • src-tauri/icons/Square284x284Logo.png is excluded by !**/*.png
  • src-tauri/icons/Square30x30Logo.png is excluded by !**/*.png
  • src-tauri/icons/Square310x310Logo.png is excluded by !**/*.png
  • src-tauri/icons/Square44x44Logo.png is excluded by !**/*.png
  • src-tauri/icons/Square71x71Logo.png is excluded by !**/*.png
  • src-tauri/icons/Square89x89Logo.png is excluded by !**/*.png
  • src-tauri/icons/StoreLogo.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-hdpi/ic_launcher.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-mdpi/ic_launcher.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png is excluded by !**/*.png
  • src-tauri/icons/icon.ico is excluded by !**/*.ico
  • src-tauri/icons/icon.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-20x20@1x.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-20x20@2x-1.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-20x20@2x.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-20x20@3x.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-29x29@1x.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-29x29@2x-1.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-29x29@2x.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-29x29@3x.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-40x40@1x.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-40x40@2x-1.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-40x40@2x.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-40x40@3x.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-512@2x.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-60x60@2x.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-60x60@3x.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-76x76@1x.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-76x76@2x.png is excluded by !**/*.png
  • src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png is excluded by !**/*.png
  • static/svelte.svg is excluded by !**/*.svg
  • static/tauri.svg is excluded by !**/*.svg
  • static/vite.svg is excluded by !**/*.svg
📒 Files selected for processing (17)
  • .gitignore
  • package.json
  • src-tauri/Cargo.toml
  • src-tauri/capabilities/default.json
  • src-tauri/capabilities/folder-windows.json
  • src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml
  • src-tauri/icons/android/values/ic_launcher_background.xml
  • src-tauri/icons/icon.icns
  • src-tauri/src/lib.rs
  • src/lib/components/themetoggle.svelte
  • src/lib/components/ui/sonner/index.js
  • src/lib/components/ui/sonner/sonner.svelte
  • src/routes/+layout.svelte
  • src/routes/+page.svelte
  • src/routes/app/+layout.svelte
  • src/routes/app/+page.svelte
  • src/routes/layout.css

Comment thread src-tauri/capabilities/folder-windows.json
Comment thread src-tauri/src/lib.rs Outdated
Comment thread src/routes/+page.svelte Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@src/routes/`+page.svelte:
- Line 60: The title expression can return an empty string for paths ending with
separators; update the title assignment that currently uses the "selected"
variable (the title: selected.split(/[/\\]/).pop() ?? "Project" line) to ensure
a truthy fallback by removing empty path segments before taking the last element
(e.g., filter(Boolean) on the split result) or by coalescing with || instead of
?? so an empty string falls back to "Project"; modify the title property
accordingly.
- Around line 47-53: The call to openDialog in async function openFolder can
reject before the existing try/catch runs; move the await openDialog({...})
invocation inside the existing try block in openFolder so any rejection is
caught and the catch block (which shows the user-facing toast) executes; update
control flow to return early if selected is falsy after the try so behavior is
unchanged.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8a843107-f32e-4959-a99a-c4228904cf3a

📥 Commits

Reviewing files that changed from the base of the PR and between 2b3a8fb and 6f47397.

📒 Files selected for processing (2)
  • src-tauri/src/lib.rs
  • src/routes/+page.svelte
🚧 Files skipped from review as they are similar to previous changes (1)
  • src-tauri/src/lib.rs

Comment thread src/routes/+page.svelte Outdated
Comment thread src/routes/+page.svelte Outdated
@anirudhisonline anirudhisonline merged commit 8a2644d into main May 6, 2026
1 check passed
@anirudhisonline anirudhisonline deleted the custom-window-toast-icons branch May 6, 2026 00:44
@anirudhisonline anirudhisonline self-assigned this May 7, 2026
@coderabbitai coderabbitai Bot mentioned this pull request May 19, 2026
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