mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-05-03 12:15:11 +02:00
Compare commits
116 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a61c7591bd | |||
| f85c405b3a | |||
| ad3212a159 | |||
| d3e07db4ad | |||
| 1db4b0719d | |||
| dff6fa986a | |||
| a4aa53ab90 | |||
| ae278ddf60 | |||
| e644f38673 | |||
| 8bfa445023 | |||
| 14fb36e347 | |||
| 5767b848fa | |||
| 277a45f56c | |||
| 8dbe7e3233 | |||
| c23fa03f07 | |||
| 631d0e256a | |||
| b4348cee92 | |||
| 3019063ae1 | |||
| 944614f46a | |||
| a368cef912 | |||
| 27790aa67c | |||
| ad910b1135 | |||
| 6b854421a1 | |||
| 5438a5cd22 | |||
| 5cd7778723 | |||
| 1a03e9761f | |||
| 1d4bffadda | |||
| b8794272ae | |||
| 2a625adff3 | |||
| 371cd8227c | |||
| 70ef6f8d3e | |||
| 5f0ac1436f | |||
| ea172bfa3c | |||
| 6aead24047 | |||
| e7a68fa637 | |||
| b5550a3b0d | |||
| 93426f8512 | |||
| 4ee61e055e | |||
| 06124af8d6 | |||
| 060219e597 | |||
| c7e9766ff5 | |||
| d4a8ce962b | |||
| cdc7eec415 | |||
| 6314b004ab | |||
| fb4c8ae54c | |||
| fccc1cfb7e | |||
| 3702308e6f | |||
| c9c8b39b56 | |||
| 3c396feedf | |||
| b514d482fa | |||
| 60e5714ceb | |||
| 654bf4891a | |||
| 6c9b61fb65 | |||
| 403f54b78c | |||
| 28ea4dbadc | |||
| 1771c6ed36 | |||
| f831b003c2 | |||
| 6b5b1053ba | |||
| 67a7bf80f8 | |||
| e25a9339f4 | |||
| 92f98a93b4 | |||
| c0f82e5a5e | |||
| 5204145c6a | |||
| b4ee33dd01 | |||
| e933acb004 | |||
| e4a9154f4a | |||
| d44ac9afed | |||
| 1b197c2d4d | |||
| 650ff5ff23 | |||
| 2930aa39a4 | |||
| 3e92ce260b | |||
| 12da195fce | |||
| 30dd109d9f | |||
| 5e5bc30ad0 | |||
| f6dca71343 | |||
| 021e573248 | |||
| 51b430be98 | |||
| fd439b143e | |||
| 2522b71f6b | |||
| 9021a73247 | |||
| 625bb1c096 | |||
| 6215afe023 | |||
| 8cf8eeab02 | |||
| 509eba8d44 | |||
| 9ac5fe84e7 | |||
| c247410319 | |||
| de45034082 | |||
| 50c6b7c644 | |||
| b79d02d896 | |||
| b75f9f5cd3 | |||
| d865ed4768 | |||
| 1107c46425 | |||
| 23a3705857 | |||
| 6f65e68340 | |||
| d1edf783e1 | |||
| 9804eeef03 | |||
| 829fd23b8e | |||
| 13bbb9cd3d | |||
| 9b162b51a6 | |||
| 57f0422ae9 | |||
| 581523244f | |||
| f924ef16e4 | |||
| c9babc028a | |||
| fdcc15a5fe | |||
| 53bf0af9dd | |||
| c4665050bb | |||
| 6f65edfd72 | |||
| 63f660996f | |||
| 8cb053f47c | |||
| cac333b076 | |||
| 5ce3e45768 | |||
| 88da3d26ad | |||
| af5500caed | |||
| dc55eb51ed | |||
| a132d8f3d5 | |||
| a7af1a81b7 |
@@ -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`.
|
||||
@@ -78,6 +78,7 @@
|
||||
"notification",
|
||||
"os",
|
||||
"process",
|
||||
"secure-storage",
|
||||
"shell",
|
||||
"store",
|
||||
"updater",
|
||||
@@ -104,6 +105,7 @@
|
||||
"notification-js",
|
||||
"os-js",
|
||||
"process-js",
|
||||
"secure-storage-js",
|
||||
"shell-js",
|
||||
"store-js",
|
||||
"updater-js"
|
||||
@@ -282,6 +284,14 @@
|
||||
"path": "./plugins/process",
|
||||
"manager": "javascript"
|
||||
},
|
||||
"secure-storage": {
|
||||
"path": "./plugins/secure-storage",
|
||||
"manager": "rust"
|
||||
},
|
||||
"secure-storage-js": {
|
||||
"path": "./plugins/secure-storage",
|
||||
"manager": "javascript"
|
||||
},
|
||||
"shell": {
|
||||
"path": "./plugins/shell",
|
||||
"manager": "rust"
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
stronghold: patch
|
||||
stronghold-js: patch
|
||||
---
|
||||
|
||||
The `stronghold` plugin is now deprecated and will be removed in v3. The `secure-storage` plugin should be a replacement for most use-cases.
|
||||
@@ -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.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"barcode-scanner": patch
|
||||
"barcode-scanner-js": patch
|
||||
---
|
||||
|
||||
Fix the `cameraView` is not removed after scanning in iOS.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"log": patch
|
||||
"log-js": patch
|
||||
---
|
||||
|
||||
Fix log file rotation when exceeding `max_file_size`.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"nfc": "patch"
|
||||
"nfc-js": "patch"
|
||||
---
|
||||
|
||||
Update return value of `isAvailable` to match TypeScript function signature
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"updater": minor
|
||||
"updater-js": minor
|
||||
---
|
||||
|
||||
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
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"upload": minor
|
||||
"upload-js": minor
|
||||
---
|
||||
|
||||
Upload plugin now supports specifying an HTTP method i.e. POST, PUT etc.
|
||||
@@ -101,6 +101,11 @@ jobs:
|
||||
- pnpm-lock.yaml
|
||||
- plugins/process/guest-js/**
|
||||
- plugins/process/src/api-iife.js
|
||||
secure-storage:
|
||||
- .github/workflows/check-generated-files.yml
|
||||
- pnpm-lock.yaml
|
||||
- plugins/secure-storage/guest-js/**
|
||||
- plugins/secure-storage/src/api-iife.js
|
||||
shell:
|
||||
- .github/workflows/check-generated-files.yml
|
||||
- pnpm-lock.yaml
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -98,6 +98,9 @@ jobs:
|
||||
tauri-plugin-process:
|
||||
- .github/workflows/lint-rust.yml
|
||||
- plugins/process/**
|
||||
tauri-plugin-secure-storage:
|
||||
- .github/workflows/lint-rust.yml
|
||||
- plugins/secure-storage/**
|
||||
tauri-plugin-shell:
|
||||
- .github/workflows/lint-rust.yml
|
||||
- plugins/shell/**
|
||||
@@ -154,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
|
||||
|
||||
@@ -137,6 +137,11 @@ jobs:
|
||||
- Cargo.toml
|
||||
- Cargo.lock
|
||||
- plugins/process/**
|
||||
tauri-plugin-secure-storage:
|
||||
- .github/workflows/test-rust.yml
|
||||
- Cargo.toml
|
||||
- Cargo.lock
|
||||
- plugins/secure-storage/**
|
||||
tauri-plugin-shell:
|
||||
- .github/workflows/test-rust.yml
|
||||
- Cargo.toml
|
||||
@@ -219,7 +224,7 @@ jobs:
|
||||
target: aarch64-linux-android,
|
||||
os: ubuntu-latest,
|
||||
runner: 'cross',
|
||||
command: 'build'
|
||||
command: 'build --verbose'
|
||||
}
|
||||
|
||||
runs-on: ${{ matrix.platform.os }}
|
||||
@@ -233,7 +238,7 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev
|
||||
|
||||
- uses: dtolnay/rust-toolchain@1.77.2
|
||||
- uses: dtolnay/rust-toolchain@1.85
|
||||
with:
|
||||
targets: ${{ matrix.platform.target }}
|
||||
|
||||
@@ -246,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'
|
||||
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
|
||||
|
||||
+1
-1
@@ -58,4 +58,4 @@ pids
|
||||
.idea
|
||||
debug.log
|
||||
TODO.md
|
||||
.aider*
|
||||
.aider.*
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
plugins/*/permissions/autogenerated/
|
||||
plugins/*/android/.tauri/tauri-api/build/
|
||||
plugins/*/android/build/intermediates/
|
||||
|
||||
Generated
+237
-61
@@ -117,6 +117,19 @@ version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "android-native-keyring-store"
|
||||
version = "0.4.0"
|
||||
source = "git+https://github.com/FabianLars/android-native-keyring-store#6d59ad7d6a84b1496175754aa00c000a59356da0"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"jni",
|
||||
"keyring-core",
|
||||
"ndk-context",
|
||||
"thiserror 2.0.12",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
@@ -207,7 +220,7 @@ checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
||||
|
||||
[[package]]
|
||||
name = "api"
|
||||
version = "2.0.34"
|
||||
version = "2.0.38"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
@@ -230,6 +243,7 @@ dependencies = [
|
||||
"tauri-plugin-opener",
|
||||
"tauri-plugin-os",
|
||||
"tauri-plugin-process",
|
||||
"tauri-plugin-secure-storage",
|
||||
"tauri-plugin-shell",
|
||||
"tauri-plugin-store",
|
||||
"tauri-plugin-updater",
|
||||
@@ -275,6 +289,17 @@ dependencies = [
|
||||
"tauri-plugin-store",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "apple-native-keyring-store"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f9955235ce557bd0ea2c64d7ff09a887885f515e98572d2640a29520d9c98c"
|
||||
dependencies = [
|
||||
"keyring-core",
|
||||
"log",
|
||||
"security-framework 3.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "1.4.1"
|
||||
@@ -881,6 +906,15 @@ dependencies = [
|
||||
"toml 0.8.20",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cbc"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6"
|
||||
dependencies = [
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.19"
|
||||
@@ -965,7 +999,7 @@ dependencies = [
|
||||
"iana-time-zone",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"windows-link",
|
||||
"windows-link 0.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3241,6 +3275,15 @@ dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "keyring-core"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64ad182c4841eb5795af9d20e6e020b65a895517f6a41e6358ed8af74ba35d98"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue"
|
||||
version = "1.1.1"
|
||||
@@ -3772,6 +3815,30 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint-dig"
|
||||
version = "0.8.4"
|
||||
@@ -3789,6 +3856,15 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
@@ -3815,6 +3891,17 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
@@ -4565,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"
|
||||
@@ -5094,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",
|
||||
@@ -5290,7 +5385,7 @@ dependencies = [
|
||||
"openssl-probe",
|
||||
"rustls-pki-types",
|
||||
"schannel",
|
||||
"security-framework 3.2.0",
|
||||
"security-framework 3.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5437,6 +5532,25 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "secret-service"
|
||||
version = "5.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a62d7f86047af0077255a29494136b9aaaf697c76ff70b8e49cded4e2623c14"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"cbc",
|
||||
"futures-util",
|
||||
"generic-array",
|
||||
"getrandom 0.2.15",
|
||||
"hkdf",
|
||||
"num",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"sha2",
|
||||
"zbus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.11.1"
|
||||
@@ -5452,9 +5566,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "3.2.0"
|
||||
version = "3.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316"
|
||||
checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"core-foundation 0.10.0",
|
||||
@@ -5465,9 +5579,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.14.0"
|
||||
version = "2.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
|
||||
checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
@@ -6359,9 +6473,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
||||
|
||||
[[package]]
|
||||
name = "tauri"
|
||||
version = "2.8.2"
|
||||
version = "2.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a54629607ea3084a8b455c1ebe888cbdfc4de02fa5edb2e40db0dc97091007e3"
|
||||
checksum = "5d545ccf7b60dcd44e07c6fb5aeb09140966f0aabd5d2aa14a6821df7bc99348"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -6496,7 +6610,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-autostart"
|
||||
version = "2.5.0"
|
||||
version = "2.5.1"
|
||||
dependencies = [
|
||||
"auto-launch",
|
||||
"serde",
|
||||
@@ -6508,7 +6622,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-barcode-scanner"
|
||||
version = "2.4.0"
|
||||
version = "2.4.2"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
@@ -6520,7 +6634,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-biometric"
|
||||
version = "2.3.0"
|
||||
version = "2.3.2"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
@@ -6533,7 +6647,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-cli"
|
||||
version = "2.4.0"
|
||||
version = "2.4.1"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"log",
|
||||
@@ -6546,7 +6660,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-clipboard-manager"
|
||||
version = "2.3.0"
|
||||
version = "2.3.2"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"log",
|
||||
@@ -6559,7 +6673,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-deep-link"
|
||||
version = "2.4.2"
|
||||
version = "2.4.5"
|
||||
dependencies = [
|
||||
"dunce",
|
||||
"plist",
|
||||
@@ -6578,7 +6692,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-dialog"
|
||||
version = "2.3.3"
|
||||
version = "2.4.2"
|
||||
dependencies = [
|
||||
"log",
|
||||
"raw-window-handle",
|
||||
@@ -6594,7 +6708,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-fs"
|
||||
version = "2.4.2"
|
||||
version = "2.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"dunce",
|
||||
@@ -6616,7 +6730,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-geolocation"
|
||||
version = "2.3.0"
|
||||
version = "2.3.2"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
@@ -6629,7 +6743,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-global-shortcut"
|
||||
version = "2.3.0"
|
||||
version = "2.3.1"
|
||||
dependencies = [
|
||||
"global-hotkey",
|
||||
"log",
|
||||
@@ -6642,7 +6756,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-haptics"
|
||||
version = "2.3.0"
|
||||
version = "2.3.2"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
@@ -6655,7 +6769,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-http"
|
||||
version = "2.5.2"
|
||||
version = "2.5.4"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"cookie_store",
|
||||
@@ -6678,7 +6792,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-localhost"
|
||||
version = "2.3.0"
|
||||
version = "2.3.1"
|
||||
dependencies = [
|
||||
"http",
|
||||
"log",
|
||||
@@ -6691,7 +6805,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-log"
|
||||
version = "2.6.0"
|
||||
version = "2.7.1"
|
||||
dependencies = [
|
||||
"android_logger",
|
||||
"byte-unit",
|
||||
@@ -6712,7 +6826,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-nfc"
|
||||
version = "2.3.1"
|
||||
version = "2.3.3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
@@ -6725,7 +6839,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-notification"
|
||||
version = "2.3.1"
|
||||
version = "2.3.3"
|
||||
dependencies = [
|
||||
"color-backtrace",
|
||||
"ctor",
|
||||
@@ -6747,7 +6861,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-opener"
|
||||
version = "2.5.0"
|
||||
version = "2.5.2"
|
||||
dependencies = [
|
||||
"dunce",
|
||||
"glob",
|
||||
@@ -6767,7 +6881,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-os"
|
||||
version = "2.3.1"
|
||||
version = "2.3.2"
|
||||
dependencies = [
|
||||
"gethostname 1.0.1",
|
||||
"log",
|
||||
@@ -6783,7 +6897,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-persisted-scope"
|
||||
version = "2.3.2"
|
||||
version = "2.3.4"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"bincode",
|
||||
@@ -6797,7 +6911,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-positioner"
|
||||
version = "2.3.0"
|
||||
version = "2.3.1"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
@@ -6810,15 +6924,32 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-process"
|
||||
version = "2.3.0"
|
||||
version = "2.3.1"
|
||||
dependencies = [
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-secure-storage"
|
||||
version = "2.0.0"
|
||||
dependencies = [
|
||||
"android-native-keyring-store",
|
||||
"apple-native-keyring-store",
|
||||
"keyring-core",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"thiserror 2.0.12",
|
||||
"windows-native-keyring-store",
|
||||
"zbus-secret-service-keyring-store",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-shell"
|
||||
version = "2.3.0"
|
||||
version = "2.3.3"
|
||||
dependencies = [
|
||||
"encoding_rs",
|
||||
"log",
|
||||
@@ -6837,7 +6968,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-single-instance"
|
||||
version = "2.3.3"
|
||||
version = "2.3.6"
|
||||
dependencies = [
|
||||
"semver",
|
||||
"serde",
|
||||
@@ -6852,7 +6983,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-sql"
|
||||
version = "2.3.0"
|
||||
version = "2.3.1"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"indexmap 2.9.0",
|
||||
@@ -6869,7 +7000,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-store"
|
||||
version = "2.4.0"
|
||||
version = "2.4.1"
|
||||
dependencies = [
|
||||
"dunce",
|
||||
"serde",
|
||||
@@ -6883,7 +7014,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-stronghold"
|
||||
version = "2.3.0"
|
||||
version = "2.3.1"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"iota-crypto",
|
||||
@@ -6934,7 +7065,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-upload"
|
||||
version = "2.3.1"
|
||||
version = "2.3.2"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
@@ -6952,7 +7083,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-websocket"
|
||||
version = "2.4.0"
|
||||
version = "2.4.1"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"http",
|
||||
@@ -6969,7 +7100,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-window-state"
|
||||
version = "2.4.0"
|
||||
version = "2.4.1"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"log",
|
||||
@@ -7007,9 +7138,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime-wry"
|
||||
version = "2.8.0"
|
||||
version = "2.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5bb0f10f831f75832ac74d14d98f701868f9a8adccef2c249b466cf70b607db9"
|
||||
checksum = "c1fe9d48bd122ff002064e88cfcd7027090d789c4302714e68fcccba0f4b7807"
|
||||
dependencies = [
|
||||
"gtk",
|
||||
"http",
|
||||
@@ -7332,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",
|
||||
@@ -7565,9 +7696,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",
|
||||
@@ -7739,6 +7870,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"
|
||||
@@ -8261,7 +8398,7 @@ dependencies = [
|
||||
"windows-collections",
|
||||
"windows-core",
|
||||
"windows-future",
|
||||
"windows-link",
|
||||
"windows-link 0.1.1",
|
||||
"windows-numerics",
|
||||
]
|
||||
|
||||
@@ -8282,7 +8419,7 @@ checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link",
|
||||
"windows-link 0.1.1",
|
||||
"windows-result",
|
||||
"windows-strings 0.4.0",
|
||||
]
|
||||
@@ -8294,7 +8431,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-link",
|
||||
"windows-link 0.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8325,6 +8462,24 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-native-keyring-store"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d37273ed015cfe7bce6fd684478cdd40435fc84a9ce781404d1fbc61c2d674d"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"keyring-core",
|
||||
"windows-sys 0.61.2",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-numerics"
|
||||
version = "0.2.0"
|
||||
@@ -8332,7 +8487,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-link",
|
||||
"windows-link 0.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8352,7 +8507,7 @@ version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad1da3e436dc7653dfdf3da67332e22bff09bb0e28b0239e1624499c7830842e"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows-link 0.1.1",
|
||||
"windows-result",
|
||||
"windows-strings 0.4.0",
|
||||
]
|
||||
@@ -8363,7 +8518,7 @@ version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows-link 0.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8372,7 +8527,7 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows-link 0.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8381,7 +8536,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows-link 0.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8429,6 +8584,15 @@ dependencies = [
|
||||
"windows-targets 0.53.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.2"
|
||||
@@ -8497,7 +8661,7 @@ version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e04a5c6627e310a23ad2358483286c7df260c964eb2d003d8efd6d0f4e79265c"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows-link 0.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8789,9 +8953,9 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.53.1"
|
||||
version = "0.53.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5698e50a589268aec06d2219f48b143222f7b5ad9aa690118b8dce0a8dcac574"
|
||||
checksum = "e3b6763512fe4b51c80b3ce9b50939d682acb4de335dfabbdb20d7a2642199b7"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"block2 0.6.0",
|
||||
@@ -8932,9 +9096,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zbus"
|
||||
version = "5.9.0"
|
||||
version = "5.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bb4f9a464286d42851d18a605f7193b8febaf5b0919d71c6399b7b26e5b0aad"
|
||||
checksum = "b622b18155f7a93d1cd2dc8c01d2d6a44e08fb9ebb7b3f9e6ed101488bad6c91"
|
||||
dependencies = [
|
||||
"async-broadcast",
|
||||
"async-executor",
|
||||
@@ -8957,7 +9121,8 @@ dependencies = [
|
||||
"tokio",
|
||||
"tracing",
|
||||
"uds_windows",
|
||||
"windows-sys 0.59.0",
|
||||
"uuid",
|
||||
"windows-sys 0.61.2",
|
||||
"winnow 0.7.12",
|
||||
"zbus_macros",
|
||||
"zbus_names",
|
||||
@@ -8965,10 +9130,21 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus_macros"
|
||||
version = "5.9.0"
|
||||
name = "zbus-secret-service-keyring-store"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef9859f68ee0c4ee2e8cde84737c78e3f4c54f946f2a38645d0d4c7a95327659"
|
||||
checksum = "0371a7e111fe248bf8e2d4648faa87b9d59ce4eabc0ff515bc3432a7d8ccf84f"
|
||||
dependencies = [
|
||||
"keyring-core",
|
||||
"secret-service",
|
||||
"zbus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus_macros"
|
||||
version = "5.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cdb94821ca8a87ca9c298b5d1cbd80e2a8b67115d99f6e4551ac49e42b6a314"
|
||||
dependencies = [
|
||||
"proc-macro-crate 3.3.0",
|
||||
"proc-macro2",
|
||||
|
||||
+2
-1
@@ -3,11 +3,12 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import eslint from '@eslint/js'
|
||||
import { defineConfig } from 'eslint/config'
|
||||
import eslintConfigPrettier from 'eslint-config-prettier'
|
||||
import eslintPluginSecurity from 'eslint-plugin-security'
|
||||
import tseslint from 'typescript-eslint'
|
||||
|
||||
export default tseslint.config(
|
||||
export default defineConfig(
|
||||
{
|
||||
ignores: [
|
||||
'**/target',
|
||||
|
||||
@@ -1,5 +1,54 @@
|
||||
# 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
|
||||
|
||||
- Upgraded to `dialog-js@2.4.0`
|
||||
- Upgraded to `log-js@2.7.0`
|
||||
|
||||
## \[2.0.31]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `shell-js@2.3.1`
|
||||
|
||||
## \[2.0.30]
|
||||
|
||||
### Dependencies
|
||||
|
||||
+20
-19
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "api",
|
||||
"private": true,
|
||||
"version": "2.0.30",
|
||||
"version": "2.0.34",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --clearScreen false",
|
||||
@@ -10,24 +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.3.3",
|
||||
"@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-shell": "^2.3.0",
|
||||
"@tauri-apps/plugin-store": "^2.4.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.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"
|
||||
@@ -36,10 +37,10 @@
|
||||
"@iconify-json/codicon": "^1.2.12",
|
||||
"@iconify-json/ph": "^1.2.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
||||
"@tauri-apps/cli": "2.8.1",
|
||||
"@tauri-apps/cli": "2.9.4",
|
||||
"@unocss/extractor-svelte": "^66.3.3",
|
||||
"svelte": "^5.20.4",
|
||||
"unocss": "^66.3.3",
|
||||
"vite": "^7.0.4"
|
||||
"vite": "^7.0.7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,58 @@
|
||||
# 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
|
||||
|
||||
- Upgraded to `dialog@2.4.0`
|
||||
- Upgraded to `log@2.7.0`
|
||||
|
||||
## \[2.0.35]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `shell@2.3.1`
|
||||
|
||||
## \[2.0.34]
|
||||
|
||||
### Dependencies
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "api"
|
||||
publish = false
|
||||
version = "2.0.34"
|
||||
version = "2.0.38"
|
||||
description = "An example Tauri Application showcasing the api"
|
||||
edition = "2021"
|
||||
rust-version = { workspace = true }
|
||||
@@ -20,24 +20,25 @@ serde = { workspace = true }
|
||||
tiny_http = "0.12"
|
||||
time = "0.3"
|
||||
log = { workspace = true }
|
||||
tauri-plugin-log = { path = "../../../plugins/log", version = "2.6.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.3.3" }
|
||||
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-shell = { path = "../../../plugins/shell", version = "2.3.0" }
|
||||
tauri-plugin-store = { path = "../../../plugins/store", version = "2.4.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.3" }
|
||||
tauri-plugin-store = { path = "../../../plugins/store", version = "2.4.1" }
|
||||
tauri-plugin-upload = { path = "../../../plugins/upload", version = "2.3.0" }
|
||||
|
||||
[dependencies.tauri]
|
||||
@@ -55,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"]
|
||||
|
||||
@@ -102,6 +102,10 @@
|
||||
"identifier": "opener:allow-open-path",
|
||||
"allow": [{ "path": "$APPDATA" }, { "path": "$APPDATA/**" }]
|
||||
},
|
||||
"upload:default"
|
||||
"upload:default",
|
||||
"secure-storage:allow-get-string",
|
||||
"secure-storage:allow-set-string",
|
||||
"secure-storage:allow-get-binary",
|
||||
"secure-storage:allow-set-binary"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@ pub struct RequestBody {
|
||||
|
||||
#[command]
|
||||
pub fn log_operation(event: String, payload: Option<String>) {
|
||||
log::info!("{} {:?}", event, payload);
|
||||
log::info!("{event} {payload:?}");
|
||||
}
|
||||
|
||||
#[command]
|
||||
pub fn perform_request(endpoint: String, body: RequestBody) -> String {
|
||||
println!("{} {:?}", endpoint, body);
|
||||
println!("{endpoint} {body:?}");
|
||||
"message response".into()
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ pub fn run() {
|
||||
.plugin(tauri_plugin_process::init())
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.plugin(tauri_plugin_secure_storage::init())
|
||||
.plugin(tauri_plugin_store::Builder::default().build())
|
||||
.plugin(tauri_plugin_upload::init())
|
||||
.setup(move |app| {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
import Biometric from './views/Biometric.svelte'
|
||||
import Geolocation from './views/Geolocation.svelte'
|
||||
import Haptics from './views/Haptics.svelte'
|
||||
import SecureStorage from './views/SecureStorage.svelte'
|
||||
|
||||
import { onMount, tick } from 'svelte'
|
||||
import { ask } from '@tauri-apps/plugin-dialog'
|
||||
@@ -103,6 +104,11 @@
|
||||
component: Store,
|
||||
icon: 'i-codicon-file-code'
|
||||
},
|
||||
{
|
||||
label: 'SecureStorage',
|
||||
component: SecureStorage,
|
||||
icon: 'i-codicon-file-code'
|
||||
},
|
||||
!isMobile && {
|
||||
label: 'Updater',
|
||||
component: Updater,
|
||||
@@ -213,9 +219,9 @@
|
||||
...r,
|
||||
{
|
||||
html:
|
||||
`<pre><strong class="text-accent dark:text-darkAccent">[${new Date().toLocaleTimeString()}]:</strong> ` +
|
||||
(typeof value === 'string' ? value : JSON.stringify(value, null, 1)) +
|
||||
'</pre>'
|
||||
`<pre><strong class="text-accent dark:text-darkAccent">[${new Date().toLocaleTimeString()}]:</strong> `
|
||||
+ (typeof value === 'string' ? value : JSON.stringify(value, null, 1))
|
||||
+ '</pre>'
|
||||
}
|
||||
])
|
||||
await tick()
|
||||
@@ -229,9 +235,9 @@
|
||||
...r,
|
||||
{
|
||||
html:
|
||||
`<pre><strong class="text-accent dark:text-darkAccent">[${new Date().toLocaleTimeString()}]:</strong> ` +
|
||||
html +
|
||||
'</pre>'
|
||||
`<pre><strong class="text-accent dark:text-darkAccent">[${new Date().toLocaleTimeString()}]:</strong> `
|
||||
+ html
|
||||
+ '</pre>'
|
||||
}
|
||||
])
|
||||
await tick()
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
let filter = null;
|
||||
let multiple = false;
|
||||
let directory = false;
|
||||
let pickerMode = "";
|
||||
|
||||
function arrayBufferToBase64(buffer, callback) {
|
||||
var blob = new Blob([buffer], {
|
||||
@@ -44,6 +45,13 @@
|
||||
await message("Tauri is awesome!");
|
||||
}
|
||||
|
||||
async function msgCustom(result) {
|
||||
const buttons = { yes: "awesome", no: "amazing", cancel: "stunning" };
|
||||
await message(`Tauri is: `, { buttons })
|
||||
.then((res) => onMessage(`Tauri is ${res}`))
|
||||
.catch(onMessage);
|
||||
}
|
||||
|
||||
function openDialog() {
|
||||
open({
|
||||
title: "My wonderful open dialog",
|
||||
@@ -58,6 +66,7 @@
|
||||
: [],
|
||||
multiple,
|
||||
directory,
|
||||
pickerMode: pickerMode === "" ? undefined : pickerMode,
|
||||
})
|
||||
.then(function (res) {
|
||||
if (Array.isArray(res)) {
|
||||
@@ -87,7 +96,7 @@
|
||||
onMessage(res);
|
||||
}
|
||||
})
|
||||
.catch(onMessage(res));
|
||||
.catch(onMessage);
|
||||
}
|
||||
})
|
||||
.catch(onMessage);
|
||||
@@ -105,7 +114,7 @@
|
||||
},
|
||||
]
|
||||
: [],
|
||||
})
|
||||
})
|
||||
.then(onMessage)
|
||||
.catch(onMessage);
|
||||
}
|
||||
@@ -135,13 +144,28 @@
|
||||
<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 />
|
||||
<button class="btn" id="open-dialog" on:click={openDialog}>Open dialog</button>
|
||||
<button class="btn" id="save-dialog" on:click={saveDialog}
|
||||
>Open save dialog</button
|
||||
>
|
||||
<button class="btn" id="prompt-dialog" on:click={prompt}>Prompt</button>
|
||||
<button class="btn" id="custom-prompt-dialog" on:click={promptCustom}
|
||||
>Prompt (custom)</button
|
||||
>
|
||||
<button class="btn" id="message-dialog" on:click={msg}>Message</button>
|
||||
|
||||
<div class="flex flex-wrap flex-col md:flex-row gap-2 children:flex-shrink-0">
|
||||
<button class="btn" id="open-dialog" on:click={openDialog}>Open dialog</button>
|
||||
<button class="btn" id="save-dialog" on:click={saveDialog}
|
||||
>Open save dialog</button
|
||||
>
|
||||
<button class="btn" id="prompt-dialog" on:click={prompt}>Prompt</button>
|
||||
<button class="btn" id="custom-prompt-dialog" on:click={promptCustom}
|
||||
>Prompt (custom)</button
|
||||
>
|
||||
<button class="btn" id="message-dialog" on:click={msg}>Message</button>
|
||||
<button class="btn" id="message-dialog" on:click={msgCustom}>Message (custom)</button>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<script>
|
||||
import { onMount } from 'svelte'
|
||||
import { getString, setString } from '@tauri-apps/plugin-secure-storage'
|
||||
|
||||
export let onMessage
|
||||
|
||||
let key
|
||||
let value
|
||||
let output
|
||||
|
||||
async function read(key) {
|
||||
try {
|
||||
output = await getString(key)
|
||||
} catch (error) {
|
||||
onMessage(error)
|
||||
}
|
||||
}
|
||||
|
||||
async function write(key, value) {
|
||||
try {
|
||||
await setString(key, value)
|
||||
} catch (error) {
|
||||
onMessage(error)
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
output = ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col childre:grow gap-1">
|
||||
<div class="flex flex-col flex-row-md gap-4">
|
||||
<div class="flex items-center gap-1">
|
||||
Key:
|
||||
<input class="grow input" bind:value={key} />
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-1">
|
||||
Value:
|
||||
<input class="grow input" bind:value />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button class="btn" on:click={() => write(key, value)}>Write</button>
|
||||
<button class="btn" on:click={() => read(key)}>Read</button>
|
||||
<button class="btn" on:click={() => reset()}>Reset Output</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Output: {output}
|
||||
</div>
|
||||
</div>
|
||||
@@ -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}
|
||||
|
||||
+9
-8
@@ -11,20 +11,21 @@
|
||||
"example:api:dev": "pnpm run --filter \"api\" tauri dev"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "9.33.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.33.0",
|
||||
"eslint": "9.39.1",
|
||||
"eslint-config-prettier": "10.1.8",
|
||||
"eslint-plugin-security": "3.0.1",
|
||||
"prettier": "3.6.2",
|
||||
"rollup": "4.47.1",
|
||||
"rollup": "4.53.2",
|
||||
"tslib": "2.8.1",
|
||||
"typescript": "5.9.2",
|
||||
"typescript-eslint": "8.40.0"
|
||||
"typescript": "5.9.3",
|
||||
"typescript-eslint": "8.47.0"
|
||||
},
|
||||
"minimumReleaseAge": 4320,
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"esbuild@<0.25.0": ">=0.25.0"
|
||||
@@ -34,6 +35,6 @@
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"pnpm": "^10.0.0"
|
||||
"pnpm": "^10.16.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,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,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"
|
||||
|
||||
@@ -331,10 +331,10 @@
|
||||
"markdownDescription": "Denies the is_enabled command without any pre-configured scope."
|
||||
},
|
||||
{
|
||||
"description": "This permission set configures if your\napplication can enable or disable auto\nstarting the application on boot.\n\n#### Granted Permissions\n\nIt allows all to check, enable and\ndisable the automatic start on boot.\n\n\n#### This default permission set includes:\n\n- `allow-enable`\n- `allow-disable`\n- `allow-is-enabled`",
|
||||
"description": "This permission set configures if your\r\napplication can enable or disable auto\r\nstarting the application on boot.\r\n\r\n#### Granted Permissions\r\n\r\nIt allows all to check, enable and\r\ndisable the automatic start on boot.\r\n\r\n\n#### This default permission set includes:\n\n- `allow-enable`\n- `allow-disable`\n- `allow-is-enabled`",
|
||||
"type": "string",
|
||||
"const": "default",
|
||||
"markdownDescription": "This permission set configures if your\napplication can enable or disable auto\nstarting the application on boot.\n\n#### Granted Permissions\n\nIt allows all to check, enable and\ndisable the automatic start on boot.\n\n\n#### This default permission set includes:\n\n- `allow-enable`\n- `allow-disable`\n- `allow-is-enabled`"
|
||||
"markdownDescription": "This permission set configures if your\r\napplication can enable or disable auto\r\nstarting the application on boot.\r\n\r\n#### Granted Permissions\r\n\r\nIt allows all to check, enable and\r\ndisable the automatic start on boot.\r\n\r\n\n#### This default permission set includes:\n\n- `allow-enable`\n- `allow-disable`\n- `allow-is-enabled`"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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,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,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": [
|
||||
|
||||
@@ -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,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]
|
||||
|
||||
@@ -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,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"
|
||||
|
||||
@@ -319,10 +319,10 @@
|
||||
"markdownDescription": "Denies the status command without any pre-configured scope."
|
||||
},
|
||||
{
|
||||
"description": "This permission set configures which\nbiometric features are by default exposed.\n\n#### Granted Permissions\n\nIt allows acccess to all biometric commands.\n\n\n#### This default permission set includes:\n\n- `allow-authenticate`\n- `allow-status`",
|
||||
"description": "This permission set configures which\r\nbiometric features are by default exposed.\r\n\r\n#### Granted Permissions\r\n\r\nIt allows acccess to all biometric commands.\r\n\r\n\n#### This default permission set includes:\n\n- `allow-authenticate`\n- `allow-status`",
|
||||
"type": "string",
|
||||
"const": "default",
|
||||
"markdownDescription": "This permission set configures which\nbiometric features are by default exposed.\n\n#### Granted Permissions\n\nIt allows acccess to all biometric commands.\n\n\n#### This default permission set includes:\n\n- `allow-authenticate`\n- `allow-status`"
|
||||
"markdownDescription": "This permission set configures which\r\nbiometric features are by default exposed.\r\n\r\n#### Granted Permissions\r\n\r\nIt allows acccess to all biometric commands.\r\n\r\n\n#### This default permission set includes:\n\n- `allow-authenticate`\n- `allow-status`"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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,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,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"
|
||||
|
||||
@@ -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,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,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"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## Default Permission
|
||||
|
||||
No features are enabled by default, as we believe
|
||||
the clipboard can be inherently dangerous and it is
|
||||
the clipboard can be inherently dangerous and it is
|
||||
application specific if read and/or write access is needed.
|
||||
|
||||
Clipboard interaction needs to be explicitly enabled.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
[default]
|
||||
description = """
|
||||
No features are enabled by default, as we believe
|
||||
the clipboard can be inherently dangerous and it is
|
||||
the clipboard can be inherently dangerous and it is
|
||||
application specific if read and/or write access is needed.
|
||||
|
||||
Clipboard interaction needs to be explicitly enabled.
|
||||
|
||||
@@ -367,10 +367,10 @@
|
||||
"markdownDescription": "Denies the write_text command without any pre-configured scope."
|
||||
},
|
||||
{
|
||||
"description": "No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n",
|
||||
"description": "No features are enabled by default, as we believe\r\nthe clipboard can be inherently dangerous and it is\r\napplication specific if read and/or write access is needed.\r\n\r\nClipboard interaction needs to be explicitly enabled.\r\n",
|
||||
"type": "string",
|
||||
"const": "default",
|
||||
"markdownDescription": "No features are enabled by default, as we believe\nthe clipboard can be inherently dangerous and it is \napplication specific if read and/or write access is needed.\n\nClipboard interaction needs to be explicitly enabled.\n"
|
||||
"markdownDescription": "No features are enabled by default, as we believe\r\nthe clipboard can be inherently dangerous and it is\r\napplication specific if read and/or write access is needed.\r\n\r\nClipboard interaction needs to be explicitly enabled.\r\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# 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).
|
||||
|
||||
## \[2.4.2]
|
||||
|
||||
- [`21d721a0`](https://github.com/tauri-apps/plugins-workspace/commit/21d721a0c2731fc201872f5b99ea8bbdc61b0b60) ([#2928](https://github.com/tauri-apps/plugins-workspace/pull/2928) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) On Linux, improved error messages when OS commands fail.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-plugin-deep-link"
|
||||
version = "2.4.2"
|
||||
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]
|
||||
|
||||
@@ -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,23 @@
|
||||
# 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
|
||||
|
||||
- Upgraded to `deep-link-js@2.4.3`
|
||||
|
||||
## \[2.2.5]
|
||||
|
||||
### Dependencies
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "deep-link-example",
|
||||
"private": true,
|
||||
"version": "2.2.5",
|
||||
"version": "2.2.8",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -10,12 +10,12 @@
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "2.8.0",
|
||||
"@tauri-apps/plugin-deep-link": "2.4.2"
|
||||
"@tauri-apps/api": "2.9.0",
|
||||
"@tauri-apps/plugin-deep-link": "2.4.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "2.8.1",
|
||||
"@tauri-apps/cli": "2.9.4",
|
||||
"typescript": "^5.7.3",
|
||||
"vite": "^7.0.4"
|
||||
"vite": "^7.0.7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@tauri-apps/plugin-deep-link",
|
||||
"version": "2.4.2",
|
||||
"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.1"
|
||||
"@tauri-apps/cli": "2.9.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,14 +23,21 @@ pub enum Error {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[error(transparent)]
|
||||
ParseIni(#[from] ini::ParseError),
|
||||
#[cfg(target_os = "linux")]
|
||||
#[error("Failed to run OS command `{0}`: {1}")]
|
||||
Execute(&'static str, #[source] std::io::Error),
|
||||
#[cfg(mobile)]
|
||||
#[error(transparent)]
|
||||
PluginInvoke(#[from] tauri::plugin::mobile::PluginInvokeError),
|
||||
}
|
||||
|
||||
// TODO(v3): change this into an error in v3,
|
||||
// see <https://github.com/tauri-apps/plugins-workspace/pull/2970#issuecomment-3244660138>.
|
||||
#[inline]
|
||||
#[cfg(target_os = "linux")]
|
||||
pub(crate) fn inspect_command_error<'a>(command: &'a str) -> impl Fn(&std::io::Error) + 'a {
|
||||
move |e| {
|
||||
tracing::error!("Failed to run OS command `{command}`: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Error {
|
||||
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
|
||||
where
|
||||
|
||||
@@ -293,6 +293,7 @@ mod imp {
|
||||
.unwrap_or_else(|| bin.into_os_string())
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
let qualified_exec = format!("{} %u", exec);
|
||||
|
||||
let target = self.app.path().data_dir()?.join("applications");
|
||||
|
||||
@@ -304,12 +305,28 @@ mod imp {
|
||||
|
||||
if let Ok(mut desktop_file) = ini::Ini::load_from_file(&target_file) {
|
||||
if let Some(section) = desktop_file.section_mut(Some("Desktop Entry")) {
|
||||
// it's ok to remove it - we only write to the file if it's missing
|
||||
// and in that case we include old_mimes
|
||||
let old_mimes = section.remove("MimeType").unwrap_or_default();
|
||||
let mut change = false;
|
||||
|
||||
// if the mime type is not present, append it to the list
|
||||
if !old_mimes.split(';').any(|mime| mime == mime_type) {
|
||||
section.append("MimeType", format!("{mime_type};{old_mimes}"));
|
||||
change = true;
|
||||
} else {
|
||||
section.insert("MimeType".to_string(), old_mimes);
|
||||
}
|
||||
|
||||
// if the exec command doesnt match, update to the new one
|
||||
let old_exec = section.remove("Exec").unwrap_or_default();
|
||||
if old_exec != qualified_exec {
|
||||
section.append("Exec", qualified_exec);
|
||||
change = true;
|
||||
} else {
|
||||
section.insert("Exec".to_string(), old_exec.to_string());
|
||||
}
|
||||
|
||||
// if any property has changed, rewrite the .desktop file
|
||||
if change {
|
||||
desktop_file.write_to_file(&target_file)?;
|
||||
}
|
||||
}
|
||||
@@ -324,7 +341,7 @@ mod imp {
|
||||
.product_name
|
||||
.clone()
|
||||
.unwrap_or_else(|| file_name.clone()),
|
||||
exec = exec,
|
||||
qualified_exec = qualified_exec,
|
||||
mime_type = mime_type
|
||||
)
|
||||
.as_bytes(),
|
||||
@@ -334,12 +351,14 @@ mod imp {
|
||||
Command::new("update-desktop-database")
|
||||
.arg(target)
|
||||
.status()
|
||||
.map_err(|error| crate::Error::Execute("update-desktop-database", error))?;
|
||||
.inspect_err(crate::error::inspect_command_error(
|
||||
"update-desktop-database",
|
||||
))?;
|
||||
|
||||
Command::new("xdg-mime")
|
||||
.args(["default", &file_name, mime_type.as_str()])
|
||||
.status()
|
||||
.map_err(|error| crate::Error::Execute("xdg-mime", error))?;
|
||||
.inspect_err(crate::error::inspect_command_error("xdg-mime"))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -444,7 +463,7 @@ mod imp {
|
||||
&format!("x-scheme-handler/{}", _protocol.as_ref()),
|
||||
])
|
||||
.output()
|
||||
.map_err(|error| crate::Error::Execute("xdg-mime", error))?;
|
||||
.inspect_err(crate::error::inspect_command_error("xdg-mime"))?;
|
||||
|
||||
Ok(String::from_utf8_lossy(&output.stdout).contains(&file_name))
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name={name}
|
||||
Exec={exec} %u
|
||||
Exec={qualified_exec}
|
||||
Terminal=false
|
||||
MimeType={mime_type}
|
||||
NoDisplay=true
|
||||
NoDisplay=true
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
# 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.
|
||||
|
||||
## \[2.3.3]
|
||||
|
||||
### Dependencies
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "tauri-plugin-dialog"
|
||||
version = "2.3.3"
|
||||
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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -38,6 +39,7 @@ class MessageOptions {
|
||||
var title: String? = null
|
||||
lateinit var message: String
|
||||
var okButtonLabel: String? = null
|
||||
var noButtonLabel: String? = null
|
||||
var cancelButtonLabel: String? = null
|
||||
}
|
||||
|
||||
@@ -60,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)
|
||||
@@ -139,9 +150,8 @@ class DialogPlugin(private val activity: Activity): Plugin(activity) {
|
||||
return
|
||||
}
|
||||
|
||||
val handler = { cancelled: Boolean, value: Boolean ->
|
||||
val handler = { value: String ->
|
||||
val ret = JSObject()
|
||||
ret.put("cancelled", cancelled)
|
||||
ret.put("value", value)
|
||||
invoke.resolve(ret)
|
||||
}
|
||||
@@ -153,24 +163,34 @@ class DialogPlugin(private val activity: Activity): Plugin(activity) {
|
||||
if (args.title != null) {
|
||||
builder.setTitle(args.title)
|
||||
}
|
||||
|
||||
val okButtonLabel = args.okButtonLabel ?: "Ok"
|
||||
|
||||
builder
|
||||
.setMessage(args.message)
|
||||
.setPositiveButton(
|
||||
args.okButtonLabel ?: "OK"
|
||||
) { dialog, _ ->
|
||||
.setPositiveButton(okButtonLabel) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
handler(false, true)
|
||||
handler(okButtonLabel)
|
||||
}
|
||||
.setOnCancelListener { dialog ->
|
||||
dialog.dismiss()
|
||||
handler(true, false)
|
||||
handler(args.cancelButtonLabel ?: "Cancel")
|
||||
}
|
||||
|
||||
if (args.noButtonLabel != null) {
|
||||
builder.setNeutralButton(args.noButtonLabel) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
handler(args.noButtonLabel!!)
|
||||
}
|
||||
}
|
||||
|
||||
if (args.cancelButtonLabel != null) {
|
||||
builder.setNegativeButton( args.cancelButtonLabel) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
handler(false, false)
|
||||
handler(args.cancelButtonLabel!!)
|
||||
}
|
||||
}
|
||||
|
||||
val dialog = builder.create()
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
if("__TAURI__"in window){var __TAURI_PLUGIN_DIALOG__=function(t){"use strict";async function n(t,n={},e){return window.__TAURI_INTERNALS__.invoke(t,n,e)}return"function"==typeof SuppressedError&&SuppressedError,t.ask=async function(t,e){const i="string"==typeof e?{title:e}:e;return await n("plugin:dialog|ask",{message:t.toString(),title:i?.title?.toString(),kind:i?.kind,yesButtonLabel:i?.okLabel?.toString(),noButtonLabel:i?.cancelLabel?.toString()})},t.confirm=async function(t,e){const i="string"==typeof e?{title:e}:e;return await n("plugin:dialog|confirm",{message:t.toString(),title:i?.title?.toString(),kind:i?.kind,okButtonLabel:i?.okLabel?.toString(),cancelButtonLabel:i?.cancelLabel?.toString()})},t.message=async function(t,e){const i="string"==typeof e?{title:e}:e;await n("plugin:dialog|message",{message:t.toString(),title:i?.title?.toString(),kind:i?.kind,okButtonLabel:i?.okLabel?.toString()})},t.open=async function(t={}){return"object"==typeof t&&Object.freeze(t),await n("plugin:dialog|open",{options:t})},t.save=async function(t={}){return"object"==typeof t&&Object.freeze(t),await n("plugin:dialog|save",{options:t})},t}({});Object.defineProperty(window.__TAURI__,"dialog",{value:__TAURI_PLUGIN_DIALOG__})}
|
||||
if("__TAURI__"in window){var __TAURI_PLUGIN_DIALOG__=function(t){"use strict";async function n(t,n={},e){return window.__TAURI_INTERNALS__.invoke(t,n,e)}function e(t){if(void 0!==t)return"string"==typeof t?t:"ok"in t&&"cancel"in t?{OkCancelCustom:[t.ok,t.cancel]}:"yes"in t&&"no"in t&&"cancel"in t?{YesNoCancelCustom:[t.yes,t.no,t.cancel]}:"ok"in t?{OkCustom:t.ok}:void 0}return"function"==typeof SuppressedError&&SuppressedError,t.ask=async function(t,e){const o="string"==typeof e?{title:e}:e;return await n("plugin:dialog|ask",{message:t.toString(),title:o?.title?.toString(),kind:o?.kind,yesButtonLabel:o?.okLabel?.toString(),noButtonLabel:o?.cancelLabel?.toString()})},t.confirm=async function(t,e){const o="string"==typeof e?{title:e}:e;return await n("plugin:dialog|confirm",{message:t.toString(),title:o?.title?.toString(),kind:o?.kind,okButtonLabel:o?.okLabel?.toString(),cancelButtonLabel:o?.cancelLabel?.toString()})},t.message=async function(t,o){const i="string"==typeof o?{title:o}:o;return n("plugin:dialog|message",{message:t.toString(),title:i?.title?.toString(),kind:i?.kind,okButtonLabel:i?.okLabel?.toString(),buttons:e(i?.buttons)})},t.open=async function(t={}){return"object"==typeof t&&Object.freeze(t),await n("plugin:dialog|open",{options:t})},t.save=async function(t={}){return"object"==typeof t&&Object.freeze(t),await n("plugin:dialog|save",{options:t})},t}({});Object.defineProperty(window.__TAURI__,"dialog",{value:__TAURI_PLUGIN_DIALOG__})}
|
||||
|
||||
@@ -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,90 @@ 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.
|
||||
*
|
||||
* @since 2.4.0
|
||||
*/
|
||||
export type MessageDialogDefaultButtons =
|
||||
| 'Ok'
|
||||
| 'OkCancel'
|
||||
| 'YesNo'
|
||||
| 'YesNoCancel'
|
||||
|
||||
/** All possible button keys. */
|
||||
type ButtonKey = 'ok' | 'cancel' | 'yes' | 'no'
|
||||
|
||||
/** Ban everything except a set of keys. */
|
||||
type BanExcept<Allowed extends ButtonKey> = Partial<
|
||||
Record<Exclude<ButtonKey, Allowed>, never>
|
||||
>
|
||||
|
||||
/**
|
||||
* The Yes, No and Cancel buttons of a message dialog.
|
||||
*
|
||||
* @since 2.4.0
|
||||
*/
|
||||
export type MessageDialogButtonsYesNoCancel = {
|
||||
/** The Yes button. */
|
||||
yes: string
|
||||
/** The No button. */
|
||||
no: string
|
||||
/** The Cancel button. */
|
||||
cancel: string
|
||||
} & BanExcept<'yes' | 'no' | 'cancel'>
|
||||
|
||||
/**
|
||||
* The Ok and Cancel buttons of a message dialog.
|
||||
*
|
||||
* @since 2.4.0
|
||||
*/
|
||||
export type MessageDialogButtonsOkCancel = {
|
||||
/** The Ok button. */
|
||||
ok: string
|
||||
/** The Cancel button. */
|
||||
cancel: string
|
||||
} & BanExcept<'ok' | 'cancel'>
|
||||
|
||||
/**
|
||||
* The Ok button of a message dialog.
|
||||
*
|
||||
* @since 2.4.0
|
||||
*/
|
||||
export type MessageDialogButtonsOk = {
|
||||
/** The Ok button. */
|
||||
ok: string
|
||||
} & BanExcept<'ok'>
|
||||
|
||||
/**
|
||||
* Custom buttons for a message dialog.
|
||||
*
|
||||
* @since 2.4.0
|
||||
*/
|
||||
export type MessageDialogCustomButtons =
|
||||
| MessageDialogButtonsYesNoCancel
|
||||
| MessageDialogButtonsOkCancel
|
||||
| MessageDialogButtonsOk
|
||||
|
||||
/**
|
||||
* The buttons of a message dialog.
|
||||
*
|
||||
* @since 2.4.0
|
||||
*/
|
||||
export type MessageDialogButtons =
|
||||
| MessageDialogDefaultButtons
|
||||
| MessageDialogCustomButtons
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@@ -85,8 +193,58 @@ interface MessageDialogOptions {
|
||||
title?: string
|
||||
/** The kind of the dialog. Defaults to `info`. */
|
||||
kind?: 'info' | 'warning' | 'error'
|
||||
/** The label of the confirm button. */
|
||||
/**
|
||||
* The label of the Ok button.
|
||||
*
|
||||
* @deprecated Use {@linkcode MessageDialogOptions.buttons} instead.
|
||||
*/
|
||||
okLabel?: string
|
||||
/**
|
||||
* The buttons of the dialog.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* // Use system default buttons texts
|
||||
* await message('Hello World!', { buttons: 'Ok' })
|
||||
* await message('Hello World!', { buttons: 'OkCancel' })
|
||||
*
|
||||
* // Or with custom button texts
|
||||
* await message('Hello World!', { buttons: { ok: 'Yes!' } })
|
||||
* await message('Take on the task?', {
|
||||
* buttons: { ok: 'Accept', cancel: 'Cancel' }
|
||||
* })
|
||||
* await message('Show the file content?', {
|
||||
* buttons: { yes: 'Show content', no: 'Show in folder', cancel: 'Cancel' }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @since 2.4.0
|
||||
*/
|
||||
buttons?: MessageDialogButtons
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to convert the buttons to the Rust type.
|
||||
*/
|
||||
function buttonsToRust(buttons: MessageDialogButtons | undefined) {
|
||||
if (buttons === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (typeof buttons === 'string') {
|
||||
return buttons
|
||||
} else if ('ok' in buttons && 'cancel' in buttons) {
|
||||
return { OkCancelCustom: [buttons.ok, buttons.cancel] }
|
||||
} else if ('yes' in buttons && 'no' in buttons && 'cancel' in buttons) {
|
||||
return {
|
||||
YesNoCancelCustom: [buttons.yes, buttons.no, buttons.cancel]
|
||||
}
|
||||
} else if ('ok' in buttons) {
|
||||
return { OkCustom: buttons.ok }
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
interface ConfirmDialogOptions {
|
||||
@@ -202,6 +360,16 @@ async function save(options: SaveDialogOptions = {}): Promise<string | null> {
|
||||
return await invoke('plugin:dialog|save', { options })
|
||||
}
|
||||
|
||||
/**
|
||||
* The result of a message dialog.
|
||||
*
|
||||
* The result is a string if the dialog has custom buttons,
|
||||
* otherwise it is one of the default buttons.
|
||||
*
|
||||
* @since 2.4.0
|
||||
*/
|
||||
export type MessageDialogResult = 'Yes' | 'No' | 'Ok' | 'Cancel' | (string & {})
|
||||
|
||||
/**
|
||||
* Shows a message dialog with an `Ok` button.
|
||||
* @example
|
||||
@@ -222,13 +390,15 @@ async function save(options: SaveDialogOptions = {}): Promise<string | null> {
|
||||
async function message(
|
||||
message: string,
|
||||
options?: string | MessageDialogOptions
|
||||
): Promise<void> {
|
||||
): Promise<MessageDialogResult> {
|
||||
const opts = typeof options === 'string' ? { title: options } : options
|
||||
await invoke('plugin:dialog|message', {
|
||||
|
||||
return invoke<MessageDialogResult>('plugin:dialog|message', {
|
||||
message: message.toString(),
|
||||
title: opts?.title?.toString(),
|
||||
kind: opts?.kind,
|
||||
okButtonLabel: opts?.okLabel?.toString()
|
||||
okButtonLabel: opts?.okLabel?.toString(),
|
||||
buttons: buttonsToRust(opts?.buttons)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import PhotosUI
|
||||
import SwiftRs
|
||||
import Tauri
|
||||
import UIKit
|
||||
import UniformTypeIdentifiers
|
||||
import WebKit
|
||||
|
||||
enum FilePickerEvent {
|
||||
@@ -20,6 +21,7 @@ struct MessageDialogOptions: Decodable {
|
||||
var title: String?
|
||||
let message: String
|
||||
var okButtonLabel: String?
|
||||
var noButtonLabel: String?
|
||||
var cancelButtonLabel: String?
|
||||
}
|
||||
|
||||
@@ -31,6 +33,7 @@ struct FilePickerOptions: Decodable {
|
||||
var multiple: Bool?
|
||||
var filters: [Filter]?
|
||||
var defaultPath: String?
|
||||
var pickerMode: PickerMode?
|
||||
}
|
||||
|
||||
struct SaveFileDialogOptions: Decodable {
|
||||
@@ -38,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!
|
||||
@@ -51,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):
|
||||
@@ -80,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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,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
|
||||
}
|
||||
|
||||
@@ -200,36 +257,38 @@ class DialogPlugin: Plugin {
|
||||
let alert = UIAlertController(
|
||||
title: args.title, message: args.message, preferredStyle: UIAlertController.Style.alert)
|
||||
|
||||
let cancelButtonLabel = args.cancelButtonLabel ?? ""
|
||||
if !cancelButtonLabel.isEmpty {
|
||||
if let cancelButtonLabel = args.cancelButtonLabel {
|
||||
alert.addAction(
|
||||
UIAlertAction(
|
||||
title: cancelButtonLabel, style: UIAlertAction.Style.default,
|
||||
handler: { (_) -> Void in
|
||||
Logger.error("cancel")
|
||||
|
||||
invoke.resolve([
|
||||
"value": false,
|
||||
"cancelled": false,
|
||||
])
|
||||
}))
|
||||
invoke.resolve(["value": cancelButtonLabel])
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
let okButtonLabel = args.okButtonLabel ?? (cancelButtonLabel.isEmpty ? "OK" : "")
|
||||
if !okButtonLabel.isEmpty {
|
||||
if let noButtonLabel = args.noButtonLabel {
|
||||
alert.addAction(
|
||||
UIAlertAction(
|
||||
title: okButtonLabel, style: UIAlertAction.Style.default,
|
||||
title: noButtonLabel, style: UIAlertAction.Style.default,
|
||||
handler: { (_) -> Void in
|
||||
Logger.error("ok")
|
||||
|
||||
invoke.resolve([
|
||||
"value": true,
|
||||
"cancelled": false,
|
||||
])
|
||||
}))
|
||||
invoke.resolve(["value": noButtonLabel])
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
let okButtonLabel = args.okButtonLabel ?? "Ok"
|
||||
alert.addAction(
|
||||
UIAlertAction(
|
||||
title: okButtonLabel, style: UIAlertAction.Style.default,
|
||||
handler: { (_) -> Void in
|
||||
invoke.resolve(["value": okButtonLabel])
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
manager.viewController?.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@tauri-apps/plugin-dialog",
|
||||
"version": "2.3.3",
|
||||
"version": "2.4.2",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"authors": [
|
||||
"Tauri Programme within The Commons Conservancy"
|
||||
|
||||
@@ -9,8 +9,8 @@ use tauri::{command, Manager, Runtime, State, Window};
|
||||
use tauri_plugin_fs::FsExt;
|
||||
|
||||
use crate::{
|
||||
Dialog, FileDialogBuilder, FilePath, MessageDialogButtons, MessageDialogKind, Result, CANCEL,
|
||||
NO, OK, YES,
|
||||
Dialog, FileDialogBuilder, FilePath, MessageDialogBuilder, MessageDialogButtons,
|
||||
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);
|
||||
@@ -248,7 +258,7 @@ fn message_dialog<R: Runtime>(
|
||||
message: String,
|
||||
kind: Option<MessageDialogKind>,
|
||||
buttons: MessageDialogButtons,
|
||||
) -> bool {
|
||||
) -> MessageDialogBuilder<R> {
|
||||
let mut builder = dialog.message(message);
|
||||
|
||||
builder = builder.buttons(buttons);
|
||||
@@ -266,7 +276,7 @@ fn message_dialog<R: Runtime>(
|
||||
builder = builder.kind(kind);
|
||||
}
|
||||
|
||||
builder.blocking_show()
|
||||
builder
|
||||
}
|
||||
|
||||
#[command]
|
||||
@@ -277,19 +287,15 @@ pub(crate) async fn message<R: Runtime>(
|
||||
message: String,
|
||||
kind: Option<MessageDialogKind>,
|
||||
ok_button_label: Option<String>,
|
||||
) -> Result<bool> {
|
||||
Ok(message_dialog(
|
||||
window,
|
||||
dialog,
|
||||
title,
|
||||
message,
|
||||
kind,
|
||||
if let Some(ok_button_label) = ok_button_label {
|
||||
MessageDialogButtons::OkCustom(ok_button_label)
|
||||
} else {
|
||||
MessageDialogButtons::Ok
|
||||
},
|
||||
))
|
||||
buttons: Option<MessageDialogButtons>,
|
||||
) -> Result<MessageDialogResult> {
|
||||
let buttons = buttons.unwrap_or(if let Some(ok_button_label) = ok_button_label {
|
||||
MessageDialogButtons::OkCustom(ok_button_label)
|
||||
} else {
|
||||
MessageDialogButtons::Ok
|
||||
});
|
||||
|
||||
Ok(message_dialog(window, dialog, title, message, kind, buttons).blocking_show_with_result())
|
||||
}
|
||||
|
||||
#[command]
|
||||
@@ -302,7 +308,7 @@ pub(crate) async fn ask<R: Runtime>(
|
||||
yes_button_label: Option<String>,
|
||||
no_button_label: Option<String>,
|
||||
) -> Result<bool> {
|
||||
Ok(message_dialog(
|
||||
let dialog = message_dialog(
|
||||
window,
|
||||
dialog,
|
||||
title,
|
||||
@@ -318,7 +324,9 @@ pub(crate) async fn ask<R: Runtime>(
|
||||
} else {
|
||||
MessageDialogButtons::YesNo
|
||||
},
|
||||
))
|
||||
);
|
||||
|
||||
Ok(dialog.blocking_show())
|
||||
}
|
||||
|
||||
#[command]
|
||||
@@ -331,7 +339,7 @@ pub(crate) async fn confirm<R: Runtime>(
|
||||
ok_button_label: Option<String>,
|
||||
cancel_button_label: Option<String>,
|
||||
) -> Result<bool> {
|
||||
Ok(message_dialog(
|
||||
let dialog = message_dialog(
|
||||
window,
|
||||
dialog,
|
||||
title,
|
||||
@@ -347,5 +355,7 @@ pub(crate) async fn confirm<R: Runtime>(
|
||||
} else {
|
||||
MessageDialogButtons::OkCancel
|
||||
},
|
||||
))
|
||||
);
|
||||
|
||||
Ok(dialog.blocking_show())
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ use rfd::{AsyncFileDialog, AsyncMessageDialog};
|
||||
use serde::de::DeserializeOwned;
|
||||
use tauri::{plugin::PluginApi, AppHandle, Runtime};
|
||||
|
||||
use crate::{models::*, FileDialogBuilder, FilePath, MessageDialogBuilder, OK};
|
||||
use crate::{models::*, FileDialogBuilder, FilePath, MessageDialogBuilder};
|
||||
|
||||
pub fn init<R: Runtime, C: DeserializeOwned>(
|
||||
app: &AppHandle<R>,
|
||||
@@ -115,6 +115,10 @@ impl From<MessageDialogButtons> for rfd::MessageButtons {
|
||||
MessageDialogButtons::YesNo => Self::YesNo,
|
||||
MessageDialogButtons::OkCustom(ok) => Self::OkCustom(ok),
|
||||
MessageDialogButtons::OkCancelCustom(ok, cancel) => Self::OkCancelCustom(ok, cancel),
|
||||
MessageDialogButtons::YesNoCancel => Self::YesNoCancel,
|
||||
MessageDialogButtons::YesNoCancelCustom(yes, no, cancel) => {
|
||||
Self::YesNoCancelCustom(yes, no, cancel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,28 +212,46 @@ pub fn save_file<R: Runtime, F: FnOnce(Option<FilePath>) + Send + 'static>(
|
||||
}
|
||||
|
||||
/// Shows a message dialog
|
||||
pub fn show_message_dialog<R: Runtime, F: FnOnce(bool) + Send + 'static>(
|
||||
pub fn show_message_dialog<R: Runtime, F: FnOnce(MessageDialogResult) + Send + 'static>(
|
||||
dialog: MessageDialogBuilder<R>,
|
||||
f: F,
|
||||
callback: F,
|
||||
) {
|
||||
use rfd::MessageDialogResult;
|
||||
|
||||
let ok_label = match &dialog.buttons {
|
||||
MessageDialogButtons::OkCustom(ok) => Some(ok.clone()),
|
||||
MessageDialogButtons::OkCancelCustom(ok, _) => Some(ok.clone()),
|
||||
_ => None,
|
||||
};
|
||||
let f = move |res| {
|
||||
f(match res {
|
||||
MessageDialogResult::Ok | MessageDialogResult::Yes => true,
|
||||
MessageDialogResult::Custom(s) => ok_label.map_or(s == OK, |ok_label| ok_label == s),
|
||||
_ => false,
|
||||
});
|
||||
};
|
||||
let f = move |res: rfd::MessageDialogResult| callback(res.into());
|
||||
|
||||
let handle = dialog.dialog.app_handle().to_owned();
|
||||
let _ = handle.run_on_main_thread(move || {
|
||||
let buttons = dialog.buttons.clone();
|
||||
let dialog = AsyncMessageDialog::from(dialog).show();
|
||||
std::thread::spawn(move || f(tauri::async_runtime::block_on(dialog)));
|
||||
std::thread::spawn(move || {
|
||||
let result = tauri::async_runtime::block_on(dialog);
|
||||
// on Linux rfd does not return rfd::MessageDialogResult::Custom, so we must map manually
|
||||
let result = match (result, buttons) {
|
||||
(rfd::MessageDialogResult::Ok, MessageDialogButtons::OkCustom(s)) => {
|
||||
rfd::MessageDialogResult::Custom(s)
|
||||
}
|
||||
(
|
||||
rfd::MessageDialogResult::Ok,
|
||||
MessageDialogButtons::OkCancelCustom(ok, _cancel),
|
||||
) => rfd::MessageDialogResult::Custom(ok),
|
||||
(
|
||||
rfd::MessageDialogResult::Cancel,
|
||||
MessageDialogButtons::OkCancelCustom(_ok, cancel),
|
||||
) => rfd::MessageDialogResult::Custom(cancel),
|
||||
(
|
||||
rfd::MessageDialogResult::Yes,
|
||||
MessageDialogButtons::YesNoCancelCustom(yes, _no, _cancel),
|
||||
) => rfd::MessageDialogResult::Custom(yes),
|
||||
(
|
||||
rfd::MessageDialogResult::No,
|
||||
MessageDialogButtons::YesNoCancelCustom(_yes, no, _cancel),
|
||||
) => rfd::MessageDialogResult::Custom(no),
|
||||
(
|
||||
rfd::MessageDialogResult::Cancel,
|
||||
MessageDialogButtons::YesNoCancelCustom(_yes, _no, cancel),
|
||||
) => rfd::MessageDialogResult::Custom(cancel),
|
||||
(result, _) => result,
|
||||
};
|
||||
f(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
+107
-13
@@ -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";
|
||||
@@ -216,6 +225,7 @@ pub(crate) struct MessageDialogPayload<'a> {
|
||||
message: &'a String,
|
||||
kind: &'a MessageDialogKind,
|
||||
ok_button_label: Option<&'a str>,
|
||||
no_button_label: Option<&'a str>,
|
||||
cancel_button_label: Option<&'a str>,
|
||||
}
|
||||
|
||||
@@ -238,13 +248,17 @@ impl<R: Runtime> MessageDialogBuilder<R> {
|
||||
|
||||
#[cfg(mobile)]
|
||||
pub(crate) fn payload(&self) -> MessageDialogPayload<'_> {
|
||||
let (ok_button_label, cancel_button_label) = match &self.buttons {
|
||||
MessageDialogButtons::Ok => (Some(OK), None),
|
||||
MessageDialogButtons::OkCancel => (Some(OK), Some(CANCEL)),
|
||||
MessageDialogButtons::YesNo => (Some(YES), Some(NO)),
|
||||
MessageDialogButtons::OkCustom(ok) => (Some(ok.as_str()), Some(CANCEL)),
|
||||
let (ok_button_label, no_button_label, cancel_button_label) = match &self.buttons {
|
||||
MessageDialogButtons::Ok => (Some(OK), None, None),
|
||||
MessageDialogButtons::OkCancel => (Some(OK), None, Some(CANCEL)),
|
||||
MessageDialogButtons::YesNo => (Some(YES), Some(NO), None),
|
||||
MessageDialogButtons::YesNoCancel => (Some(YES), Some(NO), Some(CANCEL)),
|
||||
MessageDialogButtons::OkCustom(ok) => (Some(ok.as_str()), None, None),
|
||||
MessageDialogButtons::OkCancelCustom(ok, cancel) => {
|
||||
(Some(ok.as_str()), Some(cancel.as_str()))
|
||||
(Some(ok.as_str()), None, Some(cancel.as_str()))
|
||||
}
|
||||
MessageDialogButtons::YesNoCancelCustom(yes, no, cancel) => {
|
||||
(Some(yes.as_str()), Some(no.as_str()), Some(cancel.as_str()))
|
||||
}
|
||||
};
|
||||
MessageDialogPayload {
|
||||
@@ -252,6 +266,7 @@ impl<R: Runtime> MessageDialogBuilder<R> {
|
||||
message: &self.message,
|
||||
kind: &self.kind,
|
||||
ok_button_label,
|
||||
no_button_label,
|
||||
cancel_button_label,
|
||||
}
|
||||
}
|
||||
@@ -295,16 +310,55 @@ impl<R: Runtime> MessageDialogBuilder<R> {
|
||||
}
|
||||
|
||||
/// Shows a message dialog
|
||||
///
|
||||
/// Returns `true` if the user pressed the OK/Yes button,
|
||||
pub fn show<F: FnOnce(bool) + Send + 'static>(self, f: F) {
|
||||
let ok_label = match &self.buttons {
|
||||
MessageDialogButtons::OkCustom(ok) => Some(ok.clone()),
|
||||
MessageDialogButtons::OkCancelCustom(ok, _) => Some(ok.clone()),
|
||||
MessageDialogButtons::YesNoCancelCustom(yes, _, _) => Some(yes.clone()),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
show_message_dialog(self, move |res| {
|
||||
let sucess = match res {
|
||||
MessageDialogResult::Ok | MessageDialogResult::Yes => true,
|
||||
MessageDialogResult::Custom(s) => {
|
||||
ok_label.map_or(s == OK, |ok_label| ok_label == s)
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
f(sucess)
|
||||
})
|
||||
}
|
||||
|
||||
/// Shows a message dialog and returns the button that was pressed.
|
||||
///
|
||||
/// Returns a [`MessageDialogResult`] enum that indicates which button was pressed.
|
||||
pub fn show_with_result<F: FnOnce(MessageDialogResult) + Send + 'static>(self, f: F) {
|
||||
show_message_dialog(self, f)
|
||||
}
|
||||
|
||||
/// Shows a message dialog.
|
||||
///
|
||||
/// Returns `true` if the user pressed the OK/Yes button,
|
||||
///
|
||||
/// This is a blocking operation,
|
||||
/// and should *NOT* be used when running on the main thread context.
|
||||
pub fn blocking_show(self) -> bool {
|
||||
blocking_fn!(self, show)
|
||||
}
|
||||
|
||||
/// Shows a message dialog and returns the button that was pressed.
|
||||
///
|
||||
/// Returns a [`MessageDialogResult`] enum that indicates which button was pressed.
|
||||
///
|
||||
/// This is a blocking operation,
|
||||
/// and should *NOT* be used when running on the main thread context.
|
||||
pub fn blocking_show_with_result(self) -> MessageDialogResult {
|
||||
blocking_fn!(self, show_with_result)
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Serialize)]
|
||||
pub(crate) struct Filter {
|
||||
@@ -324,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>,
|
||||
}
|
||||
@@ -335,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 :(
|
||||
@@ -350,6 +406,7 @@ impl<R: Runtime> FileDialogBuilder<R> {
|
||||
file_name: None,
|
||||
title: None,
|
||||
can_create_directories: None,
|
||||
picker_mode: None,
|
||||
#[cfg(desktop)]
|
||||
parent: None,
|
||||
}
|
||||
@@ -361,6 +418,7 @@ impl<R: Runtime> FileDialogBuilder<R> {
|
||||
file_name: &self.file_name,
|
||||
filters: &self.filters,
|
||||
multiple,
|
||||
picker_mode: &self.picker_mode,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,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
|
||||
///
|
||||
@@ -445,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.
|
||||
@@ -490,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
|
||||
///
|
||||
/// ```
|
||||
@@ -512,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
|
||||
///
|
||||
/// ```
|
||||
@@ -538,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
|
||||
///
|
||||
/// ```
|
||||
@@ -559,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
|
||||
///
|
||||
@@ -578,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
|
||||
///
|
||||
@@ -597,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
|
||||
///
|
||||
@@ -617,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
|
||||
///
|
||||
@@ -637,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
|
||||
///
|
||||
|
||||
@@ -8,7 +8,7 @@ use tauri::{
|
||||
AppHandle, Runtime,
|
||||
};
|
||||
|
||||
use crate::{FileDialogBuilder, FilePath, MessageDialogBuilder};
|
||||
use crate::{FileDialogBuilder, FilePath, MessageDialogBuilder, MessageDialogResult};
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
const PLUGIN_IDENTIFIER: &str = "app.tauri.dialog";
|
||||
@@ -107,13 +107,11 @@ pub fn save_file<R: Runtime, F: FnOnce(Option<FilePath>) + Send + 'static>(
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct ShowMessageDialogResponse {
|
||||
#[allow(dead_code)]
|
||||
cancelled: bool,
|
||||
value: bool,
|
||||
value: String,
|
||||
}
|
||||
|
||||
/// Shows a message dialog
|
||||
pub fn show_message_dialog<R: Runtime, F: FnOnce(bool) + Send + 'static>(
|
||||
pub fn show_message_dialog<R: Runtime, F: FnOnce(MessageDialogResult) + Send + 'static>(
|
||||
dialog: MessageDialogBuilder<R>,
|
||||
f: F,
|
||||
) {
|
||||
@@ -122,6 +120,8 @@ pub fn show_message_dialog<R: Runtime, F: FnOnce(bool) + Send + 'static>(
|
||||
.dialog
|
||||
.0
|
||||
.run_mobile_plugin::<ShowMessageDialogResponse>("showMessageDialog", dialog.payload());
|
||||
f(res.map(|r| r.value).unwrap_or_default())
|
||||
|
||||
let res = res.map(|res| res.value.into());
|
||||
f(res.unwrap_or_default())
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -52,7 +47,7 @@ impl Serialize for MessageDialogKind {
|
||||
|
||||
/// Set of button that will be displayed on the dialog
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||
pub enum MessageDialogButtons {
|
||||
#[default]
|
||||
/// A single `Ok` button with OS default dialog text
|
||||
@@ -61,8 +56,49 @@ pub enum MessageDialogButtons {
|
||||
OkCancel,
|
||||
/// 2 buttons `Yes` and `No` with OS default dialog texts
|
||||
YesNo,
|
||||
/// 3 buttons `Yes`, `No` and `Cancel` with OS default dialog texts
|
||||
YesNoCancel,
|
||||
/// A single `Ok` button with custom text
|
||||
OkCustom(String),
|
||||
/// 2 buttons `Ok` and `Cancel` with custom texts
|
||||
OkCancelCustom(String, String),
|
||||
/// 3 buttons `Yes`, `No` and `Cancel` with custom texts
|
||||
YesNoCancelCustom(String, String, String),
|
||||
}
|
||||
|
||||
/// Result of a message dialog
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||
pub enum MessageDialogResult {
|
||||
Yes,
|
||||
No,
|
||||
Ok,
|
||||
#[default]
|
||||
Cancel,
|
||||
#[serde(untagged)]
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
#[cfg(desktop)]
|
||||
impl From<rfd::MessageDialogResult> for MessageDialogResult {
|
||||
fn from(result: rfd::MessageDialogResult) -> Self {
|
||||
match result {
|
||||
rfd::MessageDialogResult::Yes => Self::Yes,
|
||||
rfd::MessageDialogResult::No => Self::No,
|
||||
rfd::MessageDialogResult::Ok => Self::Ok,
|
||||
rfd::MessageDialogResult::Cancel => Self::Cancel,
|
||||
rfd::MessageDialogResult::Custom(s) => Self::Custom(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for MessageDialogResult {
|
||||
fn from(value: String) -> Self {
|
||||
match value.as_str() {
|
||||
"Yes" => Self::Yes,
|
||||
"No" => Self::No,
|
||||
"Ok" => Self::Ok,
|
||||
"Cancel" => Self::Cancel,
|
||||
_ => Self::Custom(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,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" }
|
||||
|
||||
@@ -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,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": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Default Permission
|
||||
|
||||
This set of permissions describes the what kind of
|
||||
This set of permissions describes what kind of
|
||||
file system access the `fs` plugin has enabled or denied by default.
|
||||
|
||||
#### Granted Permissions
|
||||
@@ -3748,6 +3748,28 @@ This enables all index or metadata related commands without any pre-configured a
|
||||
|
||||
An empty permission you can use to modify the global scope.
|
||||
|
||||
## Example
|
||||
|
||||
```json
|
||||
{
|
||||
"identifier": "read-documents",
|
||||
"windows": ["main"],
|
||||
"permissions": [
|
||||
"fs:allow-read",
|
||||
{
|
||||
"identifier": "fs:scope",
|
||||
"allow": [
|
||||
"$APPDATA/documents/**/*"
|
||||
],
|
||||
"deny": [
|
||||
"$APPDATA/documents/secret.txt"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[default]
|
||||
description = """
|
||||
This set of permissions describes the what kind of
|
||||
This set of permissions describes what kind of
|
||||
file system access the `fs` plugin has enabled or denied by default.
|
||||
|
||||
#### Granted Permissions
|
||||
|
||||
@@ -1945,16 +1945,16 @@
|
||||
"markdownDescription": "Denies the write_text_file command without any pre-configured scope."
|
||||
},
|
||||
{
|
||||
"description": "This permissions allows to create the application specific directories.\n",
|
||||
"description": "This permissions allows to create the application specific directories.\r\n",
|
||||
"type": "string",
|
||||
"const": "create-app-specific-dirs",
|
||||
"markdownDescription": "This permissions allows to create the application specific directories.\n"
|
||||
"markdownDescription": "This permissions allows to create the application specific directories.\r\n"
|
||||
},
|
||||
{
|
||||
"description": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n#### This default permission set includes:\n\n- `create-app-specific-dirs`\n- `read-app-specific-dirs-recursive`\n- `deny-default`",
|
||||
"description": "This set of permissions describes what kind of\r\nfile system access the `fs` plugin has enabled or denied by default.\r\n\r\n#### Granted Permissions\r\n\r\nThis default permission set enables read access to the\r\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\r\nAppLog) and all files and sub directories created in it.\r\nThe location of these directories depends on the operating system,\r\nwhere the application is run.\r\n\r\nIn general these directories need to be manually created\r\nby the application at runtime, before accessing files or folders\r\nin it is possible.\r\n\r\nTherefore, it is also allowed to create all of these folders via\r\nthe `mkdir` command.\r\n\r\n#### Denied Permissions\r\n\r\nThis default permission set prevents access to critical components\r\nof the Tauri application by default.\r\nOn Windows the webview data folder access is denied.\r\n\n#### This default permission set includes:\n\n- `create-app-specific-dirs`\n- `read-app-specific-dirs-recursive`\n- `deny-default`",
|
||||
"type": "string",
|
||||
"const": "default",
|
||||
"markdownDescription": "This set of permissions describes the what kind of\nfile system access the `fs` plugin has enabled or denied by default.\n\n#### Granted Permissions\n\nThis default permission set enables read access to the\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\nAppLog) and all files and sub directories created in it.\nThe location of these directories depends on the operating system,\nwhere the application is run.\n\nIn general these directories need to be manually created\nby the application at runtime, before accessing files or folders\nin it is possible.\n\nTherefore, it is also allowed to create all of these folders via\nthe `mkdir` command.\n\n#### Denied Permissions\n\nThis default permission set prevents access to critical components\nof the Tauri application by default.\nOn Windows the webview data folder access is denied.\n\n#### This default permission set includes:\n\n- `create-app-specific-dirs`\n- `read-app-specific-dirs-recursive`\n- `deny-default`"
|
||||
"markdownDescription": "This set of permissions describes what kind of\r\nfile system access the `fs` plugin has enabled or denied by default.\r\n\r\n#### Granted Permissions\r\n\r\nThis default permission set enables read access to the\r\napplication specific directories (AppConfig, AppData, AppLocalData, AppCache,\r\nAppLog) and all files and sub directories created in it.\r\nThe location of these directories depends on the operating system,\r\nwhere the application is run.\r\n\r\nIn general these directories need to be manually created\r\nby the application at runtime, before accessing files or folders\r\nin it is possible.\r\n\r\nTherefore, it is also allowed to create all of these folders via\r\nthe `mkdir` command.\r\n\r\n#### Denied Permissions\r\n\r\nThis default permission set prevents access to critical components\r\nof the Tauri application by default.\r\nOn Windows the webview data folder access is denied.\r\n\n#### This default permission set includes:\n\n- `create-app-specific-dirs`\n- `read-app-specific-dirs-recursive`\n- `deny-default`"
|
||||
},
|
||||
{
|
||||
"description": "This denies access to dangerous Tauri relevant files and folders by default.\n#### This permission set includes:\n\n- `deny-webview-data-linux`\n- `deny-webview-data-windows`",
|
||||
@@ -1963,16 +1963,16 @@
|
||||
"markdownDescription": "This denies access to dangerous Tauri relevant files and folders by default.\n#### This permission set includes:\n\n- `deny-webview-data-linux`\n- `deny-webview-data-windows`"
|
||||
},
|
||||
{
|
||||
"description": "This denies read access to the\n`$APPLOCALDATA` folder on linux as the webview data and configuration values are stored here.\nAllowing access can lead to sensitive information disclosure and should be well considered.",
|
||||
"description": "This denies read access to the\r\n`$APPLOCALDATA` folder on linux as the webview data and configuration values are stored here.\r\nAllowing access can lead to sensitive information disclosure and should be well considered.",
|
||||
"type": "string",
|
||||
"const": "deny-webview-data-linux",
|
||||
"markdownDescription": "This denies read access to the\n`$APPLOCALDATA` folder on linux as the webview data and configuration values are stored here.\nAllowing access can lead to sensitive information disclosure and should be well considered."
|
||||
"markdownDescription": "This denies read access to the\r\n`$APPLOCALDATA` folder on linux as the webview data and configuration values are stored here.\r\nAllowing access can lead to sensitive information disclosure and should be well considered."
|
||||
},
|
||||
{
|
||||
"description": "This denies read access to the\n`$APPLOCALDATA/EBWebView` folder on windows as the webview data and configuration values are stored here.\nAllowing access can lead to sensitive information disclosure and should be well considered.",
|
||||
"description": "This denies read access to the\r\n`$APPLOCALDATA/EBWebView` folder on windows as the webview data and configuration values are stored here.\r\nAllowing access can lead to sensitive information disclosure and should be well considered.",
|
||||
"type": "string",
|
||||
"const": "deny-webview-data-windows",
|
||||
"markdownDescription": "This denies read access to the\n`$APPLOCALDATA/EBWebView` folder on windows as the webview data and configuration values are stored here.\nAllowing access can lead to sensitive information disclosure and should be well considered."
|
||||
"markdownDescription": "This denies read access to the\r\n`$APPLOCALDATA/EBWebView` folder on windows as the webview data and configuration values are stored here.\r\nAllowing access can lead to sensitive information disclosure and should be well considered."
|
||||
},
|
||||
{
|
||||
"description": "This enables all read related commands without any pre-configured accessible paths.",
|
||||
@@ -1981,10 +1981,10 @@
|
||||
"markdownDescription": "This enables all read related commands without any pre-configured accessible paths."
|
||||
},
|
||||
{
|
||||
"description": "This permission allows recursive read functionality on the application\nspecific base directories. \n",
|
||||
"description": "This permission allows recursive read functionality on the application\r\nspecific base directories. \r\n",
|
||||
"type": "string",
|
||||
"const": "read-app-specific-dirs-recursive",
|
||||
"markdownDescription": "This permission allows recursive read functionality on the application\nspecific base directories. \n"
|
||||
"markdownDescription": "This permission allows recursive read functionality on the application\r\nspecific base directories. \r\n"
|
||||
},
|
||||
{
|
||||
"description": "This enables directory read and file metadata related commands without any pre-configured accessible paths.",
|
||||
@@ -2005,10 +2005,10 @@
|
||||
"markdownDescription": "This enables all index or metadata related commands without any pre-configured accessible paths."
|
||||
},
|
||||
{
|
||||
"description": "An empty permission you can use to modify the global scope.",
|
||||
"description": "An empty permission you can use to modify the global scope.\r\n\r\n## Example\r\n\r\n```json\r\n{\r\n \"identifier\": \"read-documents\",\r\n \"windows\": [\"main\"],\r\n \"permissions\": [\r\n \"fs:allow-read\",\r\n {\r\n \"identifier\": \"fs:scope\",\r\n \"allow\": [\r\n \"$APPDATA/documents/**/*\"\r\n ],\r\n \"deny\": [\r\n \"$APPDATA/documents/secret.txt\"\r\n ]\r\n }\r\n ]\r\n}\r\n```\r\n",
|
||||
"type": "string",
|
||||
"const": "scope",
|
||||
"markdownDescription": "An empty permission you can use to modify the global scope."
|
||||
"markdownDescription": "An empty permission you can use to modify the global scope.\r\n\r\n## Example\r\n\r\n```json\r\n{\r\n \"identifier\": \"read-documents\",\r\n \"windows\": [\"main\"],\r\n \"permissions\": [\r\n \"fs:allow-read\",\r\n {\r\n \"identifier\": \"fs:scope\",\r\n \"allow\": [\r\n \"$APPDATA/documents/**/*\"\r\n ],\r\n \"deny\": [\r\n \"$APPDATA/documents/secret.txt\"\r\n ]\r\n }\r\n ]\r\n}\r\n```\r\n"
|
||||
},
|
||||
{
|
||||
"description": "This enables all write related commands without any pre-configured accessible paths.",
|
||||
|
||||
@@ -2,4 +2,27 @@
|
||||
|
||||
[[permission]]
|
||||
identifier = "scope"
|
||||
description = "An empty permission you can use to modify the global scope."
|
||||
description = """
|
||||
An empty permission you can use to modify the global scope.
|
||||
|
||||
## Example
|
||||
|
||||
```json
|
||||
{
|
||||
"identifier": "read-documents",
|
||||
"windows": ["main"],
|
||||
"permissions": [
|
||||
"fs:allow-read",
|
||||
{
|
||||
"identifier": "fs:scope",
|
||||
"allow": [
|
||||
"$APPDATA/documents/**/*"
|
||||
],
|
||||
"deny": [
|
||||
"$APPDATA/documents/secret.txt"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
"""
|
||||
|
||||
+110
-18
@@ -85,6 +85,7 @@ pub fn create<R: Runtime>(
|
||||
options: Option<BaseOptions>,
|
||||
) -> CommandResult<ResourceId> {
|
||||
let resolved_path = resolve_path(
|
||||
"create",
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -119,6 +120,7 @@ pub fn open<R: Runtime>(
|
||||
options: Option<OpenOptions>,
|
||||
) -> CommandResult<ResourceId> {
|
||||
let (file, _path) = resolve_file(
|
||||
"open",
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -167,6 +169,7 @@ pub async fn copy_file<R: Runtime>(
|
||||
options: Option<CopyFileOptions>,
|
||||
) -> CommandResult<()> {
|
||||
let resolved_from_path = resolve_path(
|
||||
"copy-file",
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -174,6 +177,7 @@ pub async fn copy_file<R: Runtime>(
|
||||
options.as_ref().and_then(|o| o.from_path_base_dir),
|
||||
)?;
|
||||
let resolved_to_path = resolve_path(
|
||||
"copy-file",
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -208,6 +212,7 @@ pub fn mkdir<R: Runtime>(
|
||||
options: Option<MkdirOptions>,
|
||||
) -> CommandResult<()> {
|
||||
let resolved_path = resolve_path(
|
||||
"mkdir",
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -255,6 +260,7 @@ pub async fn read_dir<R: Runtime>(
|
||||
options: Option<BaseOptions>,
|
||||
) -> CommandResult<Vec<DirEntry>> {
|
||||
let resolved_path = resolve_path(
|
||||
"read-dir",
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -331,8 +337,8 @@ pub async fn read<R: Runtime>(
|
||||
Ok(tauri::ipc::Response::new(data))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn read_file<R: Runtime>(
|
||||
async fn read_file_inner<R: Runtime>(
|
||||
permission: &str,
|
||||
webview: Webview<R>,
|
||||
global_scope: GlobalScope<Entry>,
|
||||
command_scope: CommandScope<Entry>,
|
||||
@@ -340,6 +346,7 @@ pub async fn read_file<R: Runtime>(
|
||||
options: Option<BaseOptions>,
|
||||
) -> CommandResult<tauri::ipc::Response> {
|
||||
let (mut file, path) = resolve_file(
|
||||
permission,
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -367,6 +374,25 @@ pub async fn read_file<R: Runtime>(
|
||||
Ok(tauri::ipc::Response::new(contents))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn read_file<R: Runtime>(
|
||||
webview: Webview<R>,
|
||||
global_scope: GlobalScope<Entry>,
|
||||
command_scope: CommandScope<Entry>,
|
||||
path: SafeFilePath,
|
||||
options: Option<BaseOptions>,
|
||||
) -> CommandResult<tauri::ipc::Response> {
|
||||
read_file_inner(
|
||||
"read-file",
|
||||
webview,
|
||||
global_scope,
|
||||
command_scope,
|
||||
path,
|
||||
options,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
// TODO, remove in v3, rely on `read_file` command instead
|
||||
#[tauri::command]
|
||||
pub async fn read_text_file<R: Runtime>(
|
||||
@@ -376,7 +402,15 @@ pub async fn read_text_file<R: Runtime>(
|
||||
path: SafeFilePath,
|
||||
options: Option<BaseOptions>,
|
||||
) -> CommandResult<tauri::ipc::Response> {
|
||||
read_file(webview, global_scope, command_scope, path, options).await
|
||||
read_file_inner(
|
||||
"read-text-file",
|
||||
webview,
|
||||
global_scope,
|
||||
command_scope,
|
||||
path,
|
||||
options,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@@ -388,6 +422,7 @@ pub fn read_text_file_lines<R: Runtime>(
|
||||
options: Option<BaseOptions>,
|
||||
) -> CommandResult<ResourceId> {
|
||||
let resolved_path = resolve_path(
|
||||
"read-text-file-lines",
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -452,6 +487,7 @@ pub fn remove<R: Runtime>(
|
||||
options: Option<RemoveOptions>,
|
||||
) -> CommandResult<()> {
|
||||
let resolved_path = resolve_path(
|
||||
"remove",
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -521,6 +557,7 @@ pub fn rename<R: Runtime>(
|
||||
options: Option<RenameOptions>,
|
||||
) -> CommandResult<()> {
|
||||
let resolved_old_path = resolve_path(
|
||||
"rename",
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -528,6 +565,7 @@ pub fn rename<R: Runtime>(
|
||||
options.as_ref().and_then(|o| o.old_path_base_dir),
|
||||
)?;
|
||||
let resolved_new_path = resolve_path(
|
||||
"rename",
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -575,6 +613,7 @@ pub async fn seek<R: Runtime>(
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
fn get_metadata<R: Runtime, F: FnOnce(&PathBuf) -> std::io::Result<std::fs::Metadata>>(
|
||||
permission: &str,
|
||||
metadata_fn: F,
|
||||
webview: &Webview<R>,
|
||||
global_scope: &GlobalScope<Entry>,
|
||||
@@ -585,6 +624,7 @@ fn get_metadata<R: Runtime, F: FnOnce(&PathBuf) -> std::io::Result<std::fs::Meta
|
||||
match path {
|
||||
SafeFilePath::Url(url) => {
|
||||
let (file, path) = resolve_file(
|
||||
permission,
|
||||
webview,
|
||||
global_scope,
|
||||
command_scope,
|
||||
@@ -606,6 +646,7 @@ fn get_metadata<R: Runtime, F: FnOnce(&PathBuf) -> std::io::Result<std::fs::Meta
|
||||
})
|
||||
}
|
||||
SafeFilePath::Path(p) => get_fs_metadata(
|
||||
permission,
|
||||
metadata_fn,
|
||||
webview,
|
||||
global_scope,
|
||||
@@ -618,6 +659,7 @@ fn get_metadata<R: Runtime, F: FnOnce(&PathBuf) -> std::io::Result<std::fs::Meta
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
fn get_metadata<R: Runtime, F: FnOnce(&PathBuf) -> std::io::Result<std::fs::Metadata>>(
|
||||
permission: &str,
|
||||
metadata_fn: F,
|
||||
webview: &Webview<R>,
|
||||
global_scope: &GlobalScope<Entry>,
|
||||
@@ -626,6 +668,7 @@ fn get_metadata<R: Runtime, F: FnOnce(&PathBuf) -> std::io::Result<std::fs::Meta
|
||||
options: Option<BaseOptions>,
|
||||
) -> CommandResult<std::fs::Metadata> {
|
||||
get_fs_metadata(
|
||||
permission,
|
||||
metadata_fn,
|
||||
webview,
|
||||
global_scope,
|
||||
@@ -636,6 +679,7 @@ fn get_metadata<R: Runtime, F: FnOnce(&PathBuf) -> std::io::Result<std::fs::Meta
|
||||
}
|
||||
|
||||
fn get_fs_metadata<R: Runtime, F: FnOnce(&PathBuf) -> std::io::Result<std::fs::Metadata>>(
|
||||
permission: &str,
|
||||
metadata_fn: F,
|
||||
webview: &Webview<R>,
|
||||
global_scope: &GlobalScope<Entry>,
|
||||
@@ -644,6 +688,7 @@ fn get_fs_metadata<R: Runtime, F: FnOnce(&PathBuf) -> std::io::Result<std::fs::M
|
||||
options: Option<BaseOptions>,
|
||||
) -> CommandResult<std::fs::Metadata> {
|
||||
let resolved_path = resolve_path(
|
||||
permission,
|
||||
webview,
|
||||
global_scope,
|
||||
command_scope,
|
||||
@@ -668,6 +713,7 @@ pub fn stat<R: Runtime>(
|
||||
options: Option<BaseOptions>,
|
||||
) -> CommandResult<FileInfo> {
|
||||
let metadata = get_metadata(
|
||||
"stat",
|
||||
|p| std::fs::metadata(p),
|
||||
&webview,
|
||||
&global_scope,
|
||||
@@ -688,6 +734,7 @@ pub fn lstat<R: Runtime>(
|
||||
options: Option<BaseOptions>,
|
||||
) -> CommandResult<FileInfo> {
|
||||
let metadata = get_metadata(
|
||||
"lstat",
|
||||
|p| std::fs::symlink_metadata(p),
|
||||
&webview,
|
||||
&global_scope,
|
||||
@@ -716,6 +763,7 @@ pub async fn truncate<R: Runtime>(
|
||||
options: Option<BaseOptions>,
|
||||
) -> CommandResult<()> {
|
||||
let resolved_path = resolve_path(
|
||||
"truncate",
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -784,23 +832,13 @@ fn default_create_value() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn write_file<R: Runtime>(
|
||||
async fn write_file_inner<R: Runtime>(
|
||||
permission: &str,
|
||||
webview: Webview<R>,
|
||||
global_scope: GlobalScope<Entry>,
|
||||
command_scope: CommandScope<Entry>,
|
||||
request: tauri::ipc::Request<'_>,
|
||||
) -> CommandResult<()> {
|
||||
let data = match request.body() {
|
||||
tauri::ipc::InvokeBody::Raw(data) => Cow::Borrowed(data),
|
||||
tauri::ipc::InvokeBody::Json(serde_json::Value::Array(data)) => Cow::Owned(
|
||||
data.iter()
|
||||
.flat_map(|v| v.as_number().and_then(|v| v.as_u64().map(|v| v as u8)))
|
||||
.collect(),
|
||||
),
|
||||
_ => return Err(anyhow::anyhow!("unexpected invoke body").into()),
|
||||
};
|
||||
|
||||
let path = request
|
||||
.headers()
|
||||
.get("path")
|
||||
@@ -811,6 +849,7 @@ pub async fn write_file<R: Runtime>(
|
||||
.map_err(|_| anyhow::anyhow!("path is not a valid UTF-8").into())
|
||||
})
|
||||
.and_then(|p| SafeFilePath::from_str(&p).map_err(CommandError::from))?;
|
||||
|
||||
let options: Option<WriteFileOptions> = request
|
||||
.headers()
|
||||
.get("options")
|
||||
@@ -818,6 +857,7 @@ pub async fn write_file<R: Runtime>(
|
||||
.and_then(|opts| serde_json::from_str(opts).ok());
|
||||
|
||||
let (mut file, path) = resolve_file(
|
||||
permission,
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -853,6 +893,16 @@ pub async fn write_file<R: Runtime>(
|
||||
},
|
||||
)?;
|
||||
|
||||
let data = match request.body() {
|
||||
tauri::ipc::InvokeBody::Raw(data) => Cow::Borrowed(data),
|
||||
tauri::ipc::InvokeBody::Json(serde_json::Value::Array(data)) => Cow::Owned(
|
||||
data.iter()
|
||||
.flat_map(|v| v.as_number().and_then(|v| v.as_u64().map(|v| v as u8)))
|
||||
.collect(),
|
||||
),
|
||||
_ => return Err(anyhow::anyhow!("unexpected invoke body").into()),
|
||||
};
|
||||
|
||||
file.write_all(&data)
|
||||
.map_err(|e| {
|
||||
format!(
|
||||
@@ -863,6 +913,16 @@ pub async fn write_file<R: Runtime>(
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn write_file<R: Runtime>(
|
||||
webview: Webview<R>,
|
||||
global_scope: GlobalScope<Entry>,
|
||||
command_scope: CommandScope<Entry>,
|
||||
request: tauri::ipc::Request<'_>,
|
||||
) -> CommandResult<()> {
|
||||
write_file_inner("write-file", webview, global_scope, command_scope, request).await
|
||||
}
|
||||
|
||||
// TODO, remove in v3, rely on `write_file` command instead
|
||||
#[tauri::command]
|
||||
pub async fn write_text_file<R: Runtime>(
|
||||
@@ -871,7 +931,14 @@ pub async fn write_text_file<R: Runtime>(
|
||||
command_scope: CommandScope<Entry>,
|
||||
request: tauri::ipc::Request<'_>,
|
||||
) -> CommandResult<()> {
|
||||
write_file(webview, global_scope, command_scope, request).await
|
||||
write_file_inner(
|
||||
"write-text-file",
|
||||
webview,
|
||||
global_scope,
|
||||
command_scope,
|
||||
request,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@@ -883,6 +950,7 @@ pub fn exists<R: Runtime>(
|
||||
options: Option<BaseOptions>,
|
||||
) -> CommandResult<bool> {
|
||||
let resolved_path = resolve_path(
|
||||
"exists",
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -901,6 +969,7 @@ pub async fn size<R: Runtime>(
|
||||
options: Option<BaseOptions>,
|
||||
) -> CommandResult<u64> {
|
||||
let resolved_path = resolve_path(
|
||||
"size",
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
@@ -943,16 +1012,25 @@ fn get_dir_size(path: &PathBuf) -> CommandResult<u64> {
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
pub fn resolve_file<R: Runtime>(
|
||||
permission: &str,
|
||||
webview: &Webview<R>,
|
||||
global_scope: &GlobalScope<Entry>,
|
||||
command_scope: &CommandScope<Entry>,
|
||||
path: SafeFilePath,
|
||||
open_options: OpenOptions,
|
||||
) -> CommandResult<(File, PathBuf)> {
|
||||
resolve_file_in_fs(webview, global_scope, command_scope, path, open_options)
|
||||
resolve_file_in_fs(
|
||||
permission,
|
||||
webview,
|
||||
global_scope,
|
||||
command_scope,
|
||||
path,
|
||||
open_options,
|
||||
)
|
||||
}
|
||||
|
||||
fn resolve_file_in_fs<R: Runtime>(
|
||||
permission: &str,
|
||||
webview: &Webview<R>,
|
||||
global_scope: &GlobalScope<Entry>,
|
||||
command_scope: &CommandScope<Entry>,
|
||||
@@ -960,6 +1038,7 @@ fn resolve_file_in_fs<R: Runtime>(
|
||||
open_options: OpenOptions,
|
||||
) -> CommandResult<(File, PathBuf)> {
|
||||
let path = resolve_path(
|
||||
permission,
|
||||
webview,
|
||||
global_scope,
|
||||
command_scope,
|
||||
@@ -980,6 +1059,7 @@ fn resolve_file_in_fs<R: Runtime>(
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub fn resolve_file<R: Runtime>(
|
||||
permission: &str,
|
||||
webview: &Webview<R>,
|
||||
global_scope: &GlobalScope<Entry>,
|
||||
command_scope: &CommandScope<Entry>,
|
||||
@@ -997,6 +1077,7 @@ pub fn resolve_file<R: Runtime>(
|
||||
Ok((file, path))
|
||||
}
|
||||
SafeFilePath::Path(path) => resolve_file_in_fs(
|
||||
permission,
|
||||
webview,
|
||||
global_scope,
|
||||
command_scope,
|
||||
@@ -1007,6 +1088,7 @@ pub fn resolve_file<R: Runtime>(
|
||||
}
|
||||
|
||||
pub fn resolve_path<R: Runtime>(
|
||||
permission: &str,
|
||||
webview: &Webview<R>,
|
||||
global_scope: &GlobalScope<Entry>,
|
||||
command_scope: &CommandScope<Entry>,
|
||||
@@ -1052,7 +1134,17 @@ pub fn resolve_path<R: Runtime>(
|
||||
if fs_scope.scope.is_allowed(&path) || scope.is_allowed(&path) {
|
||||
Ok(path)
|
||||
} else {
|
||||
Err(CommandError::Plugin(Error::PathForbidden(path)))
|
||||
#[cfg(not(debug_assertions))]
|
||||
return Err(CommandError::Plugin(Error::PathForbidden(path)));
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
Err(
|
||||
anyhow::anyhow!(
|
||||
"forbidden path: {}, maybe it is not allowed on the scope for `allow-{permission}` permission in your capability file",
|
||||
path.display()
|
||||
)
|
||||
)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ impl<R: Runtime> Fs<R> {
|
||||
std::fs::File::from_raw_fd(fd)
|
||||
})
|
||||
} else {
|
||||
todo!()
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ pub fn watch<R: Runtime>(
|
||||
.into_iter()
|
||||
.map(|path| {
|
||||
resolve_path(
|
||||
"watch",
|
||||
&webview,
|
||||
&global_scope,
|
||||
&command_scope,
|
||||
|
||||
@@ -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,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]
|
||||
|
||||
@@ -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)
|
||||
@@ -91,11 +89,9 @@ 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())
|
||||
|
||||
val locationRequest = LocationRequest.Builder(10000)
|
||||
val locationRequest = LocationRequest.Builder(timeout)
|
||||
.setMaxUpdateDelayMillis(timeout)
|
||||
.setMinUpdateIntervalMillis(5000)
|
||||
.setMinUpdateIntervalMillis(timeout)
|
||||
.setPriority(prio)
|
||||
.build()
|
||||
|
||||
@@ -145,4 +141,4 @@ public class Geolocation(private val context: Context) {
|
||||
|
||||
return lastLoc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,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 = "" }
|
||||
|
||||
@@ -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(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user