mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-04-25 11:46:06 +02:00
feat(notification): implement Android and iOS APIs (#340)
This commit is contained in:
committed by
GitHub
parent
1397172e95
commit
be1c775b8d
@@ -1,31 +1,263 @@
|
||||
package app.tauri.notification
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.webkit.WebView
|
||||
import app.tauri.PermissionState
|
||||
import app.tauri.annotation.Command
|
||||
import app.tauri.annotation.Permission
|
||||
import app.tauri.annotation.PermissionCallback
|
||||
import app.tauri.annotation.TauriPlugin
|
||||
import app.tauri.plugin.Invoke
|
||||
import app.tauri.plugin.JSArray
|
||||
import app.tauri.plugin.JSObject
|
||||
import app.tauri.plugin.Plugin
|
||||
import app.tauri.plugin.Invoke
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
|
||||
@TauriPlugin
|
||||
const val LOCAL_NOTIFICATIONS = "permissionState"
|
||||
|
||||
@TauriPlugin(
|
||||
permissions = [
|
||||
Permission(strings = [Manifest.permission.POST_NOTIFICATIONS], alias = "permissionState")
|
||||
]
|
||||
)
|
||||
class NotificationPlugin(private val activity: Activity): Plugin(activity) {
|
||||
@Command
|
||||
fun requestPermission(invoke: Invoke) {
|
||||
val ret = JSObject()
|
||||
ret.put("permissionState", "granted")
|
||||
invoke.resolve(ret)
|
||||
private var webView: WebView? = null
|
||||
private lateinit var manager: TauriNotificationManager
|
||||
private lateinit var notificationManager: NotificationManager
|
||||
private lateinit var notificationStorage: NotificationStorage
|
||||
private var channelManager = ChannelManager(activity)
|
||||
|
||||
companion object {
|
||||
var instance: NotificationPlugin? = null
|
||||
|
||||
fun triggerNotification(notification: JSObject) {
|
||||
instance?.trigger("notification", notification)
|
||||
}
|
||||
}
|
||||
|
||||
override fun load(webView: WebView) {
|
||||
instance = this
|
||||
|
||||
super.load(webView)
|
||||
this.webView = webView
|
||||
notificationStorage = NotificationStorage(activity)
|
||||
|
||||
val manager = TauriNotificationManager(
|
||||
notificationStorage,
|
||||
activity,
|
||||
activity,
|
||||
getConfig()
|
||||
)
|
||||
manager.createNotificationChannel()
|
||||
|
||||
this.manager = manager
|
||||
|
||||
notificationManager = activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
if (Intent.ACTION_MAIN != intent.action) {
|
||||
return
|
||||
}
|
||||
val dataJson = manager.handleNotificationActionPerformed(intent, notificationStorage)
|
||||
if (dataJson != null) {
|
||||
trigger("actionPerformed", dataJson)
|
||||
}
|
||||
}
|
||||
|
||||
@Command
|
||||
fun show(invoke: Invoke) {
|
||||
val notification = Notification.fromJSObject(invoke.data)
|
||||
val id = manager.schedule(notification)
|
||||
|
||||
val returnVal = JSObject().put("id", id)
|
||||
invoke.resolve(returnVal)
|
||||
}
|
||||
|
||||
@Command
|
||||
fun batch(invoke: Invoke) {
|
||||
val notificationArray = invoke.getArray("notifications")
|
||||
if (notificationArray == null) {
|
||||
invoke.reject("Missing `notifications` argument")
|
||||
return
|
||||
}
|
||||
|
||||
@Command
|
||||
fun permissionState(invoke: Invoke) {
|
||||
val ret = JSObject()
|
||||
ret.put("permissionState", "granted")
|
||||
invoke.resolve(ret)
|
||||
val notifications: MutableList<Notification> =
|
||||
ArrayList(notificationArray.length())
|
||||
val notificationsInput: List<JSONObject> = try {
|
||||
notificationArray.toList()
|
||||
} catch (e: JSONException) {
|
||||
invoke.reject("Provided notification format is invalid")
|
||||
return
|
||||
}
|
||||
|
||||
@Command
|
||||
fun notify(invoke: Invoke) {
|
||||
// TODO
|
||||
invoke.resolve()
|
||||
for (jsonNotification in notificationsInput) {
|
||||
val notification = Notification.fromJson(jsonNotification)
|
||||
notifications.add(notification)
|
||||
}
|
||||
|
||||
val ids = manager.schedule(notifications)
|
||||
notificationStorage.appendNotifications(notifications)
|
||||
|
||||
val result = JSObject()
|
||||
result.put("notifications", ids)
|
||||
invoke.resolve(result)
|
||||
}
|
||||
|
||||
@Command
|
||||
fun cancel(invoke: Invoke) {
|
||||
val notifications: List<Int> = invoke.getArray("notifications", JSArray()).toList()
|
||||
if (notifications.isEmpty()) {
|
||||
invoke.reject("Must provide notifications array as notifications option")
|
||||
return
|
||||
}
|
||||
|
||||
manager.cancel(notifications)
|
||||
invoke.resolve()
|
||||
}
|
||||
|
||||
@Command
|
||||
fun removeActive(invoke: Invoke) {
|
||||
val notifications = invoke.getArray("notifications")
|
||||
if (notifications == null) {
|
||||
notificationManager.cancelAll()
|
||||
invoke.resolve()
|
||||
} else {
|
||||
try {
|
||||
for (o in notifications.toList<Any>()) {
|
||||
if (o is JSONObject) {
|
||||
val notification = JSObject.fromJSONObject((o))
|
||||
val tag = notification.getString("tag", null)
|
||||
val id = notification.getInteger("id", 0)
|
||||
if (tag == null) {
|
||||
notificationManager.cancel(id)
|
||||
} else {
|
||||
notificationManager.cancel(tag, id)
|
||||
}
|
||||
} else {
|
||||
invoke.reject("Unexpected notification type")
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
invoke.reject(e.message)
|
||||
}
|
||||
invoke.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
@Command
|
||||
fun getPending(invoke: Invoke) {
|
||||
val notifications= notificationStorage.getSavedNotifications()
|
||||
val result = Notification.buildNotificationPendingList(notifications)
|
||||
invoke.resolve(result)
|
||||
}
|
||||
|
||||
@Command
|
||||
fun registerActionTypes(invoke: Invoke) {
|
||||
val types = invoke.getArray("types", JSArray())
|
||||
val typesArray = NotificationAction.buildTypes(types)
|
||||
notificationStorage.writeActionGroup(typesArray)
|
||||
invoke.resolve()
|
||||
}
|
||||
|
||||
@SuppressLint("ObsoleteSdkInt")
|
||||
@Command
|
||||
fun getActive(invoke: Invoke) {
|
||||
val notifications = JSArray()
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
val activeNotifications = notificationManager.activeNotifications
|
||||
for (activeNotification in activeNotifications) {
|
||||
val jsNotification = JSObject()
|
||||
jsNotification.put("id", activeNotification.id)
|
||||
jsNotification.put("tag", activeNotification.tag)
|
||||
val notification = activeNotification.notification
|
||||
if (notification != null) {
|
||||
jsNotification.put("title", notification.extras.getCharSequence(android.app.Notification.EXTRA_TITLE))
|
||||
jsNotification.put("body", notification.extras.getCharSequence(android.app.Notification.EXTRA_TEXT))
|
||||
jsNotification.put("group", notification.group)
|
||||
jsNotification.put(
|
||||
"groupSummary",
|
||||
0 != notification.flags and android.app.Notification.FLAG_GROUP_SUMMARY
|
||||
)
|
||||
val extras = JSObject()
|
||||
for (key in notification.extras.keySet()) {
|
||||
extras.put(key!!, notification.extras.getString(key))
|
||||
}
|
||||
jsNotification.put("data", extras)
|
||||
}
|
||||
notifications.put(jsNotification)
|
||||
}
|
||||
}
|
||||
val result = JSObject()
|
||||
result.put("notifications", notifications)
|
||||
invoke.resolve(result)
|
||||
}
|
||||
|
||||
@Command
|
||||
fun createChannel(invoke: Invoke) {
|
||||
channelManager.createChannel(invoke)
|
||||
}
|
||||
|
||||
@Command
|
||||
fun deleteChannel(invoke: Invoke) {
|
||||
channelManager.deleteChannel(invoke)
|
||||
}
|
||||
|
||||
@Command
|
||||
fun listChannels(invoke: Invoke) {
|
||||
channelManager.listChannels(invoke)
|
||||
}
|
||||
|
||||
@Command
|
||||
override fun checkPermissions(invoke: Invoke) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
|
||||
val permissionsResultJSON = JSObject()
|
||||
permissionsResultJSON.put("permissionState", getPermissionState())
|
||||
invoke.resolve(permissionsResultJSON)
|
||||
} else {
|
||||
super.checkPermissions(invoke)
|
||||
}
|
||||
}
|
||||
|
||||
@Command
|
||||
override fun requestPermissions(invoke: Invoke) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
|
||||
permissionState(invoke)
|
||||
} else {
|
||||
if (getPermissionState(LOCAL_NOTIFICATIONS) !== PermissionState.GRANTED) {
|
||||
requestPermissionForAlias(LOCAL_NOTIFICATIONS, invoke, "permissionsCallback")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Command
|
||||
fun permissionState(invoke: Invoke) {
|
||||
val permissionsResultJSON = JSObject()
|
||||
permissionsResultJSON.put("permissionState", getPermissionState())
|
||||
invoke.resolve(permissionsResultJSON)
|
||||
}
|
||||
|
||||
@PermissionCallback
|
||||
private fun permissionsCallback(invoke: Invoke) {
|
||||
val permissionsResultJSON = JSObject()
|
||||
permissionsResultJSON.put("display", getPermissionState())
|
||||
invoke.resolve(permissionsResultJSON)
|
||||
}
|
||||
|
||||
private fun getPermissionState(): String {
|
||||
return if (manager.areNotificationsEnabled()) {
|
||||
"granted"
|
||||
} else {
|
||||
"denied"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user