Skip to content

fix(frontend): add Tauri environment detection and safe API wrappers#432

Merged
rahulharpal1603 merged 5 commits intoAOSSIE-Org:mainfrom
Aditya30ag:fix/tauri-environment-detection
Jul 9, 2025
Merged

fix(frontend): add Tauri environment detection and safe API wrappers#432
rahulharpal1603 merged 5 commits intoAOSSIE-Org:mainfrom
Aditya30ag:fix/tauri-environment-detection

Conversation

@Aditya30ag
Copy link
Contributor

@Aditya30ag Aditya30ag commented Jul 1, 2025

FIXED: #433
Implemented environment detection and safe API wrappers to ensure the application works seamlessly in both desktop and browser modes.

  • Add isTauriEnvironment() function for environment detection
  • Create safe wrapper functions for Tauri APIs (invoke, dialog, updater, etc.)
  • Update useUpdater hook to check environment before calling Tauri APIs
  • Update FolderPicker components to use safe wrappers instead of direct imports
  • Add graceful fallbacks and user messaging for browser development mode
  • Fix TypeError: Cannot read properties of undefined errors in browser mode

This enables frontend development in browser mode without crashes while maintaining full functionality in desktop Tauri mode.

Fixes console errors when running 'npm run dev' in browser mode.

Screenshot 2025-07-01 185808

Summary by CodeRabbit

  • New Features

    • Introduced a warning screen for users attempting to run the app in a web browser, explaining that the application requires the Tauri desktop environment and providing setup instructions.
  • Improvements

    • Enhanced update and installation processes to ensure they only run within the Tauri desktop environment, preventing errors in unsupported environments.
    • The app now detects its runtime environment and restricts certain actions to Tauri, improving reliability and user guidance.
    • Updated application configuration with a new version, adjusted bundle targets, and minimum window size requirements for better desktop experience.

- Add isTauriEnvironment() function for environment detection
- Create safe wrapper functions for Tauri APIs (invoke, dialog, updater, etc.)
- Update useUpdater hook to check environment before calling Tauri APIs
- Update FolderPicker components to use safe wrappers instead of direct imports
- Add graceful fallbacks and user messaging for browser development mode
- Fix TypeError: Cannot read properties of undefined errors in browser mode

This enables frontend development in browser mode without crashes while
maintaining full functionality in desktop Tauri mode.

Fixes console errors when running 'npm run dev' in browser mode.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 1, 2025

Walkthrough

Environment detection for Tauri was introduced using a new utility function. Update and download logic in the updater hook, as well as window event handling in the main entry, now check for Tauri before invoking platform-specific APIs. A browser warning component was added to inform users when running outside Tauri.

Changes

Files/Groups Change Summary
frontend/src/utils/tauriUtils.ts Added isTauriEnvironment utility function for Tauri environment detection.
frontend/src/hooks/useUpdater.ts Update and download logic now checks for Tauri environment before proceeding.
frontend/src/main.tsx Dynamic import of Tauri APIs; renders BrowserWarning and avoids Tauri-only logic outside Tauri.
frontend/src/components/BrowserWarning.tsx Added new warning component for browser environments.
frontend/src-tauri/tauri.conf.json Updated Tauri bundle targets, version, updater public key, update endpoint, and window minimum size.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant MainApp
    participant TauriAPI
    participant BrowserWarning

    User->>MainApp: Load application
    MainApp->>MainApp: Check isTauriEnvironment()
    alt Tauri environment
        MainApp->>TauriAPI: Import and use Tauri APIs
        MainApp->>MainApp: Render main app UI
    else Browser environment
        MainApp->>BrowserWarning: Render warning message
    end
Loading

Assessment against linked issues

Objective Addressed Explanation
Add Tauri environment detection utility and use it to guard Tauri API usage (#433, #434)
Prevent JavaScript errors in browser mode by skipping Tauri-only logic (#433, #434)
Display a warning UI when running in a browser instead of desktop (#433, #434)

Poem

A bunny hopped in with a warning so bright,
"You’re not in Tauri, so things aren’t quite right!
Now checks are in place,
No more errors to chase—
Just hop to desktop for features in sight!
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9844f7f and bc1201b.

📒 Files selected for processing (1)
  • frontend/src-tauri/tauri.conf.json (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src-tauri/tauri.conf.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Backend Tests
  • GitHub Check: Tauri Tests
  • GitHub Check: Tauri Build Check (windows-latest)
  • GitHub Check: Tauri Build Check (ubuntu-22.04)
  • GitHub Check: Tauri Build Check (macos-latest, --target aarch64-apple-darwin)

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@Aditya30ag
Copy link
Contributor Author

@varunchitre15 @saisankargochhayat @heychirag @raghavpuri31
please can you guys review the code

Copy link
Contributor

@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

🧹 Nitpick comments (1)
frontend/src/utils/tauriUtils.ts (1)

43-43: Improve type safety with more specific parameter types

The options parameter and return types use any which reduces type safety. Consider using more specific interfaces or generic types.

For better type safety, consider defining specific interfaces:

interface DialogOpenOptions {
  directory?: boolean;
  multiple?: boolean;
  title?: string;
  filters?: Array<{ name: string; extensions: string[] }>;
  defaultPath?: string;
}

interface DialogSaveOptions {
  title?: string;
  defaultPath?: string;
  filters?: Array<{ name: string; extensions: string[] }>;
}

export const safeTauriDialogOpen = async (options: DialogOpenOptions): Promise<string[] | string | null> => {
  // ... implementation
};

export const safeTauriDialogSave = async (options: DialogSaveOptions): Promise<string | null> => {
  // ... implementation
};

Also applies to: 77-77, 93-93

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c8f5726 and 3655c26.

📒 Files selected for processing (5)
  • frontend/src/components/FolderPicker/AITaggingFolderPicker.tsx (2 hunks)
  • frontend/src/components/FolderPicker/FolderPicker.tsx (2 hunks)
  • frontend/src/hooks/useUpdater.ts (3 hunks)
  • frontend/src/main.tsx (2 hunks)
  • frontend/src/utils/tauriUtils.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
frontend/src/components/FolderPicker/AITaggingFolderPicker.tsx (1)
frontend/src/utils/tauriUtils.ts (2)
  • isTauriEnvironment (6-8)
  • safeTauriDialogOpen (43-57)
frontend/src/components/FolderPicker/FolderPicker.tsx (1)
frontend/src/utils/tauriUtils.ts (2)
  • isTauriEnvironment (6-8)
  • safeTauriDialogOpen (43-57)
frontend/src/hooks/useUpdater.ts (1)
frontend/src/utils/tauriUtils.ts (2)
  • isTauriEnvironment (6-8)
  • safeTauriUpdaterCheck (27-40)
🔇 Additional comments (4)
frontend/src/main.tsx (1)

6-6: Well-implemented environment-aware initialization

The changes properly integrate the new Tauri utilities:

  • Environment check prevents errors in browser mode
  • Dynamic import avoids bundling issues
  • Production + Tauri condition ensures proper initialization context

The implementation follows the established pattern consistently.

Also applies to: 13-25, 73-73

frontend/src/components/FolderPicker/FolderPicker.tsx (1)

3-3: Excellent user experience improvements for development mode

The changes properly handle both environment detection and user communication:

  • Clear import of safe utilities
  • Informative alert message guides developers on proper usage
  • Early return prevents errors in browser mode
  • Safe wrapper handles the dialog operation

Also applies to: 16-22

frontend/src/components/FolderPicker/AITaggingFolderPicker.tsx (1)

3-3: Consistent implementation across FolderPicker components

The changes mirror those in FolderPicker.tsx and maintain consistency:

  • Proper import of safe utilities
  • Same user-friendly alert message
  • Correct environment check and early return
  • Safe wrapper usage for dialog operations

Also applies to: 17-23

frontend/src/hooks/useUpdater.ts (1)

2-3: Proper environment-aware update functionality implementation

The changes correctly implement the safe Tauri pattern:

  • Clean imports of necessary utilities and types
  • Environment checks in both update check and download functions
  • Safe wrapper usage with proper error handling
  • Informative console logging for debugging

The implementation ensures update functionality is only available in the appropriate Tauri desktop environment.

Also applies to: 37-44, 71-74

Comment on lines 11 to 24
export const safeTauriInvoke = async (command: string, args?: any): Promise<any> => {
if (!isTauriEnvironment()) {
console.warn(`Tauri command "${command}" is not available in browser mode`);
return null;
}

try {
const { invoke } = await import('@tauri-apps/api/core');
return await invoke(command, args);
} catch (error) {
console.error(`Error invoking Tauri command "${command}":`, error);
throw error;
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Inconsistent error handling pattern across safe wrapper functions

The safeTauriInvoke function throws errors while other safe wrapper functions (like safeTauriUpdaterCheck) return null on errors. This inconsistency could lead to confusion and different error handling requirements across the codebase.

Consider standardizing the error handling approach. For safe wrapper functions, returning null on errors (as done in other functions) is more appropriate:

-  } catch (error) {
-    console.error(`Error invoking Tauri command "${command}":`, error);
-    throw error;
-  }
+  } catch (error) {
+    console.error(`Error invoking Tauri command "${command}":`, error);
+    return null;
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const safeTauriInvoke = async (command: string, args?: any): Promise<any> => {
if (!isTauriEnvironment()) {
console.warn(`Tauri command "${command}" is not available in browser mode`);
return null;
}
try {
const { invoke } = await import('@tauri-apps/api/core');
return await invoke(command, args);
} catch (error) {
console.error(`Error invoking Tauri command "${command}":`, error);
throw error;
}
};
export const safeTauriInvoke = async (command: string, args?: any): Promise<any> => {
if (!isTauriEnvironment()) {
console.warn(`Tauri command "${command}" is not available in browser mode`);
return null;
}
try {
const { invoke } = await import('@tauri-apps/api/core');
return await invoke(command, args);
} catch (error) {
console.error(`Error invoking Tauri command "${command}":`, error);
return null;
}
};
🤖 Prompt for AI Agents
In frontend/src/utils/tauriUtils.ts between lines 11 and 24, the safeTauriInvoke
function currently throws errors on failure, unlike other safe wrapper functions
that return null. To standardize error handling, modify safeTauriInvoke so that
instead of throwing the error in the catch block, it logs the error and returns
null. This will align its behavior with other safe wrapper functions and
simplify error handling across the codebase.

Comment on lines 60 to 74
export const safeTauriConvertFileSrc = (src: string): string => {
if (!isTauriEnvironment()) {
// In browser mode, return the src as-is or provide a fallback
return src;
}

try {
// Dynamic import to avoid errors in browser mode
const { convertFileSrc } = require('@tauri-apps/api/core');
return convertFileSrc(src);
} catch (error) {
console.error('Error converting file src:', error);
return src;
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace require() with dynamic import for consistency

The safeTauriConvertFileSrc function uses require() instead of dynamic import, which is inconsistent with other functions and could cause bundling issues in browser environments.

Apply this diff to use dynamic import consistently:

-  try {
-    // Dynamic import to avoid errors in browser mode
-    const { convertFileSrc } = require('@tauri-apps/api/core');
-    return convertFileSrc(src);
-  } catch (error) {
-    console.error('Error converting file src:', error);
-    return src;
-  }
+  try {
+    const { convertFileSrc } = await import('@tauri-apps/api/core');
+    return convertFileSrc(src);
+  } catch (error) {
+    console.error('Error converting file src:', error);
+    return src;
+  }

Note: This change requires making the function async:

-export const safeTauriConvertFileSrc = (src: string): string => {
+export const safeTauriConvertFileSrc = async (src: string): Promise<string> => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const safeTauriConvertFileSrc = (src: string): string => {
if (!isTauriEnvironment()) {
// In browser mode, return the src as-is or provide a fallback
return src;
}
try {
// Dynamic import to avoid errors in browser mode
const { convertFileSrc } = require('@tauri-apps/api/core');
return convertFileSrc(src);
} catch (error) {
console.error('Error converting file src:', error);
return src;
}
};
export const safeTauriConvertFileSrc = async (src: string): Promise<string> => {
if (!isTauriEnvironment()) {
// In browser mode, return the src as-is or provide a fallback
return src;
}
try {
const { convertFileSrc } = await import('@tauri-apps/api/core');
return convertFileSrc(src);
} catch (error) {
console.error('Error converting file src:', error);
return src;
}
};
🤖 Prompt for AI Agents
In frontend/src/utils/tauriUtils.ts around lines 60 to 74, replace the use of
require() with a dynamic import to maintain consistency and avoid bundling
issues in browser environments. To fix this, make the function async and use
await import('@tauri-apps/api/core') to dynamically load convertFileSrc, then
return the converted source. Adjust the function signature to async and update
all call sites accordingly.

@rahulharpal1603
Copy link
Contributor

rahulharpal1603 commented Jul 3, 2025

Hi @Aditya30ag, thank you for the PR.

We are grateful that you took the time to contribute to this repository. In the future, after opening an issue, first discuss it with the maintainers. Discuss possible alternatives and solutions.

After that, you start working on the coding part. This saves everyone's effort and time.

About the PR: Let's have a simple message show up when someone accidentally opens the app in a browser. We do not need the safe functions. One simple thing you can do is to render the component in the main.tsx file, you can check if we are running inside a browser, and render a big <div> stating that we need to run the command npm run tauri dev.

The issue is legit, but your approach is complicated. Although I appreciate the effort 😊

@Aditya30ag
Copy link
Contributor Author

I completely understand your point about discussing the approach before jumping into the code — I’ll make sure to follow that process moving forward. Thanks for the heads-up!

@rahulharpal1603
Copy link
Contributor

I completely understand your point about discussing the approach before jumping into the code — I’ll make sure to follow that process moving forward. Thanks for the heads-up!

Thanks for understanding. You can start working on the simpler fix.

@rahulharpal1603 rahulharpal1603 added the enhancement New feature or request label Jul 3, 2025
@Aditya30ag
Copy link
Contributor Author

Sure!!

@Aditya30ag
Copy link
Contributor Author

@rahulharpal1603 I’ve completed a few beginner issues — is there a more complex task you’d recommend I take up next?

@rahulharpal1603
Copy link
Contributor

@rahulharpal1603 I’ve completed a few beginner issues — is there a more complex task you’d recommend I take up next?

Hi, did you make the changes I suggested?

@Aditya30ag
Copy link
Contributor Author

For this pr yaa i haved done the changes
image

Implement the simpler approach

@rahulharpal1603
Copy link
Contributor

rahulharpal1603 commented Jul 9, 2025

For this pr yaa i haved done the changes
image

Implement the simpler approach

Then please push the changes into the branch with which the PR is opened. I need to review.

@Aditya30ag
Copy link
Contributor Author

ok

@Aditya30ag
Copy link
Contributor Author

Done

Copy link
Contributor

@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: 1

🧹 Nitpick comments (1)
frontend/src-tauri/tauri.conf.json (1)

10-10: Dropping the dmg target may limit macOS distribution options

Removing "dmg" keeps only the .app bundle, which cannot be easily code-signed & notarised for Gatekeeper and is awkward for end-users to drag into /Applications.
Unless you have explicit release requirements that exclude DMG, consider restoring it:

-    "targets": ["nsis", "deb", "app"],
+    "targets": ["nsis", "deb", "app", "dmg"],
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1eddf14 and 9844f7f.

📒 Files selected for processing (1)
  • frontend/src-tauri/tauri.conf.json (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Tauri Tests
  • GitHub Check: Tauri Build Check (windows-latest)
  • GitHub Check: Backend Tests
  • GitHub Check: Tauri Build Check (ubuntu-22.04)
  • GitHub Check: Tauri Build Check (macos-latest, --target aarch64-apple-darwin)
🔇 Additional comments (2)
frontend/src-tauri/tauri.conf.json (2)

32-32: Ensure version bump stays consistent across all manifests

The app version is now 0.1.0. Verify that:
package.jsonversion
src-tauri/Cargo.tomlversion
match this value; mismatches break auto-update diffing and installer metadata.


39-42: Updater key / endpoint pair must match the signing process

You swapped the public key and moved to an org-scoped release feed.

  1. Confirm this base64 string is the Ed25519 public key produced by tauri signer generate.
  2. Check that releases in AOSSIE-Org/PictoPy are signed with the matching private key, or users will receive “Signature verification failed” and the updater will silently abort.

If you’re uncertain, regenerate and re-encrypt the key pair, then push only the public key.

Comment on lines +51 to +52
"minWidth": 1280,
"minHeight": 720,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Initial window size is smaller than the enforced minimum – this will fail at runtime

width: 800 / height: 600 < minWidth: 1280 / minHeight: 720.
Tauri delegates to winit, which panics if the initial size violates the minimum constraint.

Quick fix:

-        "width": 800,
-        "height": 600,
+        "width": 1280,
+        "height": 720,

Or lower the min values to preserve the smaller default window.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"minWidth": 1280,
"minHeight": 720,
"width": 1280,
"height": 720,
"minWidth": 1280,
"minHeight": 720,
🤖 Prompt for AI Agents
In frontend/src-tauri/tauri.conf.json around lines 51 to 52, the initial window
size is set smaller than the minimum allowed size, causing runtime failure. To
fix this, either increase the initial window width and height to at least 1280
and 720 respectively, or reduce the minWidth and minHeight values to be equal to
or smaller than the initial window size to avoid conflicts.

@rahulharpal1603
Copy link
Contributor

rahulharpal1603 commented Jul 9, 2025

@Aditya30ag Please join the discord channel, all the discussions happen there. I first post the new tasks on the channel and if anyone wants them I assign them.

https://discord.com/channels/1022871757289422898/1311271974630330388

@Aditya30ag
Copy link
Contributor Author

Aditya30ag commented Jul 9, 2025

image

there is some issue not visible the screen and it was not a network issue
can you send me the invite link adityaagrwal3005@gmail.com to this email

@rahulharpal1603
Copy link
Contributor

https://discord.gg/hjUhu33uAn

Go to Projects->PictoPy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: FIX: Add Tauri Environment Detection and Safe API Wrappers

2 participants

Comments