Files
BikeControl/src-tauri/Cargo.toml
T
dtourolleandClaude Opus 5 5dff2500e2 Open picked files through the content resolver, not std::fs
Loading a GPX on Android failed for every file in the picker. The dialog
plugin fires ACTION_GET_CONTENT, which returns a `content://` URI, and
`load_profile_from_path` handed that straight to `std::fs::read_to_string`
— "no such file or directory" for a file the rider is looking at. Picking
from Nextcloud makes it plainer: a document provider backed by a server
may have no local file at all until the resolver opens the stream, so
there was never a path to find.

So the command now takes a `FilePath` and reads through tauri-plugin-fs,
which opens a path directly and a URI via the resolver. The plugin is
here for `FsExt` alone; nothing in ui/ calls its commands, so the
capabilities are unchanged.

Two things that were derived from the filename can no longer be:

  - GPX is detected by content. A document id need not contain a name,
    let alone an extension. No YAML profile begins with `<`.
  - The route name falls back to the GPX's own <name>. Providers over
    real storage encode the filename in the last segment, but an opaque
    row id would have made a wretched route name.

save_fit had the same bug on the export side — PathBuf::from on a
save-dialog URI — and now writes down a resolver descriptor when handed
one.

Note for anyone rebuilding locally: gen/android/tauri.settings.gradle is
autogenerated and lists each plugin's Android project, so the new
plugin's Kotlin only reaches the APK after `cargo tauri android init` and
scripts/sync-android-sources.sh. CI already runs both.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 19:08:36 +02:00

66 lines
2.4 KiB
TOML

[package]
name = "bikecontrol-app"
version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
description = "BikeControl desktop shell: Tauri commands and the event bridge to the UI"
[lib]
# Tauri v2 convention: the app lives in a lib so the same code can be reused by
# the Android/iOS entry points later (G-4).
name = "bikecontrol_app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2", features = [] }
[dependencies]
bikecontrol-core = { workspace = true }
bikecontrol-ble = { workspace = true }
bikecontrol-fit = { workspace = true }
tauri = { version = "2", features = [] }
tauri-plugin-dialog = "2"
# Not for the frontend — nothing in `ui/` calls the fs commands. This is here
# for `FsExt::read_to_string`, the one API that can read what the *picker*
# returns on Android: a `content://` URI rather than a path. See
# `read_picked_file` in commands.rs.
tauri-plugin-fs = "2"
uuid = { workspace = true }
chrono = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
serde_yaml_ng = { workspace = true }
roxmltree = { workspace = true }
tokio = { workspace = true }
anyhow = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
# Desktop-only: the crate is a `compile_error!` on anything that is not
# Windows/Linux/macOS, and the mobile entry points (G-4) have their own
# platform APIs for this. `wakelock.rs` degrades to a no-op there. On Android
# the equivalent is FLAG_KEEP_SCREEN_ON, set in MainActivity.kt.
[target.'cfg(any(windows, target_os = "linux", target_os = "macos"))'.dependencies]
keepawake = "0.6.0"
# Android-only (G-4). `src/android.rs` is the whole JNI surface: btleplug's Java
# backend has to be initialised from a Java thread, and `tracing` has to be
# pointed at logcat.
#
# `jni` is pinned to 0.19 because that is what btleplug 0.11 uses, and
# `platform::init` takes a `&JNIEnv` from *that* version — a 0.21 JNIEnv is a
# different type and would not compile.
[target.'cfg(target_os = "android")'.dependencies]
btleplug = { workspace = true }
jni = "0.19"
libc = "0.2"
# Pinned to the version btleplug 0.11 resolves to, and it must stay that way:
# the class cache `init` populates is a static *inside this crate*, so a second
# copy at a different version would be a second, empty cache and `connect`
# would go back to panicking.
jni-utils = "0.1.1"