Compare commits

..

66 Commits

Author SHA1 Message Date
github-actions[bot] fb62d03f73 publish new versions (#1807)
Co-authored-by: lucasfernog <lucasfernog@users.noreply.github.com>
2024-10-02 07:02:42 -03:00
Tony 7e5e34420b Cancel auto save on save (#1859) 2024-10-01 23:13:20 -03:00
Tony f12d35609a feat(store)!: fully rework and add auto save (#1550)
* Add auto save to store plugin

* Put jsdoc at constructor instead of class level

* Clippy

* Use enum instead of bool

* Some(AutoSaveMessage::Cancel) | None

* from_millis

* u64

* Add change file

* Rename to emit_on_change

* should use Duration in `with_store`

* Add breaking change notice to change file

* Emit change event for inserts by reset

* Update readme example

* Update example

* Remove extra line

* Make description clear it only works with managed

* Fix links in docstring

* Fix doc string closing

* get_mut

* Proof of concept

* fmt

* Load store on create

* cargo fmt

* Fix merge conflits

* Format

* small cleanup

* update docs, use `impl Into<JsonValue>`

* fix doctests, further simplification of api

* add store options

---------

Co-authored-by: Tillmann <28728469+tweidinger@users.noreply.github.com>
Co-authored-by: Lucas Nogueira <lucas@tauri.app>
2024-10-01 15:10:40 -03:00
Amr Bashir 44273b9889 fix(shell): fix schema requiring sidecar property even though it is optional (#1839)
* fix(shell): fix schema requiring `sidecar` property even though it is optional

* fix clippy

* make `cmd` and `sidecar` exclusive

* make args optional

* cleanup

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.app>
2024-10-01 10:16:14 -03:00
Jacob Bolda 2f7e32b5e0 [positioner] handleIconState in JS (#1822)
* [positioner] handleIconState in JS

* update readme

* fix change file version

* fixes

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.app>
2024-10-01 10:15:22 -03:00
Fabian-Lars 30bcf5dcc2 refactor(sql): Allow multiple drivers at the same time (#1838)
* refactor(sql): Allow multiple drivers at the same time

* fmt

* remove default feature comment [skip ci]

* what was that doing there [skip ci]

* disable public methods for now
2024-10-01 09:47:08 -03:00
Amr Bashir 68579934c9 fix(cli): expose hidden structs (#1856)
closes  #1843
2024-10-01 09:35:13 -03:00
Tony 04459afbb6 refactor(dialog)!: use enum instead of label for buttons (#1842)
* refactor(dialog)!: use enum instead of label

* Add change file

* Fix doc comment typo

* Move ok and cancel to lib.rs
2024-10-01 09:34:20 -03:00
Tillmann 3b2bd3065d fix sql heading 2024-09-30 14:11:44 +02:00
renovate[bot] f930505de4 chore(deps): lock file maintenance (#1852)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-30 10:19:10 +08:00
renovate[bot] 34319bd977 chore(deps): update unocss monorepo to ^0.63.0 (#1848)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-29 16:18:56 +08:00
Tony 34737186fe chore: re-generate reference.md (#1847) 2024-09-28 20:50:57 +03:00
renovate[bot] 4bd1f15bb9 fix(deps): update tauri monorepo (#1846)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-28 14:44:24 +08:00
Tillmann aabc4d3a24 Add Metadata for Plugin Compatibility (#1836)
Co-authored-by: Tillmann <112912081+tillmann-crabnebula@users.noreply.github.com>
Co-authored-by: Tillmann <28728469+tweidinger@users.noreply.github.com>
2024-09-26 14:21:25 +02:00
Fabian-Lars fc9b189e83 fix(fs): ignore OS specific paths in scope deserialization (#1837) 2024-09-26 02:43:33 +03:00
renovate[bot] b7ff3a6bdb fix(deps): update rust crate windows-registry to 0.3 (v2) (#1841)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: FabianLars <fabianlars@fabianlars.de>
2024-09-25 15:44:41 +02:00
Amr Bashir 04a0aea0ab feat(updater)!: add option to use insecure transport protocol (#1814) 2024-09-24 18:38:53 +03:00
renovate[bot] e564e2aa91 chore(deps): update dependency typescript-eslint to v8.7.0 (#1832)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-23 23:25:24 +02:00
renovate[bot] 118f6b4334 chore(deps): update dependency @rollup/plugin-node-resolve to v15.3.0 (#1831)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-23 23:11:01 +02:00
renovate[bot] fd0a52aa86 chore(deps): update eslint monorepo to v9.11.1 (#1829)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-23 22:49:03 +02:00
renovate[bot] 52e3bdab26 fix(deps): update dependency @zerodevx/svelte-json-view to v1.0.11 (v2) (#1830)
* fix(deps): update dependency @zerodevx/svelte-json-view to v1.0.11

* audit fix

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: fabianlars <fabianlars@fabianlars.de>
2024-09-23 22:45:24 +02:00
renovate[bot] dd09e3c3f4 chore(deps): update dependency @rollup/plugin-node-resolve to v15.2.4 (#1824)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-23 16:13:16 +08:00
renovate[bot] 2797954799 chore(deps): update dependency rollup to v4.22.4 (#1818)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-23 16:08:15 +08:00
renovate[bot] 025210be28 chore(deps): update eslint monorepo to v9.11.0 (#1820)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-23 16:07:35 +08:00
Amr Bashir 221f50f53b fix(updater): encode version when making requests (#1816)
* fix(updater): encode version when making requests

ref: https://github.com/tauri-apps/tauri/issues/10908

* Update .changes/updater-endpoint-version-encoded.md

* only skip `+`

* fmt

* use normal const
2024-09-20 07:57:40 -03:00
renovate[bot] 6bf1bd8d44 fix(deps): update rust crate rfd to 0.15 (v2) (#1805)
* fix(deps): update rust crate rfd to 0.15

* Fix compilation

* Add change file

* Remove platform specific note

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tony <legendmastertony@gmail.com>
2024-09-19 20:04:02 +08:00
Tony 41fe9053a0 fix(deep-link): is_registered check on windows 2024-09-19 19:58:13 +08:00
renovate[bot] 27bb5d9a27 chore(deps): update dependency rollup to v4.22.0 (v2) (#1810)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-19 12:40:55 +02:00
Austin Bennett 3168e17603 Added quotes for cmd (#1806)
* Added quotes for cmd

* Add change file

---------

Co-authored-by: Tony <legendmastertony@gmail.com>
2024-09-19 09:59:54 +08:00
Jaken Herman dd514e7a88 Docs: contaiend -> contained typos (#1802) 2024-09-17 19:31:55 +03:00
renovate[bot] 6e142b4230 fix(deps): update tauri monorepo (v2) (#1801)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-17 17:24:18 +02:00
renovate[bot] fd1c7c8dbb fix(deps): update dependency @tauri-apps/plugin-geolocation to v2.0.0-rc.2 (v2) (#1799)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-17 11:09:53 +02:00
renovate[bot] 59c63f31cc chore(deps): update dependency typescript-eslint to v8.6.0 (v2) (#1798)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-16 21:39:26 +02:00
github-actions[bot] 3cbb55aa7b publish new versions (#1796) 2024-09-16 16:29:07 -03:00
Lucas Fernandes Nogueira 60765694f5 refactor(geolocation): simplify API, defer permission checks (#1773) 2024-09-16 17:01:13 +03:00
renovate[bot] fd75401aee fix(deps): update rust crate image to 0.25 (v2) (#1418)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: FabianLars <fabianlars@fabianlars.de>
2024-09-16 13:20:08 +02:00
renovate[bot] ca34972266 fix(deps): update rust crate tokio-tungstenite to 0.24 (v2) (#1781)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-16 13:13:15 +02:00
renovate[bot] 179184326b chore(deps): update tauri monorepo (v2) (#1789)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-16 12:08:42 +02:00
github-actions[bot] d8efd3cd20 Publish New Versions (v2) (#1794)
Co-authored-by: amrbashir <amrbashir@users.noreply.github.com>
2024-09-16 07:00:22 -03:00
renovate[bot] 5d39ddcf22 chore(deps): lock file maintenance (#1791)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-16 10:21:19 +08:00
Tony 2050a3bea2 fix(upload): change tokio version to 1 instead of * (#1793) 2024-09-16 05:20:52 +03:00
Tony c078f57a09 Revert "Publish New Versions (v2)" (#1792)
This reverts commit dc5721ac13.
2024-09-16 05:20:21 +03:00
github-actions[bot] dc5721ac13 Publish New Versions (v2) (#1788)
Co-authored-by: lucasfernog <lucasfernog@users.noreply.github.com>
2024-09-15 18:37:58 -03:00
Felix Salazar 1d9741b52b [upload - http-extra] fix: download content to file when unsuccessful response (and test) #1750 (#1783)
* fix and test

* Update Cargo.toml

Co-authored-by: Fabian-Lars <fabianlars@fabianlars.de>

* Update Cargo.toml

Co-authored-by: Fabian-Lars <fabianlars@fabianlars.de>

* add .change log

* clippy fixes

* print test error

* fix tests

---------

Co-authored-by: Fabian-Lars <fabianlars@fabianlars.de>
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
2024-09-15 18:37:02 -03:00
Tony 7a37355e17 fix(window-state): deadlock when trying to restore window states on initial load (#1787)
* Fix deadlock when trying to restore window the size on initial load

* Typo
2024-09-15 18:01:27 -03:00
github-actions[bot] 5cbd593e76 publish new versions (#1772)
Co-authored-by: lucasfernog <lucasfernog@users.noreply.github.com>
2024-09-15 11:55:38 -03:00
renovate[bot] f7600b5fff chore(deps): update dependency @tauri-apps/cli to v2.0.0-rc.14 (#1786)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-15 11:37:09 -03:00
Lucas Fernandes Nogueira fb85e5dd76 chore(deps): update tauri to 2.0.0-rc.12 (#1785) 2024-09-15 11:36:23 -03:00
Lucas Fernandes Nogueira 6f3f66794a feat(deep-link): add on_open_url Rust API (#1780) 2024-09-14 21:35:31 -03:00
FabianLars 79d6e19c4b chore: Add changefile for #1777 2024-09-14 18:34:45 +02:00
Cole Shirley aebd4f6185 fix(barcode-scanner): Fix mixed up imports (internal) (#1777)
Co-authored-by: Fabian-Lars <fabianlars@fabianlars.de>
2024-09-14 18:20:21 +02:00
Lucas Fernandes Nogueira 341a5320c3 fix(clipboard): Android warnings and build on SDK under 28 (#1771) 2024-09-13 12:03:10 -03:00
Lucas Fernandes Nogueira cc03ccf5e0 fix(fs): app scopes not properly enabling paths (#1774) 2024-09-13 09:57:46 -03:00
Lucas Nogueira 009299ebec chore(prettier): ignore mobile build artifacts 2024-09-13 09:10:01 -03:00
Tony 204e5aacad fix(window-state)!: saving minimized state (#1743)
* Fix saving minimized state again

* Add change file

* Fix saving minimized size

* Add change file

* Fix missing .md

* Remove window-shadows
2024-09-13 06:29:38 +03:00
github-actions[bot] 8a45c35160 publish new versions (#1764)
Co-authored-by: lucasfernog <lucasfernog@users.noreply.github.com>
2024-09-12 15:49:29 -03:00
Lucas Nogueira ebf821afd1 chore(examples): update AndroidManifest.xml 2024-09-12 15:32:27 -03:00
Lucas Fernandes Nogueira 984110a978 fix(deep-link): emit new-url event on app load (#1770) 2024-09-12 11:20:16 -03:00
Lucas Fernandes Nogueira 2b898f0786 fix(dialog): update asset protocol scope on directory open, closes #1553 (#1769) 2024-09-12 11:10:16 -03:00
Tony b2269333e3 chore(single-instance): put deep link integration behined a feature (#1766)
* Make deep link optional for single instance

* Add change file

* Add deep-link feature to example

* Update plugins/deep-link/README.md

Co-authored-by: Fabian-Lars <fabianlars@fabianlars.de>

* format

* [skip ci] update readme

---------

Co-authored-by: Fabian-Lars <fabianlars@fabianlars.de>
2024-09-12 18:20:15 +08:00
renovate[bot] 41afcae399 chore(deps): update dependency rollup to v4.21.3 (v2) (#1767)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-12 12:01:38 +02:00
SRutile 9291e4d2ca fix(fs): support any UTF-8 path in writeFile (#1640)
* In the `writeFile` function, when `options.baseDir` is not set, convert `path` to URL to avoid errors caused by Chinese characters.

* fmt

* use TextEncoder

* use percent encoding

* add change file

* fmt

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
2024-09-11 12:02:24 -03:00
renovate[bot] 3715f3c9a6 chore(deps): update tauri monorepo (#1760)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-11 09:12:13 +08:00
github-actions[bot] 253ae66210 publish new versions (#1761) 2024-09-10 16:14:05 -03:00
Lucas Nogueira 949e2d6c45 chore: update docs 2024-09-10 16:02:38 -03:00
Lucas Fernandes Nogueira 64a6240f79 feat(deep-link): implement getCurrent on Windows/Linux (#1759)
* feat(deep-link): implement getCurrent on Windows/Linux

checks std::env::args() on initialization, also includes integration with the single-instance plugin

* fmt

* update docs, fix event

* add register_all function

* expose api

* be nicer on docs, clippy
2024-09-10 16:00:42 -03:00
274 changed files with 5852 additions and 20995 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"cli": patch
---
Expose `Matches`, `SubcommandMatches` and `ArgData` structs.
+2 -1
View File
@@ -268,7 +268,8 @@
},
"single-instance": {
"path": "./plugins/single-instance",
"manager": "rust"
"manager": "rust",
"dependencies": ["deep-link"]
},
"sql": {
"path": "./plugins/sql",
+6
View File
@@ -0,0 +1,6 @@
---
"deep-link": patch
---
Emit the `deep-link://new-url` event on Linux and Windows when the app is executed with a deep link CLI argument,
matching the iOS and macOS behavior.
@@ -0,0 +1,6 @@
---
"deep-link": patch
"deep-link-js": patch
---
Implement `get_current` on Linux and Windows.
+6
View File
@@ -0,0 +1,6 @@
---
"deep-link": patch
---
Added `DeepLink::on_open_url` function to match the JavaScript API implementation,
which wraps the `deep-link://new-url` event and also send the current deep link if there's any.
+5
View File
@@ -0,0 +1,5 @@
---
"deep-link": patch
---
Added `register_all` to register all desktop schemes - useful for Linux to not require a formal AppImage installation.
+5
View File
@@ -0,0 +1,5 @@
---
"deep-link": patch
---
Fix fails to start when having spaces in the main binary path on Windows
+5
View File
@@ -0,0 +1,5 @@
---
"dialog": patch
---
Update Tauri scopes (asset protocol) when using the `open()` command to select directories.
+5
View File
@@ -0,0 +1,5 @@
---
"dialog": patch
---
Update rfd to 0.15
+5
View File
@@ -0,0 +1,5 @@
---
sql: patch
---
It is now possible to enable multiple SQL backends at the same time. There will be no compile error anymore if no backends are enabled!
+5
View File
@@ -0,0 +1,5 @@
---
"barcode-scanner-js": patch
---
Fixed an issue which caused checkPermission and requestPermission to be mixed up.
+6
View File
@@ -0,0 +1,6 @@
---
"clipboard-manager": patch
"clipboard-manager-js": patch
---
Fix warnings and clear implementation on Android below SDK 28.
+5
View File
@@ -0,0 +1,5 @@
---
"fs": patch
---
Fix `scope-app`, `scope-app-recursive` and `scope-index` not properly enabling the application paths.
+5
View File
@@ -0,0 +1,5 @@
---
fs: patch
---
Fix failing to deserialize capability file when using an OS specific path in the scope that is not available on the current OS.
@@ -0,0 +1,5 @@
---
"window-state": patch
---
Fix can't restore a minimized window's size and position properly
@@ -0,0 +1,5 @@
---
"window-state": patch
---
Fix deadlock when trying to restore window states on initial load
@@ -0,0 +1,5 @@
---
"upload": 'patch:bug'
---
fix download content to file when unsuccessful response
+5
View File
@@ -0,0 +1,5 @@
---
"fs": patch
---
Support any UTF-8 character in the writeFile API.
@@ -0,0 +1,5 @@
---
"geolocation": patch
---
No longer request permission automatically and leave to the user how to handle the `checkPermissions` and `requestPermissions` APIs.
+5
View File
@@ -0,0 +1,5 @@
---
"dialog": patch:breaking
---
Changed `MessageDialogBuilder::ok_button_label` and `MessageDialogBuilder::cancel_button_label` to `MessageDialogBuilder::buttons` which takes an enum now
@@ -0,0 +1,6 @@
---
"positioner": patch
"positioner-js": patch
---
`handleIconState` function for use in JavaScript event handlers. This allows one to update the TrayIcon state through JavaScript and fully create and handle the TrayIcon without requiring Rust (and the side-effect of creating a TrayIcon).
+32 -1
View File
@@ -4,41 +4,72 @@
".changes/android-dialog-save.md",
".changes/barcode-dependencies.md",
".changes/barcode-scanner-validate-plist.md",
".changes/cli-hidden-structs.md",
".changes/consolidate-permission-state.md",
".changes/deep-link-event.md",
".changes/deep-link-get-current-desktop.md",
".changes/deep-link-on-new-url.md",
".changes/deep-link-register-all.md",
".changes/deep-link-space-in-path.md",
".changes/dialog-asset-scope.md",
".changes/dialog-file-response-non-exhaustive.md",
".changes/dialog-return-path.md",
".changes/dialog-rfd-015.md",
".changes/feat-multiple-sql-backends.md",
".changes/fix-barcodae-scanner-imports.md",
".changes/fix-clipboard-warnings-sdk.md",
".changes/fix-deep-link-config.md",
".changes/fix-fs-app-scopes.md",
".changes/fix-fs-scope-unknown-path.md",
".changes/fix-fs-write-file-android.md",
".changes/fix-http-plugin-abort.md",
".changes/fix-ios-file-dialog-default-mode.md",
".changes/fix-linux-updater-permission-error.md",
".changes/fix-restore-minimized-window-position.md",
".changes/fix-restore-minimized-window-state.md",
".changes/fix-restore-window-state-deadlock.md",
".changes/fix-upload-handle-non-success-download.md",
".changes/fs-dialog-file-path-methods.md",
".changes/fs-dialog-file-path-traits.md",
".changes/fs-dialog-non-exhaustive-error.md",
".changes/fs-dialog-safe-file-path.md",
".changes/fs-scope-recursive-allow-read-dir.md",
".changes/fs-windows-path.md",
".changes/fs-write-file-utf8-chars.md",
".changes/geolocation-permission-refactor.md",
".changes/geolocation-release.md",
".changes/global-shortcut-0.6.md",
".changes/haptics-release.md",
".changes/iife-varname-spacing.md",
".changes/ios-dialog-save.md",
".changes/native-dialog-button-text.md",
".changes/notification-body-optional-ios.md",
".changes/notification-permission-type-change.md",
".changes/positioner-v2-handleIconState.md",
".changes/rc.md",
".changes/remove-target-sdk.md",
".changes/resolve-content-uris.md",
".changes/shell-open-regex-match-string.md",
".changes/shell-regex-match-string.md",
".changes/shell-schema-required-sidcar.md",
".changes/single-instance-deep-link.md",
".changes/single-instance-optional-deep-link.md",
".changes/single-instance-windows-sys.0.59.md",
".changes/sql-uuid-type.md",
".changes/store-api-refactor.md",
".changes/store-auto-save.md",
".changes/store-remove-mobile-plugin.md",
".changes/swift-build-older-versions.md",
".changes/tauri-rc-8.md",
".changes/update-fs-api-docs.md",
".changes/update-geolocation-api.md",
".changes/update-tauri-rc-12.md",
".changes/update-tauri-rc-3.md",
".changes/updater-endpoint-version-encoded.md",
".changes/updater-endpoints-result.md",
".changes/updater-insecure-transport-protocol.md",
".changes/updater-js-headers-download-crate.md",
".changes/updater-js-headers-download.md"
".changes/updater-js-headers-download.md",
".changes/window-state-physical-size.md"
]
}
+6
View File
@@ -0,0 +1,6 @@
---
"shell": "patch"
---
Fix the plugin schema requiring to set `sidecar` property when it is in fact optional.
+5
View File
@@ -0,0 +1,5 @@
---
"single-instance": patch
---
Integrate with the deep link plugin out of the box.
@@ -0,0 +1,5 @@
---
"single-instance": "patch"
---
Put deep link integration behined a feature
+5
View File
@@ -0,0 +1,5 @@
---
"store-js": patch
---
**Breaking change**: Removed the `Store` constructor and added the `createStore` API.
+7
View File
@@ -0,0 +1,7 @@
---
"store": patch
---
Add a setting `auto_save` to enable a store to debounce save on modification (on calls like set, clear, delete, reset)
**Breaking change**: Removed the `with_store` API and added `StoreExt::store_builder`.
+5
View File
@@ -0,0 +1,5 @@
---
"geolocation-js": patch
---
Update API to match other plugins.
+5
View File
@@ -0,0 +1,5 @@
---
"notification": patch
---
Update to tauri 2.0.0-rc.12.
@@ -0,0 +1,5 @@
---
'updater': 'patch'
---
Encode `+` when making updater requests which can be cause incorrectly interpolating the endpoint when using `{{current_version}}` in the endpoint where the current version contains a build number, for example `1.8.0+1`.
+5
View File
@@ -0,0 +1,5 @@
---
"updater": patch
---
**Breaking change**, Changed `UpdaterBuilder::endpoints` method to return a `Result`.
@@ -0,0 +1,5 @@
---
"updater": patch
---
Add `dangerousInsecureTransportProtocol` config option to allow using insecure transport protocols, like `http`
+5
View File
@@ -0,0 +1,5 @@
---
"window-state": patch:breaking
---
Window's size is now stored in physical size instead of logical size
+2 -8
View File
@@ -148,13 +148,7 @@ jobs:
- uses: Swatinem/rust-cache@v2
- name: clippy ${{ matrix.package }}
if: matrix.package != 'tauri-plugin-sql'
run: cargo clippy --package ${{ matrix.package }} --all-targets -- -D warnings
- name: clippy ${{ matrix.package }} mysql
if: matrix.package == 'tauri-plugin-sql'
run: cargo clippy --package ${{ matrix.package }} --all-targets --no-default-features --features mysql -- -D warnings
- name: clippy ${{ matrix.package }} postgres
if: matrix.package == 'tauri-plugin-sql'
run: cargo clippy --package ${{ matrix.package }} --all-targets --no-default-features --features postgres -- -D warnings
- name: clippy ${{ matrix.package }} --all-features
run: cargo clippy --package ${{ matrix.package }} --all-targets --all-features -- -D warnings
+1 -13
View File
@@ -215,21 +215,9 @@ jobs:
run: cargo +stable install cross --git https://github.com/cross-rs/cross
- name: test ${{ matrix.package }}
if: matrix.package != 'tauri-plugin-sql' && matrix.package != 'tauri-plugin-http'
if: matrix.package != 'tauri-plugin-http'
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'
run: ${{ matrix.platform.runner }} ${{ matrix.platform.command }} --package ${{ matrix.package }} --target ${{ matrix.platform.target }} --all-targets
- name: test ${{ matrix.package }} sqlite
if: matrix.package == 'tauri-plugin-sql'
run: ${{ matrix.platform.runner }} ${{ matrix.platform.command }} --package ${{ matrix.package }} --target ${{ matrix.platform.target }} --all-targets --features sqlite
- name: test ${{ matrix.package }} mysql
if: matrix.package == 'tauri-plugin-sql'
run: ${{ matrix.platform.runner }} ${{ matrix.platform.command }} --package ${{ matrix.package }} --target ${{ matrix.platform.target }} --all-targets --features mysql
- name: test ${{ matrix.package }} postgres
if: matrix.package == 'tauri-plugin-sql'
run: ${{ matrix.platform.runner }} ${{ matrix.platform.command }} --package ${{ matrix.package }} --target ${{ matrix.platform.target }} --all-targets --features postgres
+7 -1
View File
@@ -26,9 +26,15 @@ target/
# compiled plugins
dist-js/
# plugins .tauri director
# plugins .tauri directory
/plugins/*/.tauri
# examples
examples/*/dist
plugins/*/examples/*/dist
examples/*/src-tauri/gen/schemas
plugins/*/examples/*/src-tauri/gen/schemas
# logs
logs
*.log
+6 -1
View File
@@ -19,4 +19,9 @@ plugins/*/examples/*/src-tauri/gen/
api-iife.js
init-iife.js
CHANGELOG.md
*schema.json
*schema.json
# mobile build
**/ios/.build
**/.tauri
plugins/*/android/build
Generated
+703 -474
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -11,10 +11,10 @@ resolver = "2"
[workspace.dependencies]
serde = { version = "1", features = ["derive"] }
log = "0.4"
tauri = { version = "2.0.0-rc.10", default-features = false }
tauri-build = "2.0.0-rc.9"
tauri-plugin = "2.0.0-rc.9"
tauri-utils = "2.0.0-rc.9"
tauri = { version = "2.0.0-rc.16", default-features = false }
tauri-build = "2.0.0-rc.13"
tauri-plugin = "2.0.0-rc.13"
tauri-utils = "2.0.0-rc.13"
serde_json = "1"
thiserror = "1"
url = "2"
-2
View File
@@ -1,2 +0,0 @@
/dist/*
!/dist/.gitkeep
+13
View File
@@ -1,5 +1,18 @@
# Changelog
## \[2.0.0-rc.5]
### Dependencies
- Upgraded to `store-js@2.0.0-rc.2`
## \[2.0.0-rc.4]
### Dependencies
- Upgraded to `barcode-scanner-js@2.0.0-rc.2`
- Upgraded to `clipboard-manager-js@2.0.0-rc.2`
## \[2.0.0-rc.3]
### Dependencies
View File
+12 -10
View File
@@ -1,7 +1,7 @@
{
"name": "svelte-app",
"private": true,
"version": "2.0.0-rc.3",
"version": "2.0.0-rc.5",
"type": "module",
"scripts": {
"dev": "vite --clearScreen false",
@@ -9,32 +9,34 @@
"serve": "vite preview"
},
"dependencies": {
"@tauri-apps/api": "2.0.0-rc.4",
"@tauri-apps/plugin-barcode-scanner": "2.0.0-rc.1",
"@tauri-apps/api": "2.0.0-rc.6",
"@tauri-apps/plugin-barcode-scanner": "2.0.0-rc.2",
"@tauri-apps/plugin-biometric": "2.0.0-rc.1",
"@tauri-apps/plugin-cli": "2.0.0-rc.1",
"@tauri-apps/plugin-clipboard-manager": "2.0.0-rc.1",
"@tauri-apps/plugin-clipboard-manager": "2.0.0-rc.2",
"@tauri-apps/plugin-dialog": "2.0.0-rc.1",
"@tauri-apps/plugin-fs": "2.0.0-rc.2",
"@tauri-apps/plugin-geolocation": "2.0.0-rc.2",
"@tauri-apps/plugin-global-shortcut": "2.0.0-rc.1",
"@tauri-apps/plugin-haptics": "2.0.0-rc.1",
"@tauri-apps/plugin-http": "2.0.0-rc.2",
"@tauri-apps/plugin-nfc": "2.0.0-rc.1",
"@tauri-apps/plugin-notification": "2.0.0-rc.1",
"@tauri-apps/plugin-os": "2.0.0-rc.1",
"@tauri-apps/plugin-process": "2.0.0-rc.1",
"@tauri-apps/plugin-shell": "2.0.0-rc.1",
"@tauri-apps/plugin-store": "2.0.0-rc.1",
"@tauri-apps/plugin-store": "2.0.0-rc.2",
"@tauri-apps/plugin-updater": "2.0.0-rc.2",
"@zerodevx/svelte-json-view": "1.0.10"
"@zerodevx/svelte-json-view": "1.0.11"
},
"devDependencies": {
"@iconify-json/codicon": "^1.1.37",
"@iconify-json/ph": "^1.1.8",
"@sveltejs/vite-plugin-svelte": "^3.0.1",
"@tauri-apps/cli": "2.0.0-rc.12",
"@unocss/extractor-svelte": "^0.62.0",
"@tauri-apps/cli": "2.0.0-rc.17",
"@unocss/extractor-svelte": "^0.63.0",
"svelte": "^4.2.19",
"unocss": "^0.62.0",
"vite": "^5.0.13"
"unocss": "^0.63.0",
"vite": "^5.4.7"
}
}
+30
View File
@@ -1,5 +1,35 @@
# Changelog
## \[2.0.0-rc.8]
### Dependencies
- Upgraded to `cli@2.0.0-rc.2`
- Upgraded to `dialog@2.0.0-rc.8`
- Upgraded to `fs@2.0.0-rc.6`
- Upgraded to `shell@2.0.0-rc.4`
- Upgraded to `store@2.0.0-rc.4`
- Upgraded to `updater@2.0.0-rc.4`
- Upgraded to `http@2.0.0-rc.6`
## \[2.0.0-rc.7]
### Dependencies
- Upgraded to `clipboard-manager@2.0.0-rc.4`
- Upgraded to `fs@2.0.0-rc.5`
- Upgraded to `notification@2.0.0-rc.5`
- Upgraded to `dialog@2.0.0-rc.7`
- Upgraded to `http@2.0.0-rc.5`
## \[2.0.0-rc.6]
### Dependencies
- Upgraded to `dialog@2.0.0-rc.6`
- Upgraded to `fs@2.0.0-rc.4`
- Upgraded to `http@2.0.0-rc.4`
## \[2.0.0-rc.5]
### Dependencies
+13 -13
View File
@@ -1,7 +1,7 @@
[package]
name = "api"
publish = false
version = "2.0.0-rc.5"
version = "2.0.0-rc.8"
description = "An example Tauri Application showcasing the api"
edition = "2021"
rust-version = { workspace = true }
@@ -20,21 +20,21 @@ serde = { workspace = true }
tiny_http = "0.12"
log = { workspace = true }
tauri-plugin-log = { path = "../../../plugins/log", version = "2.0.0-rc.2" }
tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.0.0-rc.3", features = [
tauri-plugin-fs = { path = "../../../plugins/fs", version = "2.0.0-rc.6", features = [
"watch",
] }
tauri-plugin-clipboard-manager = { path = "../../../plugins/clipboard-manager", version = "2.0.0-rc.3" }
tauri-plugin-dialog = { path = "../../../plugins/dialog", version = "2.0.0-rc.5" }
tauri-plugin-clipboard-manager = { path = "../../../plugins/clipboard-manager", version = "2.0.0-rc.4" }
tauri-plugin-dialog = { path = "../../../plugins/dialog", version = "2.0.0-rc.8" }
tauri-plugin-http = { path = "../../../plugins/http", features = [
"multipart",
], version = "2.0.0-rc.3" }
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.0.0-rc.4", features = [
], version = "2.0.0-rc.6" }
tauri-plugin-notification = { path = "../../../plugins/notification", version = "2.0.0-rc.5", features = [
"windows7-compat",
] }
tauri-plugin-os = { path = "../../../plugins/os", version = "2.0.0-rc.1" }
tauri-plugin-process = { path = "../../../plugins/process", version = "2.0.0-rc.1" }
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.0.0-rc.3" }
tauri-plugin-store = { path = "../../../plugins/store", version = "2.0.0-rc.3" }
tauri-plugin-shell = { path = "../../../plugins/shell", version = "2.0.0-rc.4" }
tauri-plugin-store = { path = "../../../plugins/store", version = "2.0.0-rc.4" }
[dependencies.tauri]
workspace = true
@@ -50,17 +50,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.0.0-rc.1" }
tauri-plugin-cli = { path = "../../../plugins/cli", version = "2.0.0-rc.2" }
tauri-plugin-global-shortcut = { path = "../../../plugins/global-shortcut", version = "2.0.0-rc.2" }
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.0.0-rc.3" }
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.0.0-rc.4" }
tauri-plugin-window-state = { path = "../../../plugins/window-state", version = "2.0.0-rc.3" }
[target."cfg(any(target_os = \"android\", target_os = \"ios\"))".dependencies]
tauri-plugin-barcode-scanner = { path = "../../../plugins/barcode-scanner/", version = "2.0.0-rc.4" }
tauri-plugin-nfc = { path = "../../../plugins/nfc", version = "2.0.0-rc.3" }
tauri-plugin-biometric = { path = "../../../plugins/biometric/", version = "2.0.0-rc.3" }
[target."cfg(target_os = \"windows\")".dependencies]
window-shadows = "0.2"
tauri-plugin-geolocation = { path = "../../../plugins/geolocation/", version = "2.0.0-rc.3" }
tauri-plugin-haptics = { path = "../../../plugins/haptics/", version = "2.0.0-rc.3" }
[features]
prod = ["tauri/custom-protocol"]
@@ -11,6 +11,10 @@
"barcode-scanner:allow-scan",
"barcode-scanner:allow-cancel",
"barcode-scanner:allow-request-permissions",
"barcode-scanner:allow-check-permissions"
"barcode-scanner:allow-check-permissions",
"geolocation:allow-check-permissions",
"geolocation:allow-request-permissions",
"geolocation:allow-watch-position",
"geolocation:allow-get-current-position"
]
}
-1
View File
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+5 -2
View File
@@ -45,6 +45,8 @@ pub fn run() {
app.handle().plugin(tauri_plugin_cli::init())?;
app.handle()
.plugin(tauri_plugin_global_shortcut::Builder::new().build())?;
app.handle()
.plugin(tauri_plugin_window_state::Builder::new().build())?;
app.handle()
.plugin(tauri_plugin_updater::Builder::new().build())?;
}
@@ -53,6 +55,8 @@ pub fn run() {
app.handle().plugin(tauri_plugin_barcode_scanner::init())?;
app.handle().plugin(tauri_plugin_nfc::init())?;
app.handle().plugin(tauri_plugin_biometric::init())?;
app.handle().plugin(tauri_plugin_geolocation::init())?;
app.handle().plugin(tauri_plugin_haptics::init())?;
}
let mut webview_window_builder =
@@ -63,8 +67,7 @@ pub fn run() {
.user_agent(&format!("Tauri API - {}", std::env::consts::OS))
.title("Tauri API Validation")
.inner_size(1000., 800.)
.min_inner_size(600., 400.)
.content_protected(true);
.min_inner_size(600., 400.);
}
#[cfg(target_os = "windows")]
+1 -1
View File
@@ -1,5 +1,5 @@
{
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "Tauri API",
"version": "2.0.0",
"identifier": "com.tauri.api",
+168 -165
View File
@@ -1,203 +1,208 @@
<script>
import { writable } from "svelte/store";
import { open } from "@tauri-apps/plugin-shell";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { getCurrentWebview } from "@tauri-apps/api/webview";
import * as os from "@tauri-apps/plugin-os";
import { writable } from 'svelte/store'
import { open } from '@tauri-apps/plugin-shell'
import { getCurrentWindow } from '@tauri-apps/api/window'
import { getCurrentWebview } from '@tauri-apps/api/webview'
import * as os from '@tauri-apps/plugin-os'
import Welcome from "./views/Welcome.svelte";
import Cli from "./views/Cli.svelte";
import Communication from "./views/Communication.svelte";
import Dialog from "./views/Dialog.svelte";
import FileSystem from "./views/FileSystem.svelte";
import Http from "./views/Http.svelte";
import Notifications from "./views/Notifications.svelte";
import Shortcuts from "./views/Shortcuts.svelte";
import Shell from "./views/Shell.svelte";
import Store from "./views/Store.svelte";
import Updater from "./views/Updater.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 Welcome from './views/Welcome.svelte'
import Cli from './views/Cli.svelte'
import Communication from './views/Communication.svelte'
import Dialog from './views/Dialog.svelte'
import FileSystem from './views/FileSystem.svelte'
import Http from './views/Http.svelte'
import Notifications from './views/Notifications.svelte'
import Shortcuts from './views/Shortcuts.svelte'
import Shell from './views/Shell.svelte'
import Store from './views/Store.svelte'
import Updater from './views/Updater.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 { onMount, tick } from "svelte";
import { ask } from "@tauri-apps/plugin-dialog";
import Nfc from "./views/Nfc.svelte";
import { onMount, tick } from 'svelte'
import { ask } from '@tauri-apps/plugin-dialog'
import Nfc from './views/Nfc.svelte'
const appWindow = getCurrentWindow();
const appWindow = getCurrentWindow()
if (appWindow.label !== "main") {
if (appWindow.label !== 'main') {
appWindow.onCloseRequested(async (event) => {
const confirmed = await confirm("Are you sure?");
const confirmed = await confirm('Are you sure?')
if (!confirmed) {
// user did not confirm closing the window; let's prevent it
event.preventDefault();
event.preventDefault()
}
});
})
}
getCurrentWebview().onDragDropEvent((event) => {
onMessage(`File drop: ${JSON.stringify(event.payload)}`);
});
onMessage(`File drop: ${JSON.stringify(event.payload)}`)
})
const userAgent = navigator.userAgent.toLowerCase();
const isMobile =
userAgent.includes("android") || userAgent.includes("iphone");
const userAgent = navigator.userAgent.toLowerCase()
const isMobile = userAgent.includes('android') || userAgent.includes('iphone')
const views = [
{
label: "Welcome",
label: 'Welcome',
component: Welcome,
icon: "i-ph-hand-waving",
icon: 'i-ph-hand-waving'
},
{
label: "Communication",
label: 'Communication',
component: Communication,
icon: "i-codicon-radio-tower",
icon: 'i-codicon-radio-tower'
},
!isMobile && {
label: "CLI",
label: 'CLI',
component: Cli,
icon: "i-codicon-terminal",
icon: 'i-codicon-terminal'
},
{
label: "Dialog",
label: 'Dialog',
component: Dialog,
icon: "i-codicon-multiple-windows",
icon: 'i-codicon-multiple-windows'
},
{
label: "File system",
label: 'File system',
component: FileSystem,
icon: "i-codicon-files",
icon: 'i-codicon-files'
},
{
label: "HTTP",
label: 'HTTP',
component: Http,
icon: "i-ph-globe-hemisphere-west",
icon: 'i-ph-globe-hemisphere-west'
},
{
label: "Notifications",
label: 'Notifications',
component: Notifications,
icon: "i-codicon-bell-dot",
icon: 'i-codicon-bell-dot'
},
!isMobile && {
label: "Shortcuts",
label: 'Shortcuts',
component: Shortcuts,
icon: "i-codicon-record-keys",
icon: 'i-codicon-record-keys'
},
{
label: "Shell",
label: 'Shell',
component: Shell,
icon: "i-codicon-terminal-bash",
icon: 'i-codicon-terminal-bash'
},
{
label: "Store",
label: 'Store',
component: Store,
icon: "i-codicon-file-code",
icon: 'i-codicon-file-code'
},
!isMobile && {
label: "Updater",
label: 'Updater',
component: Updater,
icon: "i-codicon-cloud-download",
icon: 'i-codicon-cloud-download'
},
{
label: "Clipboard",
label: 'Clipboard',
component: Clipboard,
icon: "i-codicon-clippy",
icon: 'i-codicon-clippy'
},
{
label: "WebRTC",
label: 'WebRTC',
component: WebRTC,
icon: "i-ph-broadcast",
icon: 'i-ph-broadcast'
},
isMobile && {
label: "Scanner",
label: 'Scanner',
component: Scanner,
icon: "i-ph-scan",
icon: 'i-ph-scan'
},
isMobile && {
label: "NFC",
label: 'NFC',
component: Nfc,
icon: "i-ph-nfc",
icon: 'i-ph-nfc'
},
isMobile && {
label: "Biometric",
label: 'Biometric',
component: Biometric,
icon: "i-ph-scan",
icon: 'i-ph-scan'
},
];
isMobile && {
label: 'Geolocation',
component: Geolocation,
icon: 'i-ph-map-pin'
}
]
let selected = views[0];
let selected = views[0]
function select(view) {
selected = view;
selected = view
}
// Window controls
let isWindowMaximized;
let isWindowMaximized
onMount(async () => {
isWindowMaximized = await appWindow.isMaximized();
isWindowMaximized = await appWindow.isMaximized()
appWindow.onResized(async () => {
isWindowMaximized = await appWindow.isMaximized();
});
});
isWindowMaximized = await appWindow.isMaximized()
})
})
function minimize() {
appWindow.minimize();
appWindow.minimize()
}
async function toggleMaximize() {
(await appWindow.isMaximized())
;(await appWindow.isMaximized())
? appWindow.unmaximize()
: appWindow.maximize();
: appWindow.maximize()
}
let confirmed_close = false;
let confirmed_close = false
async function close() {
if (!confirmed_close) {
confirmed_close = await ask(
"Are you sure that you want to close this window?",
'Are you sure that you want to close this window?',
{
title: "Tauri API",
title: 'Tauri API'
}
);
)
if (confirmed_close) {
appWindow.close();
appWindow.close()
}
}
}
// dark/light
let isDark;
let isDark
onMount(() => {
isDark = localStorage && localStorage.getItem("theme") == "dark";
applyTheme(isDark);
});
isDark = localStorage && localStorage.getItem('theme') == 'dark'
applyTheme(isDark)
})
function applyTheme(isDark) {
const html = document.querySelector("html");
isDark ? html.classList.add("dark") : html.classList.remove("dark");
localStorage && localStorage.setItem("theme", isDark ? "dark" : "");
const html = document.querySelector('html')
isDark ? html.classList.add('dark') : html.classList.remove('dark')
localStorage && localStorage.setItem('theme', isDark ? 'dark' : '')
}
function toggleDark() {
isDark = !isDark;
applyTheme(isDark);
isDark = !isDark
applyTheme(isDark)
}
// Console
let messages = writable([]);
let consoleTextEl;
let messages = writable([])
let consoleTextEl
async function onMessage(value) {
messages.update((r) => [
...r,
{
html:
`<pre><strong class="text-accent dark:text-darkAccent">[${new Date().toLocaleTimeString()}]:</strong> ` +
(typeof value === "string" ? value : JSON.stringify(value, null, 1)) +
"</pre>",
},
]);
await tick();
if (consoleTextEl) consoleTextEl.scrollTop = consoleTextEl.scrollHeight;
(typeof value === 'string' ? value : JSON.stringify(value, null, 1)) +
'</pre>'
}
])
await tick()
if (consoleTextEl) consoleTextEl.scrollTop = consoleTextEl.scrollHeight
}
// this function is renders HTML without sanitizing it so it's insecure
@@ -209,111 +214,109 @@
html:
`<pre><strong class="text-accent dark:text-darkAccent">[${new Date().toLocaleTimeString()}]:</strong> ` +
html +
"</pre>",
},
]);
await tick();
if (consoleTextEl) consoleTextEl.scrollTop = consoleTextEl.scrollHeight;
'</pre>'
}
])
await tick()
if (consoleTextEl) consoleTextEl.scrollTop = consoleTextEl.scrollHeight
}
function clear() {
messages.update(() => []);
messages.update(() => [])
}
let consoleEl, consoleH, cStartY;
let minConsoleHeight = 50;
let consoleEl, consoleH, cStartY
let minConsoleHeight = 50
function startResizingConsole(e) {
cStartY = e.clientY;
cStartY = e.clientY
const styles = window.getComputedStyle(consoleEl);
consoleH = parseInt(styles.height, 10);
const styles = window.getComputedStyle(consoleEl)
consoleH = parseInt(styles.height, 10)
const moveHandler = (e) => {
const dy = e.clientY - cStartY;
const newH = consoleH - dy;
const dy = e.clientY - cStartY
const newH = consoleH - dy
consoleEl.style.height = `${
newH < minConsoleHeight ? minConsoleHeight : newH
}px`;
};
}px`
}
const upHandler = () => {
document.removeEventListener("mouseup", upHandler);
document.removeEventListener("mousemove", moveHandler);
};
document.addEventListener("mouseup", upHandler);
document.addEventListener("mousemove", moveHandler);
document.removeEventListener('mouseup', upHandler)
document.removeEventListener('mousemove', moveHandler)
}
document.addEventListener('mouseup', upHandler)
document.addEventListener('mousemove', moveHandler)
}
let isWindows;
let isWindows
onMount(async () => {
isWindows = (await os.platform()) === "windows";
});
isWindows = (await os.platform()) === 'windows'
})
// mobile
let isSideBarOpen = false;
let sidebar;
let sidebarToggle;
let isDraggingSideBar = false;
let draggingStartPosX = 0;
let draggingEndPosX = 0;
const clamp = (min, num, max) => Math.min(Math.max(num, min), max);
let isSideBarOpen = false
let sidebar
let sidebarToggle
let isDraggingSideBar = false
let draggingStartPosX = 0
let draggingEndPosX = 0
const clamp = (min, num, max) => Math.min(Math.max(num, min), max)
function toggleSidebar(sidebar, isSideBarOpen) {
sidebar.style.setProperty(
"--translate-x",
`${isSideBarOpen ? "0" : "-18.75"}rem`
);
'--translate-x',
`${isSideBarOpen ? '0' : '-18.75'}rem`
)
}
onMount(() => {
sidebar = document.querySelector("#sidebar");
sidebarToggle = document.querySelector("#sidebarToggle");
sidebar = document.querySelector('#sidebar')
sidebarToggle = document.querySelector('#sidebarToggle')
document.addEventListener("click", (e) => {
document.addEventListener('click', (e) => {
if (sidebarToggle.contains(e.target)) {
isSideBarOpen = !isSideBarOpen;
isSideBarOpen = !isSideBarOpen
} else if (isSideBarOpen && !sidebar.contains(e.target)) {
isSideBarOpen = false;
isSideBarOpen = false
}
});
})
document.addEventListener("touchstart", (e) => {
if (sidebarToggle.contains(e.target)) return;
document.addEventListener('touchstart', (e) => {
if (sidebarToggle.contains(e.target)) return
const x = e.touches[0].clientX;
const x = e.touches[0].clientX
if ((0 < x && x < 20 && !isSideBarOpen) || isSideBarOpen) {
isDraggingSideBar = true;
draggingStartPosX = x;
isDraggingSideBar = true
draggingStartPosX = x
}
});
})
document.addEventListener("touchmove", (e) => {
document.addEventListener('touchmove', (e) => {
if (isDraggingSideBar) {
const x = e.touches[0].clientX;
draggingEndPosX = x;
const delta = (x - draggingStartPosX) / 10;
const x = e.touches[0].clientX
draggingEndPosX = x
const delta = (x - draggingStartPosX) / 10
sidebar.style.setProperty(
"--translate-x",
'--translate-x',
`-${clamp(0, isSideBarOpen ? 0 - delta : 18.75 - delta, 18.75)}rem`
);
)
}
});
})
document.addEventListener("touchend", () => {
document.addEventListener('touchend', () => {
if (isDraggingSideBar) {
const delta = (draggingEndPosX - draggingStartPosX) / 10;
isSideBarOpen = isSideBarOpen
? delta > -(18.75 / 2)
: delta > 18.75 / 2;
const delta = (draggingEndPosX - draggingStartPosX) / 10
isSideBarOpen = isSideBarOpen ? delta > -(18.75 / 2) : delta > 18.75 / 2
}
isDraggingSideBar = false;
});
});
isDraggingSideBar = false
})
})
$: {
const sidebar = document.querySelector("#sidebar");
const sidebar = document.querySelector('#sidebar')
if (sidebar) {
toggleSidebar(sidebar, isSideBarOpen);
toggleSidebar(sidebar, isSideBarOpen)
}
}
</script>
@@ -332,7 +335,7 @@
children:items-center children:justify-center"
>
<span
title={isDark ? "Switch to Light mode" : "Switch to Dark mode"}
title={isDark ? 'Switch to Light mode' : 'Switch to Dark mode'}
class="hover:bg-hoverOverlay active:bg-hoverOverlayDarker dark:hover:bg-darkHoverOverlay dark:active:bg-darkHoverOverlayDarker"
on:click={toggleDark}
>
@@ -350,7 +353,7 @@
<div class="i-codicon-chrome-minimize" />
</span>
<span
title={isWindowMaximized ? "Restore" : "Maximize"}
title={isWindowMaximized ? 'Restore' : 'Maximize'}
class="hover:bg-hoverOverlay active:bg-hoverOverlayDarker dark:hover:bg-darkHoverOverlay dark:active:bg-darkHoverOverlayDarker"
on:click={toggleMaximize}
>
@@ -393,7 +396,7 @@
bg-darkPrimaryLighter transition-colors-250 overflow-hidden grid select-none px-2"
>
<img
on:click={() => open("https://tauri.app/")}
on:click={() => open('https://tauri.app/')}
class="self-center p-7 cursor-pointer"
src="tauri_logo.png"
alt="Tauri logo"
@@ -449,8 +452,8 @@
href="##"
class="nv {selected === view ? 'nv_selected' : ''}"
on:click={() => {
select(view);
isSideBarOpen = false;
select(view)
isSideBarOpen = false
}}
>
<div class="{view.icon} mr-2" />
+28 -29
View File
@@ -1,59 +1,59 @@
<script>
import * as clipboard from "@tauri-apps/plugin-clipboard-manager";
import { open } from "@tauri-apps/plugin-dialog";
import { arrayBufferToBase64 } from "../lib/utils";
import { readFile } from "@tauri-apps/plugin-fs";
import * as clipboard from '@tauri-apps/plugin-clipboard-manager'
import { open } from '@tauri-apps/plugin-dialog'
import { arrayBufferToBase64 } from '../lib/utils'
import { readFile } from '@tauri-apps/plugin-fs'
export let onMessage;
export let insecureRenderHtml;
let text = "clipboard message";
export let onMessage
export let insecureRenderHtml
let text = 'clipboard message'
function writeText() {
clipboard
.writeText(text)
.then(() => {
onMessage("Wrote to the clipboard");
onMessage('Wrote to the clipboard')
})
.catch(onMessage);
.catch(onMessage)
}
async function writeImage() {
try {
const res = await open({
title: "Image to write to clipboard",
const path = await open({
title: 'Image to write to clipboard',
filters: [
{
name: "Clipboard IMG",
extensions: ["png", "jpg", "jpeg"],
},
],
});
const bytes = await readFile(res.path);
await clipboard.writeImage(bytes);
onMessage("wrote image");
name: 'Clipboard IMG',
extensions: ['png', 'jpg', 'jpeg']
}
]
})
const bytes = await readFile(path)
await clipboard.writeImage(bytes)
onMessage('wrote image')
} catch (e) {
onMessage(e);
onMessage(e)
}
}
async function read() {
try {
const image = await clipboard.readImage();
const image = await clipboard.readImage()
arrayBufferToBase64(await image.rgba(), function (base64) {
const src = "data:image/png;base64," + base64;
insecureRenderHtml('<img src="' + src + '"></img>');
});
return;
const src = 'data:image/png;base64,' + base64
insecureRenderHtml('<img src="' + src + '"></img>')
})
return
} catch (_) {}
clipboard
.readText()
.then((contents) => {
onMessage(`Clipboard contents: ${contents}`);
onMessage(`Clipboard contents: ${contents}`)
})
.catch((e) => {
onMessage(e);
});
onMessage(e)
})
}
</script>
@@ -65,6 +65,5 @@
/>
<button class="btn" type="button" on:click={writeText}>Write</button>
<button class="btn" type="button" on:click={writeImage}>Pick Image</button>
<button class="btn" type="button" on:click={read}>Read</button>
</div>
+29
View File
@@ -0,0 +1,29 @@
<script>
import {
checkPermissions,
requestPermissions,
getCurrentPosition
} from '@tauri-apps/plugin-geolocation'
export let onMessage
async function getPosition() {
let permissions = await checkPermissions()
if (
permissions.location === 'prompt' ||
permissions.location === 'prompt-with-rationale'
) {
permissions = await requestPermissions(['location'])
}
if (permissions.location === 'granted') {
getCurrentPosition().then(onMessage).catch(onMessage)
} else {
onMessage('permission denied')
}
}
</script>
<button class="btn" id="cli-matches" on:click={getPosition}>
Get Position
</button>
+6 -6
View File
@@ -10,20 +10,20 @@
"format:check": "prettier --check ."
},
"devDependencies": {
"@eslint/js": "9.10.0",
"@rollup/plugin-node-resolve": "15.2.3",
"@eslint/js": "9.11.1",
"@rollup/plugin-node-resolve": "15.3.0",
"@rollup/plugin-terser": "0.4.4",
"@rollup/plugin-typescript": "11.1.6",
"@types/eslint__js": "8.42.3",
"covector": "^0.12.0",
"eslint": "9.10.0",
"covector": "^0.12.3",
"eslint": "9.11.1",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-security": "3.0.1",
"prettier": "3.3.3",
"rollup": "4.21.2",
"rollup": "4.22.4",
"tslib": "2.7.0",
"typescript": "5.6.2",
"typescript-eslint": "8.5.0"
"typescript-eslint": "8.7.0"
},
"resolutions": {
"semver": ">=7.5.2",
+7
View File
@@ -13,6 +13,13 @@ links = "tauri-plugin-autostart"
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.platforms.support]
windows = { level = "full", notes = "" }
linux = { level = "full", notes = "" }
macos = { level = "full", notes = "" }
android = { level = "none", notes = "" }
ios = { level = "none", notes = "" }
[build-dependencies]
tauri-plugin = { workspace = true, features = ["build"] }
@@ -15,7 +15,7 @@ disable the automatic start on boot.
- `allow-disable`
- `allow-is-enabled`
## Permission Table
## Permission Table
<table>
<tr>
@@ -295,53 +295,39 @@
"type": "string",
"oneOf": [
{
"description": "allow-disable -> Enables the disable command without any pre-configured scope.",
"description": "Enables the disable command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-disable"
]
"const": "allow-disable"
},
{
"description": "deny-disable -> Denies the disable command without any pre-configured scope.",
"description": "Denies the disable command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-disable"
]
"const": "deny-disable"
},
{
"description": "allow-enable -> Enables the enable command without any pre-configured scope.",
"description": "Enables the enable command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-enable"
]
"const": "allow-enable"
},
{
"description": "deny-enable -> Denies the enable command without any pre-configured scope.",
"description": "Denies the enable command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-enable"
]
"const": "deny-enable"
},
{
"description": "allow-is-enabled -> Enables the is_enabled command without any pre-configured scope.",
"description": "Enables the is_enabled command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-is-enabled"
]
"const": "allow-is-enabled"
},
{
"description": "deny-is-enabled -> Denies the is_enabled command without any pre-configured scope.",
"description": "Denies the is_enabled command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-is-enabled"
]
"const": "deny-is-enabled"
},
{
"description": "default -> 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",
"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",
"type": "string",
"enum": [
"default"
]
"const": "default"
}
]
}
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.0.0-rc.2]
- [`79d6e19c`](https://github.com/tauri-apps/plugins-workspace/commit/79d6e19c4b38bae0cab29eb88df379e2237d9aac) ([#1777](https://github.com/tauri-apps/plugins-workspace/pull/1777)) Fixed an issue which caused checkPermission and requestPermission to be mixed up.
## \[2.0.0-rc.4]
- [`713c54ef`](https://github.com/tauri-apps/plugins-workspace/commit/713c54ef8365d36afd84585dcabed2fbb751223d) ([#1749](https://github.com/tauri-apps/plugins-workspace/pull/1749) by [@olivierlemasle](https://github.com/tauri-apps/plugins-workspace/../../olivierlemasle)) Remove unused Android dependencies.
+8
View File
@@ -14,6 +14,14 @@ rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
targets = ["x86_64-linux-android"]
[package.metadata.platforms.support]
windows = { level = "none", notes = "" }
linux = { level = "none", notes = "" }
macos = { level = "none", notes = "" }
android = { level = "full", notes = "" }
ios = { level = "full", notes = "" }
[build-dependencies]
tauri-plugin = { workspace = true, features = ["build"] }
+1 -1
View File
@@ -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}|request_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}|check_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 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__})}
+2 -2
View File
@@ -4,8 +4,8 @@
import {
invoke,
requestPermissions as checkPermissions_,
checkPermissions as requestPermissions_
requestPermissions as requestPermissions_,
checkPermissions as checkPermissions_
} from '@tauri-apps/api/core'
export type { PermissionState } from '@tauri-apps/api/core'
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-barcode-scanner",
"version": "2.0.0-rc.1",
"version": "2.0.0-rc.2",
"description": "Scan QR codes, EAN-13 and other kinds of barcodes on Android and iOS",
"license": "MIT or APACHE-2.0",
"authors": [
@@ -16,7 +16,7 @@ It allows all barcode related features.
- `allow-scan`
- `allow-vibrate`
## Permission Table
## Permission Table
<table>
<tr>
@@ -295,95 +295,69 @@
"type": "string",
"oneOf": [
{
"description": "allow-cancel -> Enables the cancel command without any pre-configured scope.",
"description": "Enables the cancel command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-cancel"
]
"const": "allow-cancel"
},
{
"description": "deny-cancel -> Denies the cancel command without any pre-configured scope.",
"description": "Denies the cancel command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-cancel"
]
"const": "deny-cancel"
},
{
"description": "allow-check-permissions -> Enables the check_permissions command without any pre-configured scope.",
"description": "Enables the check_permissions command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-check-permissions"
]
"const": "allow-check-permissions"
},
{
"description": "deny-check-permissions -> Denies the check_permissions command without any pre-configured scope.",
"description": "Denies the check_permissions command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-check-permissions"
]
"const": "deny-check-permissions"
},
{
"description": "allow-open-app-settings -> Enables the open_app_settings command without any pre-configured scope.",
"description": "Enables the open_app_settings command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-open-app-settings"
]
"const": "allow-open-app-settings"
},
{
"description": "deny-open-app-settings -> Denies the open_app_settings command without any pre-configured scope.",
"description": "Denies the open_app_settings command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-open-app-settings"
]
"const": "deny-open-app-settings"
},
{
"description": "allow-request-permissions -> Enables the request_permissions command without any pre-configured scope.",
"description": "Enables the request_permissions command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-request-permissions"
]
"const": "allow-request-permissions"
},
{
"description": "deny-request-permissions -> Denies the request_permissions command without any pre-configured scope.",
"description": "Denies the request_permissions command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-request-permissions"
]
"const": "deny-request-permissions"
},
{
"description": "allow-scan -> Enables the scan command without any pre-configured scope.",
"description": "Enables the scan command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-scan"
]
"const": "allow-scan"
},
{
"description": "deny-scan -> Denies the scan command without any pre-configured scope.",
"description": "Denies the scan command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-scan"
]
"const": "deny-scan"
},
{
"description": "allow-vibrate -> Enables the vibrate command without any pre-configured scope.",
"description": "Enables the vibrate command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-vibrate"
]
"const": "allow-vibrate"
},
{
"description": "deny-vibrate -> Denies the vibrate command without any pre-configured scope.",
"description": "Denies the vibrate command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-vibrate"
]
"const": "deny-vibrate"
},
{
"description": "default -> This permission set configures which\nbarcode scanning features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all barcode related features.\n\n",
"description": "This permission set configures which\nbarcode scanning features are by default exposed.\n\n#### Granted Permissions\n\nIt allows all barcode related features.\n\n",
"type": "string",
"enum": [
"default"
]
"const": "default"
}
]
}
+8
View File
@@ -13,6 +13,14 @@ rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
targets = ["x86_64-linux-android"]
[package.metadata.platforms.support]
windows = { level = "none", notes = "" }
linux = { level = "none", notes = "" }
macos = { level = "none", notes = "" }
android = { level = "full", notes = "" }
ios = { level = "full", notes = "" }
[build-dependencies]
tauri-plugin = { workspace = true, features = ["build"] }
@@ -12,7 +12,7 @@ It allows acccess to all biometric commands.
- `allow-authenticate`
- `allow-status`
## Permission Table
## Permission Table
<table>
<tr>
@@ -295,39 +295,29 @@
"type": "string",
"oneOf": [
{
"description": "allow-authenticate -> Enables the authenticate command without any pre-configured scope.",
"description": "Enables the authenticate command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-authenticate"
]
"const": "allow-authenticate"
},
{
"description": "deny-authenticate -> Denies the authenticate command without any pre-configured scope.",
"description": "Denies the authenticate command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-authenticate"
]
"const": "deny-authenticate"
},
{
"description": "allow-status -> Enables the status command without any pre-configured scope.",
"description": "Enables the status command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-status"
]
"const": "allow-status"
},
{
"description": "deny-status -> Denies the status command without any pre-configured scope.",
"description": "Denies the status command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-status"
]
"const": "deny-status"
},
{
"description": "default -> 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",
"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",
"type": "string",
"enum": [
"default"
]
"const": "default"
}
]
}
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.0.0-rc.2]
- [`68579934`](https://github.com/tauri-apps/plugins-workspace/commit/68579934c93f6ed2edbc97474560d6a8a00e8f70) ([#1856](https://github.com/tauri-apps/plugins-workspace/pull/1856) by [@amrbashir](https://github.com/tauri-apps/plugins-workspace/../../amrbashir)) Expose `Matches`, `SubcommandMatches` and `ArgData` structs.
## \[2.0.0-rc.1]
- [`e2e97db5`](https://github.com/tauri-apps/plugins-workspace/commit/e2e97db51983267f5be84d4f6f0278d58834d1f5) ([#1701](https://github.com/tauri-apps/plugins-workspace/pull/1701) by [@lucasfernog](https://github.com/tauri-apps/plugins-workspace/../../lucasfernog)) Update to tauri 2.0.0-rc.8
+9 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-cli"
version = "2.0.0-rc.1"
version = "2.0.0-rc.2"
description = "Parse arguments from your Tauri application's command line interface."
edition = { workspace = true }
authors = { workspace = true }
@@ -13,6 +13,14 @@ links = "tauri-plugin-cli"
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.platforms.support]
windows = { level = "full", notes = "" }
linux = { level = "full", notes = "" }
macos = { level = "full", notes = "" }
android = { level = "none", notes = "" }
ios = { level = "none", notes = "" }
[build-dependencies]
tauri-plugin = { workspace = true, features = ["build"] }
@@ -4,7 +4,7 @@ Allows reading the CLI matches
- `allow-cli-matches`
## Permission Table
## Permission Table
<table>
<tr>
+6 -12
View File
@@ -295,25 +295,19 @@
"type": "string",
"oneOf": [
{
"description": "allow-cli-matches -> Enables the cli_matches command without any pre-configured scope.",
"description": "Enables the cli_matches command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-cli-matches"
]
"const": "allow-cli-matches"
},
{
"description": "deny-cli-matches -> Denies the cli_matches command without any pre-configured scope.",
"description": "Denies the cli_matches command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-cli-matches"
]
"const": "deny-cli-matches"
},
{
"description": "default -> Allows reading the CLI matches",
"description": "Allows reading the CLI matches",
"type": "string",
"enum": [
"default"
]
"const": "default"
}
]
}
+2
View File
@@ -18,3 +18,5 @@ impl Serialize for Error {
serializer.serialize_str(self.to_string().as_ref())
}
}
pub type Result<T> = std::result::Result<T, Error>;
+3 -2
View File
@@ -23,8 +23,9 @@ mod error;
mod parser;
use config::{Arg, Config};
pub use error::Error;
type Result<T> = std::result::Result<T, Error>;
pub use error::{Error, Result};
pub use parser::{ArgData, Matches, SubcommandMatches};
pub struct Cli<R: Runtime>(PluginApi<R, Config>);
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## \[2.0.0-rc.2]
- [`341a5320`](https://github.com/tauri-apps/plugins-workspace/commit/341a5320c33d3c7b041abf7eb0ab7ad8009e6c3f) ([#1771](https://github.com/tauri-apps/plugins-workspace/pull/1771)) Fix warnings and clear implementation on Android below SDK 28.
## \[2.0.0-rc.1]
- [`e2e97db5`](https://github.com/tauri-apps/plugins-workspace/commit/e2e97db51983267f5be84d4f6f0278d58834d1f5) ([#1701](https://github.com/tauri-apps/plugins-workspace/pull/1701) by [@lucasfernog](https://github.com/tauri-apps/plugins-workspace/../../lucasfernog)) Update to tauri 2.0.0-rc.8
+10 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-clipboard-manager"
version = "2.0.0-rc.3"
version = "2.0.0-rc.4"
description = "Read and write to the system clipboard."
edition = { workspace = true }
authors = { workspace = true }
@@ -14,6 +14,14 @@ rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]
targets = ["x86_64-unknown-linux-gnu", "x86_64-linux-android"]
[package.metadata.platforms.support]
windows = { level = "full", notes = "" }
linux = { level = "full", notes = "" }
macos = { level = "full", notes = "" }
android = { level = "partial", notes = "Only plain-text content support" }
ios = { level = "partial", notes = "Only plain-text content support" }
[build-dependencies]
tauri-plugin = { workspace = true, features = ["build"] }
@@ -29,4 +37,4 @@ 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]
arboard = "3"
image = "0.24"
image = "0.25"
@@ -4,12 +4,12 @@
package app.tauri.clipboard
import android.R.attr.value
import android.app.Activity
import android.content.ClipData
import android.content.ClipDescription
import android.content.ClipboardManager
import android.content.Context
import android.os.Build
import app.tauri.annotation.Command
import app.tauri.annotation.InvokeArg
import app.tauri.annotation.TauriPlugin
@@ -59,6 +59,9 @@ internal class ReadClipDataSerializer @JvmOverloads constructor(t: Class<ReadCli
jgen.writeEndObject()
}
else -> {
throw Exception("unimplemented ReadClipData")
}
}
jgen.writeEndObject()
@@ -93,7 +96,7 @@ class ClipboardPlugin(private val activity: Activity) : Plugin(activity) {
is WriteOptions.PlainText -> {
ClipData.newPlainText(args.label, args.text)
} else -> {
invoke.reject("Invalid write options provided")
invoke.reject("unimplemented WriteOptions")
return
}
@@ -128,7 +131,11 @@ class ClipboardPlugin(private val activity: Activity) : Plugin(activity) {
@Command
fun clear(invoke: Invoke) {
if (manager.hasPrimaryClip()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
manager.clearPrimaryClip()
} else {
manager.setPrimaryClip(ClipData.newPlainText("", ""))
}
}
invoke.resolve()
}
@@ -114,6 +114,11 @@ async function writeHtml(html: string, altHtml?: string): Promise<void> {
/**
* Clears the clipboard.
*
* #### Platform-specific
*
* - **Android:** Only supported on SDK 28+. For older releases we write an empty string to the clipboard instead.
*
* @example
* ```typescript
* import { clear } from '@tauri-apps/plugin-clipboard-manager';
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-clipboard-manager",
"version": "2.0.0-rc.1",
"version": "2.0.0-rc.2",
"license": "MIT or APACHE-2.0",
"authors": [
"Tauri Programme within The Commons Conservancy"
@@ -8,7 +8,7 @@ Clipboard interaction needs to be explicitly enabled.
## Permission Table
## Permission Table
<table>
<tr>
@@ -295,95 +295,69 @@
"type": "string",
"oneOf": [
{
"description": "allow-clear -> Enables the clear command without any pre-configured scope.",
"description": "Enables the clear command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-clear"
]
"const": "allow-clear"
},
{
"description": "deny-clear -> Denies the clear command without any pre-configured scope.",
"description": "Denies the clear command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-clear"
]
"const": "deny-clear"
},
{
"description": "allow-read-image -> Enables the read_image command without any pre-configured scope.",
"description": "Enables the read_image command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-read-image"
]
"const": "allow-read-image"
},
{
"description": "deny-read-image -> Denies the read_image command without any pre-configured scope.",
"description": "Denies the read_image command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-read-image"
]
"const": "deny-read-image"
},
{
"description": "allow-read-text -> Enables the read_text command without any pre-configured scope.",
"description": "Enables the read_text command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-read-text"
]
"const": "allow-read-text"
},
{
"description": "deny-read-text -> Denies the read_text command without any pre-configured scope.",
"description": "Denies the read_text command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-read-text"
]
"const": "deny-read-text"
},
{
"description": "allow-write-html -> Enables the write_html command without any pre-configured scope.",
"description": "Enables the write_html command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-write-html"
]
"const": "allow-write-html"
},
{
"description": "deny-write-html -> Denies the write_html command without any pre-configured scope.",
"description": "Denies the write_html command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-write-html"
]
"const": "deny-write-html"
},
{
"description": "allow-write-image -> Enables the write_image command without any pre-configured scope.",
"description": "Enables the write_image command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-write-image"
]
"const": "allow-write-image"
},
{
"description": "deny-write-image -> Denies the write_image command without any pre-configured scope.",
"description": "Denies the write_image command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-write-image"
]
"const": "deny-write-image"
},
{
"description": "allow-write-text -> Enables the write_text command without any pre-configured scope.",
"description": "Enables the write_text command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-write-text"
]
"const": "allow-write-text"
},
{
"description": "deny-write-text -> Denies the write_text command without any pre-configured scope.",
"description": "Denies the write_text command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-write-text"
]
"const": "deny-write-text"
},
{
"description": "default -> 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\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",
"type": "string",
"enum": [
"default"
]
"const": "default"
}
]
}
+1 -1
View File
@@ -91,7 +91,7 @@ impl<R: Runtime> Clipboard<R> {
&image.bytes,
image.width as u32,
image.height as u32,
image::ColorType::Rgba8,
image::ExtendedColorType::Rgba8,
)?;
let image = Image::new_owned(buffer, image.width as u32, image.height as u32);
+21
View File
@@ -1,5 +1,23 @@
# Changelog
## \[2.0.0-rc.7]
- [`3168e176`](https://github.com/tauri-apps/plugins-workspace/commit/3168e176031a61215be542595ba90ca51f8f2d97) ([#1806](https://github.com/tauri-apps/plugins-workspace/pull/1806) by [@auggiebennett](https://github.com/tauri-apps/plugins-workspace/../../auggiebennett)) Fix fails to start when having spaces in the main binary path on Windows
## \[2.0.0-rc.6]
- [`6f3f6679`](https://github.com/tauri-apps/plugins-workspace/commit/6f3f66794a87ef9d1c16667c425d5ad7091a9c2f) ([#1780](https://github.com/tauri-apps/plugins-workspace/pull/1780)) Added `DeepLink::on_open_url` function to match the JavaScript API implementation,
which wraps the `deep-link://new-url` event and also send the current deep link if there's any.
## \[2.0.0-rc.5]
- [`984110a9`](https://github.com/tauri-apps/plugins-workspace/commit/984110a978774712bad4d746ed06134d54debcd0) ([#1770](https://github.com/tauri-apps/plugins-workspace/pull/1770) by [@lucasfernog](https://github.com/tauri-apps/plugins-workspace/../../lucasfernog)) Emit the `deep-link://new-url` event on Linux and Windows when the app is executed with a deep link CLI argument,
matching the iOS and macOS behavior.
## \[2.0.0-rc.2]
- [`64a6240f`](https://github.com/tauri-apps/plugins-workspace/commit/64a6240f79fcd52267c8d721b727ae695055d7ff) ([#1759](https://github.com/tauri-apps/plugins-workspace/pull/1759) by [@lucasfernog](https://github.com/tauri-apps/plugins-workspace/../../lucasfernog)) Implement `get_current` on Linux and Windows.
## \[2.0.0-rc.3]
- [`4654591d`](https://github.com/tauri-apps/plugins-workspace/commit/4654591d820403d6fa1a007fd55bb0d85947a6cc) ([#1732](https://github.com/tauri-apps/plugins-workspace/pull/1732) by [@lucasfernog](https://github.com/tauri-apps/plugins-workspace/../../lucasfernog)) Allow empty configuration values.
@@ -104,3 +122,6 @@
- [`eccd6f9`](https://github.com/tauri-apps/plugins-workspace/commit/eccd6f977af7629255b6f5a5205666c9079a86ed)([#504](https://github.com/tauri-apps/plugins-workspace/pull/504)) Initial release.
commit/eccd6f977af7629255b6f5a5205666c9079a86ed)([#504](https://github.com/tauri-apps/plugins-workspace/pull/504)) Initial release.
ithub.com/tauri-apps/plugins-workspace/pull/504)) Initial release.
]\(https://github.com/tauri-apps/plugins-workspace/commit/eccd6f977af7629255b6f5a5205666c9079a86ed)([#504](https://github.com/tauri-apps/plugins-workspace/pull/504)) Initial release.
commit/eccd6f977af7629255b6f5a5205666c9079a86ed)([#504](https://github.com/tauri-apps/plugins-workspace/pull/504)) Initial release.
ithub.com/tauri-apps/plugins-workspace/pull/504)) Initial release.
+9 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "tauri-plugin-deep-link"
version = "2.0.0-rc.3"
version = "2.0.0-rc.7"
description = "Set your Tauri application as the default handler for an URL"
authors = { workspace = true }
license = { workspace = true }
@@ -14,6 +14,13 @@ 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" }
[build-dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
@@ -31,7 +38,7 @@ url = { workspace = true }
[target."cfg(windows)".dependencies]
dunce = "1"
windows-registry = "0.2"
windows-registry = "0.3"
windows-result = "0.2"
[target."cfg(target_os = \"linux\")".dependencies]
+1 -1
View File
@@ -145,7 +145,7 @@ await onOpenUrl((urls) => {
})
```
Note that the Plugin will only emit events on macOS, iOS and Android. On Windows and Linux the OS will spawn a new instance of your app with the URL as a CLI argument. If you want your app to behave on Windows & Linux similar to the other platforms you can use the [single-instance](../single-instance/) plugin.
Note that the Plugin will only emit events on macOS, iOS and Android. On Windows and Linux the OS will spawn a new instance of your app with the URL as a CLI argument. If you want your app to behave on Windows & Linux similar to the other platforms you can use the [single-instance](../single-instance/) plugin with the `deep-link` feature enabled.
## Contributing
@@ -21,3 +21,5 @@ dist-ssr
*.njsproj
*.sln
*.sw?
dist/
@@ -1,5 +1,11 @@
# Changelog
## \[2.0.0-rc.1]
### Dependencies
- Upgraded to `deep-link-js@2.0.0-rc.2`
## \[2.0.0-rc.0]
### Dependencies
+5 -5
View File
@@ -1,7 +1,7 @@
{
"name": "deep-link-example",
"private": true,
"version": "2.0.0-rc.0",
"version": "2.0.0-rc.1",
"type": "module",
"scripts": {
"dev": "vite",
@@ -10,12 +10,12 @@
"tauri": "tauri"
},
"dependencies": {
"@tauri-apps/api": "2.0.0-rc.4",
"@tauri-apps/plugin-deep-link": "2.0.0-rc.1"
"@tauri-apps/api": "2.0.0-rc.6",
"@tauri-apps/plugin-deep-link": "2.0.0-rc.2"
},
"devDependencies": {
"@tauri-apps/cli": "2.0.0-rc.12",
"@tauri-apps/cli": "2.0.0-rc.17",
"typescript": "^5.2.2",
"vite": "^5.0.13"
"vite": "^5.4.7"
}
}
@@ -22,6 +22,9 @@ serde_json = { workspace = true }
tauri = { workspace = true, features = ["wry", "compression"] }
tauri-plugin-deep-link = { path = "../../../" }
tauri-plugin-log = { path = "../../../../log" }
tauri-plugin-single-instance = { path = "../../../../single-instance", features = [
"deep-link",
] }
log = "0.4"
[features]
@@ -41,15 +41,6 @@
<data android:host="tauri.app" />
</intent-filter>
<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:host="91f4-177-23-156-161.ngrok-free.app" />
<data android:pathPrefix="/open" />
</intent-filter>
<!-- DEEP LINK PLUGIN. AUTO-GENERATED. DO NOT REMOVE. -->
</activity>
@@ -17,7 +17,7 @@
<key>CFBundleShortVersionString</key>
<string>0.0.0</string>
<key>CFBundleVersion</key>
<string>0.0.0</string>
<string>0.1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
@@ -6,7 +6,6 @@
<array>
<string>applinks:fabianlars.de</string>
<string>applinks:tauri.app</string>
<string>applinks:91f4-177-23-156-161.ngrok-free.app</string>
</array>
</dict>
</plist>
@@ -2,17 +2,27 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use tauri::Listener;
use tauri_plugin_deep_link::DeepLinkExt;
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
format!("Hello, {name}! You've been greeted from Rust!")
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
#[allow(unused_mut)]
let mut builder = tauri::Builder::default();
#[cfg(desktop)]
{
builder = builder.plugin(tauri_plugin_single_instance::init(|_app, argv, _cwd| {
println!("single instance triggered: {argv:?}");
}));
}
builder
.plugin(tauri_plugin_deep_link::init())
.plugin(
tauri_plugin_log::Builder::default()
@@ -20,9 +30,17 @@ pub fn run() {
.build(),
)
.setup(|app| {
app.listen("deep-link://new-url", |url| {
dbg!(url);
// ensure deep links are registered on the system
// this is useful because AppImages requires additional setup to be available in the system
// and calling register() makes the deep links immediately available - without any user input
// additionally, we manually register on Windows on debug builds for development
#[cfg(any(target_os = "linux", all(debug_assertions, windows)))]
app.deep_link().register_all()?;
app.deep_link().on_open_url(|event| {
dbg!(event.urls());
});
Ok(())
})
.invoke_handler(tauri::generate_handler![greet])
@@ -29,8 +29,13 @@
},
"deep-link": {
"mobile": [
{ "host": "fabianlars.de", "pathPrefix": ["/intent"] },
{ "host": "tauri.app" }
{
"host": "fabianlars.de",
"pathPrefix": ["/intent"]
},
{
"host": "tauri.app"
}
],
"desktop": {
"schemes": ["fabianlars", "my-tauri-app"]
+3 -1
View File
@@ -14,7 +14,9 @@ import { type UnlistenFn, listen } from '@tauri-apps/api/event'
* const urls = await getCurrent();
* ```
*
* #### - **Windows / Linux**: Unsupported.
* #### - **Windows / Linux**: This function reads the command line arguments and checks if there's only one value, which must be an URL with scheme matching one of the configured values.
* Note that you must manually check the arguments when registering deep link schemes dynamically with [`Self::register`].
* Additionally, the deep link might have been provided as a CLI argument so you should check if its format matches what you expect..
*
* @since 2.0.0
*/
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@tauri-apps/plugin-deep-link",
"version": "2.0.0-rc.1",
"version": "2.0.0-rc.2",
"description": "Set your Tauri application as the default handler for an URL",
"license": "MIT or APACHE-2.0",
"authors": [
@@ -4,7 +4,7 @@ Allows reading the opened deep link via the get_current command
- `allow-get-current`
## Permission Table
## Permission Table
<table>
<tr>
@@ -295,67 +295,49 @@
"type": "string",
"oneOf": [
{
"description": "allow-get-current -> Enables the get_current command without any pre-configured scope.",
"description": "Enables the get_current command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-get-current"
]
"const": "allow-get-current"
},
{
"description": "deny-get-current -> Denies the get_current command without any pre-configured scope.",
"description": "Denies the get_current command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-get-current"
]
"const": "deny-get-current"
},
{
"description": "allow-is-registered -> Enables the is_registered command without any pre-configured scope.",
"description": "Enables the is_registered command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-is-registered"
]
"const": "allow-is-registered"
},
{
"description": "deny-is-registered -> Denies the is_registered command without any pre-configured scope.",
"description": "Denies the is_registered command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-is-registered"
]
"const": "deny-is-registered"
},
{
"description": "allow-register -> Enables the register command without any pre-configured scope.",
"description": "Enables the register command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-register"
]
"const": "allow-register"
},
{
"description": "deny-register -> Denies the register command without any pre-configured scope.",
"description": "Denies the register command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-register"
]
"const": "deny-register"
},
{
"description": "allow-unregister -> Enables the unregister command without any pre-configured scope.",
"description": "Enables the unregister command without any pre-configured scope.",
"type": "string",
"enum": [
"allow-unregister"
]
"const": "allow-unregister"
},
{
"description": "deny-unregister -> Denies the unregister command without any pre-configured scope.",
"description": "Denies the unregister command without any pre-configured scope.",
"type": "string",
"enum": [
"deny-unregister"
]
"const": "deny-unregister"
},
{
"description": "default -> Allows reading the opened deep link via the get_current command",
"description": "Allows reading the opened deep link via the get_current command",
"type": "string",
"enum": [
"default"
]
"const": "default"
}
]
}
+26 -3
View File
@@ -7,7 +7,7 @@
use serde::{Deserialize, Deserializer};
use tauri_utils::config::DeepLinkProtocol;
#[derive(Deserialize)]
#[derive(Deserialize, Clone)]
pub struct AssociatedDomain {
#[serde(deserialize_with = "deserialize_associated_host")]
pub host: String,
@@ -29,7 +29,7 @@ where
}
}
#[derive(Deserialize)]
#[derive(Deserialize, Clone)]
pub struct Config {
/// Mobile requires `https://<host>` urls.
#[serde(default)]
@@ -41,7 +41,7 @@ pub struct Config {
pub desktop: DesktopProtocol,
}
#[derive(Deserialize)]
#[derive(Deserialize, Clone)]
#[serde(untagged)]
#[allow(unused)] // Used in tauri-bundler
pub enum DesktopProtocol {
@@ -54,3 +54,26 @@ impl Default for DesktopProtocol {
Self::List(Vec::new())
}
}
impl DesktopProtocol {
#[allow(dead_code)]
pub fn contains_scheme(&self, scheme: &String) -> bool {
match self {
Self::One(protocol) => protocol.schemes.contains(scheme),
Self::List(protocols) => protocols
.iter()
.any(|protocol| protocol.schemes.contains(scheme)),
}
}
#[allow(dead_code)]
pub fn schemes(&self) -> Vec<String> {
match self {
Self::One(protocol) => protocol.schemes.clone(),
Self::List(protocols) => protocols
.iter()
.flat_map(|protocol| protocol.schemes.clone())
.collect(),
}
}
}
+149 -23
View File
@@ -2,10 +2,11 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use serde::de::DeserializeOwned;
use std::sync::Arc;
use tauri::{
plugin::{Builder, PluginApi, TauriPlugin},
AppHandle, Manager, Runtime,
AppHandle, EventId, Listener, Manager, Runtime,
};
mod commands;
@@ -17,12 +18,14 @@ pub use error::{Error, Result};
#[cfg(target_os = "android")]
const PLUGIN_IDENTIFIER: &str = "app.tauri.deep_link";
fn init_deep_link<R: Runtime, C: DeserializeOwned>(
fn init_deep_link<R: Runtime>(
app: &AppHandle<R>,
_api: PluginApi<R, C>,
api: PluginApi<R, Option<config::Config>>,
) -> crate::Result<DeepLink<R>> {
#[cfg(target_os = "android")]
{
let _api = api;
use tauri::{
ipc::{Channel, InvokeResponseBody},
Emitter,
@@ -56,22 +59,38 @@ fn init_deep_link<R: Runtime, C: DeserializeOwned>(
},
)?;
return Ok(DeepLink(handle));
return Ok(DeepLink {
app: app.clone(),
plugin_handle: handle,
});
}
#[cfg(not(target_os = "android"))]
Ok(DeepLink {
#[cfg(target_os = "ios")]
return Ok(DeepLink {
app: app.clone(),
current: Default::default(),
})
config: api.config().clone(),
});
#[cfg(desktop)]
{
let args = std::env::args();
let deep_link = DeepLink {
app: app.clone(),
current: Default::default(),
config: api.config().clone(),
};
deep_link.handle_cli_arguments(args);
Ok(deep_link)
}
}
#[cfg(target_os = "android")]
mod imp {
use tauri::{plugin::PluginHandle, Runtime};
use tauri::{ipc::Channel, plugin::PluginHandle, AppHandle, Runtime};
use serde::{Deserialize, Serialize};
use tauri::ipc::Channel;
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
@@ -86,16 +105,21 @@ mod imp {
}
/// Access to the deep-link APIs.
pub struct DeepLink<R: Runtime>(pub(crate) PluginHandle<R>);
pub struct DeepLink<R: Runtime> {
pub(crate) app: AppHandle<R>,
pub(crate) plugin_handle: PluginHandle<R>,
}
impl<R: Runtime> DeepLink<R> {
/// Get the current URLs that triggered the deep link. Use this on app load to check whether your app was started via a deep link.
///
/// ## Platform-specific:
///
/// - **Windows / Linux**: Unsupported, will return [`Error::UnsupportedPlatform`](`crate::Error::UnsupportedPlatform`).
/// - **Windows / Linux**: This function reads the command line arguments and checks if there's only one value, which must be an URL with scheme matching one of the configured values.
/// Note that you must manually check the arguments when registering deep link schemes dynamically with [`Self::register`].
/// Additionally, the deep link might have been provided as a CLI argument so you should check if its format matches what you expect.
pub fn get_current(&self) -> crate::Result<Option<Vec<url::Url>>> {
self.0
self.plugin_handle
.run_mobile_plugin::<GetCurrentResponse>("getCurrent", ())
.map(|v| v.url.map(|url| vec![url]))
.map_err(Into::into)
@@ -154,23 +178,76 @@ mod imp {
/// Access to the deep-link APIs.
pub struct DeepLink<R: Runtime> {
#[allow(dead_code)]
pub(crate) app: AppHandle<R>,
#[allow(dead_code)]
pub(crate) current: Mutex<Option<Vec<url::Url>>>,
pub(crate) config: Option<crate::config::Config>,
}
impl<R: Runtime> DeepLink<R> {
/// Checks if the provided list of arguments (which should match [`std::env::args`])
/// contains a deep link argument (for Linux and Windows).
///
/// On Linux and Windows the deep links trigger a new app instance with the deep link URL as its only argument.
///
/// This function does what it can to verify if the argument is actually a deep link, though it could also be a regular CLI argument.
/// To enhance its checks, we only match deep links against the schemes defined in the Tauri configuration
/// i.e. dynamic schemes WON'T be processed.
///
/// This function updates the [`Self::get_current`] value and emits a `deep-link://new-url` event.
#[cfg(desktop)]
pub fn handle_cli_arguments<S: AsRef<str>, I: Iterator<Item = S>>(&self, mut args: I) {
use tauri::Emitter;
let Some(config) = &self.config else {
return;
};
if cfg!(windows) || cfg!(target_os = "linux") {
args.next(); // bin name
let arg = args.next();
let maybe_deep_link = args.next().is_none(); // single argument
if !maybe_deep_link {
return;
}
if let Some(url) = arg.and_then(|arg| arg.as_ref().parse::<url::Url>().ok()) {
if config.desktop.contains_scheme(&url.scheme().to_string()) {
let mut current = self.current.lock().unwrap();
current.replace(vec![url.clone()]);
let _ = self.app.emit("deep-link://new-url", vec![url]);
} else if cfg!(debug_assertions) {
log::warn!("argument {url} does not match any configured deep link scheme; skipping it");
}
}
}
}
/// Get the current URLs that triggered the deep link. Use this on app load to check whether your app was started via a deep link.
///
/// ## Platform-specific:
///
/// - **Windows / Linux**: Unsupported, will return [`Error::UnsupportedPlatform`](`crate::Error::UnsupportedPlatform`).
/// - **Windows / Linux**: This function reads the command line arguments and checks if there's only one value, which must be an URL with scheme matching one of the configured values.
/// Note that you must manually check the arguments when registering deep link schemes dynamically with [`Self::register`].
/// Additionally, the deep link might have been provided as a CLI argument so you should check if its format matches what you expect.
pub fn get_current(&self) -> crate::Result<Option<Vec<url::Url>>> {
#[cfg(not(any(windows, target_os = "linux")))]
return Ok(self.current.lock().unwrap().clone());
#[cfg(any(windows, target_os = "linux"))]
Err(crate::Error::UnsupportedPlatform)
}
/// Registers all schemes defined in the configuration file.
///
/// This is useful to ensure the schemes are registered even if the user did not install the app properly
/// (e.g. an AppImage that was not properly registered with an AppImage launcher).
pub fn register_all(&self) -> crate::Result<()> {
let Some(config) = &self.config else {
return Ok(());
};
for scheme in config.desktop.schemes() {
self.register(scheme)?;
}
Ok(())
}
/// Register the app as the default handler for the specified protocol.
@@ -197,11 +274,11 @@ mod imp {
key_reg.set_string("URL Protocol", "")?;
let icon_reg = CURRENT_USER.create(format!("{key_base}\\DefaultIcon"))?;
icon_reg.set_string("", &format!("{},0", &exe))?;
icon_reg.set_string("", &format!("{exe},0"))?;
let cmd_reg = CURRENT_USER.create(format!("{key_base}\\shell\\open\\command"))?;
cmd_reg.set_string("", &format!("{} \"%1\"", &exe))?;
cmd_reg.set_string("", &format!("\"{exe}\" \"%1\""))?;
Ok(())
}
@@ -331,13 +408,13 @@ mod imp {
_protocol.as_ref()
))?;
let registered_cmd: String = cmd_reg.get_string("")?;
let registered_cmd = cmd_reg.get_string("")?;
let exe = dunce::simplified(&tauri::utils::platform::current_exe()?)
.display()
.to_string();
Ok(registered_cmd == format!("{} \"%1\"", &exe))
Ok(registered_cmd == format!("\"{exe}\" \"%1\""))
}
#[cfg(target_os = "linux")]
{
@@ -367,6 +444,7 @@ mod imp {
}
pub use imp::DeepLink;
use url::Url;
/// Extensions to [`tauri::App`], [`tauri::AppHandle`], [`tauri::WebviewWindow`], [`tauri::Webview`] and [`tauri::Window`] to access the deep-link APIs.
pub trait DeepLinkExt<R: Runtime> {
@@ -379,6 +457,54 @@ impl<R: Runtime, T: Manager<R>> crate::DeepLinkExt<R> for T {
}
}
/// Event that is triggered when the app was requested to open a new URL.
///
/// Typed [`tauri::Event`].
pub struct OpenUrlEvent {
id: EventId,
urls: Vec<Url>,
}
impl OpenUrlEvent {
/// The event ID which can be used to stop listening to the event via [`tauri::Listener::unlisten`].
pub fn id(&self) -> EventId {
self.id
}
/// The event URLs.
pub fn urls(self) -> Vec<Url> {
self.urls
}
}
impl<R: Runtime> DeepLink<R> {
/// Handle a new deep link being triggered to open the app.
///
/// To avoid race conditions, if the app was started with a deep link,
/// the closure gets immediately called with the deep link URL.
pub fn on_open_url<F: Fn(OpenUrlEvent) + Send + Sync + 'static>(&self, f: F) -> EventId {
let f = Arc::new(f);
let f_ = f.clone();
let event_id = self.app.listen("deep-link://new-url", move |event| {
if let Ok(urls) = serde_json::from_str(event.payload()) {
f(OpenUrlEvent {
id: event.id(),
urls,
})
}
});
if let Ok(Some(current)) = self.get_current() {
f_(OpenUrlEvent {
id: event_id,
urls: current,
})
}
event_id
}
}
/// Initializes the plugin.
pub fn init<R: Runtime>() -> TauriPlugin<R, Option<config::Config>> {
Builder::new("deep-link")

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