mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-04-23 11:36:13 +02:00
e438e0a62d
Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com>
283 lines
7.5 KiB
Kotlin
283 lines
7.5 KiB
Kotlin
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
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.InvokeArg
|
|
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
|
|
|
|
const val LOCAL_NOTIFICATIONS = "permissionState"
|
|
|
|
@InvokeArg
|
|
class PluginConfig {
|
|
var icon: String? = null
|
|
var sound: String? = null
|
|
var iconColor: String? = null
|
|
}
|
|
|
|
@InvokeArg
|
|
class BatchArgs {
|
|
lateinit var notifications: List<Notification>
|
|
}
|
|
|
|
@InvokeArg
|
|
class CancelArgs {
|
|
lateinit var notifications: List<Int>
|
|
}
|
|
|
|
@InvokeArg
|
|
class NotificationAction {
|
|
lateinit var id: String
|
|
var title: String? = null
|
|
var input: Boolean? = null
|
|
}
|
|
|
|
@InvokeArg
|
|
class ActionType {
|
|
lateinit var id: String
|
|
lateinit var actions: List<NotificationAction>
|
|
}
|
|
|
|
@InvokeArg
|
|
class RegisterActionTypesArgs {
|
|
lateinit var types: List<ActionType>
|
|
}
|
|
|
|
@InvokeArg
|
|
class ActiveNotification {
|
|
var id: Int = 0
|
|
var tag: String? = null
|
|
}
|
|
|
|
@InvokeArg
|
|
class RemoveActiveArgs {
|
|
var notifications: List<ActiveNotification> = listOf()
|
|
}
|
|
|
|
@TauriPlugin(
|
|
permissions = [
|
|
Permission(strings = [Manifest.permission.POST_NOTIFICATIONS], alias = "permissionState")
|
|
]
|
|
)
|
|
class NotificationPlugin(private val activity: Activity): Plugin(activity) {
|
|
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: Notification) {
|
|
instance?.triggerObject("notification", notification)
|
|
}
|
|
}
|
|
|
|
override fun load(webView: WebView) {
|
|
instance = this
|
|
|
|
super.load(webView)
|
|
this.webView = webView
|
|
notificationStorage = NotificationStorage(activity, jsonMapper())
|
|
|
|
val manager = TauriNotificationManager(
|
|
notificationStorage,
|
|
activity,
|
|
activity,
|
|
getConfig(PluginConfig::class.java)
|
|
)
|
|
manager.createNotificationChannel()
|
|
|
|
this.manager = manager
|
|
|
|
notificationManager = activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
|
|
val intent = activity.intent
|
|
intent?.let {
|
|
onIntent(it)
|
|
}
|
|
}
|
|
|
|
override fun onNewIntent(intent: Intent) {
|
|
super.onNewIntent(intent)
|
|
onIntent(intent)
|
|
}
|
|
|
|
fun onIntent(intent: 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 = invoke.parseArgs(Notification::class.java)
|
|
val id = manager.schedule(notification)
|
|
|
|
invoke.resolveObject(id)
|
|
}
|
|
|
|
@Command
|
|
fun batch(invoke: Invoke) {
|
|
val args = invoke.parseArgs(BatchArgs::class.java)
|
|
|
|
val ids = manager.schedule(args.notifications)
|
|
notificationStorage.appendNotifications(args.notifications)
|
|
|
|
invoke.resolveObject(ids)
|
|
}
|
|
|
|
@Command
|
|
fun cancel(invoke: Invoke) {
|
|
val args = invoke.parseArgs(CancelArgs::class.java)
|
|
manager.cancel(args.notifications)
|
|
invoke.resolve()
|
|
}
|
|
|
|
@Command
|
|
fun removeActive(invoke: Invoke) {
|
|
val args = invoke.parseArgs(RemoveActiveArgs::class.java)
|
|
|
|
if (args.notifications.isEmpty()) {
|
|
notificationManager.cancelAll()
|
|
invoke.resolve()
|
|
} else {
|
|
for (notification in args.notifications) {
|
|
if (notification.tag == null) {
|
|
notificationManager.cancel(notification.id)
|
|
} else {
|
|
notificationManager.cancel(notification.tag, notification.id)
|
|
}
|
|
}
|
|
invoke.resolve()
|
|
}
|
|
}
|
|
|
|
@Command
|
|
fun getPending(invoke: Invoke) {
|
|
val notifications= notificationStorage.getSavedNotifications()
|
|
val result = Notification.buildNotificationPendingList(notifications)
|
|
invoke.resolveObject(result)
|
|
}
|
|
|
|
@Command
|
|
fun registerActionTypes(invoke: Invoke) {
|
|
val args = invoke.parseArgs(RegisterActionTypesArgs::class.java)
|
|
notificationStorage.writeActionGroup(args.types)
|
|
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)
|
|
}
|
|
}
|
|
|
|
invoke.resolveObject(notifications)
|
|
}
|
|
|
|
@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"
|
|
}
|
|
}
|
|
}
|