feat: Add geolocation and haptics plugins (#1599)

* init geolocation plugin

* ios impl (w/o js api)

* generate ts api

* use newer tauri commit

* add temporary postinstall

* include src in files

* guest-js

* just ship dist-js for now

* fix watcher

* fix android compile error

* fix android build for real

* fix heading type

* initial getCurrentPosition android impl (wip)

* prevent panics if errors (strings) are sent over the channel

* Add android watchPosition implementation

* init haptics plugin (android)

* ios and new apis (ANDROID IS LIKELY BROKEN - MAY NOT EVEN COMPILE)

* use tauri-specta that accounts for raw fn arg idents

* add complete android support (it's not working great due to random soft-/hardware support)

* fix(haptics): Fix the NotificationFeedbackType::Success and Version (#1)

* Fix success feedback and version

* Apply suggestions from code review

* Update package.json

---------

Co-authored-by: Fabian-Lars <118197967+FabianLars-crabnebula@users.noreply.github.com>

* android: improve permission callback handling

* keep track of ongoing perms requests

* rebuild

* license headers

* rm sqlite feat

* fmt

* what diff u talkin bout?

* ignore dist-js again

* fix audits

* dedupe api.js

* clippy

* changefiles

* readmes

* clean up todos

* rm dsstore

* rm wrong feats

* mirror

* covector

* rebuild

* ios requires the wry feature

* lint

* update lock

---------

Co-authored-by: fabianlars <fabianlars@fabianlars.de>
Co-authored-by: Brendan Allan <brendonovich@outlook.com>
Co-authored-by: Naman Garg <155433377+naman-crabnebula@users.noreply.github.com>
Co-authored-by: Lucas Nogueira <lucas@crabnebula.dev>
This commit is contained in:
Fabian-Lars
2024-08-02 15:45:47 +02:00
committed by GitHub
parent 34df132fb1
commit 9606089b2a
102 changed files with 4896 additions and 52 deletions
+37
View File
@@ -0,0 +1,37 @@
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use tauri::{command, AppHandle, Runtime};
use crate::{HapticsExt, ImpactFeedbackStyle, NotificationFeedbackType, Result};
#[command]
#[specta::specta]
pub(crate) async fn vibrate<R: Runtime>(app: AppHandle<R>, duration: u32) -> Result<()> {
app.haptics().vibrate(duration)
}
#[command]
#[specta::specta]
pub(crate) async fn impact_feedback<R: Runtime>(
app: AppHandle<R>,
style: ImpactFeedbackStyle,
) -> Result<()> {
app.haptics().impact_feedback(style)
}
#[command]
#[specta::specta]
pub(crate) async fn notification_feedback<R: Runtime>(
app: AppHandle<R>,
r#type: NotificationFeedbackType,
) -> Result<()> {
app.haptics().notification_feedback(r#type)
}
#[command]
#[specta::specta]
pub(crate) async fn selection_feedback<R: Runtime>(app: AppHandle<R>) -> Result<()> {
app.haptics().selection_feedback()
}
+36
View File
@@ -0,0 +1,36 @@
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use serde::de::DeserializeOwned;
use tauri::{plugin::PluginApi, AppHandle, Runtime};
use crate::models::*;
pub fn init<R: Runtime, C: DeserializeOwned>(
app: &AppHandle<R>,
_api: PluginApi<R, C>,
) -> crate::Result<Haptics<R>> {
Ok(Haptics(app.clone()))
}
/// Access to the haptics APIs.
pub struct Haptics<R: Runtime>(AppHandle<R>);
impl<R: Runtime> Haptics<R> {
pub fn vibrate(&self, _duration: u32) -> crate::Result<()> {
Ok(())
}
pub fn impact_feedback(&self, _style: ImpactFeedbackStyle) -> crate::Result<()> {
Ok(())
}
pub fn notification_feedback(&self, _type: NotificationFeedbackType) -> crate::Result<()> {
Ok(())
}
pub fn selection_feedback(&self) -> crate::Result<()> {
Ok(())
}
}
+30
View File
@@ -0,0 +1,30 @@
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use serde::{ser::Serializer, Serialize};
use specta::Type;
pub type Result<T> = std::result::Result<T, Error>;
// TODO: Improve Error handling (different typed errors instead of one (stringified) PluginInvokeError for all mobile errors)
#[derive(Debug, thiserror::Error, Type)]
pub enum Error {
#[cfg(mobile)]
#[error(transparent)]
PluginInvoke(
#[serde(skip)]
#[from]
tauri::plugin::mobile::PluginInvokeError,
),
}
impl Serialize for Error {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.to_string().as_ref())
}
}
+98
View File
@@ -0,0 +1,98 @@
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use tauri::{
plugin::{Builder, TauriPlugin},
Manager, Runtime,
};
//use tauri_specta::*;
pub use models::*;
#[cfg(desktop)]
mod desktop;
#[cfg(mobile)]
mod mobile;
mod commands;
mod error;
mod models;
pub use error::{Error, Result};
#[cfg(desktop)]
use desktop::Haptics;
#[cfg(mobile)]
use mobile::Haptics;
/* macro_rules! specta_builder {
() => {
ts::builder()
.commands(collect_commands![
commands::vibrate,
commands::impact_feedback,
commands::notification_feedback,
commands::selection_feedback
])
.header("// @ts-nocheck")
.config(
specta::ts::ExportConfig::default()
.bigint(specta::ts::BigIntExportBehavior::Number),
)
};
} */
/// Extensions to [`tauri::App`], [`tauri::AppHandle`], [`tauri::WebviewWindow`], [`tauri::Webview`] and [`tauri::Window`] to access the haptics APIs.
pub trait HapticsExt<R: Runtime> {
fn haptics(&self) -> &Haptics<R>;
}
impl<R: Runtime, T: Manager<R>> crate::HapticsExt<R> for T {
fn haptics(&self) -> &Haptics<R> {
self.state::<Haptics<R>>().inner()
}
}
/// Initializes the plugin.
pub fn init<R: Runtime>() -> TauriPlugin<R> {
/* let (invoke_handler, register_events) =
specta_builder!().build_plugin_utils("haptics").unwrap(); */
Builder::new("haptics")
.invoke_handler(tauri::generate_handler![
commands::vibrate,
commands::impact_feedback,
commands::notification_feedback,
commands::selection_feedback
])
.setup(|app, api| {
#[cfg(mobile)]
let haptics = mobile::init(app, api)?;
#[cfg(desktop)]
let haptics = desktop::init(app, api)?;
app.manage(haptics);
Ok(())
})
.build()
}
/* #[cfg(test)]
mod test {
use super::*;
#[test]
fn export_types() {
specta_builder!()
.path("./guest-js/bindings.ts")
.config(
specta::ts::ExportConfig::default()
.formatter(specta::ts::formatter::prettier)
.bigint(specta::ts::BigIntExportBehavior::Number),
)
.export_for_plugin("haptics")
.expect("failed to export specta types");
}
}
*/
+76
View File
@@ -0,0 +1,76 @@
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use serde::{de::DeserializeOwned, Serialize};
use tauri::{
plugin::{PluginApi, PluginHandle},
AppHandle, Runtime,
};
use crate::models::*;
#[cfg(target_os = "android")]
const PLUGIN_IDENTIFIER: &str = "app.tauri.haptics";
#[cfg(target_os = "ios")]
tauri::ios_plugin_binding!(init_plugin_haptics);
// initializes the Kotlin or Swift plugin classes
pub fn init<R: Runtime, C: DeserializeOwned>(
_app: &AppHandle<R>,
api: PluginApi<R, C>,
) -> crate::Result<Haptics<R>> {
#[cfg(target_os = "android")]
let handle = api.register_android_plugin(PLUGIN_IDENTIFIER, "HapticsPlugin")?;
#[cfg(target_os = "ios")]
let handle = api.register_ios_plugin(init_plugin_haptics)?;
Ok(Haptics(handle))
}
/// Access to the haptics APIs.
pub struct Haptics<R: Runtime>(PluginHandle<R>);
impl<R: Runtime> Haptics<R> {
pub fn vibrate(&self, duration: u32) -> crate::Result<()> {
self.0
.run_mobile_plugin("vibrate", VibratePayload { duration })
.map_err(Into::into)
}
pub fn impact_feedback(&self, style: ImpactFeedbackStyle) -> crate::Result<()> {
self.0
.run_mobile_plugin("impactFeedback", ImpactFeedbackPayload { style })
.map_err(Into::into)
}
pub fn notification_feedback(&self, r#type: NotificationFeedbackType) -> crate::Result<()> {
self.0
.run_mobile_plugin(
"notificationFeedback",
NotificationFeedbackPayload { r#type },
)
.map_err(Into::into)
}
pub fn selection_feedback(&self) -> crate::Result<()> {
self.0
.run_mobile_plugin("selectionFeedback", ())
.map_err(Into::into)
}
}
#[derive(Serialize)]
struct VibratePayload {
duration: u32,
}
#[derive(Serialize)]
struct ImpactFeedbackPayload {
style: ImpactFeedbackStyle,
}
#[derive(Serialize)]
struct NotificationFeedbackPayload {
r#type: NotificationFeedbackType,
}
+34
View File
@@ -0,0 +1,34 @@
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use serde::{Deserialize, Serialize};
use specta::Type;
/*
#[derive(Debug, Clone, Default, Serialize, Deserialize, Type)]
#[serde(rename_all = "camelCase")]
pub struct HapticsOptions {
// TODO: support array to match web api
pub duration: u32,
}
*/
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, Type)]
#[serde(rename_all = "camelCase")]
pub enum ImpactFeedbackStyle {
Light,
#[default]
Medium,
Heavy,
Soft,
Rigid,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, Type)]
#[serde(rename_all = "camelCase")]
pub enum NotificationFeedbackType {
#[default]
Success,
Warning,
Error,
}