Merge remote-tracking branch 'origin/v2' into plugin/secure-storage

This commit is contained in:
FabianLars
2025-11-22 19:34:38 +01:00
164 changed files with 1802 additions and 1146 deletions
@@ -0,0 +1,6 @@
---
"dialog-js": minor:feat
"dialog": minor:feat
---
Add `xdg-portal` as an optional feature for `rfd`
@@ -0,0 +1,6 @@
---
"log": "minor"
"log-js": "minor"
---
Allow specifying a log formatter per target using the `format` method on `Target`.
-6
View File
@@ -1,6 +0,0 @@
---
"deep-link": patch
"deep-link-js": patch
---
Fix Exec= field in desktop handler if executable path changes
+6
View File
@@ -0,0 +1,6 @@
---
"dialog": minor
"dialog-js": minor
---
Add `pickerMode` option to file picker (currently only used on iOS)
@@ -0,0 +1,5 @@
---
"localhost": patch
---
Disable caching on responses.
-6
View File
@@ -1,6 +0,0 @@
---
"fs": patch
"fs-js": patch
---
Enhance error messages.
@@ -0,0 +1,6 @@
---
"barcode-scanner": patch
"barcode-scanner-js": patch
---
Fix the `cameraView` is not removed after scanning in iOS.
+6
View File
@@ -0,0 +1,6 @@
---
"log": patch
"log-js": patch
---
Fix log file rotation when exceeding `max_file_size`.
-6
View File
@@ -1,6 +0,0 @@
---
geolocation: patch
geolocation-js: patch
---
On Android, use the `timeout` value for `setMinUpdateIntervalMillis`, `setMaxUpdateDelayMillis` and `setIntervalMillis` instead of just `minUpdateInterval`.
+6
View File
@@ -0,0 +1,6 @@
---
"nfc": "patch"
"nfc-js": "patch"
---
Update return value of `isAvailable` to match TypeScript function signature
-6
View File
@@ -1,6 +0,0 @@
---
"opener": patch
"opener-js": patch
---
Fix opener doesn't open same origin links in the browser
+1 -1
View File
@@ -3,4 +3,4 @@
"updater-js": minor
---
Updater plugin now supports all bundle types: Deb, Rpm and AppImage for Linux; NSiS, MSI for Windows.
Updater plugin now supports all bundle types: Deb, Rpm and AppImage for Linux; NSiS, MSI for Windows. This was added in https://github.com/tauri-apps/plugins-workspace/pull/2624
+6
View File
@@ -0,0 +1,6 @@
---
"upload": minor
"upload-js": minor
---
Upload plugin now supports specifying an HTTP method i.e. POST, PUT etc.
@@ -11,7 +11,7 @@ on:
- v2
permissions:
# required for npm provenance
# required for oidc token
id-token: write
# required to create the GitHub Release
contents: write
@@ -62,7 +62,6 @@ jobs:
id: covector
env:
CARGO_TARGET_DIR: /mnt/target
NODE_AUTH_TOKEN: ${{ secrets.ORG_NPM_TOKEN }}
with:
token: ${{ secrets.GITHUB_TOKEN }}
command: 'version-or-publish'
+1
View File
@@ -157,4 +157,5 @@ jobs:
run: cargo clippy --package ${{ matrix.package }} --all-targets -- -D warnings
- name: clippy ${{ matrix.package }} --all-features
if: matrix.package != 'tauri-plugin-dialog'
run: cargo clippy --package ${{ matrix.package }} --all-targets --all-features -- -D warnings
+2 -2
View File
@@ -251,9 +251,9 @@ jobs:
run: cargo +stable install cross --git https://github.com/cross-rs/cross
- name: test ${{ matrix.package }}
if: matrix.package != 'tauri-plugin-http' && matrix.package != 'tauri-plugin-secure-storage'
if: matrix.package != 'tauri-plugin-http' && matrix.package != 'tauri-plugin-secure-storage' && matrix.package != 'tauri-plugin-dialog'
run: ${{ matrix.platform.runner }} ${{ matrix.platform.command }} --package ${{ matrix.package }} --target ${{ matrix.platform.target }} --all-targets --all-features
- name: test ${{ matrix.package }}
if: matrix.package == 'tauri-plugin-http'
if: ${{ matrix.package == 'tauri-plugin-http' || matrix.package == 'tauri-plugin-dialog' }}
run: ${{ matrix.platform.runner }} ${{ matrix.platform.command }} --package ${{ matrix.package }} --target ${{ matrix.platform.target }} --all-targets
Generated
+48 -34
View File
@@ -220,7 +220,7 @@ checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
[[package]]
name = "api"
version = "2.0.36"
version = "2.0.38"
dependencies = [
"log",
"serde",
@@ -4652,6 +4652,12 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "pollster"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3"
[[package]]
name = "poly1305"
version = "0.8.0"
@@ -5181,7 +5187,9 @@ dependencies = [
"objc2-app-kit",
"objc2-core-foundation",
"objc2-foundation 0.3.0",
"pollster",
"raw-window-handle",
"urlencoding",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
@@ -6602,7 +6610,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-autostart"
version = "2.5.0"
version = "2.5.1"
dependencies = [
"auto-launch",
"serde",
@@ -6614,7 +6622,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-barcode-scanner"
version = "2.4.0"
version = "2.4.2"
dependencies = [
"log",
"serde",
@@ -6626,7 +6634,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-biometric"
version = "2.3.0"
version = "2.3.2"
dependencies = [
"log",
"serde",
@@ -6639,7 +6647,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-cli"
version = "2.4.0"
version = "2.4.1"
dependencies = [
"clap",
"log",
@@ -6652,7 +6660,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-clipboard-manager"
version = "2.3.0"
version = "2.3.2"
dependencies = [
"arboard",
"log",
@@ -6665,7 +6673,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-deep-link"
version = "2.4.3"
version = "2.4.5"
dependencies = [
"dunce",
"plist",
@@ -6684,7 +6692,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-dialog"
version = "2.4.0"
version = "2.4.2"
dependencies = [
"log",
"raw-window-handle",
@@ -6700,7 +6708,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-fs"
version = "2.4.2"
version = "2.4.4"
dependencies = [
"anyhow",
"dunce",
@@ -6722,7 +6730,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-geolocation"
version = "2.3.0"
version = "2.3.2"
dependencies = [
"log",
"serde",
@@ -6735,7 +6743,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-global-shortcut"
version = "2.3.0"
version = "2.3.1"
dependencies = [
"global-hotkey",
"log",
@@ -6748,7 +6756,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-haptics"
version = "2.3.0"
version = "2.3.2"
dependencies = [
"log",
"serde",
@@ -6761,7 +6769,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-http"
version = "2.5.2"
version = "2.5.4"
dependencies = [
"bytes",
"cookie_store",
@@ -6784,7 +6792,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-localhost"
version = "2.3.0"
version = "2.3.1"
dependencies = [
"http",
"log",
@@ -6797,7 +6805,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-log"
version = "2.7.0"
version = "2.7.1"
dependencies = [
"android_logger",
"byte-unit",
@@ -6818,7 +6826,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-nfc"
version = "2.3.1"
version = "2.3.3"
dependencies = [
"log",
"serde",
@@ -6831,7 +6839,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-notification"
version = "2.3.1"
version = "2.3.3"
dependencies = [
"color-backtrace",
"ctor",
@@ -6853,7 +6861,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-opener"
version = "2.5.0"
version = "2.5.2"
dependencies = [
"dunce",
"glob",
@@ -6873,7 +6881,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-os"
version = "2.3.1"
version = "2.3.2"
dependencies = [
"gethostname 1.0.1",
"log",
@@ -6889,7 +6897,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-persisted-scope"
version = "2.3.2"
version = "2.3.4"
dependencies = [
"aho-corasick",
"bincode",
@@ -6903,7 +6911,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-positioner"
version = "2.3.0"
version = "2.3.1"
dependencies = [
"log",
"serde",
@@ -6916,7 +6924,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-process"
version = "2.3.0"
version = "2.3.1"
dependencies = [
"tauri",
"tauri-plugin",
@@ -6941,7 +6949,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-shell"
version = "2.3.1"
version = "2.3.3"
dependencies = [
"encoding_rs",
"log",
@@ -6960,7 +6968,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-single-instance"
version = "2.3.4"
version = "2.3.6"
dependencies = [
"semver",
"serde",
@@ -6975,7 +6983,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-sql"
version = "2.3.0"
version = "2.3.1"
dependencies = [
"futures-core",
"indexmap 2.9.0",
@@ -6992,7 +7000,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-store"
version = "2.4.0"
version = "2.4.1"
dependencies = [
"dunce",
"serde",
@@ -7006,7 +7014,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-stronghold"
version = "2.3.0"
version = "2.3.1"
dependencies = [
"hex",
"iota-crypto",
@@ -7057,7 +7065,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-upload"
version = "2.3.1"
version = "2.3.2"
dependencies = [
"futures-util",
"log",
@@ -7075,7 +7083,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-websocket"
version = "2.4.0"
version = "2.4.1"
dependencies = [
"futures-util",
"http",
@@ -7092,7 +7100,7 @@ dependencies = [
[[package]]
name = "tauri-plugin-window-state"
version = "2.4.0"
version = "2.4.1"
dependencies = [
"bitflags 2.9.0",
"log",
@@ -7455,9 +7463,9 @@ dependencies = [
[[package]]
name = "tokio-tungstenite"
version = "0.27.0"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "489a59b6730eda1b0171fcfda8b121f4bee2b35cba8645ca35c5f7ba3eb736c1"
checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857"
dependencies = [
"futures-util",
"log",
@@ -7700,9 +7708,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "tungstenite"
version = "0.27.0"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eadc29d668c91fcc564941132e17b28a7ceb2f3ebf0b9dae3e03fd7a6748eb0d"
checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442"
dependencies = [
"bytes",
"data-encoding",
@@ -7891,6 +7899,12 @@ dependencies = [
"serde",
]
[[package]]
name = "urlencoding"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]]
name = "urlpattern"
version = "0.3.0"
+36
View File
@@ -1,5 +1,41 @@
# Changelog
## \[2.0.34]
### Dependencies
- Upgraded to `barcode-scanner-js@2.4.2`
- Upgraded to `biometric-js@2.3.2`
- Upgraded to `cli-js@2.4.1`
- Upgraded to `clipboard-manager-js@2.3.2`
- Upgraded to `dialog-js@2.4.2`
- Upgraded to `fs-js@2.4.4`
- Upgraded to `global-shortcut-js@2.3.1`
- Upgraded to `http-js@2.5.4`
- Upgraded to `log-js@2.7.1`
- Upgraded to `nfc-js@2.3.3`
- Upgraded to `notification-js@2.3.3`
- Upgraded to `opener-js@2.5.2`
- Upgraded to `os-js@2.3.2`
- Upgraded to `process-js@2.3.1`
- Upgraded to `shell-js@2.3.3`
- Upgraded to `store-js@2.4.1`
## \[2.0.33]
### Dependencies
- Upgraded to `barcode-scanner-js@2.4.1`
- Upgraded to `biometric-js@2.3.1`
- Upgraded to `clipboard-manager-js@2.3.1`
- Upgraded to `dialog-js@2.4.1`
- Upgraded to `fs-js@2.4.3`
- Upgraded to `nfc-js@2.3.2`
- Upgraded to `notification-js@2.3.2`
- Upgraded to `opener-js@2.5.1`
- Upgraded to `shell-js@2.3.2`
- Upgraded to `http-js@2.5.3`
## \[2.0.32]
### Dependencies
+18 -18
View File
@@ -1,7 +1,7 @@
{
"name": "api",
"private": true,
"version": "2.0.32",
"version": "2.0.34",
"type": "module",
"scripts": {
"dev": "vite --clearScreen false",
@@ -10,25 +10,25 @@
"tauri": "tauri"
},
"dependencies": {
"@tauri-apps/api": "2.8.0",
"@tauri-apps/plugin-barcode-scanner": "^2.4.0",
"@tauri-apps/plugin-biometric": "^2.3.0",
"@tauri-apps/plugin-cli": "^2.4.0",
"@tauri-apps/plugin-clipboard-manager": "^2.3.0",
"@tauri-apps/plugin-dialog": "^2.4.0",
"@tauri-apps/plugin-fs": "^2.4.2",
"@tauri-apps/api": "2.9.0",
"@tauri-apps/plugin-barcode-scanner": "^2.4.2",
"@tauri-apps/plugin-biometric": "^2.3.2",
"@tauri-apps/plugin-cli": "^2.4.1",
"@tauri-apps/plugin-clipboard-manager": "^2.3.2",
"@tauri-apps/plugin-dialog": "^2.4.2",
"@tauri-apps/plugin-fs": "^2.4.4",
"@tauri-apps/plugin-geolocation": "^2.2.0",
"@tauri-apps/plugin-global-shortcut": "^2.3.0",
"@tauri-apps/plugin-global-shortcut": "^2.3.1",
"@tauri-apps/plugin-haptics": "^2.2.0",
"@tauri-apps/plugin-http": "^2.5.2",
"@tauri-apps/plugin-nfc": "^2.3.1",
"@tauri-apps/plugin-notification": "^2.3.1",
"@tauri-apps/plugin-opener": "^2.5.0",
"@tauri-apps/plugin-os": "^2.3.1",
"@tauri-apps/plugin-process": "^2.3.0",
"@tauri-apps/plugin-http": "^2.5.4",
"@tauri-apps/plugin-nfc": "^2.3.3",
"@tauri-apps/plugin-notification": "^2.3.3",
"@tauri-apps/plugin-opener": "^2.5.2",
"@tauri-apps/plugin-os": "^2.3.2",
"@tauri-apps/plugin-process": "^2.3.1",
"@tauri-apps/plugin-secure-storage": "file:../../plugins/secure-storage",
"@tauri-apps/plugin-shell": "^2.3.1",
"@tauri-apps/plugin-store": "^2.4.0",
"@tauri-apps/plugin-shell": "^2.3.3",
"@tauri-apps/plugin-store": "^2.4.1",
"@tauri-apps/plugin-updater": "^2.9.0",
"@tauri-apps/plugin-upload": "^2.3.0",
"@zerodevx/svelte-json-view": "1.0.11"
@@ -37,7 +37,7 @@
"@iconify-json/codicon": "^1.2.12",
"@iconify-json/ph": "^1.2.2",
"@sveltejs/vite-plugin-svelte": "^6.0.0",
"@tauri-apps/cli": "2.8.4",
"@tauri-apps/cli": "2.9.4",
"@unocss/extractor-svelte": "^66.3.3",
"svelte": "^5.20.4",
"unocss": "^66.3.3",
+40
View File
@@ -1,5 +1,45 @@
# Changelog
## \[2.0.38]
### Dependencies
- Upgraded to `barcode-scanner@2.4.2`
- Upgraded to `biometric@2.3.2`
- Upgraded to `cli@2.4.1`
- Upgraded to `clipboard-manager@2.3.2`
- Upgraded to `dialog@2.4.2`
- Upgraded to `fs@2.4.4`
- Upgraded to `geolocation@2.3.2`
- Upgraded to `global-shortcut@2.3.1`
- Upgraded to `haptics@2.3.2`
- Upgraded to `http@2.5.4`
- Upgraded to `log@2.7.1`
- Upgraded to `nfc@2.3.3`
- Upgraded to `notification@2.3.3`
- Upgraded to `opener@2.5.2`
- Upgraded to `os@2.3.2`
- Upgraded to `process@2.3.1`
- Upgraded to `shell@2.3.3`
- Upgraded to `store@2.4.1`
## \[2.0.37]
### Dependencies
- Upgraded to `barcode-scanner@2.4.1`
- Upgraded to `biometric@2.3.1`
- Upgraded to `clipboard-manager@2.3.1`
- Upgraded to `dialog@2.4.1`
- Upgraded to `fs@2.4.3`
- Upgraded to `geolocation@2.3.1`
- Upgraded to `haptics@2.3.1`
- Upgraded to `nfc@2.3.2`
- Upgraded to `notification@2.3.2`
- Upgraded to `opener@2.5.1`
- Upgraded to `shell@2.3.2`
- Upgraded to `http@2.5.3`
## \[2.0.36]
### Dependencies
+19 -19
View File
@@ -1,7 +1,7 @@
[package]
name = "api"
publish = false
version = "2.0.36"
version = "2.0.38"
description = "An example Tauri Application showcasing the api"
edition = "2021"
rust-version = { workspace = true }
@@ -20,25 +20,25 @@ serde = { workspace = true }
tiny_http = "0.12"
time = "0.3"
log = { workspace = true }
tauri-plugin-log = { path = "../../../plugins/log", version = "2.7.0" }
tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.4.2", features = [
tauri-plugin-log = { path = "../../../plugins/log", version = "2.7.1" }
tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.4.4", features = [
"watch",
] }
tauri-plugin-clipboard-manager = { path = "../../../plugins/clipboard-manager", version = "2.3.0" }
tauri-plugin-dialog = { path = "../../../plugins/dialog", version = "2.4.0" }
tauri-plugin-clipboard-manager = { path = "../../../plugins/clipboard-manager", version = "2.3.2" }
tauri-plugin-dialog = { path = "../../../plugins/dialog", version = "2.4.2" }
tauri-plugin-http = { path = "../../../plugins/http", features = [
"multipart",
"cookies",
], version = "2.5.2" }
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.3.1", features = [
], version = "2.5.4" }
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.3.3", features = [
"windows7-compat",
] }
tauri-plugin-os = { path = "../../../plugins/os", version = "2.3.1" }
tauri-plugin-process = { path = "../../../plugins/process", version = "2.3.0" }
tauri-plugin-opener = { path = "../../../plugins/opener", version = "2.5.0" }
tauri-plugin-os = { path = "../../../plugins/os", version = "2.3.2" }
tauri-plugin-process = { path = "../../../plugins/process", version = "2.3.1" }
tauri-plugin-opener = { path = "../../../plugins/opener", version = "2.5.2" }
tauri-plugin-secure-storage = { path = "../../../plugins/secure-storage" }
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.3.1" }
tauri-plugin-store = { path = "../../../plugins/store", version = "2.4.0" }
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.3.3" }
tauri-plugin-store = { path = "../../../plugins/store", version = "2.4.1" }
tauri-plugin-upload = { path = "../../../plugins/upload", version = "2.3.0" }
[dependencies.tauri]
@@ -56,17 +56,17 @@ features = [
]
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
tauri-plugin-cli = { path = "../../../plugins/cli", version = "2.4.0" }
tauri-plugin-global-shortcut = { path = "../../../plugins/global-shortcut", version = "2.3.0" }
tauri-plugin-cli = { path = "../../../plugins/cli", version = "2.4.1" }
tauri-plugin-global-shortcut = { path = "../../../plugins/global-shortcut", version = "2.3.1" }
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.9.0" }
tauri-plugin-window-state = { path = "../../../plugins/window-state", version = "2.2.0" }
[target."cfg(any(target_os = \"android\", target_os = \"ios\"))".dependencies]
tauri-plugin-barcode-scanner = { path = "../../../plugins/barcode-scanner/", version = "2.4.0" }
tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.3.1" }
tauri-plugin-biometric = { path = "../../../plugins/biometric/", version = "2.3.0" }
tauri-plugin-geolocation = { path = "../../../plugins/geolocation/", version = "2.3.0" }
tauri-plugin-haptics = { path = "../../../plugins/haptics/", version = "2.3.0" }
tauri-plugin-barcode-scanner = { path = "../../../plugins/barcode-scanner/", version = "2.4.2" }
tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.3.3" }
tauri-plugin-biometric = { path = "../../../plugins/biometric/", version = "2.3.2" }
tauri-plugin-geolocation = { path = "../../../plugins/geolocation/", version = "2.3.2" }
tauri-plugin-haptics = { path = "../../../plugins/haptics/", version = "2.3.2" }
[features]
prod = ["tauri/custom-protocol"]
@@ -14,13 +14,13 @@ val tauriProperties = Properties().apply {
}
android {
compileSdk = 34
compileSdk = 36
namespace = "com.tauri.api"
defaultConfig {
manifestPlaceholders["usesCleartextTraffic"] = "false"
applicationId = "com.tauri.api"
minSdk = 24
targetSdk = 34
targetSdk = 36
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
}
@@ -4,7 +4,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:8.5.1")
classpath("com.android.tools.build:gradle:8.11.0")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.25")
}
}
@@ -18,6 +18,6 @@ repositories {
dependencies {
compileOnly(gradleApi())
implementation("com.android.tools.build:gradle:8.5.1")
implementation("com.android.tools.build:gradle:8.11.0")
}
+15 -3
View File
@@ -8,6 +8,7 @@
let filter = null;
let multiple = false;
let directory = false;
let pickerMode = "";
function arrayBufferToBase64(buffer, callback) {
var blob = new Blob([buffer], {
@@ -65,6 +66,7 @@
: [],
multiple,
directory,
pickerMode: pickerMode === "" ? undefined : pickerMode,
})
.then(function (res) {
if (Array.isArray(res)) {
@@ -94,7 +96,7 @@
onMessage(res);
}
})
.catch(onMessage(res));
.catch(onMessage);
}
})
.catch(onMessage);
@@ -112,7 +114,7 @@
},
]
: [],
})
})
.then(onMessage)
.catch(onMessage);
}
@@ -142,6 +144,16 @@
<input type="checkbox" id="dialog-directory" bind:checked={directory} />
<label for="dialog-directory">Directory</label>
</div>
<div>
<label for="dialog-picker-mode">Picker Mode:</label>
<select id="dialog-picker-mode" bind:value={pickerMode}>
<option value="">None</option>
<option value="media">Media</option>
<option value="image">Image</option>
<option value="video">Video</option>
<option value="document">Document</option>
</select>
</div>
<br />
<div class="flex flex-wrap flex-col md:flex-row gap-2 children:flex-shrink-0">
@@ -156,4 +168,4 @@
<button class="btn" id="message-dialog" on:click={msg}>Message</button>
<button class="btn" id="message-dialog" on:click={msgCustom}>Message (custom)</button>
</div>
</div>
+44 -3
View File
@@ -1,5 +1,5 @@
<script>
import { download, upload } from '@tauri-apps/plugin-upload'
import { download, upload, HttpMethod } from '@tauri-apps/plugin-upload'
import { open } from '@tauri-apps/plugin-dialog'
import { JsonView } from '@zerodevx/svelte-json-view'
import { appDataDir } from '@tauri-apps/api/path'
@@ -16,6 +16,22 @@
let uploadUrl = 'https://httpbin.org/post'
let uploadFilePath = ''
let uploadMethod = HttpMethod.Post
// Update URL when method changes
$: {
switch (uploadMethod) {
case HttpMethod.Post:
uploadUrl = 'https://httpbin.org/post'
break
case HttpMethod.Put:
uploadUrl = 'https://httpbin.org/put'
break
case HttpMethod.Patch:
uploadUrl = 'https://httpbin.org/patch'
break
}
}
let uploadProgress = null
let uploadResult = null
let isUploading = false
@@ -197,7 +213,8 @@
},
new Map([
['User-Agent', 'Tauri Upload Plugin Demo']
])
]),
uploadMethod
)
uploadResult = {
@@ -340,12 +357,36 @@
</div>
</div>
<div>
<label for="upload-method" class="block text-sm font-medium text-gray-700 mb-1">HTTP Method:</label>
<select
id="upload-method"
bind:value={uploadMethod}
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
disabled={isUploading}
>
<option value={HttpMethod.Post}>POST</option>
<option value={HttpMethod.Put}>PUT</option>
<option value={HttpMethod.Patch}>PATCH</option>
</select>
<p class="text-xs text-gray-500 mt-1">Choose the HTTP method for the upload request</p>
</div>
<div class="bg-blue-50 border border-blue-200 p-3 rounded-md">
<div class="text-sm text-blue-800">
<strong>Upload Configuration:</strong>
<div class="font-mono text-xs mt-1">
Method: {uploadMethod} | URL: {uploadUrl || 'Not set'}
</div>
</div>
</div>
<button
on:click={startUpload}
class="w-full px-4 py-2 bg-green-500 text-white rounded-md hover:bg-green-600 disabled:opacity-50 disabled:cursor-not-allowed"
disabled={isUploading || !uploadUrl || !uploadFilePath}
>
{isUploading ? 'Uploading...' : 'Upload File'}
{isUploading ? `Uploading (${uploadMethod})...` : `Upload File (${uploadMethod})`}
</button>
{#if uploadProgress}
+7 -7
View File
@@ -11,19 +11,19 @@
"example:api:dev": "pnpm run --filter \"api\" tauri dev"
},
"devDependencies": {
"@eslint/js": "9.36.0",
"@rollup/plugin-node-resolve": "16.0.1",
"@eslint/js": "9.39.1",
"@rollup/plugin-node-resolve": "16.0.3",
"@rollup/plugin-terser": "0.4.4",
"@rollup/plugin-typescript": "12.1.4",
"@rollup/plugin-typescript": "12.3.0",
"covector": "^0.12.4",
"eslint": "9.36.0",
"eslint": "9.39.1",
"eslint-config-prettier": "10.1.8",
"eslint-plugin-security": "3.0.1",
"prettier": "3.6.2",
"rollup": "4.52.3",
"rollup": "4.53.2",
"tslib": "2.8.1",
"typescript": "5.9.2",
"typescript-eslint": "8.44.1"
"typescript": "5.9.3",
"typescript-eslint": "8.47.0"
},
"minimumReleaseAge": 4320,
"pnpm": {
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.5.1]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.5.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
+1 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-autostart"
version = "2.5.0"
version = "2.5.1"
description = "Automatically launch your application at startup."
authors = { workspace = true }
license = { workspace = true }
@@ -9,10 +9,6 @@ rust-version = { workspace = true }
repository = { workspace = true }
links = "tauri-plugin-autostart"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.platforms.support]
windows = { level = "full", notes = "" }
linux = { level = "full", notes = "" }
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-autostart",
"version": "2.5.0",
"version": "2.5.1",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
+9
View File
@@ -1,5 +1,14 @@
# Changelog
## \[2.4.2]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.4.1]
- [`654bf489`](https://github.com/tauri-apps/plugins-workspace/commit/654bf4891a35769f7e82971641d3ad99974b2dfe) ([#3038](https://github.com/tauri-apps/plugins-workspace/pull/3038) by [@daniel-mader](https://github.com/tauri-apps/plugins-workspace/../../daniel-mader)) Update `androidx.camera` from `1.1.0` to `1.5.1` to support 16 KB memory page sizes.
- [`6c9b61fb`](https://github.com/tauri-apps/plugins-workspace/commit/6c9b61fb658145d13893626112fc489f7458aa17) ([#3039](https://github.com/tauri-apps/plugins-workspace/pull/3039) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) On Android, updated compileSdk to 36.
## \[2.4.0]
- [`aa9140e1`](https://github.com/tauri-apps/plugins-workspace/commit/aa9140e1ac239ab9f015f92b2ed52bbf0eda7c12) ([#2437](https://github.com/tauri-apps/plugins-workspace/pull/2437) by [@enkhjile](https://github.com/tauri-apps/plugins-workspace/../../enkhjile)) Added support for GS1 DataBar on iOS 15.4+
+1 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-barcode-scanner"
version = "2.4.0"
version = "2.4.2"
description = "Scan QR codes, EAN-13 and other kinds of barcodes on Android and iOS"
edition = { workspace = true }
authors = { workspace = true }
@@ -10,8 +10,6 @@ repository = { workspace = true }
links = "tauri-plugin-barcode-scanner"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
targets = ["x86_64-linux-android"]
[package.metadata.platforms.support]
@@ -5,10 +5,10 @@ plugins {
android {
namespace = "app.tauri.barcodescanner"
compileSdk = 34
compileSdk = 36
defaultConfig {
minSdk = 24
minSdk = 24
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
@@ -33,16 +33,14 @@ android {
}
dependencies {
val camerax_version = "1.5.1"
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.appcompat:appcompat:1.6.0")
implementation("com.google.android.material:material:1.7.0")
implementation("androidx.camera:camera-core:1.1.0")
implementation("androidx.camera:camera-view:1.1.0")
implementation("androidx.camera:camera-lifecycle:1.1.0")
implementation("androidx.camera:camera-camera2:1.1.0")
implementation("androidx.camera:camera-lifecycle:1.1.0")
implementation("androidx.camera:camera-view:1.1.0")
implementation("androidx.camera:camera-core:${camerax_version}")
implementation("androidx.camera:camera-camera2:${camerax_version}")
implementation("androidx.camera:camera-lifecycle:${camerax_version}")
implementation("androidx.camera:camera-view:${camerax_version}")
implementation("com.google.android.gms:play-services-mlkit-barcode-scanning:18.1.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
@@ -191,6 +191,7 @@ class BarcodeScannerPlugin: Plugin, AVCaptureMetadataOutputObjectsDelegate {
if self.captureSession != nil {
self.captureSession!.stopRunning()
self.cameraView.removePreviewLayer()
self.cameraView.removeFromSuperview()
self.captureVideoPreviewLayer = nil
self.metaOutput = nil
self.captureSession = nil
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-barcode-scanner",
"version": "2.4.0",
"version": "2.4.2",
"description": "Scan QR codes, EAN-13 and other kinds of barcodes on Android and iOS",
"license": "MIT OR Apache-2.0",
"authors": [
+8
View File
@@ -1,5 +1,13 @@
# Changelog
## \[2.3.2]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.3.1]
- [`6c9b61fb`](https://github.com/tauri-apps/plugins-workspace/commit/6c9b61fb658145d13893626112fc489f7458aa17) ([#3039](https://github.com/tauri-apps/plugins-workspace/pull/3039) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) On Android, updated compileSdk to 36.
## \[2.3.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
+1 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-biometric"
version = "2.3.0"
version = "2.3.2"
description = "Prompt the user for biometric authentication on Android and iOS."
edition = { workspace = true }
authors = { workspace = true }
@@ -9,8 +9,6 @@ repository = { workspace = true }
links = "tauri-plugin-biometric"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
targets = ["x86_64-linux-android"]
[package.metadata.platforms.support]
+2 -2
View File
@@ -5,10 +5,10 @@ plugins {
android {
namespace = "app.tauri.biometric"
compileSdk = 34
compileSdk = 36
defaultConfig {
minSdk = 24
minSdk = 24
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-biometric",
"version": "2.3.0",
"version": "2.3.2",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.4.1]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.4.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
+1 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-cli"
version = "2.4.0"
version = "2.4.1"
description = "Parse arguments from your Tauri application's command line interface."
edition = { workspace = true }
authors = { workspace = true }
@@ -9,10 +9,6 @@ rust-version = { workspace = true }
repository = { workspace = true }
links = "tauri-plugin-cli"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.platforms.support]
windows = { level = "full", notes = "" }
linux = { level = "full", notes = "" }
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-cli",
"version": "2.4.0",
"version": "2.4.1",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
+8
View File
@@ -1,5 +1,13 @@
# Changelog
## \[2.3.2]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.3.1]
- [`6c9b61fb`](https://github.com/tauri-apps/plugins-workspace/commit/6c9b61fb658145d13893626112fc489f7458aa17) ([#3039](https://github.com/tauri-apps/plugins-workspace/pull/3039) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) On Android, updated compileSdk to 36.
## \[2.3.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
+2 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-clipboard-manager"
version = "2.3.0"
version = "2.3.2"
description = "Read and write to the system clipboard."
edition = { workspace = true }
authors = { workspace = true }
@@ -10,8 +10,7 @@ repository = { workspace = true }
links = "tauri-plugin-clipboard-manager"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
targets = ["x86_64-unknown-linux-gnu", "x86_64-linux-android"]
[package.metadata.platforms.support]
@@ -5,10 +5,10 @@ plugins {
android {
namespace = "app.tauri.clipboard"
compileSdk = 34
compileSdk = 36
defaultConfig {
minSdk = 24
minSdk = 24
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-clipboard-manager",
"version": "2.3.0",
"version": "2.3.2",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
+9
View File
@@ -1,5 +1,14 @@
# Changelog
## \[2.4.5]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.4.4]
- [`6c9b61fb`](https://github.com/tauri-apps/plugins-workspace/commit/6c9b61fb658145d13893626112fc489f7458aa17) ([#3039](https://github.com/tauri-apps/plugins-workspace/pull/3039) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) On Android, updated compileSdk to 36.
- [`e25a9339`](https://github.com/tauri-apps/plugins-workspace/commit/e25a9339f46268f70dc9afd0c5ab3decbf79b330) ([#3019](https://github.com/tauri-apps/plugins-workspace/pull/3019) by [@kevinschoonover](https://github.com/tauri-apps/plugins-workspace/../../kevinschoonover)) Fix Exec= field in desktop handler if executable path changes
## \[2.4.3]
- [`2522b71f`](https://github.com/tauri-apps/plugins-workspace/commit/2522b71f6bcae65c03b24415eb9295c9e7c84ffc) ([#2970](https://github.com/tauri-apps/plugins-workspace/pull/2970) by [@WSH032](https://github.com/tauri-apps/plugins-workspace/../../WSH032)) Revert the breaking change introduced by [#2928](https://github.com/tauri-apps/plugins-workspace/pull/2928).
+1 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-deep-link"
version = "2.4.3"
version = "2.4.5"
description = "Set your Tauri application as the default handler for an URL"
authors = { workspace = true }
license = { workspace = true }
@@ -10,8 +10,6 @@ repository = { workspace = true }
links = "tauri-plugin-deep-link"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
targets = ["x86_64-linux-android"]
[package.metadata.platforms.support]
+2 -2
View File
@@ -5,10 +5,10 @@ plugins {
android {
namespace = "app.tauri.deep_link"
compileSdk = 34
compileSdk = 36
defaultConfig {
minSdk = 24
minSdk = 24
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
@@ -1,5 +1,17 @@
# Changelog
## \[2.2.8]
### Dependencies
- Upgraded to `deep-link-js@2.4.5`
## \[2.2.7]
### Dependencies
- Upgraded to `deep-link-js@2.4.4`
## \[2.2.6]
### Dependencies
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "deep-link-example",
"private": true,
"version": "2.2.6",
"version": "2.2.8",
"type": "module",
"scripts": {
"dev": "vite",
@@ -10,11 +10,11 @@
"tauri": "tauri"
},
"dependencies": {
"@tauri-apps/api": "2.8.0",
"@tauri-apps/plugin-deep-link": "2.4.3"
"@tauri-apps/api": "2.9.0",
"@tauri-apps/plugin-deep-link": "2.4.5"
},
"devDependencies": {
"@tauri-apps/cli": "2.8.4",
"@tauri-apps/cli": "2.9.4",
"typescript": "^5.7.3",
"vite": "^7.0.7"
}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-deep-link",
"version": "2.4.3",
"version": "2.4.5",
"description": "Set your Tauri application as the default handler for an URL",
"license": "MIT OR Apache-2.0",
"authors": [
@@ -28,6 +28,6 @@
"@tauri-apps/api": "^2.8.0"
},
"devDependencies": {
"@tauri-apps/cli": "2.8.4"
"@tauri-apps/cli": "2.9.4"
}
}
+16
View File
@@ -1,5 +1,21 @@
# Changelog
## \[2.4.2]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
### Dependencies
- Upgraded to `fs-js@2.4.4`
## \[2.4.1]
- [`6c9b61fb`](https://github.com/tauri-apps/plugins-workspace/commit/6c9b61fb658145d13893626112fc489f7458aa17) ([#3039](https://github.com/tauri-apps/plugins-workspace/pull/3039) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) On Android, updated compileSdk to 36.
### Dependencies
- Upgraded to `fs-js@2.4.3`
## \[2.4.0]
- [`509eba8d`](https://github.com/tauri-apps/plugins-workspace/commit/509eba8d441c4f6ecf0af77b572cb2afd69a752d) ([#2641](https://github.com/tauri-apps/plugins-workspace/pull/2641) by [@amrbashir](https://github.com/tauri-apps/plugins-workspace/../../amrbashir)) Add support for showing a message dialog with 3 buttons.
+8 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-dialog"
version = "2.4.0"
version = "2.4.2"
description = "Native system dialogs for opening and saving files along with message dialogs on your Tauri application."
edition = { workspace = true }
authors = { workspace = true }
@@ -9,9 +9,12 @@ rust-version = { workspace = true }
repository = { workspace = true }
links = "tauri-plugin-dialog"
[features]
default = ["gtk3"]
xdg-portal = ["rfd/xdg-portal"]
gtk3 = ["rfd/gtk3"]
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
targets = ["x86_64-unknown-linux-gnu", "x86_64-linux-android"]
[package.metadata.platforms.support]
@@ -34,7 +37,7 @@ tauri = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
url = { workspace = true }
tauri-plugin-fs = { path = "../fs", version = "2.4.2" }
tauri-plugin-fs = { path = "../fs", version = "2.4.4" }
[target.'cfg(target_os = "ios")'.dependencies]
tauri = { workspace = true, features = ["wry"] }
@@ -42,7 +45,7 @@ tauri = { workspace = true, features = ["wry"] }
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
rfd = { version = "0.15", default-features = false, features = [
"tokio",
"gtk3",
"common-controls-v6",
] }
raw-window-handle = "0.6"
+18
View File
@@ -31,6 +31,24 @@ tauri-plugin-dialog = "2.0.0"
tauri-plugin-dialog = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
```
### Linux XDG Desktop Portal Support
By default, this plugin uses gtk to show dialogs, however since `v2.5.0` you can switch to using [XDG Desktop Portal](https://flatpak.github.io/xdg-desktop-portal/) by adding the following to your `Cargo.toml` file:
```toml
[dependencies]
tauri-plugin-dialog = { version = "2.5.0", default-features = false, features = ["xdg-portal"] }
# alternatively with Git:
tauri-plugin-dialog = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2", default-features = false, features = ["xdg-portal"] }
```
Do note if you use the `xdg-portal` feature, you need to ensure that [`zenity`](https://gitlab.gnome.org/GNOME/zenity) and an [XDG Desktop Portal backend](https://flatpak.github.io/xdg-desktop-portal#using-portals) is installed with your program.
For more information, see [XDG Desktop Portal documentation](https://flatpak.github.io/xdg-desktop-portal/) and [`rfd` documentation](https://docs.rs/rfd/latest/rfd#xdg-desktop-portal-backend).
### JavaScript
You can install the JavaScript Guest bindings using your preferred JavaScript package manager:
```sh
+2 -2
View File
@@ -5,10 +5,10 @@ plugins {
android {
namespace = "app.tauri.dialog"
compileSdk = 34
compileSdk = 36
defaultConfig {
minSdk = 24
minSdk = 24
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
@@ -31,6 +31,7 @@ class Filter {
class FilePickerOptions {
lateinit var filters: Array<Filter>
var multiple: Boolean? = null
var pickerMode: String? = null
}
@InvokeArg
@@ -61,10 +62,19 @@ class DialogPlugin(private val activity: Activity): Plugin(activity) {
// TODO: ACTION_OPEN_DOCUMENT ??
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = "*/*"
if (parsedTypes.isNotEmpty()) {
if (args.pickerMode == "image") {
intent.type = "image/*"
} else if (args.pickerMode == "video") {
intent.type = "video/*"
} else if (args.pickerMode == "media") {
intent.type = "*/*"
intent.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("video/*", "image/*"))
} else if (parsedTypes.isNotEmpty()) {
intent.type = "*/*"
intent.putExtra(Intent.EXTRA_MIME_TYPES, parsedTypes)
} else {
intent.type = "*/*"
}
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, args.multiple ?: false)
+35 -1
View File
@@ -14,6 +14,16 @@ interface DialogFilter {
name: string
/**
* Extensions to filter, without a `.` prefix.
*
* **Note:** Mobile platforms have different APIs for filtering that may not support extensions.
* iOS: Extensions are supported in the document picker, but not in the media picker.
* Android: Extensions are not supported.
*
* For these platforms, MIME types are the primary way to filter files, as opposed to extensions.
* This means the string values here labeled as `extensions` may also be a MIME type.
* This property name of `extensions` is being kept for backwards compatibility, but this may be revisited to
* specify the difference between extension or MIME type filtering.
*
* @example
* ```typescript
* extensions: ['svg', 'png']
@@ -30,7 +40,14 @@ interface DialogFilter {
interface OpenDialogOptions {
/** The title of the dialog window (desktop only). */
title?: string
/** The filters of the dialog. */
/**
* The filters of the dialog.
* On mobile platforms, if either:
* A) the {@linkcode pickerMode} is set to `media`, `image`, or `video`
* -- or --
* B) the filters include **only** either image or video mime types, the media picker will be displayed.
* Otherwise, the document picker will be displayed.
*/
filters?: DialogFilter[]
/**
* Initial directory or file path.
@@ -52,6 +69,13 @@ interface OpenDialogOptions {
recursive?: boolean
/** Whether to allow creating directories in the dialog. Enabled by default. **macOS Only** */
canCreateDirectories?: boolean
/**
* The preferred mode of the dialog.
* This is meant for mobile platforms (iOS and Android) which have distinct file and media pickers.
* If not provided, the dialog will automatically choose the best mode based on the MIME types or extensions of the {@linkcode filters}.
* On desktop, this option is ignored.
*/
pickerMode?: PickerMode
}
/**
@@ -77,6 +101,16 @@ interface SaveDialogOptions {
canCreateDirectories?: boolean
}
/**
* The preferred mode of the dialog.
* This is meant for mobile platforms (iOS and Android) which have distinct file and media pickers.
* On desktop, this option is ignored.
* If not provided, the dialog will automatically choose the best mode based on the MIME types or extensions of the {@linkcode filters}.
*
* **Note:** This option is only supported on iOS 14 and above. This parameter is ignored on iOS 13 and below.
*/
export type PickerMode = 'document' | 'media' | 'image' | 'video'
/**
* Default buttons for a message dialog.
*
+107 -51
View File
@@ -8,6 +8,7 @@ import PhotosUI
import SwiftRs
import Tauri
import UIKit
import UniformTypeIdentifiers
import WebKit
enum FilePickerEvent {
@@ -32,6 +33,7 @@ struct FilePickerOptions: Decodable {
var multiple: Bool?
var filters: [Filter]?
var defaultPath: String?
var pickerMode: PickerMode?
}
struct SaveFileDialogOptions: Decodable {
@@ -39,6 +41,13 @@ struct SaveFileDialogOptions: Decodable {
var defaultPath: String?
}
enum PickerMode: String, Decodable {
case document
case media
case image
case video
}
class DialogPlugin: Plugin {
var filePickerController: FilePickerController!
@@ -52,26 +61,6 @@ class DialogPlugin: Plugin {
@objc public func showFilePicker(_ invoke: Invoke) throws {
let args = try invoke.parseArgs(FilePickerOptions.self)
let parsedTypes = parseFiltersOption(args.filters ?? [])
var isMedia = !parsedTypes.isEmpty
var uniqueMimeType: Bool? = nil
var mimeKind: String? = nil
if !parsedTypes.isEmpty {
uniqueMimeType = true
for mime in parsedTypes {
let kind = mime.components(separatedBy: "/")[0]
if kind != "image" && kind != "video" {
isMedia = false
}
if mimeKind == nil {
mimeKind = kind
} else if mimeKind != kind {
uniqueMimeType = false
}
}
}
onFilePickerResult = { (event: FilePickerEvent) -> Void in
switch event {
case .selected(let urls):
@@ -81,51 +70,57 @@ class DialogPlugin: Plugin {
case .error(let error):
invoke.reject(error)
}
}
}
if uniqueMimeType == true || isMedia {
DispatchQueue.main.async {
if #available(iOS 14, *) {
if #available(iOS 14, *) {
let parsedTypes = parseFiltersOption(args.filters ?? [])
let mimeKinds = Set(parsedTypes.compactMap { $0.preferredMIMEType?.components(separatedBy: "/")[0] })
let filtersIncludeImage = mimeKinds.contains("image")
let filtersIncludeVideo = mimeKinds.contains("video")
let filtersIncludeNonMedia = mimeKinds.contains(where: { $0 != "image" && $0 != "video" })
// If the picker mode is media, images, or videos, we always want to show the media picker regardless of what's in the filters.
// Otherwise, if the filters A) do not include non-media types and B) include either image or video, we want to show the media picker.
if args.pickerMode == .media
|| args.pickerMode == .image
|| args.pickerMode == .video
|| (!filtersIncludeNonMedia && (filtersIncludeImage || filtersIncludeVideo)) {
DispatchQueue.main.async {
var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
configuration.selectionLimit = (args.multiple ?? false) ? 0 : 1
if uniqueMimeType == true {
if mimeKind == "image" {
configuration.filter = .images
} else if mimeKind == "video" {
configuration.filter = .videos
}
// If the filters include image or video, use the appropriate filter.
// If both are true, don't define a filter, which means we will display all media.
if args.pickerMode == .image || (filtersIncludeImage && !filtersIncludeVideo) {
configuration.filter = .images
} else if args.pickerMode == .video || (filtersIncludeVideo && !filtersIncludeImage) {
configuration.filter = .videos
}
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self.filePickerController
picker.modalPresentationStyle = .fullScreen
self.presentViewController(picker)
} else {
let picker = UIImagePickerController()
picker.delegate = self.filePickerController
if uniqueMimeType == true && mimeKind == "image" {
picker.sourceType = .photoLibrary
}
} else {
DispatchQueue.main.async {
// The UTType.item is the catch-all, allowing for any file type to be selected.
let contentTypes = parsedTypes.isEmpty ? [UTType.item] : parsedTypes
let picker: UIDocumentPickerViewController = UIDocumentPickerViewController(forOpeningContentTypes: contentTypes, asCopy: true)
if let defaultPath = args.defaultPath {
picker.directoryURL = URL(string: defaultPath)
}
picker.sourceType = .photoLibrary
picker.delegate = self.filePickerController
picker.allowsMultipleSelection = args.multiple ?? false
picker.modalPresentationStyle = .fullScreen
self.presentViewController(picker)
}
}
} else {
let documentTypes = parsedTypes.isEmpty ? ["public.data"] : parsedTypes
DispatchQueue.main.async {
let picker = UIDocumentPickerViewController(documentTypes: documentTypes, in: .import)
if let defaultPath = args.defaultPath {
picker.directoryURL = URL(string: defaultPath)
}
picker.delegate = self.filePickerController
picker.allowsMultipleSelection = args.multiple ?? false
picker.modalPresentationStyle = .fullScreen
self.presentViewController(picker)
}
showFilePickerLegacy(args: args)
}
}
@@ -173,19 +168,80 @@ class DialogPlugin: Plugin {
self.manager.viewController?.present(viewControllerToPresent, animated: true, completion: nil)
}
private func parseFiltersOption(_ filters: [Filter]) -> [String] {
@available(iOS 14, *)
private func parseFiltersOption(_ filters: [Filter]) -> [UTType] {
var parsedTypes: [UTType] = []
for filter in filters {
for ext in filter.extensions ?? [] {
// We need to support extensions as well as MIME types.
if let utType = UTType(mimeType: ext) {
parsedTypes.append(utType)
} else if let utType = UTType(filenameExtension: ext) {
parsedTypes.append(utType)
}
}
}
return parsedTypes
}
/// This function is only used for iOS < 14, and should be removed if/when the deployment target is raised to 14.
private func showFilePickerLegacy(args: FilePickerOptions) {
let parsedTypes = parseFiltersOptionLegacy(args.filters ?? [])
var filtersIncludeImage: Bool = false
var filtersIncludeVideo: Bool = false
var filtersIncludeNonMedia: Bool = false
if !parsedTypes.isEmpty {
let mimeKinds = Set(parsedTypes.map { $0.components(separatedBy: "/")[0] })
filtersIncludeImage = mimeKinds.contains("image")
filtersIncludeVideo = mimeKinds.contains("video")
filtersIncludeNonMedia = mimeKinds.contains(where: { $0 != "image" && $0 != "video" })
}
if !filtersIncludeNonMedia && (filtersIncludeImage || filtersIncludeVideo) {
DispatchQueue.main.async {
let picker = UIImagePickerController()
picker.delegate = self.filePickerController
if filtersIncludeImage && !filtersIncludeVideo {
picker.sourceType = .photoLibrary
}
picker.modalPresentationStyle = .fullScreen
self.presentViewController(picker)
}
} else {
let documentTypes = parsedTypes.isEmpty ? ["public.data"] : parsedTypes
DispatchQueue.main.async {
let picker = UIDocumentPickerViewController(documentTypes: documentTypes, in: .import)
if let defaultPath = args.defaultPath {
picker.directoryURL = URL(string: defaultPath)
}
picker.delegate = self.filePickerController
picker.allowsMultipleSelection = args.multiple ?? false
picker.modalPresentationStyle = .fullScreen
self.presentViewController(picker)
}
}
}
/// This function is only used for iOS < 14, and should be removed if/when the deployment target is raised to 14.
private func parseFiltersOptionLegacy(_ filters: [Filter]) -> [String] {
var parsedTypes: [String] = []
for filter in filters {
for ext in filter.extensions ?? [] {
guard
let utType: String = UTTypeCreatePreferredIdentifierForTag(
kUTTagClassMIMEType, ext as CFString, nil)?.takeRetainedValue() as String?
let utType: String = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, ext as CFString, nil)?.takeRetainedValue() as String?
else {
continue
}
parsedTypes.append(utType)
}
}
return parsedTypes
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-dialog",
"version": "2.4.0",
"version": "2.4.2",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
+11 -1
View File
@@ -10,7 +10,7 @@ use tauri_plugin_fs::FsExt;
use crate::{
Dialog, FileDialogBuilder, FilePath, MessageDialogBuilder, MessageDialogButtons,
MessageDialogKind, MessageDialogResult, Result, CANCEL, NO, OK, YES,
MessageDialogKind, MessageDialogResult, PickerMode, Result, CANCEL, NO, OK, YES,
};
#[derive(Serialize)]
@@ -56,6 +56,13 @@ pub struct OpenDialogOptions {
recursive: bool,
/// Whether to allow creating directories in the dialog **macOS Only**
can_create_directories: Option<bool>,
/// The preferred mode of the dialog.
/// This is meant for mobile platforms (iOS and Android) which have distinct file and media pickers.
/// On desktop, this option is ignored.
/// If not provided, the dialog will automatically choose the best mode based on the MIME types of the filters.
#[serde(default)]
#[cfg_attr(mobile, allow(dead_code))]
picker_mode: Option<PickerMode>,
}
/// The options for the save dialog API.
@@ -127,6 +134,9 @@ pub(crate) async fn open<R: Runtime>(
if let Some(can) = options.can_create_directories {
dialog_builder = dialog_builder.set_can_create_directories(can);
}
if let Some(picker_mode) = options.picker_mode {
dialog_builder = dialog_builder.set_picker_mode(picker_mode);
}
for filter in options.filters {
let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
+56 -7
View File
@@ -9,7 +9,7 @@
html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png"
)]
use serde::Serialize;
use serde::{Deserialize, Serialize};
use tauri::{
plugin::{Builder, TauriPlugin},
Manager, Runtime,
@@ -44,6 +44,15 @@ pub use desktop::Dialog;
#[cfg(mobile)]
pub use mobile::Dialog;
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "lowercase")]
pub enum PickerMode {
Document,
Media,
Image,
Video,
}
pub(crate) const OK: &str = "Ok";
pub(crate) const CANCEL: &str = "Cancel";
pub(crate) const YES: &str = "Yes";
@@ -369,6 +378,7 @@ pub struct FileDialogBuilder<R: Runtime> {
pub(crate) file_name: Option<String>,
pub(crate) title: Option<String>,
pub(crate) can_create_directories: Option<bool>,
pub(crate) picker_mode: Option<PickerMode>,
#[cfg(desktop)]
pub(crate) parent: Option<crate::desktop::WindowHandle>,
}
@@ -380,6 +390,7 @@ pub(crate) struct FileDialogPayload<'a> {
file_name: &'a Option<String>,
filters: &'a Vec<Filter>,
multiple: bool,
picker_mode: &'a Option<PickerMode>,
}
// raw window handle :(
@@ -395,6 +406,7 @@ impl<R: Runtime> FileDialogBuilder<R> {
file_name: None,
title: None,
can_create_directories: None,
picker_mode: None,
#[cfg(desktop)]
parent: None,
}
@@ -406,6 +418,7 @@ impl<R: Runtime> FileDialogBuilder<R> {
file_name: &self.file_name,
filters: &self.filters,
multiple,
picker_mode: &self.picker_mode,
}
}
@@ -466,11 +479,21 @@ impl<R: Runtime> FileDialogBuilder<R> {
self
}
/// Set the picker mode of the dialog.
/// This is meant for mobile platforms (iOS and Android) which have distinct file and media pickers.
/// On desktop, this option is ignored.
/// If not provided, the dialog will automatically choose the best mode based on the MIME types of the filters.
pub fn set_picker_mode(mut self, mode: PickerMode) -> Self {
self.picker_mode.replace(mode);
self
}
/// Shows the dialog to select a single file.
///
/// This is not a blocking operation,
/// and should be used when running on the main thread to avoid deadlocks with the event loop.
///
/// For usage in other contexts such as commands, prefer [`Self::pick_file`].
/// See [`Self::blocking_pick_file`] for a blocking version for use in other contexts.
///
/// # Examples
///
@@ -490,9 +513,12 @@ impl<R: Runtime> FileDialogBuilder<R> {
}
/// Shows the dialog to select multiple files.
///
/// This is not a blocking operation,
/// and should be used when running on the main thread to avoid deadlocks with the event loop.
///
/// See [`Self::blocking_pick_files`] for a blocking version for use in other contexts.
///
/// # Reading the files
///
/// The file paths cannot be read directly on Android as they are behind a content URI.
@@ -535,9 +561,12 @@ impl<R: Runtime> FileDialogBuilder<R> {
}
/// Shows the dialog to select a single folder.
///
/// This is not a blocking operation,
/// and should be used when running on the main thread to avoid deadlocks with the event loop.
///
/// See [`Self::blocking_pick_folder`] for a blocking version for use in other contexts.
///
/// # Examples
///
/// ```
@@ -557,9 +586,12 @@ impl<R: Runtime> FileDialogBuilder<R> {
}
/// Shows the dialog to select multiple folders.
///
/// This is not a blocking operation,
/// and should be used when running on the main thread to avoid deadlocks with the event loop.
///
/// See [`Self::blocking_pick_folders`] for a blocking version for use in other contexts.
///
/// # Examples
///
/// ```
@@ -583,6 +615,8 @@ impl<R: Runtime> FileDialogBuilder<R> {
/// This is not a blocking operation,
/// and should be used when running on the main thread to avoid deadlocks with the event loop.
///
/// See [`Self::blocking_save_file`] for a blocking version for use in other contexts.
///
/// # Examples
///
/// ```
@@ -604,8 +638,11 @@ impl<R: Runtime> FileDialogBuilder<R> {
/// Blocking APIs.
impl<R: Runtime> FileDialogBuilder<R> {
/// Shows the dialog to select a single file.
///
/// This is a blocking operation,
/// and should *NOT* be used when running on the main thread context.
/// and should *NOT* be used when running on the main thread.
///
/// See [`Self::pick_file`] for a non-blocking version for use in main-thread contexts.
///
/// # Examples
///
@@ -623,8 +660,11 @@ impl<R: Runtime> FileDialogBuilder<R> {
}
/// Shows the dialog to select multiple files.
///
/// This is a blocking operation,
/// and should *NOT* be used when running on the main thread context.
/// and should *NOT* be used when running on the main thread.
///
/// See [`Self::pick_files`] for a non-blocking version for use in main-thread contexts.
///
/// # Examples
///
@@ -642,8 +682,11 @@ impl<R: Runtime> FileDialogBuilder<R> {
}
/// Shows the dialog to select a single folder.
///
/// This is a blocking operation,
/// and should *NOT* be used when running on the main thread context.
/// and should *NOT* be used when running on the main thread.
///
/// See [`Self::pick_folder`] for a non-blocking version for use in main-thread contexts.
///
/// # Examples
///
@@ -662,8 +705,11 @@ impl<R: Runtime> FileDialogBuilder<R> {
}
/// Shows the dialog to select multiple folders.
///
/// This is a blocking operation,
/// and should *NOT* be used when running on the main thread context.
/// and should *NOT* be used when running on the main thread.
///
/// See [`Self::pick_folders`] for a non-blocking version for use in main-thread contexts.
///
/// # Examples
///
@@ -682,8 +728,11 @@ impl<R: Runtime> FileDialogBuilder<R> {
}
/// Shows the dialog to save a file.
///
/// This is a blocking operation,
/// and should *NOT* be used when running on the main thread context.
/// and should *NOT* be used when running on the main thread.
///
/// See [`Self::save_file`] for a non-blocking version for use in main-thread contexts.
///
/// # Examples
///
+2 -7
View File
@@ -6,9 +6,10 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
/// Types of message, ask and confirm dialogs.
#[non_exhaustive]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
pub enum MessageDialogKind {
/// Information dialog.
#[default]
Info,
/// Warning dialog.
Warning,
@@ -16,12 +17,6 @@ pub enum MessageDialogKind {
Error,
}
impl Default for MessageDialogKind {
fn default() -> Self {
Self::Info
}
}
impl<'de> Deserialize<'de> for MessageDialogKind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
+9
View File
@@ -1,5 +1,14 @@
# Changelog
## \[2.4.4]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.4.3]
- [`6c9b61fb`](https://github.com/tauri-apps/plugins-workspace/commit/6c9b61fb658145d13893626112fc489f7458aa17) ([#3039](https://github.com/tauri-apps/plugins-workspace/pull/3039) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) On Android, updated compileSdk to 36.
- [`6b5b1053`](https://github.com/tauri-apps/plugins-workspace/commit/6b5b1053ba8aeb789dd5cb5fb05b7e98f3b8de0b) ([#1939](https://github.com/tauri-apps/plugins-workspace/pull/1939) by [@amrbashir](https://github.com/tauri-apps/plugins-workspace/../../amrbashir)) Enhance error messages.
## \[2.4.2]
- [`4eb36b0f`](https://github.com/tauri-apps/plugins-workspace/commit/4eb36b0ff57acb0bb1b911c583efa3bf2f56aa32) ([#2907](https://github.com/tauri-apps/plugins-workspace/pull/2907) by [@Legend-Master](https://github.com/tauri-apps/plugins-workspace/../../Legend-Master)) Fixed calling `writeFile` with `data: ReadableStream` throws `Invalid argument`
+1 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-fs"
version = "2.4.2"
version = "2.4.4"
description = "Access the file system."
authors = { workspace = true }
license = { workspace = true }
@@ -9,10 +9,6 @@ rust-version = { workspace = true }
repository = { workspace = true }
links = "tauri-plugin-fs"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.platforms.support]
windows = { level = "full", notes = "Apps installed via MSI or NSIS in `perMachine` and `both` mode require admin permissions for write access in `$RESOURCES` folder" }
linux = { level = "full", notes = "No write access to `$RESOURCES` folder" }
+1 -2
View File
@@ -5,11 +5,10 @@ plugins {
android {
namespace = "com.plugin.fs"
compileSdk = 34
compileSdk = 36
defaultConfig {
minSdk = 21
targetSdk = 34
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-fs",
"version": "2.4.2",
"version": "2.4.4",
"description": "Access the file system.",
"license": "MIT OR Apache-2.0",
"authors": [
+9
View File
@@ -1,5 +1,14 @@
# Changelog
## \[2.3.2]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.3.1]
- [`6c9b61fb`](https://github.com/tauri-apps/plugins-workspace/commit/6c9b61fb658145d13893626112fc489f7458aa17) ([#3039](https://github.com/tauri-apps/plugins-workspace/pull/3039) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) On Android, updated compileSdk to 36.
- [`e933acb0`](https://github.com/tauri-apps/plugins-workspace/commit/e933acb0044b4d49053eae6492b542351160e66a) ([#3010](https://github.com/tauri-apps/plugins-workspace/pull/3010) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) On Android, use the `timeout` value for `setMinUpdateIntervalMillis`, `setMaxUpdateDelayMillis` and `setIntervalMillis` instead of just `minUpdateInterval`.
## \[2.3.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
+1 -3
View File
@@ -1,7 +1,7 @@
[package]
name = "tauri-plugin-geolocation"
description = "Get and track the device's current position"
version = "2.3.0"
version = "2.3.2"
edition = { workspace = true }
authors = { workspace = true }
license = { workspace = true }
@@ -9,8 +9,6 @@ repository = { workspace = true }
links = "tauri-plugin-geolocation"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
targets = ["x86_64-linux-android"]
[package.metadata.platforms.support]
+2 -2
View File
@@ -5,10 +5,10 @@ plugins {
android {
namespace = "app.tauri.geolocation"
compileSdk = 34
compileSdk = 36
defaultConfig {
minSdk = 24
minSdk = 24
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
@@ -49,8 +49,6 @@ public class Geolocation(private val context: Context) {
val lowPrio = if (networkEnabled) Priority.PRIORITY_BALANCED_POWER_ACCURACY else Priority.PRIORITY_LOW_POWER
val prio = if (enableHighAccuracy) Priority.PRIORITY_HIGH_ACCURACY else lowPrio
Logger.error(prio.toString())
LocationServices
.getFusedLocationProviderClient(context)
.getCurrentLocation(prio, null)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-geolocation",
"version": "2.3.0",
"version": "2.3.2",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.3.1]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.3.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
+1 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-global-shortcut"
version = "2.3.0"
version = "2.3.1"
description = "Register global hotkeys listeners on your Tauri application."
edition = { workspace = true }
authors = { workspace = true }
@@ -9,10 +9,6 @@ rust-version = { workspace = true }
repository = { workspace = true }
links = "tauri-plugin-global-shortcut"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.platforms.support]
windows = { level = "full", notes = "" }
linux = { level = "full", notes = "" }
+1 -1
View File
@@ -54,7 +54,7 @@ fn main() {
.setup(|app| {
#[cfg(desktop)]
{
use tauri::Manager;
use tauri::Emitter;
use tauri_plugin_global_shortcut::{Code, Modifiers, ShortcutState};
app.handle().plugin(
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-global-shortcut",
"version": "2.3.0",
"version": "2.3.1",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
+8
View File
@@ -1,5 +1,13 @@
# Changelog
## \[2.3.2]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.3.1]
- [`6c9b61fb`](https://github.com/tauri-apps/plugins-workspace/commit/6c9b61fb658145d13893626112fc489f7458aa17) ([#3039](https://github.com/tauri-apps/plugins-workspace/pull/3039) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) On Android, updated compileSdk to 36.
## \[2.3.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
+1 -3
View File
@@ -1,7 +1,7 @@
[package]
name = "tauri-plugin-haptics"
description = "Haptic feedback and vibrations on Android and iOS"
version = "2.3.0"
version = "2.3.2"
edition = { workspace = true }
authors = { workspace = true }
license = { workspace = true }
@@ -9,8 +9,6 @@ repository = { workspace = true }
links = "tauri-plugin-haptics"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
targets = ["x86_64-linux-android"]
[package.metadata.platforms.support]
+2 -2
View File
@@ -5,10 +5,10 @@ plugins {
android {
namespace = "app.tauri.haptics"
compileSdk = 34
compileSdk = 36
defaultConfig {
minSdk = 24
minSdk = 24
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
@@ -2,12 +2,12 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
import AudioToolbox
import CoreHaptics
import SwiftRs
import Tauri
import UIKit
import WebKit
import CoreHaptics
import AudioToolbox
class ImpactFeedbackOptions: Decodable {
let style: ImpactFeedbackStyle
@@ -69,19 +69,21 @@ class HapticsPlugin: Plugin {
try engine.start()
engine.resetHandler = { [] in
do {
try engine.start()
try engine.start()
} catch {
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
}
}
// TODO: Make some of this (or all) configurable?
let intensity: CHHapticEventParameter = CHHapticEventParameter(parameterID: .hapticIntensity, value: 1.0)
let sharpness: CHHapticEventParameter = CHHapticEventParameter(parameterID: .hapticSharpness, value: 1.0)
let intensity: CHHapticEventParameter = CHHapticEventParameter(
parameterID: .hapticIntensity, value: 1.0)
let sharpness: CHHapticEventParameter = CHHapticEventParameter(
parameterID: .hapticSharpness, value: 1.0)
let continuousEvent = CHHapticEvent(
eventType: .hapticContinuous,
parameters: [intensity, sharpness],
relativeTime: 0.0,
duration: args.duration/1000
duration: args.duration / 1000
)
let pattern = try CHHapticPattern(events: [continuousEvent], parameters: [])
let player = try engine.makePlayer(with: pattern)
@@ -94,8 +96,6 @@ class HapticsPlugin: Plugin {
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
}
Logger.error("VIBRATE END")
invoke.resolve()
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-haptics",
"version": "2.3.0",
"version": "2.3.2",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
+14
View File
@@ -1,5 +1,19 @@
# Changelog
## \[2.5.4]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
### Dependencies
- Upgraded to `fs-js@2.4.4`
## \[2.5.3]
### Dependencies
- Upgraded to `fs-js@2.4.3`
## \[2.5.2]
### Dependencies
+2 -6
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-http"
version = "2.5.2"
version = "2.5.4"
description = "Access an HTTP client written in Rust."
edition = { workspace = true }
authors = { workspace = true }
@@ -9,10 +9,6 @@ rust-version = { workspace = true }
repository = { workspace = true }
links = "tauri-plugin-http"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.platforms.support]
windows = { level = "full", notes = "" }
linux = { level = "full", notes = "" }
@@ -34,7 +30,7 @@ serde_json = { workspace = true }
tauri = { workspace = true }
thiserror = { workspace = true }
tokio = { version = "1", features = ["sync", "macros"] }
tauri-plugin-fs = { path = "../fs", version = "2.4.2" }
tauri-plugin-fs = { path = "../fs", version = "2.4.4" }
urlpattern = "0.3"
regex = "1"
http = "1"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-http",
"version": "2.5.2",
"version": "2.5.4",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.3.1]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.3.0]
- [`f209b2f2`](https://github.com/tauri-apps/plugins-workspace/commit/f209b2f23cb29133c97ad5961fb46ef794dbe063) ([#2804](https://github.com/tauri-apps/plugins-workspace/pull/2804) by [@renovate](https://github.com/tauri-apps/plugins-workspace/../../renovate)) Updated tauri to 2.6
+1 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-localhost"
version = "2.3.0"
version = "2.3.1"
description = "Expose your apps assets through a localhost server instead of the default custom protocol."
authors = { workspace = true }
license = { workspace = true }
@@ -8,10 +8,6 @@ edition = { workspace = true }
rust-version = { workspace = true }
repository = { workspace = true }
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.platforms.support]
windows = { level = "full", notes = "" }
linux = { level = "full", notes = "" }
+34 -18
View File
@@ -41,27 +41,43 @@ First you need to register the core plugin with Tauri:
`src-tauri/src/lib.rs`
```rust
use tauri::{Manager, window::WindowBuilder, WindowUrl};
#[cfg(not(dev))]
use tauri::{ipc::CapabilityBuilder, Manager, Url};
use tauri::{WebviewUrl, WebviewWindowBuilder};
fn main() {
let port = portpicker::pick_unused_port().expect("failed to find unused port");
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
let port = portpicker::pick_unused_port().expect("failed to find unused port");
tauri::Builder::default()
.plugin(tauri_plugin_localhost::Builder::new(port).build())
.setup(move |app| {
app.ipc_scope().configure_remote_access(
RemoteDomainAccessScope::new("localhost")
.add_window("main")
);
tauri::Builder::default()
.plugin(tauri_plugin_localhost::Builder::new(port).build())
.setup(move |app| {
// In `tauri dev` mode you usually use your dev server.
#[cfg(dev)]
let url = WebviewUrl::App(std::path::PathBuf::from("/"));
let url = format!("http://localhost:{}", port).parse().unwrap();
WindowBuilder::new(app, "main".to_string(), WindowUrl::External(url))
.title("Localhost Example")
.build()?;
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
#[cfg(not(dev))]
let url = {
let url: Url = format!("http://localhost:{}", port).parse().unwrap();
app.add_capability(
CapabilityBuilder::new("localhost")
.remote(url.to_string())
.window("main"),
)?;
WebviewUrl::External(url)
};
// This requires you to remove the window from tauri.conf.json
WebviewWindowBuilder::new(app, "main".to_string(), url)
.title("Localhost Example")
.build()?;
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
```
+4
View File
@@ -105,6 +105,10 @@ impl Builder {
.insert("Content-Security-Policy".into(), csp);
}
response
.headers
.insert("Cache-Control".into(), "no-cache".into());
if let Some(on_request) = &on_request {
on_request(&request, &mut response);
}
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.7.1]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.7.0]
- [`625bb1c0`](https://github.com/tauri-apps/plugins-workspace/commit/625bb1c0965394b88522643731f78ccbcca84add) ([#2965](https://github.com/tauri-apps/plugins-workspace/pull/2965) by [@lucasfernog](https://github.com/tauri-apps/plugins-workspace/../../lucasfernog)) Re-export the log crate.
+1 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-log"
version = "2.7.0"
version = "2.7.1"
description = "Configurable logging for your Tauri app."
authors = { workspace = true }
license = { workspace = true }
@@ -9,10 +9,6 @@ rust-version = { workspace = true }
repository = { workspace = true }
links = "tauri-plugin-log"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.platforms.support]
windows = { level = "full", notes = "" }
linux = { level = "full", notes = "" }
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-log",
"version": "2.7.0",
"version": "2.7.1",
"description": "Configurable logging for your Tauri app.",
"license": "MIT OR Apache-2.0",
"authors": [
+218 -102
View File
@@ -14,6 +14,8 @@ use log::{LevelFilter, Record};
use serde::Serialize;
use serde_repr::{Deserialize_repr, Serialize_repr};
use std::borrow::Cow;
use std::fs::OpenOptions;
use std::io::Write;
use std::{
fmt::Arguments,
fs::{self, File},
@@ -41,14 +43,15 @@ mod ios {
));
}
const DEFAULT_MAX_FILE_SIZE: u128 = 40000;
const DEFAULT_MAX_FILE_SIZE: u64 = 40000;
const DEFAULT_ROTATION_STRATEGY: RotationStrategy = RotationStrategy::KeepOne;
const DEFAULT_TIMEZONE_STRATEGY: TimezoneStrategy = TimezoneStrategy::UseUtc;
const DEFAULT_LOG_TARGETS: [Target; 2] = [
Target::new(TargetKind::Stdout),
Target::new(TargetKind::LogDir { file_name: None }),
];
const LOG_DATE_FORMAT: &str = "[year]-[month]-[day]_[hour]-[minute]-[second]";
const LOG_DATE_FORMAT: &[time::format_description::FormatItem<'_>] =
format_description!("[year]-[month]-[day]_[hour]-[minute]-[second]");
#[derive(Debug, thiserror::Error)]
pub enum Error {
@@ -116,6 +119,7 @@ impl From<log::Level> for LogLevel {
}
}
#[derive(Debug, Clone)]
pub enum RotationStrategy {
/// Will keep all the logs, renaming them to include the date.
KeepAll,
@@ -142,6 +146,174 @@ impl TimezoneStrategy {
}
}
/// A custom log writer that rotates the log file when it exceeds specified size.
struct RotatingFile {
dir: PathBuf,
file_name: String,
path: PathBuf,
max_size: u64,
current_size: u64,
rotation_strategy: RotationStrategy,
timezone_strategy: TimezoneStrategy,
inner: Option<File>,
buffer: Vec<u8>,
}
impl RotatingFile {
pub fn new(
dir: impl AsRef<Path>,
file_name: String,
max_size: u64,
rotation_strategy: RotationStrategy,
timezone_strategy: TimezoneStrategy,
) -> Result<Self, Error> {
let dir = dir.as_ref().to_path_buf();
let path = dir.join(&file_name).with_extension("log");
let mut rotator = Self {
dir,
file_name,
path,
max_size,
current_size: 0,
rotation_strategy,
timezone_strategy,
inner: None,
buffer: Vec::new(),
};
rotator.open_file()?;
if rotator.current_size >= rotator.max_size {
rotator.rotate()?;
}
if let RotationStrategy::KeepSome(keep_count) = rotator.rotation_strategy {
rotator.remove_old_files(keep_count)?;
}
Ok(rotator)
}
fn open_file(&mut self) -> Result<(), Error> {
let file = OpenOptions::new()
.create(true)
.append(true)
.open(&self.path)?;
self.current_size = file.metadata()?.len();
self.inner = Some(file);
Ok(())
}
fn rotate(&mut self) -> Result<(), Error> {
if let Some(mut file) = self.inner.take() {
let _ = file.flush();
}
if self.path.exists() {
match self.rotation_strategy {
RotationStrategy::KeepAll => {
self.rename_file_to_dated()?;
}
RotationStrategy::KeepSome(keep_count) => {
// remove_old_files excludes the active file.
// So we need to keep (keep_count - 1) archived files to make room for the one we are about to archive.
self.remove_old_files(keep_count - 1)?;
self.rename_file_to_dated()?;
}
RotationStrategy::KeepOne => {
fs::remove_file(&self.path)?;
}
}
}
self.open_file()?;
Ok(())
}
/// Remove old log files until the number of old log files is equal to the keep_count,
/// the current active log file is not included in the keep_count.
fn remove_old_files(&self, keep_count: usize) -> Result<(), Error> {
let mut files = fs::read_dir(&self.dir)?
.filter_map(|entry| {
let entry = entry.ok()?;
let path = entry.path();
let old_file_name = path.file_name()?.to_string_lossy().into_owned();
if old_file_name.starts_with(&self.file_name)
// exclude the current active file
&& old_file_name != format!("{}.log", self.file_name)
{
let date = old_file_name
.strip_prefix(&self.file_name)?
.strip_prefix("_")?
.strip_suffix(".log")?;
Some((path, date.to_string()))
} else {
None
}
})
.collect::<Vec<_>>();
files.sort_by(|a, b| a.1.cmp(&b.1));
if files.len() > keep_count {
let files_to_remove = files.len() - keep_count;
for (old_log_path, _) in files.iter().take(files_to_remove) {
fs::remove_file(old_log_path)?;
}
}
Ok(())
}
fn rename_file_to_dated(&self) -> Result<(), Error> {
let to = self.dir.join(format!(
"{}_{}.log",
self.file_name,
self.timezone_strategy
.get_now()
.format(LOG_DATE_FORMAT)
.unwrap(),
));
if to.is_file() {
// designated rotated log file name already exists
// highly unlikely but defensively handle anyway by adding .bak to filename
let mut to_bak = to.clone();
to_bak.set_file_name(format!(
"{}.bak",
to_bak.file_name().unwrap().to_string_lossy()
));
fs::rename(&to, to_bak)?;
}
fs::rename(&self.path, &to)?;
Ok(())
}
}
impl Write for RotatingFile {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.buffer.extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
if self.buffer.is_empty() {
return Ok(());
}
if self.inner.is_none() {
self.open_file().map_err(std::io::Error::other)?;
}
if self.current_size != 0 && self.current_size + (self.buffer.len() as u64) > self.max_size
{
self.rotate().map_err(std::io::Error::other)?;
}
if let Some(file) = self.inner.as_mut() {
file.write_all(&self.buffer)?;
self.current_size += self.buffer.len() as u64;
file.flush()?;
}
self.buffer.clear();
Ok(())
}
}
#[derive(Debug, Serialize, Clone)]
struct RecordPayload {
message: String,
@@ -182,10 +354,13 @@ pub enum TargetKind {
Dispatch(fern::Dispatch),
}
type Formatter = dyn Fn(FormatCallback, &Arguments, &Record) + Send + Sync + 'static;
/// A log target.
pub struct Target {
kind: TargetKind,
filters: Vec<Box<Filter>>,
formatter: Option<Box<Formatter>>,
}
impl Target {
@@ -194,6 +369,7 @@ impl Target {
Self {
kind,
filters: Vec::new(),
formatter: None,
}
}
@@ -205,6 +381,15 @@ impl Target {
self.filters.push(Box::new(filter));
self
}
#[inline]
pub fn format<F>(mut self, formatter: F) -> Self
where
F: Fn(FormatCallback, &Arguments, &Record) + Send + Sync + 'static,
{
self.formatter.replace(Box::new(formatter));
self
}
}
pub struct Builder {
@@ -238,7 +423,7 @@ impl Default for Builder {
dispatch,
rotation_strategy: DEFAULT_ROTATION_STRATEGY,
timezone_strategy: DEFAULT_TIMEZONE_STRATEGY,
max_file_size: DEFAULT_MAX_FILE_SIZE,
max_file_size: DEFAULT_MAX_FILE_SIZE as u128,
targets: DEFAULT_LOG_TARGETS.into(),
is_skip_logger: false,
}
@@ -271,8 +456,19 @@ impl Builder {
self
}
/// Sets the maximum file size for log rotation.
///
/// Values larger than `u64::MAX` will be clamped to `u64::MAX`.
/// In v3, this parameter will be changed to `u64`.
pub fn max_file_size(mut self, max_file_size: u128) -> Self {
self.max_file_size = max_file_size;
self.max_file_size = max_file_size.min(u64::MAX as u128);
self
}
pub fn clear_format(mut self) -> Self {
self.dispatch = self.dispatch.format(|out, message, _record| {
out.finish(format_args!("{message}"));
});
self
}
@@ -373,7 +569,7 @@ impl Builder {
mut dispatch: fern::Dispatch,
rotation_strategy: RotationStrategy,
timezone_strategy: TimezoneStrategy,
max_file_size: u128,
max_file_size: u64,
targets: Vec<Target>,
) -> Result<(log::LevelFilter, Box<dyn log::Log>), Error> {
let app_name = &app_handle.package_info().name;
@@ -384,6 +580,9 @@ impl Builder {
for filter in target.filters {
target_dispatch = target_dispatch.filter(filter);
}
if let Some(formatter) = target.formatter {
target_dispatch = target_dispatch.format(formatter);
}
let logger = match target.kind {
#[cfg(target_os = "android")]
@@ -416,14 +615,14 @@ impl Builder {
fs::create_dir_all(&path)?;
}
fern::log_file(get_log_file_path(
let rotator = RotatingFile::new(
&path,
file_name.as_deref().unwrap_or(app_name),
&rotation_strategy,
&timezone_strategy,
file_name.unwrap_or(app_name.clone()),
max_file_size,
)?)?
.into()
rotation_strategy.clone(),
timezone_strategy.clone(),
)?;
fern::Output::writer(Box::new(rotator), "\n")
}
TargetKind::LogDir { file_name } => {
let path = app_handle.path().app_log_dir()?;
@@ -431,14 +630,14 @@ impl Builder {
fs::create_dir_all(&path)?;
}
fern::log_file(get_log_file_path(
let rotator = RotatingFile::new(
&path,
file_name.as_deref().unwrap_or(app_name),
&rotation_strategy,
&timezone_strategy,
file_name.unwrap_or(app_name.clone()),
max_file_size,
)?)?
.into()
rotation_strategy.clone(),
timezone_strategy.clone(),
)?;
fern::Output::writer(Box::new(rotator), "\n")
}
TargetKind::Webview => {
let app_handle = app_handle.clone();
@@ -482,7 +681,7 @@ impl Builder {
self.dispatch,
self.rotation_strategy,
self.timezone_strategy,
self.max_file_size,
self.max_file_size as u64,
self.targets,
)?;
@@ -498,7 +697,7 @@ impl Builder {
self.dispatch,
self.rotation_strategy,
self.timezone_strategy,
self.max_file_size,
self.max_file_size as u64,
self.targets,
)?;
attach_logger(max_level, log)?;
@@ -518,86 +717,3 @@ pub fn attach_logger(
log::set_max_level(max_level);
Ok(())
}
fn rename_file_to_dated(
path: &impl AsRef<Path>,
dir: &impl AsRef<Path>,
file_name: &str,
timezone_strategy: &TimezoneStrategy,
) -> Result<(), Error> {
let to = dir.as_ref().join(format!(
"{}_{}.log",
file_name,
timezone_strategy
.get_now()
.format(&time::format_description::parse(LOG_DATE_FORMAT).unwrap())
.unwrap(),
));
if to.is_file() {
// designated rotated log file name already exists
// highly unlikely but defensively handle anyway by adding .bak to filename
let mut to_bak = to.clone();
to_bak.set_file_name(format!(
"{}.bak",
to_bak.file_name().unwrap().to_string_lossy()
));
fs::rename(&to, to_bak)?;
}
fs::rename(path, to)?;
Ok(())
}
fn get_log_file_path(
dir: &impl AsRef<Path>,
file_name: &str,
rotation_strategy: &RotationStrategy,
timezone_strategy: &TimezoneStrategy,
max_file_size: u128,
) -> Result<PathBuf, Error> {
let path = dir.as_ref().join(format!("{file_name}.log"));
if path.exists() {
let log_size = File::open(&path)?.metadata()?.len() as u128;
if log_size > max_file_size {
match rotation_strategy {
RotationStrategy::KeepAll => {
rename_file_to_dated(&path, dir, file_name, timezone_strategy)?;
}
RotationStrategy::KeepSome(how_many) => {
let mut files = fs::read_dir(dir)?
.filter_map(|entry| {
let entry = entry.ok()?;
let path = entry.path();
let old_file_name = path.file_name()?.to_string_lossy().into_owned();
if old_file_name.starts_with(file_name) {
let date = old_file_name
.strip_prefix(file_name)?
.strip_prefix("_")?
.strip_suffix(".log")?;
Some((path, date.to_string()))
} else {
None
}
})
.collect::<Vec<_>>();
// Regular sorting, so the oldest files are first. Lexicographical
// sorting is fine due to the date format.
files.sort_by(|a, b| a.1.cmp(&b.1));
// We want to make space for the file we will be soon renaming, AND
// the file we will be creating. Thus we need to keep how_many - 2 files.
if files.len() > (*how_many - 2) {
files.truncate(files.len() + 2 - *how_many);
for (old_log_path, _) in files {
fs::remove_file(old_log_path)?;
}
}
rename_file_to_dated(&path, dir, file_name, timezone_strategy)?;
}
RotationStrategy::KeepOne => {
fs::remove_file(&path)?;
}
}
}
}
Ok(path)
}
+8
View File
@@ -1,5 +1,13 @@
# Changelog
## \[2.3.3]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.3.2]
- [`6c9b61fb`](https://github.com/tauri-apps/plugins-workspace/commit/6c9b61fb658145d13893626112fc489f7458aa17) ([#3039](https://github.com/tauri-apps/plugins-workspace/pull/3039) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) On Android, updated compileSdk to 36.
## \[2.3.1]
- [`fe23a5e0`](https://github.com/tauri-apps/plugins-workspace/commit/fe23a5e01399a6ad61426bf8a94a6bb97227cf88) ([#2885](https://github.com/tauri-apps/plugins-workspace/pull/2885) by [@zaphim12](https://github.com/tauri-apps/plugins-workspace/../../zaphim12)) On iOS, the reader session will now get closed properly on errors, preventing dangling invalid sessions that could prevent subsequent write attempts.
+1 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-nfc"
version = "2.3.1"
version = "2.3.3"
description = "Read and write NFC tags on Android and iOS."
edition = { workspace = true }
authors = { workspace = true }
@@ -9,8 +9,6 @@ repository = { workspace = true }
links = "tauri-plugin-nfc"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
targets = ["x86_64-linux-android"]
[package.metadata.platforms.support]
+2 -2
View File
@@ -5,10 +5,10 @@ plugins {
android {
namespace = "app.tauri.nfc"
compileSdk = 34
compileSdk = 36
defaultConfig {
minSdk = 24
minSdk = 24
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
+4 -1
View File
@@ -269,5 +269,8 @@ export async function write(
}
export async function isAvailable(): Promise<boolean> {
return await invoke('plugin:nfc|is_available')
const { available }: { available: boolean } = await invoke(
'plugin:nfc|is_available'
)
return available
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-nfc",
"version": "2.3.1",
"version": "2.3.3",
"license": "MIT OR Apache-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
+8
View File
@@ -1,5 +1,13 @@
# Changelog
## \[2.3.3]
- [`93426f85`](https://github.com/tauri-apps/plugins-workspace/commit/93426f85120f49beb9f40222bff45185a32d54a9) Fixed an issue that caused docs.rs builds to fail. No user facing changes.
## \[2.3.2]
- [`6c9b61fb`](https://github.com/tauri-apps/plugins-workspace/commit/6c9b61fb658145d13893626112fc489f7458aa17) ([#3039](https://github.com/tauri-apps/plugins-workspace/pull/3039) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) On Android, updated compileSdk to 36.
## \[2.3.1]
- [`8abb31ee`](https://github.com/tauri-apps/plugins-workspace/commit/8abb31ee59c68197102c0aa699d690b34646ec3c) ([#2905](https://github.com/tauri-apps/plugins-workspace/pull/2905) by [@ChristianPavilonis](https://github.com/tauri-apps/plugins-workspace/../../ChristianPavilonis)) Fix notification scheduling on iOS.
+1 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-notification"
version = "2.3.1"
version = "2.3.3"
description = "Send desktop and mobile notifications on your Tauri application."
edition = { workspace = true }
authors = { workspace = true }
@@ -10,8 +10,6 @@ repository = { workspace = true }
links = "tauri-plugin-notification"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
targets = ["x86_64-unknown-linux-gnu", "x86_64-linux-android"]
[package.metadata.platforms.support]
@@ -5,10 +5,10 @@ plugins {
android {
namespace = "app.tauri.notification"
compileSdk = 34
compileSdk = 36
defaultConfig {
minSdk = 24
minSdk = 24
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")

Some files were not shown because too many files have changed in this diff Show More