Skip to content

Commit

Permalink
feat: use PermissionState type from tauri, closes #979 (#1701)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog authored Aug 29, 2024
1 parent 9ea9e05 commit e2e97db
Show file tree
Hide file tree
Showing 17 changed files with 55 additions and 89 deletions.
10 changes: 10 additions & 0 deletions .changes/consolidate-permission-state.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"barcode-scanner": patch
"barcode-scanner-js": patch
"geolocation": patch
"geolocation-js": patch
"notification": patch
"notification-js": patch
---

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).
5 changes: 5 additions & 0 deletions .changes/notification-permission-type-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"notification-js": patch
---

**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.
2 changes: 1 addition & 1 deletion .changes/tauri-rc-7.md → .changes/tauri-rc-8.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@
"geolocation-js": patch
---

Update to tauri 2.0.0-rc.7
Update to tauri 2.0.0-rc.8
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ resolver = "2"
[workspace.dependencies]
serde = { version = "1", features = ["derive"] }
log = "0.4"
tauri = { version = "2.0.0-rc.7", default-features = false }
tauri = { version = "2.0.0-rc.8", default-features = false }
tauri-build = "2.0.0-rc.7"
tauri-plugin = "2.0.0-rc.7"
tauri-utils = "2.0.0-rc.7"
Expand Down
3 changes: 3 additions & 0 deletions plugins/barcode-scanner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ serde_json = { workspace = true }
tauri = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }

[target.'cfg(target_os = "ios")'.dependencies]
tauri = { workspace = true, features = ["wry"] }
2 changes: 1 addition & 1 deletion plugins/barcode-scanner/api-iife.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 10 additions & 6 deletions plugins/barcode-scanner/guest-js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

import { invoke } from "@tauri-apps/api/core";
import {
invoke,
requestPermissions as checkPermissions_,
checkPermissions as requestPermissions_,
} from "@tauri-apps/api/core";

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

export enum Format {
QRCode = "QR_CODE",
Expand Down Expand Up @@ -53,17 +57,17 @@ export async function cancel(): Promise<void> {
* Get permission state.
*/
export async function checkPermissions(): Promise<PermissionState> {
return await invoke<{ camera: PermissionState }>(
"plugin:barcode-scanner|check_permissions",
return await checkPermissions_<{ camera: PermissionState }>(
"barcode-scanner",
).then((r) => r.camera);
}

/**
* Request permissions to use the camera.
*/
export async function requestPermissions(): Promise<PermissionState> {
return await invoke<{ camera: PermissionState }>(
"plugin:barcode-scanner|request_permissions",
return await requestPermissions_<{ camera: PermissionState }>(
"barcode-scanner",
).then((r) => r.camera);
}

Expand Down
14 changes: 1 addition & 13 deletions plugins/geolocation/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use serde::{Deserialize, Serialize};
use specta::Type;
use tauri::plugin::PermissionState;

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

/// Permission state.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize, Type)]
#[serde(rename_all = "camelCase")]
pub enum PermissionState {
/// Permission access has been granted.
Granted,
/// Permission access has been denied.
Denied,
/// The end user should be prompted for permission.
#[default]
Prompt,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, Type)]
#[serde(rename_all = "camelCase")]
pub struct PositionOptions {
Expand Down
8 changes: 3 additions & 5 deletions plugins/notification/guest-js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
addPluginListener,
} from "@tauri-apps/api/core";

export type { PermissionState } from "@tauri-apps/api/core";

/**
* Options to send a notification.
*
Expand Down Expand Up @@ -304,9 +306,6 @@ interface Channel {
visibility?: Visibility;
}

/** Possible permission values. */
type Permission = "granted" | "denied" | "default";

/**
* Checks if the permission to send notifications is granted.
* @example
Expand Down Expand Up @@ -340,7 +339,7 @@ async function isPermissionGranted(): Promise<boolean> {
*
* @since 2.0.0
*/
async function requestPermission(): Promise<Permission> {
async function requestPermission(): Promise<NotificationPermission> {
return await window.Notification.requestPermission();
}

Expand Down Expand Up @@ -570,7 +569,6 @@ async function onAction(
export type {
Attachment,
Options,
Permission,
Action,
ActionType,
PendingNotification,
Expand Down
15 changes: 7 additions & 8 deletions plugins/notification/guest-js/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: MIT

import { invoke } from "@tauri-apps/api/core";
import type { PermissionState } from "@tauri-apps/api/core";
import type { Options } from "./index";

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

function setNotificationPermission(
value: "granted" | "denied" | "default",
): void {
function setNotificationPermission(value: NotificationPermission): void {
permissionSettable = true;
// @ts-expect-error we can actually set this value on the webview
window.Notification.permission = value;
permissionSettable = false;
}

async function requestPermission(): Promise<
"default" | "denied" | "granted" | "prompt"
> {
return await invoke<"prompt" | "default" | "granted" | "denied">(
async function requestPermission(): Promise<PermissionState> {
return await invoke<PermissionState>(
"plugin:notification|request_permission",
).then((permission) => {
setNotificationPermission(
permission === "prompt" ? "default" : permission,
permission === "prompt" || permission === "prompt-with-rationale"
? "default"
: permission,
);
return permission;
});
Expand Down
6 changes: 3 additions & 3 deletions plugins/notification/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use tauri::{command, AppHandle, Runtime, State};
use tauri::{command, plugin::PermissionState, AppHandle, Runtime, State};

use crate::{Notification, NotificationData, PermissionState, Result};
use crate::{Notification, NotificationData, Result};

#[command]
pub(crate) async fn is_permission_granted<R: Runtime>(
Expand All @@ -15,7 +15,7 @@ pub(crate) async fn is_permission_granted<R: Runtime>(
match state {
PermissionState::Granted => Ok(Some(true)),
PermissionState::Denied => Ok(Some(false)),
PermissionState::Unknown => Ok(None),
PermissionState::Unknown | PermissionState::PromptWithRationale => Ok(None),
}
}

Expand Down
7 changes: 5 additions & 2 deletions plugins/notification/src/desktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
// SPDX-License-Identifier: MIT

use serde::de::DeserializeOwned;
use tauri::{plugin::PluginApi, AppHandle, Runtime};
use tauri::{
plugin::{PermissionState, PluginApi},
AppHandle, Runtime,
};

use crate::{models::*, NotificationBuilder};
use crate::NotificationBuilder;

pub fn init<R: Runtime, C: DeserializeOwned>(
app: &AppHandle<R>,
Expand Down
2 changes: 1 addition & 1 deletion plugins/notification/src/init-iife.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions plugins/notification/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use tauri::{
};

pub use models::*;
pub use tauri::plugin::PermissionState;

#[cfg(desktop)]
mod desktop;
Expand Down
2 changes: 1 addition & 1 deletion plugins/notification/src/mobile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use serde::{de::DeserializeOwned, Deserialize};
use tauri::{
plugin::{PluginApi, PluginHandle},
plugin::{PermissionState, PluginApi, PluginHandle},
AppHandle, Runtime,
};

Expand Down
45 changes: 0 additions & 45 deletions plugins/notification/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,51 +209,6 @@ impl Default for NotificationData {
}
}

/// Permission state.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PermissionState {
/// Permission access has been granted.
Granted,
/// Permission access has been denied.
Denied,
/// Unknown state. Must request permission.
Unknown,
}

impl Display for PermissionState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Granted => write!(f, "granted"),
Self::Denied => write!(f, "denied"),
Self::Unknown => write!(f, "Unknown"),
}
}
}

impl Serialize for PermissionState {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.to_string().as_ref())
}
}

impl<'de> Deserialize<'de> for PermissionState {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
match s.to_lowercase().as_str() {
"granted" => Ok(Self::Granted),
"denied" => Ok(Self::Denied),
"prompt" => Ok(Self::Unknown),
_ => Err(DeError::custom(format!("unknown permission state '{s}'"))),
}
}
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PendingNotification {
Expand Down

0 comments on commit e2e97db

Please sign in to comment.