diff --git a/README.md b/README.md
index 9fa50ed..ec6dcfb 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,8 @@


+
+
Simple and easy to use Kotlin Multiplatform Push Notification library (using Firebase Cloud Messaging) targeting ios and android.
This library is used in [FindTravelNow](https://github.com/mirzemehdi/FindTravelNow-KMM/) production KMP project.
@@ -12,7 +14,7 @@ You can check out [Documentation](https://mirzemehdi.github.io/KMPNotifier) for
## Features
- 🔔 Local and Push Notification (Firebase Cloud Messaging)
- - 📱 Multiplatform (android and iOS)
+ - 📱 Multiplatform (android, iOS and desktop(alpha)) (Desktop supports only local notification for now)
## Installation
Before starting you need to setup basic setup using Firebase official guideline (like initializing project in Firebase, adding `google-services.json` to android, `GoogleService-Info.plist` to iOS).
@@ -64,7 +66,7 @@ plugins {
### Platform Setup
-In both platforms on Application Start you need to initialize library using
+In all platforms on Application Start you need to initialize library using
```kotlin
NotifierManager.initialize(NotificationPlatformConfiguration) //passing android or ios configuration depending on the platform
```
@@ -152,6 +154,39 @@ struct iOSApp: App {
+
+
+
+ Desktop
+
+### Desktop Setup
+You need to put notification icon into resources/common folder. For more information:
+[Compose Desktop Resources](https://github.com/JetBrains/compose-multiplatform/blob/master/tutorials/Native_distributions_and_local_execution/README.md#packaging-resources)
+ ```kotlin
+fun main() = application {
+
+ NotifierManager.initialize(
+ NotificationPlatformConfiguration.Desktop(
+ showPushNotification = true,
+ notificationIconPath = composeDesktopResourcesPath() + File.separator + "ic_notification.png"
+ )
+ )
+
+ AppInitializer.onApplicationStart()
+ Window(
+ onCloseRequest = ::exitApplication,
+ title = "KMPNotifier Desktop",
+ ) {
+ println("Desktop app is started")
+ App()
+
+ }
+}
+```
+
+
+
+
## Usage
diff --git a/build.gradle.kts b/build.gradle.kts
index 1fba091..a28eadc 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -21,7 +21,7 @@ plugins {
allprojects {
group = "io.github.mirzemehdi"
- version = "1.0.1"
+ version = "1.1.0"
val sonatypeUsername = gradleLocalProperties(rootDir).getProperty("sonatypeUsername")
val sonatypePassword = gradleLocalProperties(rootDir).getProperty("sonatypePassword")
val gpgKeySecret = gradleLocalProperties(rootDir).getProperty("gpgKeySecret")
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 8eaf580..f21d1f7 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -47,7 +47,6 @@ koin-core = { group = "io.insert-koin", name = "koin-core", version.ref = "koin"
firebase-messaging = { group = "com.google.firebase", name = "firebase-messaging-ktx" ,version.ref="firebase-messaging"}
-
[plugins]
jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" }
composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
diff --git a/kmpnotifier/api/android/kmpnotifier.api b/kmpnotifier/api/android/kmpnotifier.api
new file mode 100644
index 0000000..534da55
--- /dev/null
+++ b/kmpnotifier/api/android/kmpnotifier.api
@@ -0,0 +1,117 @@
+public final class com/mmk/kmpnotifier/extensions/NotifierManagerExtKt {
+ public static final fun onCreateOrOnNewIntent (Lcom/mmk/kmpnotifier/notification/NotifierManager;Landroid/content/Intent;)V
+}
+
+public abstract interface class com/mmk/kmpnotifier/notification/Notifier {
+ public abstract fun notify (ILjava/lang/String;Ljava/lang/String;Ljava/util/Map;)V
+ public abstract fun notify (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)I
+ public abstract fun remove (I)V
+ public abstract fun removeAll ()V
+}
+
+public final class com/mmk/kmpnotifier/notification/Notifier$DefaultImpls {
+ public static synthetic fun notify$default (Lcom/mmk/kmpnotifier/notification/Notifier;ILjava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)V
+ public static synthetic fun notify$default (Lcom/mmk/kmpnotifier/notification/Notifier;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)I
+}
+
+public final class com/mmk/kmpnotifier/notification/NotifierManager {
+ public static final field INSTANCE Lcom/mmk/kmpnotifier/notification/NotifierManager;
+ public final fun addListener (Lcom/mmk/kmpnotifier/notification/NotifierManager$Listener;)V
+ public final fun getLocalNotifier ()Lcom/mmk/kmpnotifier/notification/Notifier;
+ public final fun getPermissionUtil ()Lcom/mmk/kmpnotifier/permission/PermissionUtil;
+ public final fun getPushNotifier ()Lcom/mmk/kmpnotifier/notification/PushNotifier;
+ public final fun initialize (Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration;)V
+}
+
+public abstract interface class com/mmk/kmpnotifier/notification/NotifierManager$Listener {
+ public abstract fun onNewToken (Ljava/lang/String;)V
+ public abstract fun onNotificationClicked (Ljava/util/Map;)V
+ public abstract fun onPayloadData (Ljava/util/Map;)V
+ public abstract fun onPushNotification (Ljava/lang/String;Ljava/lang/String;)V
+}
+
+public final class com/mmk/kmpnotifier/notification/NotifierManager$Listener$DefaultImpls {
+ public static fun onNewToken (Lcom/mmk/kmpnotifier/notification/NotifierManager$Listener;Ljava/lang/String;)V
+ public static fun onNotificationClicked (Lcom/mmk/kmpnotifier/notification/NotifierManager$Listener;Ljava/util/Map;)V
+ public static fun onPayloadData (Lcom/mmk/kmpnotifier/notification/NotifierManager$Listener;Ljava/util/Map;)V
+ public static fun onPushNotification (Lcom/mmk/kmpnotifier/notification/NotifierManager$Listener;Ljava/lang/String;Ljava/lang/String;)V
+}
+
+public abstract interface class com/mmk/kmpnotifier/notification/PushNotifier {
+ public abstract fun deleteMyToken (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+ public abstract fun getToken (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+ public abstract fun subscribeToTopic (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+ public abstract fun unSubscribeFromTopic (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+}
+
+public abstract interface class com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration {
+}
+
+public final class com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Android : com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration {
+ public fun (ILjava/lang/Integer;Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Android$NotificationChannelData;Z)V
+ public synthetic fun (ILjava/lang/Integer;Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Android$NotificationChannelData;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public final fun getNotificationChannelData ()Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Android$NotificationChannelData;
+ public final fun getNotificationIconColorResId ()Ljava/lang/Integer;
+ public final fun getNotificationIconResId ()I
+ public final fun getShowPushNotification ()Z
+}
+
+public final class com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Android$NotificationChannelData {
+ public fun ()V
+ public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public final fun getDescription ()Ljava/lang/String;
+ public final fun getId ()Ljava/lang/String;
+ public final fun getName ()Ljava/lang/String;
+}
+
+public final class com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Desktop : com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration {
+ public fun ()V
+ public fun (ZLjava/lang/String;)V
+ public synthetic fun (ZLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public final fun component1 ()Z
+ public final fun component2 ()Ljava/lang/String;
+ public final fun copy (ZLjava/lang/String;)Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Desktop;
+ public static synthetic fun copy$default (Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Desktop;ZLjava/lang/String;ILjava/lang/Object;)Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Desktop;
+ public fun equals (Ljava/lang/Object;)Z
+ public final fun getNotificationIconPath ()Ljava/lang/String;
+ public final fun getShowPushNotification ()Z
+ public fun hashCode ()I
+ public fun toString ()Ljava/lang/String;
+}
+
+public final class com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Ios : com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration {
+ public fun ()V
+ public fun (ZZ)V
+ public synthetic fun (ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public final fun component1 ()Z
+ public final fun component2 ()Z
+ public final fun copy (ZZ)Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Ios;
+ public static synthetic fun copy$default (Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Ios;ZZILjava/lang/Object;)Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Ios;
+ public fun equals (Ljava/lang/Object;)Z
+ public final fun getAskNotificationPermissionOnStart ()Z
+ public final fun getShowPushNotification ()Z
+ public fun hashCode ()I
+ public fun toString ()Ljava/lang/String;
+}
+
+public final class com/mmk/kmpnotifier/permission/AndroidPermissionUtil {
+ public fun (Landroidx/activity/ComponentActivity;)V
+ public final fun askNotificationPermission (Lkotlin/jvm/functions/Function1;)V
+ public static synthetic fun askNotificationPermission$default (Lcom/mmk/kmpnotifier/permission/AndroidPermissionUtil;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
+}
+
+public final class com/mmk/kmpnotifier/permission/AndroidPermissionUtilKt {
+ public static final fun permissionUtil (Landroidx/activity/ComponentActivity;)Lkotlin/Lazy;
+}
+
+public abstract interface class com/mmk/kmpnotifier/permission/PermissionUtil {
+ public abstract fun askNotificationPermission (Lkotlin/jvm/functions/Function0;)V
+ public abstract fun hasNotificationPermission (Lkotlin/jvm/functions/Function1;)V
+}
+
+public final class com/mmk/kmpnotifier/permission/PermissionUtil$DefaultImpls {
+ public static synthetic fun askNotificationPermission$default (Lcom/mmk/kmpnotifier/permission/PermissionUtil;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V
+ public static synthetic fun hasNotificationPermission$default (Lcom/mmk/kmpnotifier/permission/PermissionUtil;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
+}
+
diff --git a/kmpnotifier/api/jvm/kmpnotifier.api b/kmpnotifier/api/jvm/kmpnotifier.api
new file mode 100644
index 0000000..1bf571a
--- /dev/null
+++ b/kmpnotifier/api/jvm/kmpnotifier.api
@@ -0,0 +1,107 @@
+public final class com/mmk/kmpnotifier/extensions/DesktopPlatformExtKt {
+ public static final fun composeDesktopResourcesPath ()Ljava/lang/String;
+}
+
+public abstract interface class com/mmk/kmpnotifier/notification/Notifier {
+ public abstract fun notify (ILjava/lang/String;Ljava/lang/String;Ljava/util/Map;)V
+ public abstract fun notify (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;)I
+ public abstract fun remove (I)V
+ public abstract fun removeAll ()V
+}
+
+public final class com/mmk/kmpnotifier/notification/Notifier$DefaultImpls {
+ public static synthetic fun notify$default (Lcom/mmk/kmpnotifier/notification/Notifier;ILjava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)V
+ public static synthetic fun notify$default (Lcom/mmk/kmpnotifier/notification/Notifier;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)I
+}
+
+public final class com/mmk/kmpnotifier/notification/NotifierManager {
+ public static final field INSTANCE Lcom/mmk/kmpnotifier/notification/NotifierManager;
+ public final fun addListener (Lcom/mmk/kmpnotifier/notification/NotifierManager$Listener;)V
+ public final fun getLocalNotifier ()Lcom/mmk/kmpnotifier/notification/Notifier;
+ public final fun getPermissionUtil ()Lcom/mmk/kmpnotifier/permission/PermissionUtil;
+ public final fun getPushNotifier ()Lcom/mmk/kmpnotifier/notification/PushNotifier;
+ public final fun initialize (Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration;)V
+}
+
+public abstract interface class com/mmk/kmpnotifier/notification/NotifierManager$Listener {
+ public abstract fun onNewToken (Ljava/lang/String;)V
+ public abstract fun onNotificationClicked (Ljava/util/Map;)V
+ public abstract fun onPayloadData (Ljava/util/Map;)V
+ public abstract fun onPushNotification (Ljava/lang/String;Ljava/lang/String;)V
+}
+
+public final class com/mmk/kmpnotifier/notification/NotifierManager$Listener$DefaultImpls {
+ public static fun onNewToken (Lcom/mmk/kmpnotifier/notification/NotifierManager$Listener;Ljava/lang/String;)V
+ public static fun onNotificationClicked (Lcom/mmk/kmpnotifier/notification/NotifierManager$Listener;Ljava/util/Map;)V
+ public static fun onPayloadData (Lcom/mmk/kmpnotifier/notification/NotifierManager$Listener;Ljava/util/Map;)V
+ public static fun onPushNotification (Lcom/mmk/kmpnotifier/notification/NotifierManager$Listener;Ljava/lang/String;Ljava/lang/String;)V
+}
+
+public abstract interface class com/mmk/kmpnotifier/notification/PushNotifier {
+ public abstract fun deleteMyToken (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+ public abstract fun getToken (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+ public abstract fun subscribeToTopic (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+ public abstract fun unSubscribeFromTopic (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+}
+
+public abstract interface class com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration {
+}
+
+public final class com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Android : com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration {
+ public fun (ILjava/lang/Integer;Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Android$NotificationChannelData;Z)V
+ public synthetic fun (ILjava/lang/Integer;Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Android$NotificationChannelData;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public final fun getNotificationChannelData ()Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Android$NotificationChannelData;
+ public final fun getNotificationIconColorResId ()Ljava/lang/Integer;
+ public final fun getNotificationIconResId ()I
+ public final fun getShowPushNotification ()Z
+}
+
+public final class com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Android$NotificationChannelData {
+ public fun ()V
+ public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public final fun getDescription ()Ljava/lang/String;
+ public final fun getId ()Ljava/lang/String;
+ public final fun getName ()Ljava/lang/String;
+}
+
+public final class com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Desktop : com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration {
+ public fun ()V
+ public fun (ZLjava/lang/String;)V
+ public synthetic fun (ZLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public final fun component1 ()Z
+ public final fun component2 ()Ljava/lang/String;
+ public final fun copy (ZLjava/lang/String;)Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Desktop;
+ public static synthetic fun copy$default (Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Desktop;ZLjava/lang/String;ILjava/lang/Object;)Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Desktop;
+ public fun equals (Ljava/lang/Object;)Z
+ public final fun getNotificationIconPath ()Ljava/lang/String;
+ public final fun getShowPushNotification ()Z
+ public fun hashCode ()I
+ public fun toString ()Ljava/lang/String;
+}
+
+public final class com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Ios : com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration {
+ public fun ()V
+ public fun (ZZ)V
+ public synthetic fun (ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public final fun component1 ()Z
+ public final fun component2 ()Z
+ public final fun copy (ZZ)Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Ios;
+ public static synthetic fun copy$default (Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Ios;ZZILjava/lang/Object;)Lcom/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration$Ios;
+ public fun equals (Ljava/lang/Object;)Z
+ public final fun getAskNotificationPermissionOnStart ()Z
+ public final fun getShowPushNotification ()Z
+ public fun hashCode ()I
+ public fun toString ()Ljava/lang/String;
+}
+
+public abstract interface class com/mmk/kmpnotifier/permission/PermissionUtil {
+ public abstract fun askNotificationPermission (Lkotlin/jvm/functions/Function0;)V
+ public abstract fun hasNotificationPermission (Lkotlin/jvm/functions/Function1;)V
+}
+
+public final class com/mmk/kmpnotifier/permission/PermissionUtil$DefaultImpls {
+ public static synthetic fun askNotificationPermission$default (Lcom/mmk/kmpnotifier/permission/PermissionUtil;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V
+ public static synthetic fun hasNotificationPermission$default (Lcom/mmk/kmpnotifier/permission/PermissionUtil;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
+}
+
diff --git a/kmpnotifier/build.gradle.kts b/kmpnotifier/build.gradle.kts
index c594d31..639f8be 100644
--- a/kmpnotifier/build.gradle.kts
+++ b/kmpnotifier/build.gradle.kts
@@ -16,7 +16,7 @@ kotlin {
}
}
-
+ jvm()
iosX64()
iosArm64()
iosSimulatorArm64()
@@ -47,6 +47,11 @@ kotlin {
implementation(libs.koin.core)
implementation(libs.kotlinx.coroutine)
}
+
+ commonTest.dependencies {
+ implementation(libs.kotlin.test)
+ }
+
}
}
diff --git a/kmpnotifier/src/commonMain/kotlin/com/mmk/kmpnotifier/di/LibDependencyInitializer.kt b/kmpnotifier/src/commonMain/kotlin/com/mmk/kmpnotifier/di/LibDependencyInitializer.kt
index 03b0a11..b01358f 100644
--- a/kmpnotifier/src/commonMain/kotlin/com/mmk/kmpnotifier/di/LibDependencyInitializer.kt
+++ b/kmpnotifier/src/commonMain/kotlin/com/mmk/kmpnotifier/di/LibDependencyInitializer.kt
@@ -42,13 +42,14 @@ private fun Koin.onLibraryInitialized() {
get() //This will make sure that that when lib is initialized, init method is called
when (platform) {
- Platform.Android -> Unit //In Android platform permission should be asked in activity
+ Platform.Android, Platform.Desktop -> Unit //In Android platform permission should be asked in activity
Platform.Ios -> {
val askNotificationPermissionOnStart =
(configuration as? NotificationPlatformConfiguration.Ios)?.askNotificationPermissionOnStart
?: true
if (askNotificationPermissionOnStart) permissionUtil.askNotificationPermission()
}
+
}
}
diff --git a/kmpnotifier/src/commonMain/kotlin/com/mmk/kmpnotifier/di/PlatformModule.kt b/kmpnotifier/src/commonMain/kotlin/com/mmk/kmpnotifier/di/PlatformModule.kt
index 5d8d5a6..97e225d 100644
--- a/kmpnotifier/src/commonMain/kotlin/com/mmk/kmpnotifier/di/PlatformModule.kt
+++ b/kmpnotifier/src/commonMain/kotlin/com/mmk/kmpnotifier/di/PlatformModule.kt
@@ -6,5 +6,6 @@ import org.koin.core.module.Module
internal sealed interface Platform {
data object Android : Platform
data object Ios : Platform
+ data object Desktop : Platform
}
internal expect val platformModule: Module
\ No newline at end of file
diff --git a/kmpnotifier/src/commonMain/kotlin/com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration.kt b/kmpnotifier/src/commonMain/kotlin/com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration.kt
index 6a9261a..2c1363a 100644
--- a/kmpnotifier/src/commonMain/kotlin/com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration.kt
+++ b/kmpnotifier/src/commonMain/kotlin/com/mmk/kmpnotifier/notification/configuration/NotificationPlatformConfiguration.kt
@@ -1,5 +1,6 @@
package com.mmk.kmpnotifier.notification.configuration
+
/**
* You can configure some customization for notifications depending on the platform
*/
@@ -55,4 +56,10 @@ public sealed interface NotificationPlatformConfiguration {
public val showPushNotification: Boolean = true,
public val askNotificationPermissionOnStart: Boolean = true
) : NotificationPlatformConfiguration
+
+
+ public data class Desktop(
+ public val showPushNotification: Boolean = true,
+ public val notificationIconPath: String? = null
+ ) : NotificationPlatformConfiguration
}
\ No newline at end of file
diff --git a/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/di/PlatformModule.jvm.kt b/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/di/PlatformModule.jvm.kt
new file mode 100644
index 0000000..aae4cc1
--- /dev/null
+++ b/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/di/PlatformModule.jvm.kt
@@ -0,0 +1,25 @@
+package com.mmk.kmpnotifier.di
+
+import com.mmk.kmpnotifier.firebase.FirebaseDesktopPushNotifier
+import com.mmk.kmpnotifier.notification.DesktopNotifierFactory
+import com.mmk.kmpnotifier.notification.Notifier
+import com.mmk.kmpnotifier.notification.PushNotifier
+import com.mmk.kmpnotifier.notification.configuration.NotificationPlatformConfiguration
+import com.mmk.kmpnotifier.permission.DesktopPermissionUtil
+import com.mmk.kmpnotifier.permission.PermissionUtil
+import org.koin.core.module.Module
+import org.koin.core.module.dsl.factoryOf
+import org.koin.dsl.bind
+import org.koin.dsl.module
+
+internal actual val platformModule: Module = module {
+ factory { Platform.Desktop } bind Platform::class
+
+ factory {
+ val configuration =
+ get() as NotificationPlatformConfiguration.Desktop
+ DesktopNotifierFactory.getNotifier(configuration = configuration)
+ } bind Notifier::class
+ factoryOf(::DesktopPermissionUtil) bind PermissionUtil::class
+ factoryOf(::FirebaseDesktopPushNotifier) bind PushNotifier::class
+}
\ No newline at end of file
diff --git a/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/extensions/DesktopPlatformExt.kt b/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/extensions/DesktopPlatformExt.kt
new file mode 100644
index 0000000..c4d483c
--- /dev/null
+++ b/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/extensions/DesktopPlatformExt.kt
@@ -0,0 +1,27 @@
+package com.mmk.kmpnotifier.extensions
+
+import java.io.File
+
+internal sealed interface DesktopPlatform {
+ data object Linux : DesktopPlatform
+ data object Windows : DesktopPlatform
+ data object MacOs : DesktopPlatform
+}
+
+internal fun getDesktopPlatformType(): DesktopPlatform? {
+ val name = System.getProperty("os.name")
+ return when {
+ name?.contains("Linux") == true -> DesktopPlatform.Linux
+ name?.contains("Win") == true -> DesktopPlatform.Windows
+ name?.contains("Mac") == true -> DesktopPlatform.MacOs
+ else -> null
+ }
+}
+
+public fun composeDesktopResourcesPath(): String? {
+ return runCatching {
+ val resourcesDirectory = File(System.getProperty("compose.application.resources.dir"))
+ return resourcesDirectory.canonicalPath
+ }.getOrNull()
+
+}
\ No newline at end of file
diff --git a/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/firebase/FirebaseDesktopPushNotifier.kt b/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/firebase/FirebaseDesktopPushNotifier.kt
new file mode 100644
index 0000000..6b5d2ec
--- /dev/null
+++ b/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/firebase/FirebaseDesktopPushNotifier.kt
@@ -0,0 +1,22 @@
+package com.mmk.kmpnotifier.firebase
+
+import com.mmk.kmpnotifier.notification.PushNotifier
+
+internal class FirebaseDesktopPushNotifier:PushNotifier {
+ override suspend fun getToken(): String? {
+ println("Get firebase toekn")
+ return null
+ }
+
+ override suspend fun deleteMyToken() {
+ println("Delete firebase toekn")
+ }
+
+ override suspend fun subscribeToTopic(topic: String) {
+ println("Subscribe firebase topic")
+ }
+
+ override suspend fun unSubscribeFromTopic(topic: String) {
+ println("Unsubscribe firebase topic")
+ }
+}
\ No newline at end of file
diff --git a/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/notification/DesktopNotifierFactory.kt b/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/notification/DesktopNotifierFactory.kt
new file mode 100644
index 0000000..32c881c
--- /dev/null
+++ b/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/notification/DesktopNotifierFactory.kt
@@ -0,0 +1,15 @@
+package com.mmk.kmpnotifier.notification
+
+import com.mmk.kmpnotifier.notification.configuration.NotificationPlatformConfiguration
+import com.mmk.kmpnotifier.notification.impl.JOptionPaneNotifier
+import com.mmk.kmpnotifier.notification.impl.TrayNotifier
+
+internal object DesktopNotifierFactory {
+ fun getNotifier(configuration: NotificationPlatformConfiguration.Desktop): Notifier {
+ return when {
+ TrayNotifier.isSupported -> TrayNotifier(configuration = configuration)
+ //TODO for now return JOptionPaneNotifier for not supported platforms
+ else -> JOptionPaneNotifier(configuration = configuration)
+ }
+ }
+}
\ No newline at end of file
diff --git a/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/notification/impl/JOptionPaneNotifier.kt b/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/notification/impl/JOptionPaneNotifier.kt
new file mode 100644
index 0000000..6340759
--- /dev/null
+++ b/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/notification/impl/JOptionPaneNotifier.kt
@@ -0,0 +1,34 @@
+package com.mmk.kmpnotifier.notification.impl
+
+import com.mmk.kmpnotifier.notification.Notifier
+import com.mmk.kmpnotifier.notification.configuration.NotificationPlatformConfiguration
+import javax.swing.ImageIcon
+import javax.swing.JOptionPane
+
+internal class JOptionPaneNotifier(private val configuration: NotificationPlatformConfiguration.Desktop) :
+ Notifier {
+
+ override fun notify(title: String, body: String, payloadData: Map): Int {
+ val id = -1
+ notify(id = id, title = title, body = body, payloadData)
+ return id
+ }
+
+ override fun notify(id: Int, title: String, body: String, payloadData: Map) {
+ JOptionPane.showMessageDialog(
+ null,
+ body,
+ title,
+ JOptionPane.INFORMATION_MESSAGE,
+ ImageIcon(configuration.notificationIconPath)
+ )
+ }
+
+ override fun remove(id: Int) {
+ println("No remove functionality")
+ }
+
+ override fun removeAll() {
+ println("No removeAll functionality")
+ }
+}
\ No newline at end of file
diff --git a/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/notification/impl/TrayNotifier.kt b/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/notification/impl/TrayNotifier.kt
new file mode 100644
index 0000000..ed4fe07
--- /dev/null
+++ b/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/notification/impl/TrayNotifier.kt
@@ -0,0 +1,58 @@
+package com.mmk.kmpnotifier.notification.impl
+
+import com.mmk.kmpnotifier.notification.Notifier
+import com.mmk.kmpnotifier.notification.configuration.NotificationPlatformConfiguration
+import java.awt.SystemTray
+import java.awt.Toolkit
+import java.awt.TrayIcon
+import kotlin.random.Random
+
+internal class TrayNotifier(private val configuration: NotificationPlatformConfiguration.Desktop) :
+ Notifier {
+
+ private val trayIcons: MutableMap = mutableMapOf()
+
+ companion object {
+ val isSupported by lazy {
+ SystemTray.isSupported().also {
+ if (it.not()) System.err.println(
+ "Tray is not supported on the current platform. "
+ )
+ }
+ }
+ }
+
+ override fun notify(title: String, body: String, payloadData: Map): Int {
+ if (isSupported.not()) return -1
+ val notificationID = Random.nextInt(0, Int.MAX_VALUE)
+ notify(notificationID, title, body, payloadData)
+ return notificationID
+ }
+
+ override fun notify(
+ id: Int,
+ title: String,
+ body: String,
+ payloadData: Map
+ ) {
+ if (isSupported.not()) return
+ val icon = Toolkit.getDefaultToolkit().getImage(configuration.notificationIconPath)
+ val trayIcon = TrayIcon(icon).apply {
+ isImageAutoSize = true
+ }
+ SystemTray.getSystemTray().add(trayIcon)
+ .also { trayIcons[id] = trayIcon }
+ trayIcon.displayMessage(title, body, TrayIcon.MessageType.INFO)
+ }
+
+ override fun remove(id: Int) {
+ val systemTray = SystemTray.getSystemTray()
+ val trayIcon = trayIcons.getOrDefault(id, null)
+ trayIcon?.let { systemTray.remove(it) }
+ }
+
+ override fun removeAll() {
+ val systemTray = SystemTray.getSystemTray()
+ systemTray.trayIcons.forEach { systemTray.remove(it) }
+ }
+}
\ No newline at end of file
diff --git a/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/permission/DesktopPermissionUtil.kt b/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/permission/DesktopPermissionUtil.kt
new file mode 100644
index 0000000..5c5aa21
--- /dev/null
+++ b/kmpnotifier/src/jvmMain/kotlin/com/mmk/kmpnotifier/permission/DesktopPermissionUtil.kt
@@ -0,0 +1,13 @@
+package com.mmk.kmpnotifier.permission
+
+internal class DesktopPermissionUtil:PermissionUtil {
+ override fun hasNotificationPermission(onPermissionResult: (Boolean) -> Unit) {
+ println("Desktop has permission result")
+ onPermissionResult(true)
+ }
+
+ override fun askNotificationPermission(onPermissionGranted: () -> Unit) {
+ println("Desktop ask permission")
+ onPermissionGranted()
+ }
+}
\ No newline at end of file
diff --git a/sample/api/android/sample.api b/sample/api/android/sample.api
new file mode 100644
index 0000000..78fbd7a
--- /dev/null
+++ b/sample/api/android/sample.api
@@ -0,0 +1,47 @@
+public final class com/mmk/kmpnotifier/sample/AppInitializer {
+ public static final field $stable I
+ public static final field INSTANCE Lcom/mmk/kmpnotifier/sample/AppInitializer;
+ public final fun onApplicationStart ()V
+}
+
+public final class com/mmk/kmpnotifier/sample/AppKt {
+ public static final fun App (Landroidx/compose/runtime/Composer;I)V
+}
+
+public final class com/mmk/kmpnotifier/sample/ComposableSingletons$AppKt {
+ public static final field INSTANCE Lcom/mmk/kmpnotifier/sample/ComposableSingletons$AppKt;
+ public static field lambda-1 Lkotlin/jvm/functions/Function3;
+ public static field lambda-2 Lkotlin/jvm/functions/Function3;
+ public static field lambda-3 Lkotlin/jvm/functions/Function3;
+ public fun ()V
+ public final fun getLambda-1$sample_release ()Lkotlin/jvm/functions/Function3;
+ public final fun getLambda-2$sample_release ()Lkotlin/jvm/functions/Function3;
+ public final fun getLambda-3$sample_release ()Lkotlin/jvm/functions/Function3;
+}
+
+public final class com/mmk/kmpnotifier/sample/ComposableSingletons$MainActivityKt {
+ public static final field INSTANCE Lcom/mmk/kmpnotifier/sample/ComposableSingletons$MainActivityKt;
+ public static field lambda-1 Lkotlin/jvm/functions/Function2;
+ public fun ()V
+ public final fun getLambda-1$sample_release ()Lkotlin/jvm/functions/Function2;
+}
+
+public final class com/mmk/kmpnotifier/sample/MainActivity : androidx/activity/ComponentActivity {
+ public static final field $stable I
+ public fun ()V
+}
+
+public final class com/mmk/kmpnotifier/sample/MainActivityKt {
+ public static final fun AppAndroidPreview (Landroidx/compose/runtime/Composer;I)V
+}
+
+public final class com/mmk/kmpnotifier/sample/MainApplication : android/app/Application {
+ public static final field $stable I
+ public fun ()V
+ public fun onCreate ()V
+}
+
+public final class com/mmk/kmpnotifier/sample/Platform_androidKt {
+ public static final fun onApplicationStartPlatformSpecific ()V
+}
+
diff --git a/sample/api/desktop/sample.api b/sample/api/desktop/sample.api
new file mode 100644
index 0000000..9289235
--- /dev/null
+++ b/sample/api/desktop/sample.api
@@ -0,0 +1,39 @@
+public final class com/mmk/kmpnotifier/sample/AppInitializer {
+ public static final field $stable I
+ public static final field INSTANCE Lcom/mmk/kmpnotifier/sample/AppInitializer;
+ public final fun onApplicationStart ()V
+}
+
+public final class com/mmk/kmpnotifier/sample/AppKt {
+ public static final fun App (Landroidx/compose/runtime/Composer;I)V
+}
+
+public final class com/mmk/kmpnotifier/sample/ComposableSingletons$AppKt {
+ public static final field INSTANCE Lcom/mmk/kmpnotifier/sample/ComposableSingletons$AppKt;
+ public static field lambda-1 Lkotlin/jvm/functions/Function3;
+ public static field lambda-2 Lkotlin/jvm/functions/Function3;
+ public static field lambda-3 Lkotlin/jvm/functions/Function3;
+ public fun ()V
+ public final fun getLambda-1$sample ()Lkotlin/jvm/functions/Function3;
+ public final fun getLambda-2$sample ()Lkotlin/jvm/functions/Function3;
+ public final fun getLambda-3$sample ()Lkotlin/jvm/functions/Function3;
+}
+
+public final class com/mmk/kmpnotifier/sample/ComposableSingletons$MainKt {
+ public static final field INSTANCE Lcom/mmk/kmpnotifier/sample/ComposableSingletons$MainKt;
+ public static field lambda-1 Lkotlin/jvm/functions/Function3;
+ public static field lambda-2 Lkotlin/jvm/functions/Function3;
+ public fun ()V
+ public final fun getLambda-1$sample ()Lkotlin/jvm/functions/Function3;
+ public final fun getLambda-2$sample ()Lkotlin/jvm/functions/Function3;
+}
+
+public final class com/mmk/kmpnotifier/sample/MainKt {
+ public static final fun main ()V
+ public static synthetic fun main ([Ljava/lang/String;)V
+}
+
+public final class com/mmk/kmpnotifier/sample/Platform_desktopKt {
+ public static final fun onApplicationStartPlatformSpecific ()V
+}
+
diff --git a/sample/build.gradle.kts b/sample/build.gradle.kts
index 5cbb6fe..1ae25be 100644
--- a/sample/build.gradle.kts
+++ b/sample/build.gradle.kts
@@ -1,4 +1,5 @@
import org.jetbrains.compose.ExperimentalComposeLibrary
+import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins {
alias(libs.plugins.kotlinMultiplatform)
@@ -17,6 +18,7 @@ kotlin {
}
}
}
+ jvm("desktop")
listOf(
iosX64(),
iosArm64(),
@@ -29,6 +31,7 @@ kotlin {
}
}
sourceSets {
+ val desktopMain by getting
androidMain.dependencies {
implementation(libs.compose.ui)
@@ -39,10 +42,13 @@ kotlin {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material)
- @OptIn(ExperimentalComposeLibrary::class)
implementation(compose.components.resources)
api(project(":kmpnotifier"))
}
+ desktopMain.dependencies {
+ implementation(compose.desktop.currentOs)
+ implementation(compose.desktop.common)
+ }
}
}
@@ -82,4 +88,15 @@ android {
debugImplementation(libs.compose.ui.tooling)
}
}
+compose.desktop {
+ application {
+ mainClass = "com.mmk.kmpnotifier.sample.MainKt"
+ nativeDistributions {
+ targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
+ packageName = "KMPNotifier"
+ packageVersion = "1.0.0"
+ appResourcesRootDir.set(project.layout.projectDirectory.dir("resources"))
+ }
+ }
+}
diff --git a/sample/resources/common/ic_notification.png b/sample/resources/common/ic_notification.png
new file mode 100644
index 0000000..4a0728a
Binary files /dev/null and b/sample/resources/common/ic_notification.png differ
diff --git a/sample/src/commonMain/composeResources/drawable/ic_notification.png b/sample/src/commonMain/composeResources/drawable/ic_notification.png
new file mode 100644
index 0000000..4a0728a
Binary files /dev/null and b/sample/src/commonMain/composeResources/drawable/ic_notification.png differ
diff --git a/sample/src/commonMain/kotlin/com/mmk/kmpnotifier/sample/App.kt b/sample/src/commonMain/kotlin/com/mmk/kmpnotifier/sample/App.kt
index 8ab6ab3..c85a110 100644
--- a/sample/src/commonMain/kotlin/com/mmk/kmpnotifier/sample/App.kt
+++ b/sample/src/commonMain/kotlin/com/mmk/kmpnotifier/sample/App.kt
@@ -23,6 +23,7 @@ import com.mmk.kmpnotifier.notification.NotifierManager
fun App() {
var myPushNotificationToken by remember { mutableStateOf("") }
LaunchedEffect(true) {
+
println("LaunchedEffectApp is called")
NotifierManager.addListener(object : NotifierManager.Listener {
override fun onNewToken(token: String) {
diff --git a/sample/src/desktopMain/kotlin/com/mmk/kmpnotifier/sample/Main.kt b/sample/src/desktopMain/kotlin/com/mmk/kmpnotifier/sample/Main.kt
new file mode 100644
index 0000000..2634374
--- /dev/null
+++ b/sample/src/desktopMain/kotlin/com/mmk/kmpnotifier/sample/Main.kt
@@ -0,0 +1,17 @@
+package com.mmk.kmpnotifier.sample
+
+import androidx.compose.ui.window.Window
+import androidx.compose.ui.window.application
+
+
+fun main() = application {
+ AppInitializer.onApplicationStart()
+ Window(
+ onCloseRequest = ::exitApplication,
+ title = "KMPNotifier Desktop",
+ ) {
+ println("Desktop app is started")
+ App()
+
+ }
+}
\ No newline at end of file
diff --git a/sample/src/desktopMain/kotlin/com/mmk/kmpnotifier/sample/Platform.desktop.kt b/sample/src/desktopMain/kotlin/com/mmk/kmpnotifier/sample/Platform.desktop.kt
new file mode 100644
index 0000000..8944288
--- /dev/null
+++ b/sample/src/desktopMain/kotlin/com/mmk/kmpnotifier/sample/Platform.desktop.kt
@@ -0,0 +1,16 @@
+package com.mmk.kmpnotifier.sample
+
+import com.mmk.kmpnotifier.extensions.composeDesktopResourcesPath
+import com.mmk.kmpnotifier.notification.NotifierManager
+import com.mmk.kmpnotifier.notification.configuration.NotificationPlatformConfiguration
+import java.io.File
+
+actual fun onApplicationStartPlatformSpecific() {
+ println("Desktop app is initialized")
+ NotifierManager.initialize(
+ NotificationPlatformConfiguration.Desktop(
+ showPushNotification = true,
+ notificationIconPath = composeDesktopResourcesPath() + File.separator + "ic_notification.png"
+ )
+ )
+}
\ No newline at end of file