Skip to content

Conversation

@haslinghuis
Copy link
Member

@haslinghuis haslinghuis commented Mar 11, 2025

What

This pull request introduces the integration of Tauri into the project, along with some configuration and dependency updates.

How

The most important changes include

  • adding new scripts and dependencies to package.json
  • creating Tauri-specific configuration files
  • updating build settings in vite.config.js.
  • added DockerFile so developers can use the same environment (needs testing)
  • See DOCKER.MD

Why

  • Tau-ri is preferred over Electron (as Electron would basically be the counterpart of NW.js)
  • Focus is on adding serial, DFU, TCP (MDNS) on Android
  • IMO desktop support would only be useful for SITL

Todo

  • implement serial connection, raw tcp for Android at first
  • update YAML for CI
  • update comments below

References

Requirements

# Update your system
sudo apt update && sudo apt upgrade -y

sudo apt install pkg-config
sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file libssl-dev libgtk-3-dev
sudo apt install libayatana-appindicator3-dev librsvg2-dev

# Install rust and cargo

# Remove snap rust if present
sudo snap remove rust

# Install via rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"

# Start development
yarn && yarn tauri:dev

Docker

echo 'FROM rust:latest
WORKDIR /app
RUN apt-get update && apt-get install -y libwebkit2gtk-4.1-dev build-essential curl wget libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && apt-get install -y nodejs
RUN npm install -g yarn
COPY . .
RUN yarn install
CMD ["yarn", "tauri:dev"]' > Dockerfile

# Build and run the Docker container
docker build -t betaflight-dev .
docker run -it betaflight-dev

Tauri Integration:

Build Configuration:

  • vite.config.js: Updated the build output directory and added an alias for the src directory. [1] [2]

Summary by CodeRabbit

  • New Features

    • Adds desktop and Android app support via Tauri with native runtime detection and a new native serial backend.
  • Chores

    • Adds Tauri tooling, Android emulator/ADB scripts, packaging/build config, capability defaults, output cleanup and dev server settings, and updated ignore rules.
    • Adds Docker build environment and Android environment helper.
  • Documentation

    • Adds Docker and Android development guides and setup instructions.

@haslinghuis haslinghuis added the dependencies Pull requests that update a dependency file label Mar 11, 2025
@haslinghuis haslinghuis added this to the 11.0 milestone Mar 11, 2025
@haslinghuis haslinghuis self-assigned this Mar 11, 2025
@netlify
Copy link

netlify bot commented Mar 11, 2025

Deploy Preview for origin-betaflight-app ready!

Name Link
🔨 Latest commit 6e96780
🔍 Latest deploy log https://app.netlify.com/sites/origin-betaflight-app/deploys/67eb037d01c55000084a875e
😎 Deploy Preview https://deploy-preview-4379.dev.app.betaflight.com
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@haslinghuis haslinghuis moved this to App in 2025.12.0 Mar 11, 2025
@McGiverGim
Copy link
Member

I haven't tested it, but two questions or confirmations:

  • the instructions to build are for Linux. I suppose we can use other OS like windows for example to develop.
  • if we merge this, we need to revert all the capacitor code. I suppose that this is only a test and for this reason it does not do that

I'm right?

@haslinghuis
Copy link
Member Author

For now this is for evaluation purpose

@hcws
Copy link

hcws commented Mar 23, 2025

I'm new to PWA , I want use tauri to communite with mavsdk , I want to base this project, I have no idea with this PWA , I don't know how to add tauri callback in this PWA,Can you give me some ideas.

@sonarqubecloud
Copy link

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 3, 2025

Walkthrough

Adds Tauri 2.x integration (desktop and mobile) with Rust manifests, entrypoints, build scripts and config; front-end Tauri detection and new Tauri serial adapter; Vite and ESLint tweaks; many Android emulator/adb and Tauri npm scripts; Docker-based dev environment, Android env helper, Android docs, and .gitignore entries for Tauri artifacts.

Changes

Cohort / File(s) Change Summary
Ignore rules
/.gitignore
Added ignore entries for Tauri build artifacts: src-tauri/target/, src-tauri/gen/.
NPM scripts & deps
package.json
Added Android emulator/adb management scripts and Tauri scripts (tauri:dev, tauri:build, tauri:dev:android, tauri:build:android, etc.) and added dependencies @tauri-apps/api, @tauri-apps/cli.
Tauri Rust manifest & build
src-tauri/Cargo.toml, src-tauri/build.rs
New Cargo manifest for betaflight-app (tauri, plugins, serde) and a simple build.rs invoking tauri_build::build().
Tauri Rust app entrypoints
src-tauri/src/main.rs, src-tauri/src/lib.rs
Added desktop main() (Windows subsystem attr for release) and mobile mobile_entry (Android/iOS), both initializing Tauri and registering tauri_plugin_shell and tauri_plugin_serialplugin.
Tauri config & capabilities
src-tauri/tauri.conf.json, src-tauri/capabilities/default.json
Added Tauri configuration (app metadata, build/dev commands, window and bundle settings, security) and default capability granting core:default, shell:allow-open, and serialplugin:default.
Frontend runtime detection
src/js/utils/checkBrowserCompatibility.js
Import isTauri, expose tauriDetected, and treat environment as native when Tauri is detected; added logging.
Serial integration & protocol
src/js/port_handler.js, src/js/serial.js, src/js/protocols/TauriSerial.js, src/js/serial.js
Added Tauri-aware serial handling: runtime serialProtocol (tauriserial/webserial), new TauriSerial class implementing port discovery, connect/read/send/disconnect flows and events, dynamic loading/selection of Tauri adapter, and event-forwarding helper _setupEventForwardingFor.
Build & dev config
vite.config.js, eslint.config.js
Vite: set build.outDir to dist, emptyOutDir: true, server.host: true, HMR config; PWA devOptions tweak. ESLint: expanded ignore patterns and registered vue plugin in Vue block.
Docker / Dev docs & env helper
DockerFile, DOCKER.MD, android-env.sh
Added Dockerfile provisioning Rust/Android/Node toolchain, DOCKER.MD with container/dev instructions, and android-env.sh to configure Android SDK/NDK env vars.
Docs: Android guide
ANDROID.md
Added comprehensive Android development guide covering prerequisites, workflow, scripts, common issues, and architecture notes.
Tauri project files (misc)
src-tauri/...
Added Tauri project layout and supporting files (configs, capabilities, gen placeholders, tauri.conf.json).

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor User
    participant Frontend as Frontend (JS)
    participant TauriRust as Tauri (Rust/plugin)
    participant SerialPlugin as tauri-plugin-serialplugin
    participant OS

    User->>Frontend: open app (desktop/mobile)
    Frontend->>Frontend: checkBrowserCompatibility() -> detect Tauri
    alt Tauri detected
        Frontend->>TauriRust: initialize app (webview)
        Frontend->>SerialPlugin: request device list / open port (via @tauri-apps/api)
        SerialPlugin->>OS: access native serial devices
        SerialPlugin-->>Frontend: emit device events / data
        Frontend->>Frontend: route events via Serial/TauriSerial -> PortHandler
    else Browser only
        Frontend->>Frontend: use Web Serial APIs (webserial)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Files deserving extra attention:
    • src-tauri/Cargo.toml (dependency versions, features)
    • src-tauri/tauri.conf.json (dev/build commands, devUrl, capabilities)
    • src-tauri/src/{main.rs,lib.rs} (entrypoints and plugin registration)
    • src/js/protocols/TauriSerial.js, src/js/serial.js, src/js/port_handler.js (serial protocol correctness, event semantics, batching/timeout behavior)
    • DockerFile and android-env.sh (toolchain assumptions and environment variables)

Possibly related issues

Possibly related PRs

Suggested labels

RN: IMPROVEMENT

Suggested reviewers

  • VitroidFPV
  • nerdCopter

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title "Add initial Tauri v2 support" clearly and concisely summarizes the primary change in the pull request. The changeset consistently focuses on integrating Tauri v2 into the project through multiple coordinated changes including configuration files, dependencies, build settings, and serial protocol implementations. The title is specific enough to convey the main objective without being overly verbose, making it appropriate for scanning project history.
Description Check ✅ Passed The description is comprehensive and well-organized, providing clear sections covering What (integration of Tauri), How (specific changes to package.json, configuration files, vite.config.js, Docker setup), Why (reasoning for Tauri over Electron and focus on Android serial/DFU/TCP support), and References with setup requirements. The description includes detailed subsections for Tauri Integration, Build Configuration, Docker setup, and system requirements. While the repository's description template consists mainly of general guidelines rather than a specific structural format, the author's description fulfills the informational needs by explaining the purpose, scope, and implementation of the changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

coderabbitai[bot]
coderabbitai bot previously requested changes Jun 3, 2025
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)
src-tauri/src/main.rs (1)

6-11: Consider improving error handling for production use.

The main function structure is correct and follows Tauri best practices. However, using .expect() will cause the application to panic on startup errors.

For production use, consider implementing more graceful error handling:

fn main() {
-    tauri::Builder::default()
-        .plugin(tauri_plugin_shell::init())
-        .run(tauri::generate_context!())
-        .expect("error while running tauri application");
+    if let Err(e) = tauri::Builder::default()
+        .plugin(tauri_plugin_shell::init())
+        .run(tauri::generate_context!()) {
+        eprintln!("Failed to start application: {}", e);
+        std::process::exit(1);
+    }
}

Given this is experimental/evaluation code, the current approach is acceptable for now.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1809bb8 and 31e7be6.

⛔ Files ignored due to path filters (3)
  • src-tauri/Cargo.lock is excluded by !**/*.lock
  • src-tauri/icons/bf_icon_128.png is excluded by !**/*.png
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (8)
  • .gitignore (1 hunks)
  • package.json (2 hunks)
  • src-tauri/Cargo.toml (1 hunks)
  • src-tauri/build.rs (1 hunks)
  • src-tauri/src/main.rs (1 hunks)
  • src-tauri/tauri.conf.json (1 hunks)
  • src/js/utils/checkBrowserCompatibility.js (1 hunks)
  • vite.config.js (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src-tauri/src/main.rs (1)
src-tauri/build.rs (1)
  • main (1-3)
src-tauri/build.rs (1)
src-tauri/src/main.rs (1)
  • main (6-11)
🔇 Additional comments (16)
.gitignore (1)

45-47: LGTM! Standard Tauri ignore patterns added.

The added entries correctly exclude Tauri build artifacts:

  • src-tauri/target/ for Rust/Cargo compilation artifacts
  • src-tauri/gen/ for Tauri-generated code

These are essential for keeping build outputs out of version control.

src-tauri/build.rs (1)

1-3: LGTM! Standard minimal Tauri build script.

This is the correct minimal implementation for a Tauri build script. The tauri_build::build() call handles all necessary Tauri-specific build steps during compilation.

vite.config.js (2)

59-60: LGTM! Build configuration aligned with Tauri requirements.

The explicit outDir: "dist" and emptyOutDir: true settings ensure that the frontend build outputs are correctly placed and cleaned for Tauri consumption.


120-120: LGTM! Convenient alias for source directory.

The "@": resolve(__dirname, "src") alias provides a clean way to reference the source directory in imports, which is a common pattern in Vue.js projects.

src-tauri/src/main.rs (1)

1-4: LGTM! Correct Windows subsystem configuration.

The conditional compilation attribute properly suppresses the console window on Windows in release builds, which is appropriate for a desktop GUI application.

src/js/utils/checkBrowserCompatibility.js (2)

63-65: LGTM! Standard Tauri detection implementation.

The function correctly uses the __TAURI_INTERNALS__ global variable to detect when running in a Tauri environment, which is the recommended approach according to Tauri documentation.


73-73: Good integration with existing platform detection.

Correctly treats Tauri as a native platform alongside Capacitor, which makes sense since both provide native desktop/mobile app capabilities that don't require web browser APIs like WebSerial or WebUSB.

src-tauri/tauri.conf.json (3)

25-28:

❓ Verification inconclusive

Bundle targets are Linux-focused - confirm platform strategy.

The bundle configuration only targets Linux packages (deb, appimage). Given that the PR mentions this is for evaluation purposes, confirm whether Windows and macOS targets will be added later or if Linux-only distribution is intentional.


🌐 Web query:

What are the recommended bundle targets for Tauri v2 cross-platform desktop applications?

💡 Result:

In Tauri v2, when configuring your cross-platform desktop application, you can specify the bundle targets in the tauri.conf.json configuration file under the bundle section. The targets property defines the formats in which your application will be bundled. By default, this is set to "all", which includes all available targets. You can customize this to include specific targets as needed.

The available bundle targets are:

  • Windows:

    • "nsis": NSIS installer (.exe)
    • "msi": Microsoft Installer (.msi)
    • "app": Windows application bundle (.app)
    • "dmg": Apple Disk Image (.dmg)
  • macOS:

    • "app": macOS application bundle (.app)
    • "dmg": Apple Disk Image (.dmg)
  • Linux:

    • "deb": Debian package (.deb)
    • "rpm": RPM package (.rpm)
    • "appimage": AppImage bundle (.appimage)
  • Cross-Platform:

    • "all": Bundles all available targets

To specify the bundle targets in your tauri.conf.json file, you can set the targets property under the bundle section. For example, to bundle your application for Windows and macOS, you would configure it as follows:

{
  "bundle": {
    "targets": ["nsis", "app", "dmg"]
  }
}

This configuration will generate installers for Windows (.exe), and application bundles for macOS (.app and .dmg). For a comprehensive list of all available bundle targets and their configurations, refer to the Tauri documentation. (tauri.app)

Citations:


Clarify cross-platform bundle targets

Currently in src-tauri/tauri.conf.json (around lines 25–28) your bundle targets are set to:

"bundle": {
  "active": true,
  "targets": ["deb", "appimage"],
  "icon": ["icons/bf_icon_128.png"]
}

– those are Linux-only formats. Tauri v2 also supports Windows ("nsis", "msi", "app", "dmg") and macOS ("app", "dmg") bundles, or a single "all" target to cover everything.

Please confirm whether you intend to ship Linux-only (for evaluation) or if you’ll add Windows/macOS targets (or switch to "all") before release.


5-9:

✅ Verification successful

Verify build commands consistency.

The build commands reference yarn dev and yarn build scripts. Ensure these correspond to the scripts defined in package.json and that the development server runs on the configured port (8000).


🏁 Script executed:

#!/bin/bash
# Verify that the referenced yarn scripts exist in package.json
echo "Checking for yarn scripts referenced in tauri.conf.json..."
jq -r '.scripts | keys[]' package.json | grep -E "^(dev|build)$" || echo "Missing required scripts"

# Check if dev script uses port 8000
echo "Checking dev script configuration..."
jq -r '.scripts.dev' package.json

Length of output: 325


🏁 Script executed:

#!/bin/bash
# Locate any Vite config files in the repo
echo "Locating vite config files..."
vite_configs=$(fd -t f -H "vite.config.*")
if [ -z "$vite_configs" ]; then
  echo "No vite.config.* files found."
else
  for cfg in $vite_configs; do
    echo "Inspecting $cfg for server port settings:"
    grep -R "server" -n "$cfg" -A3 || echo "No 'server' block in $cfg"
    grep -R "port" -n "$cfg" || echo "No explicit port setting in $cfg"
  done
fi

Length of output: 1222


Build commands and devUrl verified

  • Both dev and build scripts exist in package.json.
  • The Vite dev server is explicitly configured with
    server: {
      port: 8000,
      strictPort: true,
    }
    which matches "devUrl": "http://localhost:8000" in tauri.conf.json.
  • The frontend build output defaults to dist, so "frontendDist": "../dist" is correct.

No changes required.


30-34:

❓ Verification inconclusive

Shell plugin enabled - verify security implications.

The shell plugin with open: true allows the application to execute system commands and open files/URLs. Ensure this is necessary for the application's functionality and that proper input validation is implemented wherever this plugin is used.


🏁 Script executed:

#!/bin/bash
# Search for usage of Tauri shell plugin in the codebase
echo "Searching for shell plugin usage..."
rg -A 3 -B 3 "shell|invoke.*shell|@tauri-apps.*shell" --type js

Length of output: 146


This will confirm whether the shell plugin is actually referenced in your Rust code.


🏁 Script executed:

#!/bin/bash
echo "Searching for shell plugin usage in Rust code..."
# Look for direct imports of the shell plugin
rg -n "use .*shell" --type rs
# Look for any references to the plugin namespace
rg -n "tauri_plugin_shell" --type rs
# Look for any invocation or initialization calls
rg -A3 -B3 "shell::" --type rs

Length of output: 287


🏁 Script executed:

#!/bin/bash
echo "Locating Cargo.toml files..."
find . -maxdepth 4 -type f -name Cargo.toml

echo
echo "Checking for tauri-plugin-shell in Cargo.toml dependencies..."
rg -n "tauri-plugin-shell" -g "*.toml"

echo
echo "Searching Rust source for plugin initialization or references..."
rg -n "tauri_plugin_shell" -g "*.rs"
rg -n "shell::init" -g "*.rs"
rg -n "plugin(" -g "*.rs" | grep shell || true

echo
echo "Searching front-end code for shell plugin invocations..."
rg -n "plugin:shell" -g "*.js" -g "*.ts" -g "*.tsx"

Length of output: 1014


Verify Shell Plugin Necessity and Usage

The Tauri Shell plugin is enabled in your configuration and initialized in the Rust backend, but we didn’t find any front-end invocations. Please confirm whether you actually need this plugin, and if so, ensure every call is properly validated to avoid command injection or unintended file/URL access.

• src-tauri/tauri.conf.json (lines 30–34): "plugins": { "shell": { "open": true } }
• src-tauri/Cargo.toml (line 15): tauri-plugin-shell = "2.0.0"
• src-tauri/src/main.rs (line 8): .plugin(tauri_plugin_shell::init())

If the shell plugin isn’t used, remove it to reduce your attack surface. Otherwise, audit all places where you call into the shell API and enforce strict input validation.

package.json (2)

26-27: LGTM! Standard Tauri script integration.

The script names follow Tauri conventions and integrate well with the existing build workflow. These scripts correspond to the build commands configured in tauri.conf.json.


25-25: Minor modification to prepare script looks correct.

The husky install preparation remains intact, which is good for maintaining git hooks functionality.

src-tauri/Cargo.toml (4)

1-8: Excellent version consistency across the project.

The package metadata properly matches the version (11.0.0) and project details from package.json and tauri.conf.json, ensuring consistency across the Tauri integration.


13-17: Standard and appropriate Tauri dependencies.

The dependency selection is correct for a basic Tauri v2 application:

  • Core Tauri framework
  • Shell plugin for system interactions
  • Serde for JSON serialization (standard for Tauri apps)

19-21: Custom protocol feature is a good security practice.

Enabling the custom-protocol feature is recommended for production Tauri applications as it provides better security than the default localhost-based approach during development.


10-11:

✅ Verification successful

Verify Tauri build dependency version compatibility.

Let's ensure the tauri-build version is compatible with the runtime tauri dependency version (both should be from the same major.minor release).


🌐 Web query:

Are tauri-build 2.0.6 and tauri 2.0.6 compatible versions for Tauri v2 applications?

💡 Result:

Yes, tauri-build 2.0.6 and tauri 2.0.6 are compatible versions for Tauri v2 applications. The Tauri framework follows semantic versioning principles where the major version number is incremented for breaking changes, and minor or patch updates are backward compatible within the same major version. This means you should always be able to safely upgrade to the latest minor or patch versions without compatibility issues between related crates like tauri and tauri-build[2][8].

Specifically, at version 2.0.6, tauri and tauri-build are aligned as part of the Tauri 2.x stable release series, ensuring compatibility for building and running Tauri v2 applications[1][6]. It is recommended to keep the versions of the Tauri core crates (like tauri and tauri-build) in sync, generally using the exact same version number, to avoid any subtle incompatibilities[8].

Therefore, using tauri 2.0.6 together with tauri-build 2.0.6 is the correct approach for Tauri v2 apps.

Citations:


Tauri build dependency version compatibility confirmed

The tauri-build entry in src-tauri/Cargo.toml is already at version 2.0.6, matching the runtime tauri = "2.0.6" release. Since Tauri follows semantic versioning within the 2.x series, these versions are fully compatible—no changes needed.

@haslinghuis haslinghuis force-pushed the tauri branch 2 times, most recently from 2da39ae to 7455b58 Compare June 7, 2025 23:27
@sonarqubecloud
Copy link

sonarqubecloud bot commented Jun 7, 2025

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 (3)
android-env.sh (2)

10-22: NDK auto-detection using ls is fragile; should prefer explicit version or safer method.

Selecting the first NDK via ls -1 applies lexicographic ordering (e.g., 25.1.8 may sort before 26.0.0), which is unlikely to match user intent. This could silently pick an outdated or incompatible NDK.

Consider one of the following approaches:

  • Request explicit version: Prompt user to set NDK_VERSION via env var or script parameter.
  • Select latest: Use a more robust method (e.g., sort versions numerically and pick the highest).
  • Use a known good default: Document the expected NDK version and fail if not found.

For now, a safer fallback is to use bash parameter expansion instead of ls:

-if [ -d "$ANDROID_HOME/ndk" ]; then
-    NDK_VERSION=$(ls -1 "$ANDROID_HOME/ndk" | head -n 1)
+if [ -d "$ANDROID_HOME/ndk" ]; then
+    NDK_VERSION=$(printf '%s\n' "$ANDROID_HOME"/ndk/*/ | xargs -I {} basename {} | head -n 1)

Or, more idiomatically with bash:

+if [ -d "$ANDROID_HOME/ndk" ]; then
+    NDK_VERSION=$(cd "$ANDROID_HOME/ndk" && for dir in */; do echo "${dir%/}"; done | sort -V | tail -n 1)

30-43: Add validation for critical Android tools.

The script verifies SDK directory existence but doesn't check for essential tools (adb, sdkmanager, etc.). This could leave users with an incomplete setup that fails downstream.

Consider adding a validation function:

 # Verify the setup
 echo ""
 echo "Android environment variables set:"
 echo "ANDROID_HOME=$ANDROID_HOME"
 echo "ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT"
 echo "NDK_HOME=$NDK_HOME"
 echo ""

+# Verify critical tools exist
+if ! command -v adb &> /dev/null; then
+    echo "WARNING: adb not found in PATH. Ensure Android SDK platform-tools are installed."
+fi

 # Check if SDK exists
 if [ ! -d "$ANDROID_HOME" ]; then
     echo "ERROR: Android SDK not found at $ANDROID_HOME"
     echo "Please install Android SDK or update the ANDROID_HOME path in this script"
     return 1 2>/dev/null || exit 1
 fi
src-tauri/src/lib.rs (1)

1-8: Mobile entry point structure is correct with consistent plugin initialization.

The conditional compilation, mobile entry point attribute, and Tauri initialization follow the standard pattern. Verification confirms that both the mobile (lib.rs:5) and desktop (main.rs:8) entry points initialize the same shell plugin, ensuring cross-platform consistency.

Consider this optional improvement for better error diagnostics:

-        .expect("error while running tauri application");
+        .unwrap_or_else(|e| panic!("Failed to run Tauri application: {}", e));
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d77ffcd and 7522fcd.

📒 Files selected for processing (5)
  • android-env.sh (1 hunks)
  • package.json (2 hunks)
  • src-tauri/Cargo.toml (1 hunks)
  • src-tauri/src/lib.rs (1 hunks)
  • src/js/utils/checkBrowserCompatibility.js (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • package.json
  • src-tauri/Cargo.toml
🔇 Additional comments (4)
android-env.sh (3)

1-9: Good: Clear structure and standard bash conventions.

The shebang, header comments, and hardcoded path with an adjustment note are well-structured. The dual export of ANDROID_HOME and ANDROID_SDK_ROOT is appropriate.


25-28: Clarify: Is adding NDK_HOME directly to PATH correct?

Typically, NDK paths are added as $NDK_HOME/toolchains/llvm/prebuilt/<platform>/bin or similar, not the NDK root. Verify that adding the root NDK directory to PATH is intentional and doesn't cause conflicts.


45-45: Good: Confirmation message guides next steps.

The success message clearly tells users how to proceed after setup.

src/js/utils/checkBrowserCompatibility.js (1)

73-73: LGTM! Tauri correctly treated as native platform.

The change appropriately extends the native platform check to include Tauri alongside Capacitor, which is consistent with Tauri being a desktop application framework.

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)
ANDROID.md (1)

163-175: Consider noting platform limitations for emulator setup.

The section correctly documents Linux/Wayland workarounds (QT_QPA_PLATFORM=xcb, SwiftShader, Mesa drivers). However, this guide is currently Linux-focused. Consider a brief note at the top indicating:

  • Linux: Fully covered (including Wayland fixes)
  • macOS: May need different graphics setup (GPU acceleration availability differs)
  • Windows: Emulator scripts use bash syntax (documented elsewhere or use cross-platform tools)

Or, if Android emulator dev is Linux-only by design for this project, explicitly state that in the Prerequisites section.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 35c46eb and a101a60.

📒 Files selected for processing (2)
  • ANDROID.md (1 hunks)
  • package.json (2 hunks)
🔇 Additional comments (4)
package.json (2)

30-33: Tauri CLI wrapper scripts are appropriately minimal.

The tauri:dev, tauri:build, tauri:dev:android, and tauri:build:android scripts are simple, correct wrappers around the Tauri CLI. These will work cross-platform since the Tauri CLI handles platform differences.


55-56: Tauri dependencies at ^2.5.0 are current and correct.

The versions match the latest stable Tauri 2.x releases. This was already addressed in the prior review and is correctly resolved.

ANDROID.md (2)

1-100: Excellent comprehensive Android development guide.

The guide is well-structured, thorough, and practical. Step-by-step setup, clear project structure documentation, and comprehensive troubleshooting all follow best practices. All referenced yarn scripts exist in package.json and are correctly described. The environment setup via android-env.sh is a good DX improvement.


328-345: Architecture notes are clear and valuable.

The separation of desktop vs. mobile entry points, build process stages, and devUrl vs. frontendDist fallback behavior are well-explained. This helps future contributors understand the design.

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: 3

🧹 Nitpick comments (4)
ANDROID.md (3)

34-67: Consider adding android-env.sh template to the repository.

The documentation references android-env.sh extensively, but this file doesn't appear to be included in the PR. To improve developer experience, consider:

  1. Adding android-env.sh.template to the repo root
  2. Including it in .gitignore as android-env.sh (for local customization)
  3. Updating setup instructions to copy the template

This would reduce setup friction and ensure consistency across the team.

Would you like me to generate the template file and .gitignore updates?


163-175: Consider noting that emulator graphics issues are Linux/Wayland-specific.

The troubleshooting section for EGL/Wayland errors is comprehensive, but could benefit from a brief note that these are primarily Linux issues. Windows users (using the :win32 script variants) won't encounter these problems.

Add after line 163:

> **Note:** These issues are specific to Linux with Wayland compositors. Windows and macOS users typically won't encounter these graphics configuration problems.

1-31: ---

Consider making Android NDK version flexible; Tauri v2.5.0 does not mandate a specific version.

Tauri v2.5.0 does not require a specific NDK release—the docs recommend installing Android NDK via Android Studio's SDK Manager without specifying a fixed version. The guide's requirement for NDK version 29.0.14033849 is unnecessarily restrictive. Either clarify this as a tested/recommended version for the Betaflight project, or update the guide to allow developers to use the latest NDK available through Android Studio, as Tauri supports this flexibility.

package.json (1)

26-28: Windows emulator check script doesn't provide equivalent feedback.

The :default variant (line 28) provides clear "Emulator running" / "No emulator" messages, while the :win32 variant (line 27) only shows raw adb devices output. Consider making them equivalent for consistent UX:

-    "android:emu:check:win32": "%ANDROID_HOME%\\platform-tools\\adb.exe devices",
+    "android:emu:check:win32": "for /f \"tokens=*\" %i in ('%ANDROID_HOME%\\platform-tools\\adb.exe devices ^| findstr emulator') do @(echo Emulator running) || @(echo No emulator)",

Or use a more maintainable approach with a cross-platform Node.js script if the batch syntax is too brittle.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f512d1 and 387e73e.

📒 Files selected for processing (4)
  • ANDROID.md (1 hunks)
  • package.json (2 hunks)
  • src/js/utils/checkBrowserCompatibility.js (3 hunks)
  • vite.config.js (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/js/utils/checkBrowserCompatibility.js
🔇 Additional comments (10)
vite.config.js (4)

59-60: LGTM! Build output configuration aligns with Tauri integration.

Setting outDir: "dist" and emptyOutDir: true is consistent with the Tauri configuration's frontendDist: "../dist" path and ensures clean builds.


89-91: Clarify PWA and Tauri coexistence strategy.

Disabling PWA dev options (enabled: false) while adding Tauri integration may cause confusion. Since the project retains VitePWA plugin configuration and the PR comments mention Tauri is "for evaluation," please verify:

  1. Is PWA support being phased out or maintained alongside Tauri?
  2. Should devOptions.enabled remain false in production, or is this a temporary setting for Tauri testing?

Consider documenting this decision in README or ANDROID.md to guide contributors.


129-129: LGTM! Network access required for mobile development.

Setting host: true allows the Android emulator/device to connect to the Vite dev server, which is essential for the Tauri Android workflow documented in ANDROID.md.

Security note: The dev server will be accessible on your local network. Ensure you're on a trusted network during development.


130-134: LGTM! HMR configuration correctly supports Android development.

The WebSocket configuration with protocol: "ws", host: "localhost", and clientPort: 8000 aligns with the adb reverse tcp:8000 tcp:8000 tunnel documented in ANDROID.md, enabling hot module replacement on Android devices/emulators.

ANDROID.md (5)

87-133: LGTM! Project structure documentation is clear and helpful.

The configuration examples for Cargo.toml, lib.rs, tauri.conf.json, and build.gradle.kts provide essential reference material for troubleshooting and understanding the Tauri setup.


176-239: LGTM! Development workflow is well-documented.

The section clearly explains the distinction between dev mode (using devUrl) and build mode (using dist), including the fallback behavior. The note about tauri:dev:android:with-dist provides a helpful convenience option.


250-318: LGTM! Comprehensive troubleshooting guide.

The Common Issues section covers the most likely problems developers will encounter, with clear explanations of causes and actionable solutions. This will significantly reduce setup friction.


320-337: Clarify the relationship between Tauri and Capacitor.

The guide lists Capacitor scripts as "Alternative," but doesn't explain when to use each framework or if one is deprecated. Since both are present in package.json, please document:

  1. Which framework is recommended for new development?
  2. Will Capacitor be maintained or phased out?
  3. Are there use cases where one is preferred over the other?

This relates to the earlier PWA/Tauri coexistence question in vite.config.js.


373-373: Date inconsistency: Document shows October 2025, but PR was created March 2025.

Line 373 states "Last Updated: October 24, 2025," but the PR summary shows it was created on 2025-03-11. Please update to the correct date or clarify if this is a future-dated document.

-**Last Updated**: October 24, 2025
+**Last Updated**: March 11, 2025

Likely an incorrect or invalid review comment.

package.json (1)

72-73: LGTM! Tauri dependencies are at the latest stable version.

Both @tauri-apps/api and @tauri-apps/cli are correctly set to ^2.5.0, which is the latest stable release for Tauri v2. The past review concern has been properly addressed.

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: 0

🧹 Nitpick comments (2)
android-env.sh (2)

5-7: Hardcoded Android SDK path requires manual edit for non-standard installations.

Line 5 acknowledges that the SDK path may differ but the script hard-codes $HOME/Android/Sdk. Developers with custom SDK locations must manually edit this script. Consider accepting an environment variable override:

 # Set Android SDK path (adjust if your SDK is in a different location)
-export ANDROID_HOME="$HOME/Android/Sdk"
+export ANDROID_HOME="${ANDROID_SDK_HOME:-$HOME/Android/Sdk}"
 export ANDROID_SDK_ROOT="$ANDROID_HOME"

This allows ANDROID_SDK_HOME=/custom/path ./android-env.sh without editing the file.


10-14: NDK version selection uses lexicographic order; document or improve for clarity.

Line 11 picks the first NDK version alphabetically (e.g., "27.0.12" vs "26.0.11" depending on lexical sort). If multiple NDK versions are installed, this may not select the intended one. Consider:

  1. Document the selection strategy in a comment (if current behavior is acceptable).
  2. Improve by sorting versions numerically or picking the latest:
-    NDK_VERSION=$(ls -1 "$ANDROID_HOME/ndk" | head -n 1)
+    NDK_VERSION=$(ls -1 "$ANDROID_HOME/ndk" | sort -V | tail -n 1)  # Pick highest version

This ensures the newest NDK is selected by default.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e5cbca7 and 033ed2d.

📒 Files selected for processing (3)
  • android-env.sh (1 hunks)
  • package.json (2 hunks)
  • src/js/utils/checkBrowserCompatibility.js (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/js/utils/checkBrowserCompatibility.js
🔇 Additional comments (3)
package.json (3)

44-50: Clarify whether tauri:build:android needs a preceding yarn build step.

The script tauri:dev:android:with-dist (line 49) chains yarn build && before calling yarn tauri:dev:android, but tauri:build:android (line 50) calls tauri android build directly without building web assets first.

If web assets must be built before the Android build step, consider:

-    "tauri:build:android": "tauri android build"
+    "tauri:build:android": "yarn build && tauri android build"

Alternatively, if tauri android build already handles web asset compilation, please add a comment to clarify this design choice.


69-73: ✅ Tauri dependencies updated to latest stable v2.5.0.

Both @tauri-apps/api and @tauri-apps/cli are correctly pinned to ^2.5.0, which matches the latest stable Tauri v2 releases as of the PR review. The caret version constraints allow for minor and patch updates while maintaining compatibility.


23-40: ✅ Cross-platform Android emulator and ADB scripts properly use run-script-os dispatcher pattern.

All four Android emulator/ADB scripts (lines 23–40) correctly implement platform-specific variants:

  • Each uses run-script-os as a dispatcher
  • :win32 variants use Windows command syntax (%ANDROID_HOME%\, adb.exe)
  • :default variants use POSIX syntax ($ANDROID_HOME/, adb)
  • Boot completion verification is consistent across both Windows (line 36) and Unix (line 37) implementations

The implementation properly handles cross-platform execution and prevents shell failures on Windows.

@sonarqubecloud
Copy link

@github-actions
Copy link
Contributor

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)
src-tauri/src/lib.rs (1)

1-9: Consider a more descriptive error message for mobile platforms.

The generic error message on line 8 could be more helpful for debugging mobile-specific issues. Consider including platform information or more context about where the failure occurred.

Apply this diff to improve the error message:

     tauri::Builder::default()
         .plugin(tauri_plugin_shell::init())
     .plugin(tauri_plugin_serialplugin::init())
         .run(tauri::generate_context!())
-        .expect("error while running tauri application");
+        .expect("failed to run Tauri mobile application (Android/iOS)");
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 033ed2d and 0fa4034.

⛔ Files ignored due to path filters (1)
  • src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • android-env.sh (1 hunks)
  • eslint.config.js (1 hunks)
  • package.json (2 hunks)
  • src-tauri/Cargo.toml (1 hunks)
  • src-tauri/capabilities/default.json (1 hunks)
  • src-tauri/src/lib.rs (1 hunks)
  • src-tauri/src/main.rs (1 hunks)
  • src/js/port_handler.js (9 hunks)
  • src/js/protocols/TauriSerial.js (1 hunks)
  • src/js/serial.js (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src-tauri/capabilities/default.json
  • src-tauri/src/main.rs
  • package.json
  • android-env.sh
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-10-24T00:41:16.372Z
Learnt from: haslinghuis
PR: betaflight/betaflight-configurator#4379
File: src-tauri/Cargo.toml:0-0
Timestamp: 2025-10-24T00:41:16.372Z
Learning: The Betaflight Configurator project uses CalVer (calendar versioning) format for versioning (e.g., "2025.12.0") rather than traditional SemVer, while still using SemVer for internal API versioning.

Applied to files:

  • src-tauri/Cargo.toml
📚 Learning: 2025-05-14T21:51:09.253Z
Learnt from: haslinghuis
PR: betaflight/betaflight-configurator#0
File: :0-0
Timestamp: 2025-05-14T21:51:09.253Z
Learning: On Android Chrome browsers, Web Bluetooth API is supported for BLE devices and Web USB API is supported, but Web Serial API is not supported (except limited Bluetooth serial support added in 2025). The Betaflight Configurator should detect and use available APIs on Android rather than requiring all three.

Applied to files:

  • src/js/port_handler.js
📚 Learning: 2025-06-19T22:13:09.136Z
Learnt from: blckmn
PR: betaflight/betaflight-configurator#4521
File: src/js/protocols/WebSerial.js:148-151
Timestamp: 2025-06-19T22:13:09.136Z
Learning: In WebSerial.js, there's a timing issue where the cached `this.ports` array doesn't immediately reflect newly permitted devices after `requestPermissionDevice()` completes. The `getDevices()` method needs to refresh the device list from the browser API to return accurate data immediately following a permission request and user acceptance.

Applied to files:

  • src/js/port_handler.js
🧬 Code graph analysis (1)
src/js/port_handler.js (3)
src/js/utils/checkBrowserCompatibility.js (1)
  • checkWebSerialSupport (137-149)
src/components/eventBus.js (2)
  • EventBus (3-8)
  • EventBus (3-8)
src/js/serial.js (2)
  • serial (238-238)
  • serial (238-238)
🔇 Additional comments (14)
eslint.config.js (2)

50-60: LGTM: Ignores expanded for Tauri build artifacts.

The additional ignore patterns correctly exclude Tauri build outputs and align with the new build structure introduced in this PR.


67-69: LGTM: Necessary plugin registration for Vue processor.

This correctly registers the Vue plugin in the Vue-specific configuration block, which is required for the processor: "vue/vue" reference at line 70 to resolve properly in ESLint's flat config format.

src-tauri/Cargo.toml (1)

1-27: LGTM!

The Cargo.toml configuration is well-structured. The CalVer versioning aligns with project conventions, and Rust edition 2024 is correctly specified. Dependencies and features are appropriately configured for the Tauri application.

src/js/protocols/TauriSerial.js (4)

82-124: LGTM!

The device loading and filtering logic is well-implemented. The handling of both numeric and string VID/PID values (lines 92-97) is defensive and correct. Filtering to known Betaflight-compatible devices provides a good user experience.


138-194: LGTM!

The connection flow is correctly implemented with proper state management, error handling, and event dispatching. The graceful handling of timeout setting failures (lines 164-166) ensures robustness across different plugin versions.


209-266: Send implementation is correct but batch write path is unreachable.

The data sending logic properly handles multiple input types and implements 63-byte batching for macOS AT32 (lines 242-248). However, the batch write path will never execute since isNeedBatchWrite is always false (see earlier comment on line 69).

Once the AT32 detection is implemented, this send logic should work correctly.


10-39: The review comment suggests unavailable error codes that this plugin does not expose.

Based on investigation of tauri-plugin-serialplugin version 2.11, the plugin uses string-based error messages rather than error codes. The plugin documentation confirms that errors are caught as strings (e.g., "no data received within {timeout} ms"), not as error code properties. Therefore, the suggestion to use error.code !== "TIMEOUT" is not applicable.

However, the underlying concern about fragile string matching has merit. The current substring check error.toString().includes("no data received") is loose and will match any error containing those words. A more robust approach would match the expected error pattern more precisely:

             } catch (error) {
                 // Timeout is expected when no data available
-                if (!error.toString().includes("no data received")) {
+                if (!/no data received within \d+ ms/.test(error.toString())) {
                     console.warn(`${logHead} Poll error:`, error);
                 }

Alternatively, add a comment explaining why the plugin uses string-based errors and document the expected error format for future maintainers.

src/js/serial.js (3)

30-42: Consider error visibility for TauriSerial import failures.

The dynamic import of TauriSerial only logs a warning on failure (line 40). For production use, a failed import in a Tauri environment means serial functionality won't work, which could be confusing for users.

Since this PR is for evaluation, the current warning may be sufficient. However, consider whether a more visible error (e.g., UI notification) would improve the user experience in production.

This is appropriate for an evaluation PR, but please confirm whether production builds should:

  1. Keep the current warning-only approach
  2. Show a user-facing error notification
  3. Have a fallback mechanism

56-86: LGTM!

The _setupEventForwardingFor helper is well-designed. It reduces code duplication, includes a type guard (line 61), and correctly handles the special case of receive events by wrapping data and adding protocol type information.


92-110: LGTM!

The protocol selection logic correctly prefers the Tauri serial implementation when available and falls back gracefully to Web Serial. The precedence order (virtual → websocket → bluetooth → tauri → webserial) is appropriate.

src/js/port_handler.js (4)

41-54: LGTM! Runtime serial protocol detection is well-implemented.

The runtime determination of serialProtocol (lines 53-54) enables the same codebase to work in both web and Tauri environments. The fallback to Web Serial when Tauri is not available ensures broad compatibility.

The isTauri() check on line 42 also ensures serial functionality is available on platforms where Web Serial API is limited (e.g., Android via the Tauri plugin).

Based on learnings


64-76: LGTM!

The device addition handler correctly routes events based on protocol type, with proper fallback to Web Serial. The logging on line 75 aids debugging by showing the protocol type alongside the device detail.


115-146: LGTM!

Device removal handling is robust with proper path extraction, protocol-based routing, and appropriate event emission. The defensive check for missing device path (lines 122-129) prevents errors from malformed events.


305-366: LGTM!

The updateDeviceList method correctly handles the tauriserial case (lines 325-329) and appropriately maps both webserial and tauriserial devices to the same currentSerialPorts array (line 351), which reflects their semantic equivalence as serial port providers.

Comment on lines +68 to +69
// Detect if running on macOS with AT32 (needs batch writes)
this.isNeedBatchWrite = false;
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 | 🟠 Major

Batch write detection for macOS AT32 is not implemented.

Line 68's comment indicates this should detect macOS with AT32 devices, but isNeedBatchWrite is hardcoded to false. This means the batch write logic (lines 242-248) will never execute, potentially causing issues with AT32 devices on macOS that require 63-byte batching.

To implement the detection, you'll need to:

  1. Detect the platform (macOS)
  2. Identify AT32 devices (possibly via vendorId/productId in connect())
  3. Set isNeedBatchWrite accordingly

Would you like me to help implement the AT32 device detection logic? I can generate a solution if you provide the vendor/product IDs for AT32 devices or confirm how they should be identified.

🤖 Prompt for AI Agents
In src/js/protocols/TauriSerial.js around lines 68-69, the isNeedBatchWrite flag
is hardcoded false but should be set when running on macOS with AT32 devices so
the batch write code at lines ~242-248 can run; update the constructor or
connect() to detect platform (process.platform === 'darwin' or equivalent in
Tauri runtime), inspect the connected device(s) vendorId/productId (or device
identifier returned by connect()), compare against the AT32 vendor/product IDs
you provide (or a configurable list), and set this.isNeedBatchWrite = true when
both macOS and an AT32 device are detected; ensure detection occurs before any
write operations so the existing batch write path is reachable.

Comment on lines +313 to +315
if (this.openCanceled) {
this.openCanceled = false;
}
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 | 🟡 Minor

Dead code: openCanceled flag is never set.

The openCanceled flag is initialized to false (line 50) and reset here but is never set to true anywhere in the class. This code has no effect and should either be removed or accompanied by a TODO comment if it's a placeholder for future cancellation functionality.

Apply this diff to remove the dead code:

         } finally {
-            if (this.openCanceled) {
-                this.openCanceled = false;
-            }
         }
     }

Or if this is a future feature, add a TODO:

         } finally {
+            // TODO: Implement connection cancellation support
             if (this.openCanceled) {
                 this.openCanceled = false;
             }
         }
📝 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
if (this.openCanceled) {
this.openCanceled = false;
}
} finally {
}
🤖 Prompt for AI Agents
In src/js/protocols/TauriSerial.js around lines 313 to 315, the openCanceled
flag is dead (never set anywhere) and the conditional resetting block has no
effect; either remove the if (this.openCanceled) { this.openCanceled = false; }
lines to eliminate dead code, or, if cancellation is intended, add a TODO
comment explaining the planned cancellation behavior and ensure the flag is
actually set where cancellation should occur (e.g., in a cancelOpen() or error
handler) and referenced consistently across the class.

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

Labels

dependencies Pull requests that update a dependency file

Projects

Status: App

Development

Successfully merging this pull request may close these issues.

4 participants