about summary refs log tree commit diff
path: root/modules/expo-background-notification-handler/android
diff options
context:
space:
mode:
Diffstat (limited to 'modules/expo-background-notification-handler/android')
-rw-r--r--modules/expo-background-notification-handler/android/build.gradle93
-rw-r--r--modules/expo-background-notification-handler/android/src/main/AndroidManifest.xml2
-rw-r--r--modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandler.kt39
-rw-r--r--modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandlerInterface.kt7
-rw-r--r--modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/ExpoBackgroundNotificationHandlerModule.kt70
-rw-r--r--modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/NotificationPrefs.kt134
6 files changed, 345 insertions, 0 deletions
diff --git a/modules/expo-background-notification-handler/android/build.gradle b/modules/expo-background-notification-handler/android/build.gradle
new file mode 100644
index 000000000..e18eee934
--- /dev/null
+++ b/modules/expo-background-notification-handler/android/build.gradle
@@ -0,0 +1,93 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply plugin: 'maven-publish'
+
+group = 'expo.modules.backgroundnotificationhandler'
+version = '0.5.0'
+
+buildscript {
+  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
+  if (expoModulesCorePlugin.exists()) {
+    apply from: expoModulesCorePlugin
+    applyKotlinExpoModulesCorePlugin()
+  }
+
+  // Simple helper that allows the root project to override versions declared by this library.
+  ext.safeExtGet = { prop, fallback ->
+    rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
+  }
+
+  // Ensures backward compatibility
+  ext.getKotlinVersion = {
+    if (ext.has("kotlinVersion")) {
+      ext.kotlinVersion()
+    } else {
+      ext.safeExtGet("kotlinVersion", "1.8.10")
+    }
+  }
+
+  repositories {
+    mavenCentral()
+  }
+
+  dependencies {
+    classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}")
+  }
+}
+
+afterEvaluate {
+  publishing {
+    publications {
+      release(MavenPublication) {
+        from components.release
+      }
+    }
+    repositories {
+      maven {
+        url = mavenLocal().url
+      }
+    }
+  }
+}
+
+android {
+  compileSdkVersion safeExtGet("compileSdkVersion", 33)
+
+  def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
+  if (agpVersion.tokenize('.')[0].toInteger() < 8) {
+    compileOptions {
+      sourceCompatibility JavaVersion.VERSION_11
+      targetCompatibility JavaVersion.VERSION_11
+    }
+
+    kotlinOptions {
+      jvmTarget = JavaVersion.VERSION_11.majorVersion
+    }
+  }
+
+  namespace "expo.modules.backgroundnotificationhandler"
+  defaultConfig {
+    minSdkVersion safeExtGet("minSdkVersion", 21)
+    targetSdkVersion safeExtGet("targetSdkVersion", 34)
+    versionCode 1
+    versionName "0.5.0"
+  }
+  lintOptions {
+    abortOnError false
+  }
+  publishing {
+    singleVariant("release") {
+      withSourcesJar()
+    }
+  }
+}
+
+repositories {
+  mavenCentral()
+}
+
+dependencies {
+  implementation project(':expo-modules-core')
+  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
+  implementation 'com.google.firebase:firebase-messaging-ktx:24.0.0'
+}
diff --git a/modules/expo-background-notification-handler/android/src/main/AndroidManifest.xml b/modules/expo-background-notification-handler/android/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..bdae66c8f
--- /dev/null
+++ b/modules/expo-background-notification-handler/android/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+<manifest>
+</manifest>
diff --git a/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandler.kt b/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandler.kt
new file mode 100644
index 000000000..344508523
--- /dev/null
+++ b/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandler.kt
@@ -0,0 +1,39 @@
+package expo.modules.backgroundnotificationhandler
+
+import android.content.Context
+import com.google.firebase.messaging.RemoteMessage
+
+class BackgroundNotificationHandler(
+  private val context: Context,
+  private val notifInterface: BackgroundNotificationHandlerInterface
+) {
+  fun handleMessage(remoteMessage: RemoteMessage) {
+    if (ExpoBackgroundNotificationHandlerModule.isForegrounded) {
+      // We'll let expo-notifications handle the notification if the app is foregrounded
+      return
+    }
+
+    if (remoteMessage.data["reason"] == "chat-message") {
+      mutateWithChatMessage(remoteMessage)
+    }
+
+    notifInterface.showMessage(remoteMessage)
+  }
+
+  private fun mutateWithChatMessage(remoteMessage: RemoteMessage) {
+    if (NotificationPrefs(context).getBoolean("playSoundChat")) {
+      // If oreo or higher
+      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
+        remoteMessage.data["channelId"] = "chat-messages"
+      } else {
+        remoteMessage.data["sound"] = "dm.mp3"
+      }
+    } else {
+      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
+        remoteMessage.data["channelId"] = "chat-messages-muted"
+      } else {
+        remoteMessage.data["sound"] = null
+      }
+    }
+  }
+}
diff --git a/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandlerInterface.kt b/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandlerInterface.kt
new file mode 100644
index 000000000..41fb65eb6
--- /dev/null
+++ b/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandlerInterface.kt
@@ -0,0 +1,7 @@
+package expo.modules.backgroundnotificationhandler
+
+import com.google.firebase.messaging.RemoteMessage
+
+interface BackgroundNotificationHandlerInterface {
+  fun showMessage(remoteMessage: RemoteMessage)
+}
diff --git a/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/ExpoBackgroundNotificationHandlerModule.kt b/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/ExpoBackgroundNotificationHandlerModule.kt
new file mode 100644
index 000000000..083ff1223
--- /dev/null
+++ b/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/ExpoBackgroundNotificationHandlerModule.kt
@@ -0,0 +1,70 @@
+package expo.modules.backgroundnotificationhandler
+
+import expo.modules.kotlin.modules.Module
+import expo.modules.kotlin.modules.ModuleDefinition
+
+class ExpoBackgroundNotificationHandlerModule : Module() {
+  companion object {
+    var isForegrounded = false
+  }
+
+  override fun definition() = ModuleDefinition {
+    Name("ExpoBackgroundNotificationHandler")
+
+    OnCreate {
+      NotificationPrefs(appContext.reactContext).initialize()
+    }
+
+    OnActivityEntersForeground {
+      isForegrounded = true
+    }
+
+    OnActivityEntersBackground {
+      isForegrounded = false
+    }
+
+    AsyncFunction("getAllPrefsAsync") {
+      return@AsyncFunction NotificationPrefs(appContext.reactContext).getAllPrefs()
+    }
+
+    AsyncFunction("getBoolAsync") { forKey: String ->
+      return@AsyncFunction NotificationPrefs(appContext.reactContext).getBoolean(forKey)
+    }
+
+    AsyncFunction("getStringAsync") { forKey: String ->
+      return@AsyncFunction NotificationPrefs(appContext.reactContext).getString(forKey)
+    }
+
+    AsyncFunction("getStringArrayAsync") { forKey: String ->
+      return@AsyncFunction NotificationPrefs(appContext.reactContext).getStringArray(forKey)
+    }
+
+    AsyncFunction("setBoolAsync") { forKey: String, value: Boolean ->
+      NotificationPrefs(appContext.reactContext).setBoolean(forKey, value)
+    }
+
+    AsyncFunction("setStringAsync") { forKey: String, value: String ->
+      NotificationPrefs(appContext.reactContext).setString(forKey, value)
+    }
+
+    AsyncFunction("setStringArrayAsync") { forKey: String, value: Array<String> ->
+      NotificationPrefs(appContext.reactContext).setStringArray(forKey, value)
+    }
+
+    AsyncFunction("addToStringArrayAsync") { forKey: String, string: String ->
+      NotificationPrefs(appContext.reactContext).addToStringArray(forKey, string)
+    }
+
+    AsyncFunction("removeFromStringArrayAsync") { forKey: String, string: String ->
+      NotificationPrefs(appContext.reactContext).removeFromStringArray(forKey, string)
+    }
+
+    AsyncFunction("addManyToStringArrayAsync") { forKey: String, strings: Array<String> ->
+      NotificationPrefs(appContext.reactContext).addManyToStringArray(forKey, strings)
+    }
+
+    AsyncFunction("removeManyFromStringArrayAsync") { forKey: String, strings: Array<String> ->
+      NotificationPrefs(appContext.reactContext).removeManyFromStringArray(forKey, strings)
+    }
+  }
+}
diff --git a/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/NotificationPrefs.kt b/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/NotificationPrefs.kt
new file mode 100644
index 000000000..17ef9205e
--- /dev/null
+++ b/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/NotificationPrefs.kt
@@ -0,0 +1,134 @@
+package expo.modules.backgroundnotificationhandler
+
+import android.content.Context
+
+val DEFAULTS = mapOf<String, Any>(
+  "playSoundChat" to true,
+  "playSoundFollow" to false,
+  "playSoundLike" to false,
+  "playSoundMention" to false,
+  "playSoundQuote" to false,
+  "playSoundReply" to false,
+  "playSoundRepost" to false,
+  "mutedThreads" to mapOf<String, List<String>>()
+)
+
+class NotificationPrefs (private val context: Context?) {
+  private val prefs = context?.getSharedPreferences("xyz.blueskyweb.app", Context.MODE_PRIVATE)
+    ?: throw Error("Context is null")
+
+  fun initialize() {
+    prefs
+      .edit()
+      .apply {
+        DEFAULTS.forEach { (key, value) ->
+          if (prefs.contains(key)) {
+            return@forEach
+          }
+
+          when (value) {
+            is Boolean -> {
+              putBoolean(key, value)
+            }
+            is String -> {
+              putString(key, value)
+            }
+            is Array<*> -> {
+              putStringSet(key, value.map { it.toString() }.toSet())
+            }
+            is Map<*, *> -> {
+              putStringSet(key, value.map { it.toString() }.toSet())
+            }
+          }
+        }
+      }
+      .apply()
+  }
+
+  fun getAllPrefs(): MutableMap<String, *> {
+    return prefs.all
+  }
+
+  fun getBoolean(key: String): Boolean {
+    return prefs.getBoolean(key, false)
+  }
+
+  fun getString(key: String): String? {
+    return prefs.getString(key, null)
+  }
+
+  fun getStringArray(key: String): Array<String>? {
+    return prefs.getStringSet(key, null)?.toTypedArray()
+  }
+
+  fun setBoolean(key: String, value: Boolean) {
+    prefs
+      .edit()
+      .apply {
+        putBoolean(key, value)
+      }
+      .apply()
+  }
+
+  fun setString(key: String, value: String) {
+    prefs
+      .edit()
+      .apply {
+        putString(key, value)
+      }
+      .apply()
+  }
+
+  fun setStringArray(key: String, value: Array<String>) {
+    prefs
+      .edit()
+      .apply {
+        putStringSet(key, value.toSet())
+      }
+      .apply()
+  }
+
+  fun addToStringArray(key: String, string: String) {
+    prefs
+      .edit()
+      .apply {
+        val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf()
+        set.add(string)
+        putStringSet(key, set)
+      }
+      .apply()
+  }
+
+  fun removeFromStringArray(key: String, string: String) {
+    prefs
+      .edit()
+      .apply {
+        val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf()
+        set.remove(string)
+        putStringSet(key, set)
+      }
+      .apply()
+  }
+
+  fun addManyToStringArray(key: String, strings: Array<String>) {
+    prefs
+      .edit()
+      .apply {
+        val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf()
+        set.addAll(strings.toSet())
+        putStringSet(key, set)
+      }
+      .apply()
+  }
+
+  fun removeManyFromStringArray(key: String, strings: Array<String>) {
+    prefs
+      .edit()
+      .apply {
+        val set = prefs.getStringSet(key, null)?.toMutableSet() ?: mutableSetOf()
+        set.removeAll(strings.toSet())
+        putStringSet(key, set)
+      }
+      .apply()
+  }
+}
\ No newline at end of file