mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-05-03 12:15:11 +02:00
Compare commits
181 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 | |||
| 1a0b791650 | |||
| 2d03e2eac2 | |||
| 21d721a0c2 | |||
| 8abb31ee59 | |||
| 0354046817 | |||
| 04a0954857 | |||
| 9e4e859bea | |||
| 2371804172 | |||
| 90f9b9310a | |||
| 1c58f3372c | |||
| 75617a6a92 | |||
| 5a963a0496 | |||
| 76f4e7bb84 | |||
| 670ac1d7c1 | |||
| ed0deef2cf | |||
| 50cebdb6d5 | |||
| dd2ea9cfa5 | |||
| 515182a179 | |||
| d1edf783e1 | |||
| d3d290ab8a | |||
| b51c827b2c | |||
| a4b71a1992 | |||
| 4eb36b0ff5 | |||
| 9804eeef03 | |||
| 829fd23b8e | |||
| 13bbb9cd3d | |||
| 9b162b51a6 | |||
| 57f0422ae9 | |||
| 581523244f | |||
| b8056f484c | |||
| f924ef16e4 | |||
| c9babc028a | |||
| fdcc15a5fe | |||
| 53bf0af9dd | |||
| c4665050bb | |||
| 6f65edfd72 | |||
| 63f660996f | |||
| 8cb053f47c | |||
| cac333b076 | |||
| 5ce3e45768 | |||
| 88da3d26ad | |||
| af5500caed | |||
| dc55eb51ed | |||
| 5ac8fbb1fa | |||
| e0323ec752 | |||
| cc98e6a892 | |||
| af22ae0a97 | |||
| 2f24c7a70c | |||
| fe23a5e013 | |||
| ff6d23ede1 | |||
| 449dd117a4 | |||
| 9b43f48856 | |||
| af08c66faa | |||
| 7974acae22 | |||
| a985359e69 | |||
| 97bebcf6e8 | |||
| a132d8f3d5 | |||
| a7af1a81b7 | |||
| 27ddcd0abe | |||
| d7fb5623d6 | |||
| d4f8299b12 | |||
| 341919ed57 | |||
| 124f2191aa | |||
| 0970b94949 | |||
| 7340242d4e | |||
| d66aa6ff78 | |||
| 6f345870df | |||
| 708fa4e2b7 | |||
| b729203059 | |||
| 2f9c71aae7 | |||
| 80d4d8e128 | |||
| e7a98b0d2e | |||
| 44a1f65912 | |||
| 6210cd31df | |||
| 467f07b7de | |||
| 7ba6e08a86 | |||
| 989470f0d7 | |||
| ca3c3aa28a | |||
| aa9140e1ac | |||
| 6a8f255878 | |||
| 8ac494da7c | |||
| 1635282868 | |||
| 4587e4a2b3 | |||
| 1135dc7ed3 | |||
| fe01894e7f | |||
| 36400b5678 | |||
| ead3c268e1 |
@@ -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
+378
-159
File diff suppressed because it is too large
Load Diff
+5
-5
@@ -12,10 +12,10 @@ resolver = "2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
tracing = "0.1"
|
||||
log = "0.4"
|
||||
tauri = { version = "2.6", default-features = false }
|
||||
tauri-build = "2.3"
|
||||
tauri-plugin = "2.3"
|
||||
tauri-utils = "2.5"
|
||||
tauri = { version = "2.8.2", default-features = false }
|
||||
tauri-build = "2.4"
|
||||
tauri-plugin = "2.4"
|
||||
tauri-utils = "2.7"
|
||||
serde_json = "1"
|
||||
thiserror = "2"
|
||||
url = "2"
|
||||
@@ -23,7 +23,7 @@ schemars = "0.8"
|
||||
dunce = "1"
|
||||
specta = "^2.0.0-rc.16"
|
||||
glob = "0.3"
|
||||
zbus = "5"
|
||||
zbus = "5.9"
|
||||
|
||||
[workspace.package]
|
||||
edition = "2021"
|
||||
|
||||
@@ -33,7 +33,7 @@ This repo and all plugins require a Rust version of at least **1.77.2**
|
||||
| [store](plugins/store) | Persistent key value storage. | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| [stronghold](plugins/stronghold) | Encrypted, secure database. | ✅ | ✅ | ✅ | ? | ? |
|
||||
| [updater](plugins/updater) | In-app updates for Tauri applications. | ✅ | ✅ | ✅ | ❌ | ❌ |
|
||||
| [upload](plugins/upload) | Tauri plugin for file uploads through HTTP. | ✅ | ✅ | ✅ | ? | ? |
|
||||
| [upload](plugins/upload) | Tauri plugin for file uploads through HTTP. | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| [websocket](plugins/websocket) | Open a WebSocket connection using a Rust client in JS. | ✅ | ✅ | ✅ | ? | ? |
|
||||
| [window-state](plugins/window-state) | Persist window sizes and positions. | ✅ | ✅ | ✅ | ❌ | ❌ |
|
||||
|
||||
|
||||
+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,87 @@
|
||||
# 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
|
||||
|
||||
- Upgraded to `notification-js@2.3.1`
|
||||
|
||||
## \[2.0.29]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `fs-js@2.4.2`
|
||||
- Upgraded to `nfc-js@2.3.1`
|
||||
- Upgraded to `opener-js@2.5.0`
|
||||
- Upgraded to `os-js@2.3.1`
|
||||
- Upgraded to `store-js@2.4.0`
|
||||
- Upgraded to `dialog-js@2.3.3`
|
||||
- Upgraded to `http-js@2.5.2`
|
||||
|
||||
## \[2.0.28]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `dialog-js@2.3.2`
|
||||
|
||||
## \[2.0.27]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `barcode-scanner-js@2.4.0`
|
||||
- Upgraded to `fs-js@2.4.1`
|
||||
- Upgraded to `dialog-js@2.3.1`
|
||||
- Upgraded to `http-js@2.5.1`
|
||||
|
||||
## \[2.0.26]
|
||||
|
||||
### Dependencies
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, viewport-fit=cover"
|
||||
content="width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=0"
|
||||
/>
|
||||
<title>Svelte + Vite App</title>
|
||||
</head>
|
||||
|
||||
+24
-22
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "api",
|
||||
"private": true,
|
||||
"version": "2.0.26",
|
||||
"version": "2.0.34",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --clearScreen false",
|
||||
@@ -10,35 +10,37 @@
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "2.6.0",
|
||||
"@tauri-apps/plugin-barcode-scanner": "^2.3.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.0",
|
||||
"@tauri-apps/plugin-fs": "^2.4.0",
|
||||
"@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.0",
|
||||
"@tauri-apps/plugin-nfc": "^2.3.0",
|
||||
"@tauri-apps/plugin-notification": "^2.3.0",
|
||||
"@tauri-apps/plugin-opener": "^2.4.0",
|
||||
"@tauri-apps/plugin-os": "^2.3.0",
|
||||
"@tauri-apps/plugin-process": "^2.3.0",
|
||||
"@tauri-apps/plugin-shell": "^2.3.0",
|
||||
"@tauri-apps/plugin-store": "^2.3.0",
|
||||
"@tauri-apps/plugin-http": "^2.5.4",
|
||||
"@tauri-apps/plugin-nfc": "^2.3.3",
|
||||
"@tauri-apps/plugin-notification": "^2.3.3",
|
||||
"@tauri-apps/plugin-opener": "^2.5.2",
|
||||
"@tauri-apps/plugin-os": "^2.3.2",
|
||||
"@tauri-apps/plugin-process": "^2.3.1",
|
||||
"@tauri-apps/plugin-secure-storage": "file:../../plugins/secure-storage",
|
||||
"@tauri-apps/plugin-shell": "^2.3.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"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/codicon": "^1.2.12",
|
||||
"@iconify-json/ph": "^1.2.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||
"@tauri-apps/cli": "2.6.0",
|
||||
"@unocss/extractor-svelte": "^66.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
||||
"@tauri-apps/cli": "2.9.4",
|
||||
"@unocss/extractor-svelte": "^66.3.3",
|
||||
"svelte": "^5.20.4",
|
||||
"unocss": "^66.0.0",
|
||||
"vite": "^6.2.6"
|
||||
"unocss": "^66.3.3",
|
||||
"vite": "^7.0.7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,91 @@
|
||||
# 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
|
||||
|
||||
- Upgraded to `notification@2.3.1`
|
||||
|
||||
## \[2.0.33]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `fs@2.4.2`
|
||||
- Upgraded to `nfc@2.3.1`
|
||||
- Upgraded to `opener@2.5.0`
|
||||
- Upgraded to `os@2.3.1`
|
||||
- Upgraded to `store@2.4.0`
|
||||
- Upgraded to `dialog@2.3.3`
|
||||
- Upgraded to `http@2.5.2`
|
||||
|
||||
## \[2.0.32]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `dialog@2.3.2`
|
||||
|
||||
## \[2.0.31]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `barcode-scanner@2.4.0`
|
||||
- Upgraded to `fs@2.4.1`
|
||||
- Upgraded to `dialog@2.3.1`
|
||||
- Upgraded to `http@2.5.1`
|
||||
|
||||
## \[2.0.30]
|
||||
|
||||
### Dependencies
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "api"
|
||||
publish = false
|
||||
version = "2.0.30"
|
||||
version = "2.0.38"
|
||||
description = "An example Tauri Application showcasing the api"
|
||||
edition = "2021"
|
||||
rust-version = { workspace = true }
|
||||
@@ -20,24 +20,26 @@ 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.0", 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.0" }
|
||||
tauri-plugin-clipboard-manager = { path = "../../../plugins/clipboard-manager", version = "2.3.2" }
|
||||
tauri-plugin-dialog = { path = "../../../plugins/dialog", version = "2.4.2" }
|
||||
tauri-plugin-http = { path = "../../../plugins/http", features = [
|
||||
"multipart",
|
||||
"cookies",
|
||||
], version = "2.5.0" }
|
||||
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.3.0", 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.0" }
|
||||
tauri-plugin-process = { path = "../../../plugins/process", version = "2.3.0" }
|
||||
tauri-plugin-opener = { path = "../../../plugins/opener", version = "2.4.0" }
|
||||
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.3.0" }
|
||||
tauri-plugin-store = { path = "../../../plugins/store", version = "2.3.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]
|
||||
workspace = true
|
||||
@@ -54,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.3.0" }
|
||||
tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.3.0" }
|
||||
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"]
|
||||
|
||||
@@ -68,6 +68,9 @@
|
||||
"fs:allow-rename",
|
||||
"fs:allow-mkdir",
|
||||
"fs:allow-remove",
|
||||
"fs:allow-stat",
|
||||
"fs:allow-fstat",
|
||||
"fs:allow-lstat",
|
||||
"fs:allow-write-text-file",
|
||||
"fs:read-meta",
|
||||
"fs:scope-download-recursive",
|
||||
@@ -75,6 +78,9 @@
|
||||
{
|
||||
"identifier": "fs:scope-appdata-recursive",
|
||||
"allow": [
|
||||
{
|
||||
"path": "$APPDATA/db/"
|
||||
},
|
||||
{
|
||||
"path": "$APPDATA/db/**"
|
||||
}
|
||||
@@ -95,6 +101,11 @@
|
||||
{
|
||||
"identifier": "opener:allow-open-path",
|
||||
"allow": [{ "path": "$APPDATA" }, { "path": "$APPDATA/**" }]
|
||||
}
|
||||
},
|
||||
"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,7 +38,9 @@ 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| {
|
||||
#[cfg(desktop)]
|
||||
{
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
import Opener from './views/Opener.svelte'
|
||||
import Store from './views/Store.svelte'
|
||||
import Updater from './views/Updater.svelte'
|
||||
import Upload from './views/Upload.svelte'
|
||||
import Clipboard from './views/Clipboard.svelte'
|
||||
import WebRTC from './views/WebRTC.svelte'
|
||||
import Scanner from './views/Scanner.svelte'
|
||||
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'
|
||||
@@ -102,11 +104,21 @@
|
||||
component: Store,
|
||||
icon: 'i-codicon-file-code'
|
||||
},
|
||||
{
|
||||
label: 'SecureStorage',
|
||||
component: SecureStorage,
|
||||
icon: 'i-codicon-file-code'
|
||||
},
|
||||
!isMobile && {
|
||||
label: 'Updater',
|
||||
component: Updater,
|
||||
icon: 'i-codicon-cloud-download'
|
||||
},
|
||||
{
|
||||
label: 'Upload',
|
||||
component: Upload,
|
||||
icon: 'i-codicon-cloud-upload'
|
||||
},
|
||||
{
|
||||
label: 'Clipboard',
|
||||
component: Clipboard,
|
||||
@@ -207,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()
|
||||
@@ -223,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>
|
||||
|
||||
@@ -1,194 +1,214 @@
|
||||
<script>
|
||||
import * as fs from "@tauri-apps/plugin-fs";
|
||||
import { convertFileSrc } from "@tauri-apps/api/core";
|
||||
import { arrayBufferToBase64 } from "../lib/utils";
|
||||
import { onDestroy } from "svelte";
|
||||
import * as fs from '@tauri-apps/plugin-fs'
|
||||
import * as os from '@tauri-apps/plugin-os'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { arrayBufferToBase64 } from '../lib/utils'
|
||||
import { onDestroy, onMount } from 'svelte'
|
||||
|
||||
export let onMessage;
|
||||
export let insecureRenderHtml;
|
||||
const { onMessage, insecureRenderHtml } = $props()
|
||||
|
||||
let path = "";
|
||||
let img;
|
||||
let path = $state('')
|
||||
let img
|
||||
/** @type {fs.FileHandle} */
|
||||
let file;
|
||||
let renameTo;
|
||||
let watchPath = "";
|
||||
let watchDebounceDelay = "0";
|
||||
let watchRecursive = false;
|
||||
let unwatchFn;
|
||||
let unwatchPath = "";
|
||||
let file = $state()
|
||||
let renameTo = $state()
|
||||
let watchPath = $state('')
|
||||
let watchDebounceDelay = $state(0)
|
||||
let watchRecursive = $state(false)
|
||||
/** @type {fs.BaseDirectory | undefined} */
|
||||
let baseDir = $state()
|
||||
let unwatchFn
|
||||
let unwatchPath = ''
|
||||
let isMobile = $state(false)
|
||||
|
||||
function getDir() {
|
||||
const dirSelect = document.getElementById("dir");
|
||||
return dirSelect.value ? parseInt(dir.value) : null;
|
||||
}
|
||||
onMount(() => {
|
||||
let platform = os.platform()
|
||||
isMobile = platform === 'android' || platform === 'ios'
|
||||
})
|
||||
|
||||
const DirOptions = Object.keys(fs.BaseDirectory)
|
||||
.filter((key) => isNaN(parseInt(key)))
|
||||
.map((dir) => [dir, fs.BaseDirectory[dir]]);
|
||||
const dirOptions = Object.keys(fs.BaseDirectory).filter((key) =>
|
||||
isNaN(parseInt(key))
|
||||
)
|
||||
|
||||
function open() {
|
||||
fs.open(path, {
|
||||
baseDir: getDir(),
|
||||
baseDir,
|
||||
read: true,
|
||||
write: true,
|
||||
create: true,
|
||||
create: true
|
||||
})
|
||||
.then((f) => {
|
||||
file = f;
|
||||
onMessage(`Opened ${path}`);
|
||||
file = f
|
||||
onMessage(`Opened ${path}`)
|
||||
})
|
||||
.catch(onMessage);
|
||||
.catch(onMessage)
|
||||
}
|
||||
|
||||
function mkdir() {
|
||||
fs.mkdir(path, { baseDir: getDir() })
|
||||
fs.mkdir(path, { baseDir, recursive: true })
|
||||
.then(() => {
|
||||
onMessage(`Created dir ${path}`);
|
||||
onMessage(`Created dir ${path}`)
|
||||
})
|
||||
.catch(onMessage);
|
||||
.catch(onMessage)
|
||||
}
|
||||
|
||||
function remove() {
|
||||
fs.remove(path, { baseDir: getDir() })
|
||||
fs.remove(path, { baseDir })
|
||||
.then(() => {
|
||||
onMessage(`Removed ${path}`);
|
||||
onMessage(`Removed ${path}`)
|
||||
})
|
||||
.catch(onMessage);
|
||||
.catch(onMessage)
|
||||
}
|
||||
|
||||
function rename() {
|
||||
fs.rename(path, renameTo, {
|
||||
oldPathBaseDir: getDir(),
|
||||
newPathBaseDir: getDir(),
|
||||
oldPathBaseDir,
|
||||
newPathBaseDir
|
||||
})
|
||||
.then(() => {
|
||||
onMessage(`Renamed ${path} to ${renameTo}`);
|
||||
onMessage(`Renamed ${path} to ${renameTo}`)
|
||||
})
|
||||
.catch(onMessage);
|
||||
.catch(onMessage)
|
||||
}
|
||||
|
||||
function truncate() {
|
||||
file
|
||||
.truncate(0)
|
||||
.then(() => {
|
||||
onMessage(`Truncated file`);
|
||||
onMessage(`Truncated file`)
|
||||
})
|
||||
.catch(onMessage);
|
||||
.catch(onMessage)
|
||||
}
|
||||
|
||||
function write() {
|
||||
const encoder = new TextEncoder()
|
||||
file
|
||||
.write(encoder.encode('Hello from Tauri :)'))
|
||||
.then(() => {
|
||||
onMessage(`wrote to file`)
|
||||
})
|
||||
.catch(onMessage)
|
||||
}
|
||||
|
||||
function stat() {
|
||||
file
|
||||
.stat()
|
||||
.then((stat) => {
|
||||
onMessage(`File stat ${JSON.stringify(stat)}`);
|
||||
onMessage(`File stat ${JSON.stringify(stat)}`)
|
||||
})
|
||||
.catch(onMessage);
|
||||
.catch(onMessage)
|
||||
}
|
||||
|
||||
function read() {
|
||||
const opts = {
|
||||
baseDir: getDir(),
|
||||
};
|
||||
baseDir
|
||||
}
|
||||
fs.stat(path, opts)
|
||||
.then((stat) => {
|
||||
const isFile = stat.isFile;
|
||||
const isFile = stat.isFile
|
||||
|
||||
const promise = isFile
|
||||
? fs.readFile(path, opts)
|
||||
: fs.readDir(path, opts);
|
||||
: fs.readDir(path, opts)
|
||||
promise
|
||||
.then(function (response) {
|
||||
if (isFile) {
|
||||
if (path.includes(".png") || path.includes(".jpg")) {
|
||||
if (path.includes('.png') || path.includes('.jpg')) {
|
||||
arrayBufferToBase64(
|
||||
new Uint8Array(response),
|
||||
function (base64) {
|
||||
const src = "data:image/png;base64," + base64;
|
||||
insecureRenderHtml('<img src="' + src + '"></img>');
|
||||
const src = 'data:image/png;base64,' + base64
|
||||
insecureRenderHtml('<img src="' + src + '"></img>')
|
||||
}
|
||||
);
|
||||
)
|
||||
} else {
|
||||
const value = String.fromCharCode.apply(null, response);
|
||||
const value = String.fromCharCode.apply(null, response)
|
||||
insecureRenderHtml(
|
||||
'<textarea id="file-response"></textarea><button id="file-save">Save</button>'
|
||||
);
|
||||
)
|
||||
setTimeout(() => {
|
||||
const fileInput = document.getElementById("file-response");
|
||||
fileInput.value = value;
|
||||
const fileInput = document.getElementById('file-response')
|
||||
fileInput.value = value
|
||||
document
|
||||
.getElementById("file-save")
|
||||
.addEventListener("click", function () {
|
||||
.getElementById('file-save')
|
||||
.addEventListener('click', function () {
|
||||
fs.writeTextFile(path, fileInput.value, {
|
||||
baseDir: getDir(),
|
||||
}).catch(onMessage);
|
||||
});
|
||||
});
|
||||
baseDir
|
||||
}).catch(onMessage)
|
||||
})
|
||||
})
|
||||
}
|
||||
} else {
|
||||
onMessage(response);
|
||||
onMessage(response)
|
||||
}
|
||||
})
|
||||
.catch(onMessage);
|
||||
.catch(onMessage)
|
||||
})
|
||||
.catch(onMessage);
|
||||
.catch(onMessage)
|
||||
}
|
||||
|
||||
function setSrc() {
|
||||
img.src = convertFileSrc(path);
|
||||
img.src = convertFileSrc(path)
|
||||
}
|
||||
|
||||
function watch() {
|
||||
unwatch();
|
||||
unwatch()
|
||||
if (watchPath) {
|
||||
onMessage(`Watching ${watchPath} for changes`);
|
||||
onMessage(`Watching ${watchPath} for changes`)
|
||||
let options = {
|
||||
recursive: watchRecursive,
|
||||
delayMs: parseInt(watchDebounceDelay),
|
||||
};
|
||||
delayMs: watchDebounceDelay
|
||||
}
|
||||
if (options.delayMs === 0) {
|
||||
fs.watchImmediate(watchPath, onMessage, options)
|
||||
.then((fn) => {
|
||||
unwatchFn = fn;
|
||||
unwatchPath = watchPath;
|
||||
unwatchFn = fn
|
||||
unwatchPath = watchPath
|
||||
})
|
||||
.catch(onMessage);
|
||||
.catch(onMessage)
|
||||
} else {
|
||||
fs.watch(watchPath, onMessage, options)
|
||||
.then((fn) => {
|
||||
unwatchFn = fn;
|
||||
unwatchPath = watchPath;
|
||||
unwatchFn = fn
|
||||
unwatchPath = watchPath
|
||||
})
|
||||
.catch(onMessage);
|
||||
.catch(onMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function unwatch() {
|
||||
if (unwatchFn) {
|
||||
onMessage(`Stopped watching ${unwatchPath} for changes`);
|
||||
unwatchFn();
|
||||
onMessage(`Stopped watching ${unwatchPath} for changes`)
|
||||
unwatchFn()
|
||||
}
|
||||
unwatchFn = undefined;
|
||||
unwatchPath = undefined;
|
||||
unwatchFn = undefined
|
||||
unwatchPath = undefined
|
||||
}
|
||||
|
||||
onDestroy(() => {
|
||||
if (file) {
|
||||
file.close();
|
||||
file.close()
|
||||
}
|
||||
if (unwatchFn) {
|
||||
unwatchFn();
|
||||
unwatchFn()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col">
|
||||
{#if isMobile}
|
||||
<div>
|
||||
On mobile, paths outside of App* paths require the use of dialogs
|
||||
regardless of Tauri's scope mechanism.
|
||||
</div>
|
||||
<br />
|
||||
{/if}
|
||||
<div class="flex gap-1">
|
||||
<select class="input" id="dir">
|
||||
<option value="">None</option>
|
||||
{#each DirOptions as dir}
|
||||
<option value={dir[1]}>{dir[0]}</option>
|
||||
<select class="input" bind:value={baseDir}>
|
||||
<option value={undefined} selected>None</option>
|
||||
{#each dirOptions as dir}
|
||||
<option value={fs.BaseDirectory[dir]}>{dir}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<input
|
||||
@@ -199,20 +219,21 @@
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<button class="btn" on:click={open}>Open</button>
|
||||
<button class="btn" on:click={read}>Read</button>
|
||||
<button class="btn" on:click={mkdir}>Mkdir</button>
|
||||
<button class="btn" on:click={remove}>Remove</button>
|
||||
<button class="btn" onclick={open}>Open</button>
|
||||
<button class="btn" onclick={read}>Read</button>
|
||||
<button class="btn" onclick={mkdir}>Mkdir</button>
|
||||
<button class="btn" onclick={remove}>Remove</button>
|
||||
<div class="flex flex-row">
|
||||
<button class="btn" on:click={rename}>Rename</button>
|
||||
<button class="btn" onclick={rename}>Rename</button>
|
||||
<input class="input" bind:value={renameTo} placeholder="To" />
|
||||
</div>
|
||||
<button class="btn" type="button" on:click={setSrc}>Use as img src</button>
|
||||
<button class="btn" type="button" onclick={setSrc}>Use as img src</button>
|
||||
</div>
|
||||
{#if file}
|
||||
<div>
|
||||
<button class="btn" on:click={truncate}>Truncate</button>
|
||||
<button class="btn" on:click={stat}>Stat</button>
|
||||
<button class="btn" onclick={write}>Write</button>
|
||||
<button class="btn" onclick={truncate}>Truncate</button>
|
||||
<button class="btn" onclick={stat}>Stat</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -241,8 +262,8 @@
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<button class="btn" on:click={watch}>Watch</button>
|
||||
<button class="btn" on:click={unwatch}>Unwatch</button>
|
||||
<button class="btn" onclick={watch}>Watch</button>
|
||||
<button class="btn" onclick={unwatch}>Unwatch</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
<script>
|
||||
import { sendNotification } from '@tauri-apps/plugin-notification'
|
||||
export let onMessage
|
||||
|
||||
let sound = ''
|
||||
|
||||
// send the notification directly
|
||||
// the backend is responsible for checking the permission
|
||||
function _sendNotification() {
|
||||
new Notification('Notification title', {
|
||||
body: 'This is the notification body'
|
||||
sendNotification({
|
||||
title: 'Notification title',
|
||||
body: 'This is the notification body',
|
||||
sound: sound || null
|
||||
})
|
||||
}
|
||||
|
||||
// alternatively, check the permission ourselves
|
||||
function sendNotification() {
|
||||
function triggerNotification() {
|
||||
if (Notification.permission === 'default') {
|
||||
Notification.requestPermission()
|
||||
.then(function (response) {
|
||||
@@ -29,6 +34,11 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<button class="btn" id="notification" on:click={sendNotification}>
|
||||
<input
|
||||
class="input grow"
|
||||
placeholder="Notification sound..."
|
||||
bind:value={sound}
|
||||
/>
|
||||
<button class="btn" id="notification" on:click={triggerNotification}>
|
||||
Send test notification
|
||||
</button>
|
||||
|
||||
@@ -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,71 +1,85 @@
|
||||
<script>
|
||||
import { LazyStore } from "@tauri-apps/plugin-store";
|
||||
import { onMount } from "svelte";
|
||||
import { appDataDir, resolve } from '@tauri-apps/api/path'
|
||||
import { LazyStore } from '@tauri-apps/plugin-store'
|
||||
import { onMount } from 'svelte'
|
||||
|
||||
export let onMessage;
|
||||
let { onMessage } = $props()
|
||||
|
||||
let key;
|
||||
let value;
|
||||
let key = $state()
|
||||
let value = $state()
|
||||
|
||||
let store = new LazyStore("cache.json");
|
||||
let cache = {};
|
||||
const storeName = 'cache.json'
|
||||
|
||||
let store = new LazyStore(storeName)
|
||||
let path = $state('')
|
||||
let cache = $state({})
|
||||
|
||||
async function refreshEntries() {
|
||||
try {
|
||||
const values = await store.entries();
|
||||
cache = {};
|
||||
const values = await store.entries()
|
||||
cache = {}
|
||||
for (const [key, value] of values) {
|
||||
cache[key] = value;
|
||||
cache[key] = value
|
||||
}
|
||||
} catch (error) {
|
||||
onMessage(error);
|
||||
onMessage(error)
|
||||
}
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
await refreshEntries();
|
||||
});
|
||||
path = await resolve(await appDataDir(), storeName)
|
||||
await refreshEntries()
|
||||
})
|
||||
|
||||
async function write(key, value) {
|
||||
try {
|
||||
if (value) {
|
||||
await store.set(key, value);
|
||||
await store.set(key, value)
|
||||
} else {
|
||||
await store.delete(key);
|
||||
await store.delete(key)
|
||||
}
|
||||
const v = await store.get(key);
|
||||
const v = await store.get(key)
|
||||
if (v === undefined) {
|
||||
delete cache[key];
|
||||
cache = cache;
|
||||
delete cache[key]
|
||||
cache = cache
|
||||
} else {
|
||||
cache[key] = v;
|
||||
cache[key] = v
|
||||
}
|
||||
} catch (error) {
|
||||
onMessage(error);
|
||||
onMessage(error)
|
||||
}
|
||||
}
|
||||
|
||||
async function reset() {
|
||||
try {
|
||||
await store.reset();
|
||||
await store.reset()
|
||||
} catch (error) {
|
||||
onMessage(error);
|
||||
onMessage(error)
|
||||
}
|
||||
await refreshEntries();
|
||||
await refreshEntries()
|
||||
}
|
||||
|
||||
async function reload() {
|
||||
try {
|
||||
await store.reload({ overrideDefaults: true })
|
||||
} catch (error) {
|
||||
onMessage(error)
|
||||
}
|
||||
await refreshEntries()
|
||||
}
|
||||
|
||||
async function close() {
|
||||
try {
|
||||
await store.close();
|
||||
onMessage("Store is now closed, any new operations will error out");
|
||||
await store.close()
|
||||
onMessage('Store is now closed, any new operations will error out')
|
||||
} catch (error) {
|
||||
onMessage(error);
|
||||
onMessage(error)
|
||||
}
|
||||
}
|
||||
|
||||
function reopen() {
|
||||
store = new LazyStore("cache.json");
|
||||
onMessage("We made a new `LazyStore` instance, operations will now work");
|
||||
store = new LazyStore(storeName)
|
||||
onMessage('We made a new `LazyStore` instance, operations will now work')
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -82,14 +96,17 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button class="btn" on:click={() => write(key, value)}>Write</button>
|
||||
<button class="btn" on:click={() => reset()}>Reset</button>
|
||||
<button class="btn" on:click={() => close()}>Close</button>
|
||||
<button class="btn" on:click={() => reopen()}>Re-open</button>
|
||||
<button class="btn" onclick={() => write(key, value)}>Write</button>
|
||||
<button class="btn" onclick={() => reset()}>Reset</button>
|
||||
<button class="btn" onclick={() => reload()}>Reload</button>
|
||||
<button class="btn" onclick={() => close()}>Close</button>
|
||||
<button class="btn" onclick={() => reopen()}>Re-open</button>
|
||||
</div>
|
||||
<div>Store at <code>{path}</code> on disk</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>Store Values</h2>
|
||||
{#each Object.entries(cache) as [k, v]}
|
||||
<div>{k} = {v}</div>
|
||||
{/each}
|
||||
|
||||
@@ -0,0 +1,417 @@
|
||||
<script>
|
||||
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'
|
||||
import { onMount } from 'svelte'
|
||||
|
||||
export let onMessage
|
||||
|
||||
let downloadUrl = 'https://httpbin.org/json'
|
||||
let downloadFolder = ''
|
||||
let downloadPath = ''
|
||||
let downloadProgress = null
|
||||
let downloadResult = null
|
||||
let isDownloading = false
|
||||
|
||||
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
|
||||
|
||||
onMount(async () => {
|
||||
try {
|
||||
const defaultDir = await appDataDir()
|
||||
if (!downloadFolder) {
|
||||
downloadFolder = defaultDir
|
||||
updateDownloadPath()
|
||||
}
|
||||
} catch (error) {
|
||||
onMessage({ error: `Failed to get default directory: ${error.toString()}` })
|
||||
}
|
||||
})
|
||||
|
||||
async function selectDownloadFolder() {
|
||||
try {
|
||||
const selected = await open({
|
||||
directory: true,
|
||||
multiple: false,
|
||||
defaultPath: downloadFolder || undefined
|
||||
})
|
||||
if (selected) {
|
||||
downloadFolder = selected
|
||||
updateDownloadPath()
|
||||
}
|
||||
} catch (error) {
|
||||
onMessage({ error: error.toString() })
|
||||
}
|
||||
}
|
||||
|
||||
function getFilenameFromUrl(url) {
|
||||
try {
|
||||
const urlObj = new URL(url)
|
||||
let pathname = urlObj.pathname
|
||||
|
||||
// Remove leading slash
|
||||
if (pathname.startsWith('/')) {
|
||||
pathname = pathname.substring(1)
|
||||
}
|
||||
|
||||
// If pathname is empty or ends with slash, use a default name
|
||||
if (!pathname || pathname.endsWith('/')) {
|
||||
return 'downloaded-file.json'
|
||||
}
|
||||
|
||||
// Extract filename from pathname
|
||||
const segments = pathname.split('/')
|
||||
let filename = segments[segments.length - 1]
|
||||
|
||||
// If no extension, try to infer from URL or use default
|
||||
if (!filename.includes('.')) {
|
||||
// Check if URL suggests a file type
|
||||
if (url.includes('json') || urlObj.searchParams.has('format') && urlObj.searchParams.get('format') === 'json') {
|
||||
filename += '.json'
|
||||
} else if (url.includes('xml')) {
|
||||
filename += '.xml'
|
||||
} else if (url.includes('csv')) {
|
||||
filename += '.csv'
|
||||
} else {
|
||||
filename += '.txt'
|
||||
}
|
||||
}
|
||||
|
||||
return filename
|
||||
} catch (error) {
|
||||
return 'downloaded-file.json'
|
||||
}
|
||||
}
|
||||
|
||||
function updateDownloadPath() {
|
||||
if (downloadFolder && downloadUrl) {
|
||||
const filename = getFilenameFromUrl(downloadUrl)
|
||||
downloadPath = `${downloadFolder}/${filename}`
|
||||
} else {
|
||||
downloadPath = ''
|
||||
}
|
||||
}
|
||||
|
||||
// Update download path when URL changes
|
||||
$: if (downloadUrl) {
|
||||
updateDownloadPath()
|
||||
}
|
||||
|
||||
async function selectUploadFile() {
|
||||
try {
|
||||
const selected = await open({
|
||||
directory: false,
|
||||
multiple: false
|
||||
})
|
||||
if (selected) {
|
||||
uploadFilePath = selected
|
||||
}
|
||||
} catch (error) {
|
||||
onMessage({ error: error.toString() })
|
||||
}
|
||||
}
|
||||
|
||||
async function startDownload() {
|
||||
if (!downloadUrl || !downloadFolder) {
|
||||
onMessage({ error: 'Please provide both URL and download folder' })
|
||||
return
|
||||
}
|
||||
|
||||
// Ensure download path is updated
|
||||
updateDownloadPath()
|
||||
|
||||
if (!downloadPath) {
|
||||
onMessage({ error: 'Could not generate download path' })
|
||||
return
|
||||
}
|
||||
|
||||
isDownloading = true
|
||||
downloadProgress = null
|
||||
downloadResult = null
|
||||
|
||||
try {
|
||||
await download(
|
||||
downloadUrl,
|
||||
downloadPath,
|
||||
(progress) => {
|
||||
downloadProgress = {
|
||||
progress: progress.progress,
|
||||
progressTotal: progress.progressTotal,
|
||||
total: progress.total,
|
||||
transferSpeed: progress.transferSpeed,
|
||||
percentage: progress.total > 0 ? Math.round((progress.progressTotal / progress.total) * 100) : 0
|
||||
}
|
||||
},
|
||||
new Map([
|
||||
['User-Agent', 'Tauri Upload Plugin Demo']
|
||||
])
|
||||
)
|
||||
|
||||
downloadResult = {
|
||||
success: true,
|
||||
message: `File downloaded successfully to: ${downloadPath}`,
|
||||
finalProgress: downloadProgress
|
||||
}
|
||||
|
||||
onMessage({
|
||||
type: 'download',
|
||||
result: downloadResult
|
||||
})
|
||||
} catch (error) {
|
||||
downloadResult = {
|
||||
success: false,
|
||||
error: error.toString()
|
||||
}
|
||||
onMessage({ error: error.toString() })
|
||||
} finally {
|
||||
isDownloading = false
|
||||
}
|
||||
}
|
||||
|
||||
async function startUpload() {
|
||||
if (!uploadUrl || !uploadFilePath) {
|
||||
onMessage({ error: 'Please provide both URL and file path' })
|
||||
return
|
||||
}
|
||||
|
||||
isUploading = true
|
||||
uploadProgress = null
|
||||
uploadResult = null
|
||||
|
||||
try {
|
||||
const response = await upload(
|
||||
uploadUrl,
|
||||
uploadFilePath,
|
||||
(progress) => {
|
||||
uploadProgress = {
|
||||
progress: progress.progress,
|
||||
progressTotal: progress.progressTotal,
|
||||
total: progress.total,
|
||||
transferSpeed: progress.transferSpeed,
|
||||
percentage: progress.total > 0 ? Math.round((progress.progressTotal / progress.total) * 100) : 0
|
||||
}
|
||||
},
|
||||
new Map([
|
||||
['User-Agent', 'Tauri Upload Plugin Demo']
|
||||
]),
|
||||
uploadMethod
|
||||
)
|
||||
|
||||
uploadResult = {
|
||||
success: true,
|
||||
response: response,
|
||||
finalProgress: uploadProgress
|
||||
}
|
||||
|
||||
onMessage({
|
||||
type: 'upload',
|
||||
result: uploadResult
|
||||
})
|
||||
} catch (error) {
|
||||
uploadResult = {
|
||||
success: false,
|
||||
error: error.toString()
|
||||
}
|
||||
onMessage({ error: error.toString() })
|
||||
} finally {
|
||||
isUploading = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="space-y-6">
|
||||
<div class="bg-gray-50 p-4 rounded-lg">
|
||||
<h3 class="text-lg font-semibold mb-4 text-gray-800">File Download</h3>
|
||||
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<label for="download-url" class="block text-sm font-medium text-gray-700 mb-1">Download URL:</label>
|
||||
<input
|
||||
id="download-url"
|
||||
bind:value={downloadUrl}
|
||||
type="url"
|
||||
placeholder="https://example.com/file.json"
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
disabled={isDownloading}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="download-folder" class="block text-sm font-medium text-gray-700 mb-1">Download folder:</label>
|
||||
<div class="flex gap-2">
|
||||
<input
|
||||
id="download-folder"
|
||||
bind:value={downloadFolder}
|
||||
type="text"
|
||||
placeholder="Select download folder..."
|
||||
class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
disabled={isDownloading}
|
||||
/>
|
||||
<button
|
||||
on:click={selectDownloadFolder}
|
||||
class="px-4 py-2 bg-gray-500 text-white rounded-md hover:bg-gray-600 disabled:opacity-50"
|
||||
disabled={isDownloading}
|
||||
>
|
||||
Browse
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if downloadPath}
|
||||
<div class="bg-blue-50 border border-blue-200 p-3 rounded-md">
|
||||
<div class="text-sm text-blue-800">
|
||||
<strong>File will be saved as:</strong>
|
||||
<div class="font-mono text-xs mt-1 break-all">{downloadPath}</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<button
|
||||
on:click={startDownload}
|
||||
class="w-full px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
disabled={isDownloading || !downloadUrl || !downloadFolder}
|
||||
>
|
||||
{isDownloading ? 'Downloading...' : 'Download File'}
|
||||
</button>
|
||||
|
||||
{#if downloadProgress}
|
||||
<div class="bg-white p-3 rounded border">
|
||||
<div class="flex justify-between text-sm text-gray-600 mb-1">
|
||||
<span>Progress: {downloadProgress.percentage}%</span>
|
||||
<span>Speed: {Math.round(downloadProgress.transferSpeed / 1024)} KB/s</span>
|
||||
</div>
|
||||
<div class="w-full bg-gray-200 rounded-full h-2">
|
||||
<div
|
||||
class="bg-blue-500 h-2 rounded-full transition-all duration-300"
|
||||
style="width: {downloadProgress.percentage}%"
|
||||
></div>
|
||||
</div>
|
||||
<div class="text-xs text-gray-500 mt-1">
|
||||
{Math.round(downloadProgress.progressTotal / 1024)} KB / {Math.round(downloadProgress.total / 1024)} KB
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if downloadResult}
|
||||
<div class="bg-white p-3 rounded border">
|
||||
<JsonView json={downloadResult} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-50 p-4 rounded-lg">
|
||||
<h3 class="text-lg font-semibold mb-4 text-gray-800">File Upload</h3>
|
||||
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<label for="upload-url" class="block text-sm font-medium text-gray-700 mb-1">Upload URL:</label>
|
||||
<input
|
||||
id="upload-url"
|
||||
bind:value={uploadUrl}
|
||||
type="url"
|
||||
placeholder="https://httpbin.org/post"
|
||||
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}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="upload-file" class="block text-sm font-medium text-gray-700 mb-1">File to upload:</label>
|
||||
<div class="flex gap-2">
|
||||
<input
|
||||
id="upload-file"
|
||||
bind:value={uploadFilePath}
|
||||
type="text"
|
||||
placeholder="Select file to upload..."
|
||||
class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500"
|
||||
disabled={isUploading}
|
||||
/>
|
||||
<button
|
||||
on:click={selectUploadFile}
|
||||
class="px-4 py-2 bg-gray-500 text-white rounded-md hover:bg-gray-600 disabled:opacity-50"
|
||||
disabled={isUploading}
|
||||
>
|
||||
Browse
|
||||
</button>
|
||||
</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 (${uploadMethod})...` : `Upload File (${uploadMethod})`}
|
||||
</button>
|
||||
|
||||
{#if uploadProgress}
|
||||
<div class="bg-white p-3 rounded border">
|
||||
<div class="flex justify-between text-sm text-gray-600 mb-1">
|
||||
<span>Progress: {uploadProgress.percentage}%</span>
|
||||
<span>Speed: {Math.round(uploadProgress.transferSpeed / 1024)} KB/s</span>
|
||||
</div>
|
||||
<div class="w-full bg-gray-200 rounded-full h-2">
|
||||
<div
|
||||
class="bg-green-500 h-2 rounded-full transition-all duration-300"
|
||||
style="width: {uploadProgress.percentage}%"
|
||||
></div>
|
||||
</div>
|
||||
<div class="text-xs text-gray-500 mt-1">
|
||||
{Math.round(uploadProgress.progressTotal / 1024)} KB / {Math.round(uploadProgress.total / 1024)} KB
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if uploadResult}
|
||||
<div class="bg-white p-3 rounded border">
|
||||
<JsonView json={uploadResult} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
+11
-10
@@ -11,20 +11,21 @@
|
||||
"example:api:dev": "pnpm run --filter \"api\" tauri dev"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "9.29.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.3",
|
||||
"@rollup/plugin-typescript": "12.3.0",
|
||||
"covector": "^0.12.4",
|
||||
"eslint": "9.29.0",
|
||||
"eslint-config-prettier": "10.1.5",
|
||||
"eslint": "9.39.1",
|
||||
"eslint-config-prettier": "10.1.8",
|
||||
"eslint-plugin-security": "3.0.1",
|
||||
"prettier": "3.6.1",
|
||||
"rollup": "4.44.0",
|
||||
"prettier": "3.6.2",
|
||||
"rollup": "4.53.2",
|
||||
"tslib": "2.8.1",
|
||||
"typescript": "5.8.3",
|
||||
"typescript-eslint": "8.35.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 = "" }
|
||||
|
||||
@@ -33,21 +33,12 @@ tauri-plugin-autostart = { git = "https://github.com/tauri-apps/plugins-workspac
|
||||
|
||||
You can install the JavaScript Guest bindings using your preferred JavaScript package manager:
|
||||
|
||||
> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use.
|
||||
|
||||
```sh
|
||||
pnpm add @tauri-apps/plugin-autostart
|
||||
# or
|
||||
npm add @tauri-apps/plugin-autostart
|
||||
# or
|
||||
yarn add @tauri-apps/plugin-autostart
|
||||
|
||||
# alternatively with Git:
|
||||
pnpm add https://github.com/tauri-apps/tauri-plugin-autostart#v2
|
||||
# or
|
||||
npm add https://github.com/tauri-apps/tauri-plugin-autostart#v2
|
||||
# or
|
||||
yarn add https://github.com/tauri-apps/tauri-plugin-autostart#v2
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -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"
|
||||
@@ -24,6 +24,6 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2.6.0"
|
||||
"@tauri-apps/api": "^2.8.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,18 @@
|
||||
# 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+
|
||||
|
||||
## \[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-barcode-scanner"
|
||||
version = "2.3.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]
|
||||
|
||||
@@ -33,21 +33,12 @@ tauri-plugin-barcode-scanner = { git = "https://github.com/tauri-apps/plugins-wo
|
||||
|
||||
You can install the JavaScript Guest bindings using your preferred JavaScript package manager:
|
||||
|
||||
> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use.
|
||||
|
||||
```sh
|
||||
pnpm add @tauri-apps/plugin-barcode-scanner
|
||||
# or
|
||||
npm add @tauri-apps/plugin-barcode-scanner
|
||||
# or
|
||||
yarn add @tauri-apps/plugin-barcode-scanner
|
||||
|
||||
# alternatively with Git:
|
||||
pnpm add https://github.com/tauri-apps/tauri-plugin-barcode-scanner#v2
|
||||
# or
|
||||
npm add https://github.com/tauri-apps/tauri-plugin-barcode-scanner#v2
|
||||
# or
|
||||
yarn add https://github.com/tauri-apps/tauri-plugin-barcode-scanner#v2
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -1 +1 @@
|
||||
if("__TAURI__"in window){var __TAURI_PLUGIN_BARCODE_SCANNER__=function(n){"use strict";async function e(n,e={},r){return window.__TAURI_INTERNALS__.invoke(n,e,r)}var r;return"function"==typeof SuppressedError&&SuppressedError,n.Format=void 0,(r=n.Format||(n.Format={})).QRCode="QR_CODE",r.UPC_A="UPC_A",r.UPC_E="UPC_E",r.EAN8="EAN_8",r.EAN13="EAN_13",r.Code39="CODE_39",r.Code93="CODE_93",r.Code128="CODE_128",r.Codabar="CODABAR",r.ITF="ITF",r.Aztec="AZTEC",r.DataMatrix="DATA_MATRIX",r.PDF417="PDF_417",n.cancel=async function(){await e("plugin:barcode-scanner|cancel")},n.checkPermissions=async function(){return await async function(n){return e(`plugin:${n}|check_permissions`)}("barcode-scanner").then((n=>n.camera))},n.openAppSettings=async function(){await e("plugin:barcode-scanner|open_app_settings")},n.requestPermissions=async function(){return await async function(n){return e(`plugin:${n}|request_permissions`)}("barcode-scanner").then((n=>n.camera))},n.scan=async function(n){return await e("plugin:barcode-scanner|scan",{...n})},n}({});Object.defineProperty(window.__TAURI__,"barcodeScanner",{value:__TAURI_PLUGIN_BARCODE_SCANNER__})}
|
||||
if("__TAURI__"in window){var __TAURI_PLUGIN_BARCODE_SCANNER__=function(n){"use strict";async function a(n,a={},e){return window.__TAURI_INTERNALS__.invoke(n,a,e)}var e;return"function"==typeof SuppressedError&&SuppressedError,n.Format=void 0,(e=n.Format||(n.Format={})).QRCode="QR_CODE",e.UPC_A="UPC_A",e.UPC_E="UPC_E",e.EAN8="EAN_8",e.EAN13="EAN_13",e.Code39="CODE_39",e.Code93="CODE_93",e.Code128="CODE_128",e.Codabar="CODABAR",e.ITF="ITF",e.Aztec="AZTEC",e.DataMatrix="DATA_MATRIX",e.PDF417="PDF_417",e.GS1DataBar="GS1_DATA_BAR",e.GS1DataBarLimited="GS1_DATA_BAR_LIMITED",e.GS1DataBarExpanded="GS1_DATA_BAR_EXPANDED",n.cancel=async function(){await a("plugin:barcode-scanner|cancel")},n.checkPermissions=async function(){return await async function(n){return a(`plugin:${n}|check_permissions`)}("barcode-scanner").then((n=>n.camera))},n.openAppSettings=async function(){await a("plugin:barcode-scanner|open_app_settings")},n.requestPermissions=async function(){return await async function(n){return a(`plugin:${n}|request_permissions`)}("barcode-scanner").then((n=>n.camera))},n.scan=async function(n){return await a("plugin:barcode-scanner|scan",{...n})},n}({});Object.defineProperty(window.__TAURI__,"barcodeScanner",{value:__TAURI_PLUGIN_BARCODE_SCANNER__})}
|
||||
|
||||
@@ -12,6 +12,9 @@ export type { PermissionState } from '@tauri-apps/api/core'
|
||||
|
||||
export enum Format {
|
||||
QRCode = 'QR_CODE',
|
||||
/**
|
||||
* Not supported on iOS.
|
||||
*/
|
||||
UPC_A = 'UPC_A',
|
||||
UPC_E = 'UPC_E',
|
||||
EAN8 = 'EAN_8',
|
||||
@@ -19,11 +22,26 @@ export enum Format {
|
||||
Code39 = 'CODE_39',
|
||||
Code93 = 'CODE_93',
|
||||
Code128 = 'CODE_128',
|
||||
/**
|
||||
* Not supported on iOS.
|
||||
*/
|
||||
Codabar = 'CODABAR',
|
||||
ITF = 'ITF',
|
||||
Aztec = 'AZTEC',
|
||||
DataMatrix = 'DATA_MATRIX',
|
||||
PDF417 = 'PDF_417'
|
||||
PDF417 = 'PDF_417',
|
||||
/**
|
||||
* Not supported on Android. Requires iOS 15.4+
|
||||
*/
|
||||
GS1DataBar = 'GS1_DATA_BAR',
|
||||
/**
|
||||
* Not supported on Android. Requires iOS 15.4+
|
||||
*/
|
||||
GS1DataBarLimited = 'GS1_DATA_BAR_LIMITED',
|
||||
/**
|
||||
* Not supported on Android. Requires iOS 15.4+
|
||||
*/
|
||||
GS1DataBarExpanded = 'GS1_DATA_BAR_EXPANDED'
|
||||
}
|
||||
|
||||
export interface ScanOptions {
|
||||
|
||||
@@ -27,8 +27,11 @@ enum SupportedFormat: String, CaseIterable, Decodable {
|
||||
case DATA_MATRIX
|
||||
case PDF_417
|
||||
case QR_CODE
|
||||
case GS1_DATA_BAR
|
||||
case GS1_DATA_BAR_LIMITED
|
||||
case GS1_DATA_BAR_EXPANDED
|
||||
|
||||
var value: AVMetadataObject.ObjectType {
|
||||
var value: AVMetadataObject.ObjectType? {
|
||||
switch self {
|
||||
case .UPC_E: return AVMetadataObject.ObjectType.upce
|
||||
case .EAN_8: return AVMetadataObject.ObjectType.ean8
|
||||
@@ -41,6 +44,24 @@ enum SupportedFormat: String, CaseIterable, Decodable {
|
||||
case .DATA_MATRIX: return AVMetadataObject.ObjectType.dataMatrix
|
||||
case .PDF_417: return AVMetadataObject.ObjectType.pdf417
|
||||
case .QR_CODE: return AVMetadataObject.ObjectType.qr
|
||||
case .GS1_DATA_BAR:
|
||||
if #available(iOS 15.4, *) {
|
||||
return AVMetadataObject.ObjectType.gs1DataBar
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case .GS1_DATA_BAR_LIMITED:
|
||||
if #available(iOS 15.4, *) {
|
||||
return AVMetadataObject.ObjectType.gs1DataBarLimited
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case .GS1_DATA_BAR_EXPANDED:
|
||||
if #available(iOS 15.4, *) {
|
||||
return AVMetadataObject.ObjectType.gs1DataBarExpanded
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,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
|
||||
@@ -242,13 +264,20 @@ class BarcodeScannerPlugin: Plugin, AVCaptureMetadataOutputObjectsDelegate {
|
||||
scanFormats = [AVMetadataObject.ObjectType]()
|
||||
|
||||
(args.formats ?? []).forEach { format in
|
||||
scanFormats.append(format.value)
|
||||
if let formatValue = format.value {
|
||||
scanFormats.append(formatValue)
|
||||
} else {
|
||||
invoke.reject("Unsupported barcode format on this iOS version: \(format)")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if scanFormats.count == 0 {
|
||||
for supportedFormat in SupportedFormat.allCases {
|
||||
scanFormats.append(supportedFormat.value)
|
||||
}
|
||||
if scanFormats.isEmpty {
|
||||
for supportedFormat in SupportedFormat.allCases {
|
||||
if let formatValue = supportedFormat.value {
|
||||
scanFormats.append(formatValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.metaOutput!.metadataObjectTypes = self.scanFormats
|
||||
|
||||
@@ -52,6 +52,15 @@ func discoverCaptureDevices() -> [AVCaptureDevice] {
|
||||
}
|
||||
|
||||
func formatStringFromMetadata(_ type: AVMetadataObject.ObjectType) -> String {
|
||||
if #available(iOS 15.4, *) {
|
||||
if type == .gs1DataBar {
|
||||
return "GS1_DATA_BAR"
|
||||
} else if type == .gs1DataBarLimited {
|
||||
return "GS1_DATA_BAR_LIMITED"
|
||||
} else if type == .gs1DataBarExpanded {
|
||||
return "GS1_DATA_BAR_EXPANDED"
|
||||
}
|
||||
}
|
||||
switch type {
|
||||
case AVMetadataObject.ObjectType.upce:
|
||||
return "UPC_E"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@tauri-apps/plugin-barcode-scanner",
|
||||
"version": "2.3.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": [
|
||||
@@ -25,6 +25,6 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2.6.0"
|
||||
"@tauri-apps/api": "^2.8.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -33,8 +33,6 @@ tauri-plugin-biometric = { git = "https://github.com/tauri-apps/plugins-workspac
|
||||
|
||||
You can install the JavaScript Guest bindings using your preferred JavaScript package manager:
|
||||
|
||||
> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use.
|
||||
|
||||
<!-- Add the branch for installations using git! -->
|
||||
|
||||
```sh
|
||||
@@ -43,13 +41,6 @@ pnpm add @tauri-apps/plugin-biometric
|
||||
npm add @tauri-apps/plugin-biometric
|
||||
# or
|
||||
yarn add @tauri-apps/plugin-biometric
|
||||
|
||||
# alternatively with Git:
|
||||
pnpm add https://github.com/tauri-apps/tauri-plugin-biometric#v2
|
||||
# or
|
||||
npm add https://github.com/tauri-apps/tauri-plugin-biometric#v2
|
||||
# or
|
||||
yarn add https://github.com/tauri-apps/tauri-plugin-biometric#v2
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -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"
|
||||
@@ -25,6 +25,6 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2.6.0"
|
||||
"@tauri-apps/api": "^2.8.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = "" }
|
||||
|
||||
@@ -34,21 +34,12 @@ tauri-plugin-cli = { git = "https://github.com/tauri-apps/plugins-workspace", br
|
||||
|
||||
You can install the JavaScript Guest bindings using your preferred JavaScript package manager:
|
||||
|
||||
> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use.
|
||||
|
||||
```sh
|
||||
pnpm add @tauri-apps/plugin-cli
|
||||
# or
|
||||
npm add @tauri-apps/plugin-cli
|
||||
# or
|
||||
yarn add @tauri-apps/plugin-cli
|
||||
|
||||
# alternatively with Git:
|
||||
pnpm add https://github.com/tauri-apps/tauri-plugin-cli#v2
|
||||
# or
|
||||
npm add https://github.com/tauri-apps/tauri-plugin-cli#v2
|
||||
# or
|
||||
yarn add https://github.com/tauri-apps/tauri-plugin-cli#v2
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -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"
|
||||
@@ -24,6 +24,6 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2.6.0"
|
||||
"@tauri-apps/api": "^2.8.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -33,21 +33,12 @@ tauri-plugin-clipboard-manager = { git = "https://github.com/tauri-apps/plugins-
|
||||
|
||||
You can install the JavaScript Guest bindings using your preferred JavaScript package manager:
|
||||
|
||||
> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use.
|
||||
|
||||
```sh
|
||||
pnpm add @tauri-apps/plugin-clipboard-manager
|
||||
# or
|
||||
npm add @tauri-apps/plugin-clipboard-manager
|
||||
# or
|
||||
yarn add @tauri-apps/plugin-clipboard-manager
|
||||
|
||||
# alternatively with Git:
|
||||
pnpm add https://github.com/tauri-apps/tauri-plugin-clipboard-manager#v2
|
||||
# or
|
||||
npm add https://github.com/tauri-apps/tauri-plugin-clipboard-manager#v2
|
||||
# or
|
||||
yarn add https://github.com/tauri-apps/tauri-plugin-clipboard-manager#v2
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -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"
|
||||
@@ -24,6 +24,6 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2.6.0"
|
||||
"@tauri-apps/api": "^2.8.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,27 @@
|
||||
# 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.
|
||||
|
||||
## \[2.4.1]
|
||||
|
||||
- [`d4f8299b`](https://github.com/tauri-apps/plugins-workspace/commit/d4f8299b12f107718c70692840a63768d65baaf9) ([#2844](https://github.com/tauri-apps/plugins-workspace/pull/2844) by [@yobson1](https://github.com/tauri-apps/plugins-workspace/../../yobson1)) Fix deep link protocol handler not set as default on linux
|
||||
Fix duplicate protocols added to MimeType section in .desktop files on linux
|
||||
|
||||
## \[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-deep-link"
|
||||
version = "2.4.0"
|
||||
version = "2.4.5"
|
||||
description = "Set your Tauri application as the default handler for an URL"
|
||||
authors = { workspace = true }
|
||||
license = { workspace = true }
|
||||
@@ -10,16 +10,14 @@ 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]
|
||||
windows = { level = "full", notes = "" }
|
||||
linux = { level = "full", notes = "" }
|
||||
macos = { level = "partial", notes = "Runtime deep link registration is not supported" }
|
||||
android = { level = "partial", notes = "Runtime deep link registration is not supported" }
|
||||
ios = { level = "partial", notes = "Runtime deep link registration is not supported" }
|
||||
macos = { level = "partial", notes = "Deep links must be registered in config. Dynamic registration at runtime is not supported." }
|
||||
android = { level = "partial", notes = "Deep links must be registered in config. Dynamic registration at runtime is not supported." }
|
||||
ios = { level = "partial", notes = "Deep links must be registered in config. Dynamic registration at runtime is not supported." }
|
||||
|
||||
[build-dependencies]
|
||||
serde = { workspace = true }
|
||||
@@ -27,6 +25,9 @@ serde_json = { workspace = true }
|
||||
tauri-utils = { workspace = true }
|
||||
tauri-plugin = { workspace = true, features = ["build"] }
|
||||
|
||||
[target."cfg(target_os = \"macos\")".build-dependencies]
|
||||
plist = "1"
|
||||
|
||||
[dependencies]
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
@@ -33,21 +33,12 @@ tauri-plugin-deep-link = { git = "https://github.com/tauri-apps/plugins-workspac
|
||||
|
||||
You can install the JavaScript Guest bindings using your preferred JavaScript package manager:
|
||||
|
||||
> Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use.
|
||||
|
||||
```sh
|
||||
pnpm add @tauri-apps/plugin-deep-link
|
||||
# or
|
||||
npm add @tauri-apps/plugin-deep-link
|
||||
# or
|
||||
yarn add @tauri-apps/plugin-deep-link
|
||||
|
||||
# alternatively with Git:
|
||||
pnpm add https://github.com/tauri-apps/tauri-plugin-deep-link#v2
|
||||
# or
|
||||
npm add https://github.com/tauri-apps/tauri-plugin-deep-link#v2
|
||||
# or
|
||||
yarn add https://github.com/tauri-apps/tauri-plugin-deep-link#v2
|
||||
```
|
||||
|
||||
## Setting up
|
||||
|
||||
@@ -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")
|
||||
|
||||
+119
-26
@@ -10,50 +10,64 @@ const COMMANDS: &[&str] = &["get_current", "register", "unregister", "is_registe
|
||||
|
||||
// TODO: Consider using activity-alias in case users may have multiple activities in their app.
|
||||
fn intent_filter(domain: &AssociatedDomain) -> String {
|
||||
let host = domain
|
||||
.host
|
||||
.as_ref()
|
||||
.map(|h| format!(r#"<data android:host="{h}" />"#))
|
||||
.unwrap_or_default();
|
||||
|
||||
let auto_verify = if domain.is_app_link() {
|
||||
r#"android:autoVerify="true" "#.to_string()
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
format!(
|
||||
r#"<intent-filter android:autoVerify="true">
|
||||
r#"<intent-filter {auto_verify}>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
{}
|
||||
<data android:host="{}" />
|
||||
{}
|
||||
{}
|
||||
{}
|
||||
{}
|
||||
{schemes}
|
||||
{host}
|
||||
{domains}
|
||||
{path_patterns}
|
||||
{path_prefixes}
|
||||
{path_suffixes}
|
||||
</intent-filter>"#,
|
||||
domain
|
||||
schemes = domain
|
||||
.scheme
|
||||
.iter()
|
||||
.map(|scheme| format!(r#"<data android:scheme="{scheme}" />"#))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n "),
|
||||
domain.host,
|
||||
domain
|
||||
host = host,
|
||||
domains = domain
|
||||
.path
|
||||
.iter()
|
||||
.map(|path| format!(r#"<data android:path="{path}" />"#))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n "),
|
||||
domain
|
||||
path_patterns = domain
|
||||
.path_pattern
|
||||
.iter()
|
||||
.map(|pattern| format!(r#"<data android:pathPattern="{pattern}" />"#))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n "),
|
||||
domain
|
||||
path_prefixes = domain
|
||||
.path_prefix
|
||||
.iter()
|
||||
.map(|prefix| format!(r#"<data android:pathPrefix="{prefix}" />"#))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n "),
|
||||
domain
|
||||
path_suffixes = domain
|
||||
.path_suffix
|
||||
.iter()
|
||||
.map(|suffix| format!(r#"<data android:pathSuffix="{suffix}" />"#))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n "),
|
||||
)
|
||||
.trim()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
@@ -68,6 +82,16 @@ fn main() {
|
||||
}
|
||||
|
||||
if let Some(config) = tauri_plugin::plugin_config::<Config>("deep-link") {
|
||||
let errors: Vec<String> = config
|
||||
.mobile
|
||||
.iter()
|
||||
.filter_map(|d| d.validate().err())
|
||||
.collect();
|
||||
|
||||
if !errors.is_empty() {
|
||||
panic!("Deep link config validation failed:\n{}", errors.join("\n"));
|
||||
}
|
||||
|
||||
tauri_plugin::mobile::update_android_manifest(
|
||||
"DEEP LINK PLUGIN",
|
||||
"activity",
|
||||
@@ -80,20 +104,89 @@ fn main() {
|
||||
)
|
||||
.expect("failed to rewrite AndroidManifest.xml");
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
{
|
||||
tauri_plugin::mobile::update_entitlements(|entitlements| {
|
||||
entitlements.insert(
|
||||
"com.apple.developer.associated-domains".into(),
|
||||
config
|
||||
.mobile
|
||||
.into_iter()
|
||||
.map(|d| format!("applinks:{}", d.host).into())
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
);
|
||||
})
|
||||
.expect("failed to update entitlements");
|
||||
// we need to ensure that the entitlements are only
|
||||
// generated for explicit app links and not
|
||||
// other deep links because then they
|
||||
// are just going to complain and not be built or signed
|
||||
let has_app_links = config.mobile.iter().any(|d| d.is_app_link());
|
||||
|
||||
if !has_app_links {
|
||||
tauri_plugin::mobile::update_entitlements(|entitlements| {
|
||||
entitlements.remove("com.apple.developer.associated-domains");
|
||||
})
|
||||
.expect("failed to update entitlements");
|
||||
} else {
|
||||
tauri_plugin::mobile::update_entitlements(|entitlements| {
|
||||
entitlements.insert(
|
||||
"com.apple.developer.associated-domains".into(),
|
||||
config
|
||||
.mobile
|
||||
.iter()
|
||||
.filter(|d| d.is_app_link())
|
||||
.filter_map(|d| d.host.as_ref())
|
||||
.map(|host| format!("applinks:{}", host).into())
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
);
|
||||
})
|
||||
.expect("failed to update entitlements");
|
||||
}
|
||||
|
||||
let deep_link_domains = config
|
||||
.mobile
|
||||
.iter()
|
||||
.filter_map(|domain| {
|
||||
if domain.is_app_link() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(domain)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if deep_link_domains.is_empty() {
|
||||
tauri_plugin::mobile::update_info_plist(|info_plist| {
|
||||
info_plist.remove("CFBundleURLTypes");
|
||||
})
|
||||
.expect("failed to update Info.plist");
|
||||
} else {
|
||||
tauri_plugin::mobile::update_info_plist(|info_plist| {
|
||||
info_plist.insert(
|
||||
"CFBundleURLTypes".into(),
|
||||
deep_link_domains
|
||||
.iter()
|
||||
.map(|domain| {
|
||||
let schemes = domain
|
||||
.scheme
|
||||
.iter()
|
||||
.filter(|scheme| {
|
||||
scheme.as_str() != "https" && scheme.as_str() != "http"
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut dict = plist::Dictionary::new();
|
||||
dict.insert(
|
||||
"CFBundleURLSchemes".into(),
|
||||
schemes
|
||||
.iter()
|
||||
.map(|s| s.to_string().into())
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
);
|
||||
dict.insert(
|
||||
"CFBundleURLName".into(),
|
||||
format!("{}", domain.scheme[0]).into(),
|
||||
);
|
||||
plist::Value::Dictionary(dict)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
);
|
||||
})
|
||||
.expect("failed to update Info.plist");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# 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
|
||||
|
||||
- Upgraded to `deep-link-js@2.4.2`
|
||||
|
||||
## \[2.2.4]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `deep-link-js@2.4.1`
|
||||
|
||||
## \[2.2.3]
|
||||
|
||||
### Dependencies
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "deep-link-example",
|
||||
"private": true,
|
||||
"version": "2.2.3",
|
||||
"version": "2.2.8",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
@@ -10,12 +10,12 @@
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "2.6.0",
|
||||
"@tauri-apps/plugin-deep-link": "2.4.0"
|
||||
"@tauri-apps/api": "2.9.0",
|
||||
"@tauri-apps/plugin-deep-link": "2.4.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "2.6.0",
|
||||
"@tauri-apps/cli": "2.9.4",
|
||||
"typescript": "^5.7.3",
|
||||
"vite": "^6.2.6"
|
||||
"vite": "^7.0.7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,13 +14,13 @@ val tauriProperties = Properties().apply {
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk = 34
|
||||
compileSdk = 36
|
||||
namespace = "com.tauri.deep_link_example"
|
||||
defaultConfig {
|
||||
manifestPlaceholders["usesCleartextTraffic"] = "false"
|
||||
applicationId = "com.tauri.deep_link_example"
|
||||
minSdk = 24
|
||||
targetSdk = 34
|
||||
targetSdk = 36
|
||||
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
|
||||
versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
|
||||
}
|
||||
@@ -58,9 +58,10 @@ rust {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("androidx.webkit:webkit:1.6.1")
|
||||
implementation("androidx.appcompat:appcompat:1.6.1")
|
||||
implementation("com.google.android.material:material:1.8.0")
|
||||
implementation("androidx.webkit:webkit:1.14.0")
|
||||
implementation("androidx.appcompat:appcompat:1.7.1")
|
||||
implementation("androidx.activity:activity-ktx:1.10.1")
|
||||
implementation("com.google.android.material:material:1.12.0")
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
androidTestImplementation("androidx.test.ext:junit:1.1.4")
|
||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0")
|
||||
|
||||
+21
-4
@@ -23,23 +23,40 @@
|
||||
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
||||
</intent-filter>
|
||||
<!-- DEEP LINK PLUGIN. AUTO-GENERATED. DO NOT REMOVE. -->
|
||||
<intent-filter android:autoVerify="true">
|
||||
<intent-filter android:autoVerify="true" >
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="http" />
|
||||
<data android:scheme="https" />
|
||||
<data android:scheme="http" />
|
||||
<data android:host="fabianlars.de" />
|
||||
|
||||
|
||||
<data android:pathPrefix="/intent" />
|
||||
|
||||
</intent-filter>
|
||||
<intent-filter android:autoVerify="true">
|
||||
<intent-filter android:autoVerify="true" >
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="http" />
|
||||
<data android:scheme="https" />
|
||||
<data android:scheme="http" />
|
||||
<data android:host="tauri.app" />
|
||||
|
||||
|
||||
|
||||
|
||||
</intent-filter>
|
||||
<intent-filter >
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="taurideeplink" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</intent-filter>
|
||||
<!-- DEEP LINK PLUGIN. AUTO-GENERATED. DO NOT REMOVE. -->
|
||||
</activity>
|
||||
|
||||
+9
-5
@@ -1,7 +1,11 @@
|
||||
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package com.tauri.deep_link_example
|
||||
|
||||
class MainActivity : TauriActivity()
|
||||
import android.os.Bundle
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
|
||||
class MainActivity : TauriActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
enableEdgeToEdge()
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
||||
#Tue May 10 19:22:52 CST 2022
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
+77
-77
@@ -1,116 +1,116 @@
|
||||
{
|
||||
"images": [
|
||||
"images" : [
|
||||
{
|
||||
"size": "20x20",
|
||||
"idiom": "iphone",
|
||||
"filename": "AppIcon-20x20@2x.png",
|
||||
"scale": "2x"
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size": "20x20",
|
||||
"idiom": "iphone",
|
||||
"filename": "AppIcon-20x20@3x.png",
|
||||
"scale": "3x"
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-20x20@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size": "29x29",
|
||||
"idiom": "iphone",
|
||||
"filename": "AppIcon-29x29@2x-1.png",
|
||||
"scale": "2x"
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-29x29@2x-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size": "29x29",
|
||||
"idiom": "iphone",
|
||||
"filename": "AppIcon-29x29@3x.png",
|
||||
"scale": "3x"
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-29x29@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size": "40x40",
|
||||
"idiom": "iphone",
|
||||
"filename": "AppIcon-40x40@2x.png",
|
||||
"scale": "2x"
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size": "40x40",
|
||||
"idiom": "iphone",
|
||||
"filename": "AppIcon-40x40@3x.png",
|
||||
"scale": "3x"
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-40x40@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size": "60x60",
|
||||
"idiom": "iphone",
|
||||
"filename": "AppIcon-60x60@2x.png",
|
||||
"scale": "2x"
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-60x60@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size": "60x60",
|
||||
"idiom": "iphone",
|
||||
"filename": "AppIcon-60x60@3x.png",
|
||||
"scale": "3x"
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-60x60@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size": "20x20",
|
||||
"idiom": "ipad",
|
||||
"filename": "AppIcon-20x20@1x.png",
|
||||
"scale": "1x"
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-20x20@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size": "20x20",
|
||||
"idiom": "ipad",
|
||||
"filename": "AppIcon-20x20@2x-1.png",
|
||||
"scale": "2x"
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-20x20@2x-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size": "29x29",
|
||||
"idiom": "ipad",
|
||||
"filename": "AppIcon-29x29@1x.png",
|
||||
"scale": "1x"
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size": "29x29",
|
||||
"idiom": "ipad",
|
||||
"filename": "AppIcon-29x29@2x.png",
|
||||
"scale": "2x"
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size": "40x40",
|
||||
"idiom": "ipad",
|
||||
"filename": "AppIcon-40x40@1x.png",
|
||||
"scale": "1x"
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-40x40@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size": "40x40",
|
||||
"idiom": "ipad",
|
||||
"filename": "AppIcon-40x40@2x-1.png",
|
||||
"scale": "2x"
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-40x40@2x-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size": "76x76",
|
||||
"idiom": "ipad",
|
||||
"filename": "AppIcon-76x76@1x.png",
|
||||
"scale": "1x"
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-76x76@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size": "76x76",
|
||||
"idiom": "ipad",
|
||||
"filename": "AppIcon-76x76@2x.png",
|
||||
"scale": "2x"
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-76x76@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size": "83.5x83.5",
|
||||
"idiom": "ipad",
|
||||
"filename": "AppIcon-83.5x83.5@2x.png",
|
||||
"scale": "2x"
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-83.5x83.5@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size": "1024x1024",
|
||||
"idiom": "ios-marketing",
|
||||
"filename": "AppIcon-512@2x.png",
|
||||
"scale": "1x"
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "AppIcon-512@2x.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"version": 1,
|
||||
"author": "xcode"
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"info": {
|
||||
"version": 1,
|
||||
"author": "xcode"
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17150" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17150" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Y6W-OH-hqX">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17122"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
|
||||
+12
-34
@@ -3,7 +3,7 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 56;
|
||||
objectVersion = 63;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
@@ -167,6 +167,8 @@
|
||||
dependencies = (
|
||||
);
|
||||
name = "deep-link-example_iOS";
|
||||
packageProductDependencies = (
|
||||
);
|
||||
productName = "deep-link-example_iOS";
|
||||
productReference = 1CAAFA750FD735A285DC1238 /* deep-link-example.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
@@ -189,6 +191,7 @@
|
||||
en,
|
||||
);
|
||||
mainGroup = 1DC58B1705AA3ECC6B887FE7;
|
||||
minimizedProjectReferenceProxies = 1;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
@@ -227,7 +230,6 @@
|
||||
outputPaths = (
|
||||
"$(SRCROOT)/Externals/x86_64/${CONFIGURATION}/libapp.a",
|
||||
"$(SRCROOT)/Externals/arm64/${CONFIGURATION}/libapp.a",
|
||||
"$(SRCROOT)/Externals/arm64-sim/${CONFIGURATION}/libapp.a",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
@@ -314,18 +316,13 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ARCHS = (
|
||||
arm64,
|
||||
"arm64-sim",
|
||||
);
|
||||
ARCHS = arm64;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "deep-link-example_iOS/deep-link-example_iOS.entitlements";
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = Q93MBH6S2F;
|
||||
DEVELOPMENT_TEAM = "Q93MBH6S2F";
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphoneos*]" = "arm64-sim x86_64";
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
"EXCLUDED_ARCHS[sdk=iphoneos*]" = x86_64;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\".\"",
|
||||
@@ -335,13 +332,6 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
"LIBRARY_SEARCH_PATHS[arch=arm64-sim]" = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION)",
|
||||
"$(SDKROOT)/usr/lib/swift",
|
||||
"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
|
||||
"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
|
||||
);
|
||||
"LIBRARY_SEARCH_PATHS[arch=arm64]" = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION)",
|
||||
@@ -360,7 +350,7 @@
|
||||
PRODUCT_NAME = "deep-link-example";
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALID_ARCHS = "arm64 arm64-sim";
|
||||
VALID_ARCHS = arm64;
|
||||
};
|
||||
name = debug;
|
||||
};
|
||||
@@ -424,18 +414,13 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ARCHS = (
|
||||
arm64,
|
||||
"arm64-sim",
|
||||
);
|
||||
ARCHS = arm64;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "deep-link-example_iOS/deep-link-example_iOS.entitlements";
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = Q93MBH6S2F;
|
||||
DEVELOPMENT_TEAM = "Q93MBH6S2F";
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphoneos*]" = "arm64-sim x86_64";
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
"EXCLUDED_ARCHS[sdk=iphoneos*]" = x86_64;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\".\"",
|
||||
@@ -445,13 +430,6 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
"LIBRARY_SEARCH_PATHS[arch=arm64-sim]" = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION)",
|
||||
"$(SDKROOT)/usr/lib/swift",
|
||||
"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
|
||||
"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
|
||||
);
|
||||
"LIBRARY_SEARCH_PATHS[arch=arm64]" = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION)",
|
||||
@@ -470,7 +448,7 @@
|
||||
PRODUCT_NAME = "deep-link-example";
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALID_ARCHS = "arm64 arm64-sim";
|
||||
VALID_ARCHS = arm64;
|
||||
};
|
||||
name = release;
|
||||
};
|
||||
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
+12
-1
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.0.0</string>
|
||||
<string>0.1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.1.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
@@ -40,5 +40,16 @@
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>taurideeplink</string>
|
||||
</array>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>taurideeplink</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,7 +1,3 @@
|
||||
# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: deep-link-example
|
||||
options:
|
||||
bundleIdPrefix: com.tauri.deep-link-example
|
||||
@@ -16,7 +12,6 @@ settingGroups:
|
||||
base:
|
||||
PRODUCT_NAME: deep-link-example
|
||||
PRODUCT_BUNDLE_IDENTIFIER: com.tauri.deep-link-example
|
||||
DEVELOPMENT_TEAM: Q93MBH6S2F
|
||||
targetTemplates:
|
||||
app:
|
||||
type: application
|
||||
@@ -56,8 +51,8 @@ targets:
|
||||
- UIInterfaceOrientationPortraitUpsideDown
|
||||
- UIInterfaceOrientationLandscapeLeft
|
||||
- UIInterfaceOrientationLandscapeRight
|
||||
CFBundleShortVersionString: 0.0.0
|
||||
CFBundleVersion: 0.0.0
|
||||
CFBundleShortVersionString: 0.1.0
|
||||
CFBundleVersion: '0.1.0'
|
||||
entitlements:
|
||||
path: deep-link-example_iOS/deep-link-example_iOS.entitlements
|
||||
scheme:
|
||||
@@ -67,14 +62,12 @@ targets:
|
||||
settings:
|
||||
base:
|
||||
ENABLE_BITCODE: false
|
||||
ARCHS: [arm64, arm64-sim]
|
||||
VALID_ARCHS: arm64 arm64-sim
|
||||
ARCHS: [arm64]
|
||||
VALID_ARCHS: arm64
|
||||
LIBRARY_SEARCH_PATHS[arch=x86_64]: $(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
|
||||
LIBRARY_SEARCH_PATHS[arch=arm64]: $(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
|
||||
LIBRARY_SEARCH_PATHS[arch=arm64-sim]: $(inherited) $(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: true
|
||||
EXCLUDED_ARCHS[sdk=iphonesimulator*]: arm64
|
||||
EXCLUDED_ARCHS[sdk=iphoneos*]: arm64-sim x86_64
|
||||
EXCLUDED_ARCHS[sdk=iphoneos*]: x86_64
|
||||
groups: [app]
|
||||
dependencies:
|
||||
- framework: libapp.a
|
||||
@@ -93,4 +86,3 @@ targets:
|
||||
outputFiles:
|
||||
- $(SRCROOT)/Externals/x86_64/${CONFIGURATION}/libapp.a
|
||||
- $(SRCROOT)/Externals/arm64/${CONFIGURATION}/libapp.a
|
||||
- $(SRCROOT)/Externals/arm64-sim/${CONFIGURATION}/libapp.a
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
},
|
||||
{
|
||||
"host": "tauri.app"
|
||||
},
|
||||
{
|
||||
"scheme": ["taurideeplink"]
|
||||
}
|
||||
],
|
||||
"desktop": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@tauri-apps/plugin-deep-link",
|
||||
"version": "2.4.0",
|
||||
"version": "2.4.5",
|
||||
"description": "Set your Tauri application as the default handler for an URL",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"authors": [
|
||||
@@ -25,6 +25,9 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2.6.0"
|
||||
"@tauri-apps/api": "^2.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "2.9.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,8 @@ use tauri_utils::config::DeepLinkProtocol;
|
||||
pub struct AssociatedDomain {
|
||||
#[serde(default = "default_schemes")]
|
||||
pub scheme: Vec<String>,
|
||||
|
||||
#[serde(deserialize_with = "deserialize_associated_host")]
|
||||
pub host: String,
|
||||
|
||||
#[serde(default, deserialize_with = "deserialize_associated_host")]
|
||||
pub host: Option<String>, // Optional custom uri schemes dont NEED a host (may have one still), but required for https/http schemes
|
||||
#[serde(default)]
|
||||
pub path: Vec<String>,
|
||||
#[serde(default, alias = "path-pattern", rename = "pathPattern")]
|
||||
@@ -23,6 +21,41 @@ pub struct AssociatedDomain {
|
||||
pub path_prefix: Vec<String>,
|
||||
#[serde(default, alias = "path-suffix", rename = "pathSuffix")]
|
||||
pub path_suffix: Vec<String>,
|
||||
#[serde(default, alias = "app-link", rename = "appLink")]
|
||||
pub app_link: Option<bool>,
|
||||
}
|
||||
|
||||
impl AssociatedDomain {
|
||||
/// Returns true if the domain uses http or https scheme.
|
||||
pub fn is_web_link(&self) -> bool {
|
||||
self.scheme.iter().any(|s| s == "https" || s == "http")
|
||||
}
|
||||
|
||||
/// Returns true if the domain uses http or https scheme and has proper host configuration.
|
||||
pub fn is_app_link(&self) -> bool {
|
||||
self.app_link
|
||||
.unwrap_or_else(|| self.is_web_link() && self.host.is_some())
|
||||
}
|
||||
|
||||
pub fn validate(&self) -> Result<(), String> {
|
||||
// Rule 1: All web links require a host.
|
||||
if self.is_web_link() && self.host.is_none() {
|
||||
return Err("Web link requires a host".into());
|
||||
}
|
||||
|
||||
// Rule 2: If it's an App Link, ensure http(s) and host.
|
||||
if self.is_app_link() {
|
||||
if !self.is_web_link() {
|
||||
return Err("AppLink must be a valid web link (https/http + host)".into());
|
||||
}
|
||||
if self.scheme.iter().any(|s| s == "http") && !self.scheme.iter().any(|s| s == "https")
|
||||
{
|
||||
eprintln!("Warning: AppLink uses only 'http' — allowed on Android but not secure for production.");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Consider removing this in v3
|
||||
@@ -30,18 +63,19 @@ fn default_schemes() -> Vec<String> {
|
||||
vec!["https".to_string(), "http".to_string()]
|
||||
}
|
||||
|
||||
fn deserialize_associated_host<'de, D>(deserializer: D) -> Result<String, D::Error>
|
||||
fn deserialize_associated_host<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let host = String::deserialize(deserializer)?;
|
||||
if let Some((scheme, _host)) = host.split_once("://") {
|
||||
Err(serde::de::Error::custom(format!(
|
||||
"host `{host}` cannot start with a scheme, please remove the `{scheme}://` prefix"
|
||||
)))
|
||||
} else {
|
||||
Ok(host)
|
||||
let opt = Option::<String>::deserialize(deserializer)?;
|
||||
if let Some(ref host) = opt {
|
||||
if let Some((scheme, _)) = host.split_once("://") {
|
||||
return Err(serde::de::Error::custom(format!(
|
||||
"host `{host}` cannot start with a scheme, please remove the `{scheme}://` prefix"
|
||||
)));
|
||||
}
|
||||
}
|
||||
Ok(opt)
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
|
||||
@@ -28,6 +28,16 @@ pub enum Error {
|
||||
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
|
||||
|
||||
@@ -254,6 +254,7 @@ mod imp {
|
||||
///
|
||||
/// ## Platform-specific:
|
||||
///
|
||||
/// - **Linux**: Needs the `xdg-mime` and `update-desktop-database` commands available on the system.
|
||||
/// - **macOS / Android / iOS**: Unsupported, will return [`Error::UnsupportedPlatform`](`crate::Error::UnsupportedPlatform`).
|
||||
pub fn register<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<()> {
|
||||
#[cfg(windows)]
|
||||
@@ -292,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");
|
||||
|
||||
@@ -303,12 +305,30 @@ 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")) {
|
||||
let old_mimes = section.remove("MimeType");
|
||||
section.append(
|
||||
"MimeType",
|
||||
format!("{mime_type};{}", old_mimes.unwrap_or_default()),
|
||||
);
|
||||
desktop_file.write_to_file(&target_file)?;
|
||||
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)?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let mut file = File::create(target_file)?;
|
||||
@@ -321,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(),
|
||||
@@ -330,11 +350,15 @@ mod imp {
|
||||
|
||||
Command::new("update-desktop-database")
|
||||
.arg(target)
|
||||
.status()?;
|
||||
.status()
|
||||
.inspect_err(crate::error::inspect_command_error(
|
||||
"update-desktop-database",
|
||||
))?;
|
||||
|
||||
Command::new("xdg-mime")
|
||||
.args(["default", &file_name, _protocol.as_ref()])
|
||||
.status()?;
|
||||
.args(["default", &file_name, mime_type.as_str()])
|
||||
.status()
|
||||
.inspect_err(crate::error::inspect_command_error("xdg-mime"))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -403,6 +427,7 @@ mod imp {
|
||||
///
|
||||
/// ## Platform-specific:
|
||||
///
|
||||
/// - **Linux**: Needs the `xdg-mime` command available on the system.
|
||||
/// - **macOS / Android / iOS**: Unsupported, will return [`Error::UnsupportedPlatform`](`crate::Error::UnsupportedPlatform`).
|
||||
pub fn is_registered<S: AsRef<str>>(&self, _protocol: S) -> crate::Result<bool> {
|
||||
#[cfg(windows)]
|
||||
@@ -437,7 +462,8 @@ mod imp {
|
||||
"default",
|
||||
&format!("x-scheme-handler/{}", _protocol.as_ref()),
|
||||
])
|
||||
.output()?;
|
||||
.output()
|
||||
.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,41 @@
|
||||
# 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
|
||||
|
||||
- Upgraded to `fs-js@2.4.2`
|
||||
|
||||
## \[2.3.2]
|
||||
|
||||
- [`af08c66f`](https://github.com/tauri-apps/plugins-workspace/commit/af08c66faafe0dffc4b0a80aef030cd3f0f89a9c) ([#2871](https://github.com/tauri-apps/plugins-workspace/pull/2871) by [@FabianLars](https://github.com/tauri-apps/plugins-workspace/../../FabianLars)) Fixed an issue that caused the file picker not to open on Android when extension filters were set.
|
||||
|
||||
## \[2.3.1]
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Upgraded to `fs-js@2.4.1`
|
||||
|
||||
## \[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-dialog"
|
||||
version = "2.3.0"
|
||||
version = "2.4.2"
|
||||
description = "Native system dialogs for opening and saving files along with message dialogs on your Tauri application."
|
||||
edition = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
@@ -9,9 +9,12 @@ rust-version = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
links = "tauri-plugin-dialog"
|
||||
|
||||
[features]
|
||||
default = ["gtk3"]
|
||||
xdg-portal = ["rfd/xdg-portal"]
|
||||
gtk3 = ["rfd/gtk3"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
rustc-args = ["--cfg", "docsrs"]
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
targets = ["x86_64-unknown-linux-gnu", "x86_64-linux-android"]
|
||||
|
||||
[package.metadata.platforms.support]
|
||||
@@ -34,7 +37,7 @@ tauri = { workspace = true }
|
||||
log = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
url = { workspace = true }
|
||||
tauri-plugin-fs = { path = "../fs", version = "2.4.0" }
|
||||
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"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user