Skip to content

Commit e2e97db

Browse files
authored
feat: use PermissionState type from tauri, closes #979 (#1701)
1 parent 9ea9e05 commit e2e97db

17 files changed

+55
-89
lines changed
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"barcode-scanner": patch
3+
"barcode-scanner-js": patch
4+
"geolocation": patch
5+
"geolocation-js": patch
6+
"notification": patch
7+
"notification-js": patch
8+
---
9+
10+
Use `PermissionState` from the `tauri` crate, which now also includes a "prompt with rationale" variant for Android (returned when your app must explain to the user why it needs the permission).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"notification-js": patch
3+
---
4+
5+
**Breaking change**: The permission type when using the API is now `'granted' | 'denied' | 'prompt' | 'prompt-with-rationale'` instead of `'granted' | 'denied' | 'default'` for consistency with Rust types. When using the `window.Notification` API the type is unchanged to match the Web API type.

.changes/tauri-rc-7.md renamed to .changes/tauri-rc-8.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,4 @@
5858
"geolocation-js": patch
5959
---
6060

61-
Update to tauri 2.0.0-rc.7
61+
Update to tauri 2.0.0-rc.8

Cargo.lock

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ resolver = "2"
1111
[workspace.dependencies]
1212
serde = { version = "1", features = ["derive"] }
1313
log = "0.4"
14-
tauri = { version = "2.0.0-rc.7", default-features = false }
14+
tauri = { version = "2.0.0-rc.8", default-features = false }
1515
tauri-build = "2.0.0-rc.7"
1616
tauri-plugin = "2.0.0-rc.7"
1717
tauri-utils = "2.0.0-rc.7"

plugins/barcode-scanner/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,6 @@ serde_json = { workspace = true }
2323
tauri = { workspace = true }
2424
log = { workspace = true }
2525
thiserror = { workspace = true }
26+
27+
[target.'cfg(target_os = "ios")'.dependencies]
28+
tauri = { workspace = true, features = ["wry"] }

plugins/barcode-scanner/api-iife.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/barcode-scanner/guest-js/index.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
// SPDX-License-Identifier: Apache-2.0
33
// SPDX-License-Identifier: MIT
44

5-
import { invoke } from "@tauri-apps/api/core";
5+
import {
6+
invoke,
7+
requestPermissions as checkPermissions_,
8+
checkPermissions as requestPermissions_,
9+
} from "@tauri-apps/api/core";
610

7-
export type PermissionState = "granted" | "denied" | "prompt";
11+
export type { PermissionState } from "@tauri-apps/api/core";
812

913
export enum Format {
1014
QRCode = "QR_CODE",
@@ -53,17 +57,17 @@ export async function cancel(): Promise<void> {
5357
* Get permission state.
5458
*/
5559
export async function checkPermissions(): Promise<PermissionState> {
56-
return await invoke<{ camera: PermissionState }>(
57-
"plugin:barcode-scanner|check_permissions",
60+
return await checkPermissions_<{ camera: PermissionState }>(
61+
"barcode-scanner",
5862
).then((r) => r.camera);
5963
}
6064

6165
/**
6266
* Request permissions to use the camera.
6367
*/
6468
export async function requestPermissions(): Promise<PermissionState> {
65-
return await invoke<{ camera: PermissionState }>(
66-
"plugin:barcode-scanner|request_permissions",
69+
return await requestPermissions_<{ camera: PermissionState }>(
70+
"barcode-scanner",
6771
).then((r) => r.camera);
6872
}
6973

plugins/geolocation/src/models.rs

+1-13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use serde::{Deserialize, Serialize};
66
use specta::Type;
7+
use tauri::plugin::PermissionState;
78

89
#[derive(Debug, Clone, Default, Serialize, Deserialize, Type)]
910
#[serde(rename_all = "camelCase")]
@@ -24,19 +25,6 @@ pub struct PermissionStatus {
2425
pub coarse_location: PermissionState,
2526
}
2627

27-
/// Permission state.
28-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize, Type)]
29-
#[serde(rename_all = "camelCase")]
30-
pub enum PermissionState {
31-
/// Permission access has been granted.
32-
Granted,
33-
/// Permission access has been denied.
34-
Denied,
35-
/// The end user should be prompted for permission.
36-
#[default]
37-
Prompt,
38-
}
39-
4028
#[derive(Debug, Clone, Default, Serialize, Deserialize, Type)]
4129
#[serde(rename_all = "camelCase")]
4230
pub struct PositionOptions {

plugins/notification/guest-js/index.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import {
1515
addPluginListener,
1616
} from "@tauri-apps/api/core";
1717

18+
export type { PermissionState } from "@tauri-apps/api/core";
19+
1820
/**
1921
* Options to send a notification.
2022
*
@@ -304,9 +306,6 @@ interface Channel {
304306
visibility?: Visibility;
305307
}
306308

307-
/** Possible permission values. */
308-
type Permission = "granted" | "denied" | "default";
309-
310309
/**
311310
* Checks if the permission to send notifications is granted.
312311
* @example
@@ -340,7 +339,7 @@ async function isPermissionGranted(): Promise<boolean> {
340339
*
341340
* @since 2.0.0
342341
*/
343-
async function requestPermission(): Promise<Permission> {
342+
async function requestPermission(): Promise<NotificationPermission> {
344343
return await window.Notification.requestPermission();
345344
}
346345

@@ -570,7 +569,6 @@ async function onAction(
570569
export type {
571570
Attachment,
572571
Options,
573-
Permission,
574572
Action,
575573
ActionType,
576574
PendingNotification,

plugins/notification/guest-js/init.ts

+7-8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// SPDX-License-Identifier: MIT
44

55
import { invoke } from "@tauri-apps/api/core";
6+
import type { PermissionState } from "@tauri-apps/api/core";
67
import type { Options } from "./index";
78

89
(function () {
@@ -19,23 +20,21 @@ import type { Options } from "./index";
1920
return await invoke("plugin:notification|is_permission_granted");
2021
}
2122

22-
function setNotificationPermission(
23-
value: "granted" | "denied" | "default",
24-
): void {
23+
function setNotificationPermission(value: NotificationPermission): void {
2524
permissionSettable = true;
2625
// @ts-expect-error we can actually set this value on the webview
2726
window.Notification.permission = value;
2827
permissionSettable = false;
2928
}
3029

31-
async function requestPermission(): Promise<
32-
"default" | "denied" | "granted" | "prompt"
33-
> {
34-
return await invoke<"prompt" | "default" | "granted" | "denied">(
30+
async function requestPermission(): Promise<PermissionState> {
31+
return await invoke<PermissionState>(
3532
"plugin:notification|request_permission",
3633
).then((permission) => {
3734
setNotificationPermission(
38-
permission === "prompt" ? "default" : permission,
35+
permission === "prompt" || permission === "prompt-with-rationale"
36+
? "default"
37+
: permission,
3938
);
4039
return permission;
4140
});

plugins/notification/src/commands.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
// SPDX-License-Identifier: Apache-2.0
33
// SPDX-License-Identifier: MIT
44

5-
use tauri::{command, AppHandle, Runtime, State};
5+
use tauri::{command, plugin::PermissionState, AppHandle, Runtime, State};
66

7-
use crate::{Notification, NotificationData, PermissionState, Result};
7+
use crate::{Notification, NotificationData, Result};
88

99
#[command]
1010
pub(crate) async fn is_permission_granted<R: Runtime>(
@@ -15,7 +15,7 @@ pub(crate) async fn is_permission_granted<R: Runtime>(
1515
match state {
1616
PermissionState::Granted => Ok(Some(true)),
1717
PermissionState::Denied => Ok(Some(false)),
18-
PermissionState::Unknown => Ok(None),
18+
PermissionState::Unknown | PermissionState::PromptWithRationale => Ok(None),
1919
}
2020
}
2121

plugins/notification/src/desktop.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
// SPDX-License-Identifier: MIT
44

55
use serde::de::DeserializeOwned;
6-
use tauri::{plugin::PluginApi, AppHandle, Runtime};
6+
use tauri::{
7+
plugin::{PermissionState, PluginApi},
8+
AppHandle, Runtime,
9+
};
710

8-
use crate::{models::*, NotificationBuilder};
11+
use crate::NotificationBuilder;
912

1013
pub fn init<R: Runtime, C: DeserializeOwned>(
1114
app: &AppHandle<R>,

plugins/notification/src/init-iife.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/notification/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use tauri::{
2222
};
2323

2424
pub use models::*;
25+
pub use tauri::plugin::PermissionState;
2526

2627
#[cfg(desktop)]
2728
mod desktop;

plugins/notification/src/mobile.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use serde::{de::DeserializeOwned, Deserialize};
66
use tauri::{
7-
plugin::{PluginApi, PluginHandle},
7+
plugin::{PermissionState, PluginApi, PluginHandle},
88
AppHandle, Runtime,
99
};
1010

plugins/notification/src/models.rs

-45
Original file line numberDiff line numberDiff line change
@@ -209,51 +209,6 @@ impl Default for NotificationData {
209209
}
210210
}
211211

212-
/// Permission state.
213-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
214-
pub enum PermissionState {
215-
/// Permission access has been granted.
216-
Granted,
217-
/// Permission access has been denied.
218-
Denied,
219-
/// Unknown state. Must request permission.
220-
Unknown,
221-
}
222-
223-
impl Display for PermissionState {
224-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
225-
match self {
226-
Self::Granted => write!(f, "granted"),
227-
Self::Denied => write!(f, "denied"),
228-
Self::Unknown => write!(f, "Unknown"),
229-
}
230-
}
231-
}
232-
233-
impl Serialize for PermissionState {
234-
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
235-
where
236-
S: Serializer,
237-
{
238-
serializer.serialize_str(self.to_string().as_ref())
239-
}
240-
}
241-
242-
impl<'de> Deserialize<'de> for PermissionState {
243-
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
244-
where
245-
D: Deserializer<'de>,
246-
{
247-
let s = String::deserialize(deserializer)?;
248-
match s.to_lowercase().as_str() {
249-
"granted" => Ok(Self::Granted),
250-
"denied" => Ok(Self::Denied),
251-
"prompt" => Ok(Self::Unknown),
252-
_ => Err(DeError::custom(format!("unknown permission state '{s}'"))),
253-
}
254-
}
255-
}
256-
257212
#[derive(Debug, Deserialize)]
258213
#[serde(rename_all = "camelCase")]
259214
pub struct PendingNotification {

0 commit comments

Comments
 (0)