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
@@ -0,0 +1,143 @@
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
package app.tauri.haptics
import android.app.Activity
import android.content.Context
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import android.os.VibratorManager
import app.tauri.Logger
import app.tauri.annotation.Command
import app.tauri.annotation.InvokeArg
import app.tauri.annotation.TauriPlugin
import app.tauri.haptics.patterns.ImpactPatternHeavy
import app.tauri.haptics.patterns.ImpactPatternLight
import app.tauri.haptics.patterns.ImpactPatternMedium
import app.tauri.haptics.patterns.ImpactPatternRigid
import app.tauri.haptics.patterns.ImpactPatternSoft
import app.tauri.haptics.patterns.NotificationPatternError
import app.tauri.haptics.patterns.NotificationPatternSuccess
import app.tauri.haptics.patterns.NotificationPatternWarning
import app.tauri.haptics.patterns.Pattern
import app.tauri.haptics.patterns.SelectionPattern
import app.tauri.plugin.Invoke
import app.tauri.plugin.Plugin
import com.fasterxml.jackson.annotation.JsonProperty
@InvokeArg
class HapticsOptions {
var duration: Long = 300
}
@InvokeArg
class NotificationFeedbackArgs {
val type: NotificationFeedbackType = NotificationFeedbackType.Success
}
@InvokeArg
enum class NotificationFeedbackType {
@JsonProperty("success")
Success,
@JsonProperty("warning")
Warning,
@JsonProperty("error")
Error;
fun into(): Pattern {
return when(this) {
Success -> NotificationPatternSuccess
Warning -> NotificationPatternWarning
Error -> NotificationPatternError
}
}
}
@InvokeArg
class ImpactFeedbackArgs {
val style: ImpactFeedbackStyle = ImpactFeedbackStyle.Medium
}
@InvokeArg
enum class ImpactFeedbackStyle {
@JsonProperty("light")
Light,
@JsonProperty("medium")
Medium,
@JsonProperty("heavy")
Heavy,
@JsonProperty("soft")
Soft,
@JsonProperty("rigid")
Rigid;
fun into(): Pattern {
return when(this) {
Light -> ImpactPatternLight
Medium -> ImpactPatternMedium
Heavy -> ImpactPatternHeavy
Soft -> ImpactPatternSoft
Rigid -> ImpactPatternRigid
}
}
}
@TauriPlugin
class HapticsPlugin(private val activity: Activity): Plugin(activity) {
private val vibrator: Vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val vibManager = activity.applicationContext.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
vibManager.defaultVibrator
} else {
@Suppress("DEPRECATION")
activity.applicationContext.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
}
//
// TAURI COMMANDS
//
@Command
fun vibrate(invoke: Invoke) {
val args = invoke.parseArgs(HapticsOptions::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(args.duration, VibrationEffect.DEFAULT_AMPLITUDE))
} else {
vibrator.vibrate(args.duration)
}
invoke.resolve()
}
@Command
fun impactFeedback(invoke: Invoke) {
val args = invoke.parseArgs(ImpactFeedbackArgs::class.java)
vibratePattern(args.style.into())
invoke.resolve()
}
@Command
fun notificationFeedback(invoke: Invoke) {
val args = invoke.parseArgs(NotificationFeedbackArgs::class.java)
vibratePattern(args.type.into())
invoke.resolve()
}
// TODO: Consider breaking this up into Start,Change,End like capacitor
@Command
fun selectionFeedback(invoke: Invoke) {
vibratePattern(SelectionPattern)
invoke.resolve()
}
// INTERNAL FUNCTIONS
private fun vibratePattern(pattern: Pattern) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createWaveform(pattern.timings, pattern.amplitudes, -1))
} else {
vibrator.vibrate(pattern.oldSDKPattern, -1)
}
}
}