diff --git a/modules/expo-background-notification-handler/android/build.gradle b/modules/expo-background-notification-handler/android/build.gradle index e18eee9343..375ab53a44 100644 --- a/modules/expo-background-notification-handler/android/build.gradle +++ b/modules/expo-background-notification-handler/android/build.gradle @@ -6,88 +6,89 @@ 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") + def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle") + if (expoModulesCorePlugin.exists()) { + apply from: expoModulesCorePlugin + applyKotlinExpoModulesCorePlugin() } - } - repositories { - mavenCentral() - } + // 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 + } - dependencies { - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getKotlinVersion()}") - } + // 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 - } + publishing { + publications { + release(MavenPublication) { + from components.release + } + } + repositories { + maven { + url = mavenLocal().url + } + } } - repositories { - maven { - url = mavenLocal().url - } - } - } } android { - compileSdkVersion safeExtGet("compileSdkVersion", 33) + 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 + 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 + } } - 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" } - } - - 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() + lintOptions { + abortOnError false + } + publishing { + singleVariant("release") { + withSourcesJar() + } } - } } repositories { - mavenCentral() + 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' + implementation project(':expo-bluesky-swiss-army') + 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/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandler.kt b/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/BackgroundNotificationHandler.kt index 198187ae82..d4b3c5c4f5 100644 --- 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 @@ -2,6 +2,7 @@ package expo.modules.backgroundnotificationhandler import android.content.Context import com.google.firebase.messaging.RemoteMessage +import expo.modules.blueskyswissarmy.sharedprefs.Preferences enum class NotificationType(val type: String) { Like("like"), @@ -36,7 +37,7 @@ class BackgroundNotificationHandler( } private fun mutateWithChatMessage(remoteMessage: RemoteMessage) { - if (NotificationPrefs(context).getBoolean("playSoundChat")) { + if (Preferences(context).getBoolean("playSoundChat") == true) { // If oreo or higher if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { remoteMessage.data["channelId"] = "chat-messages" 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 index 1c6cdee0d0..a6068c0ca5 100644 --- 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 @@ -1,8 +1,20 @@ package expo.modules.backgroundnotificationhandler +import expo.modules.blueskyswissarmy.sharedprefs.Preferences import expo.modules.kotlin.modules.Module import expo.modules.kotlin.modules.ModuleDefinition +val DEFAULTS = mapOf( + "playSoundChat" to true, + "playSoundFollow" to false, + "playSoundLike" to false, + "playSoundMention" to false, + "playSoundQuote" to false, + "playSoundReply" to false, + "playSoundRepost" to false, + "mutedThreads" to mapOf>() +) + class ExpoBackgroundNotificationHandlerModule : Module() { companion object { var isForegrounded = false @@ -12,7 +24,17 @@ class ExpoBackgroundNotificationHandlerModule : Module() { Name("ExpoBackgroundNotificationHandler") OnCreate { - NotificationPrefs(appContext.reactContext).initialize() + val context = appContext.reactContext ?: throw Error("Context is null") + DEFAULTS.forEach { (key, value) -> + if (Preferences(context).hasValue(key)) { + return@forEach + } + + Preferences(context)._(key, value) + + when (value) { + } + } } OnActivityEntersForeground { @@ -23,50 +45,6 @@ class ExpoBackgroundNotificationHandlerModule : Module() { 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 -> - 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 -> - NotificationPrefs(appContext.reactContext).addManyToStringArray(forKey, strings) - } - - AsyncFunction("removeManyFromStringArrayAsync") { forKey: String, strings: Array -> - NotificationPrefs(appContext.reactContext).removeManyFromStringArray(forKey, strings) - } - AsyncFunction("setBadgeCountAsync") { _: String, _: Int -> // This does nothing on Android } 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 deleted file mode 100644 index 17ef9205ef..0000000000 --- a/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/NotificationPrefs.kt +++ /dev/null @@ -1,134 +0,0 @@ -package expo.modules.backgroundnotificationhandler - -import android.content.Context - -val DEFAULTS = mapOf( - "playSoundChat" to true, - "playSoundFollow" to false, - "playSoundLike" to false, - "playSoundMention" to false, - "playSoundQuote" to false, - "playSoundReply" to false, - "playSoundRepost" to false, - "mutedThreads" to mapOf>() -) - -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 { - 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? { - 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) { - 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) { - 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) { - 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 diff --git a/modules/expo-bluesky-swiss-army/android/src/main/java/expo/modules/blueskyswissarmy/sharedprefs/Preferences.kt b/modules/expo-bluesky-swiss-army/android/src/main/java/expo/modules/blueskyswissarmy/sharedprefs/Preferences.kt index b58a2736b3..e4d6784877 100644 --- a/modules/expo-bluesky-swiss-army/android/src/main/java/expo/modules/blueskyswissarmy/sharedprefs/Preferences.kt +++ b/modules/expo-bluesky-swiss-army/android/src/main/java/expo/modules/blueskyswissarmy/sharedprefs/Preferences.kt @@ -121,6 +121,19 @@ class Preferences(private val context: Context) { return safeInstance.getFloat(key, 0.0f) } + fun _setAnyValue(key: String, value: Any) { + val safeInstance = getInstance(context) + safeInstance.edit().apply { + when (value) { + is String -> putString(key, value) + is Float -> putFloat(key, value) + is Boolean -> putBoolean(key, value) + is Set<*> -> putStringSet(key, value.map { it.toString() }.toSet()) + else -> throw Error("Unsupported type: ${value::class.java}") + } + }.apply() + } + fun getBoolean(key: String): Boolean? { val safeInstance = getInstance(context) if (!safeInstance.contains(key)) { @@ -159,4 +172,22 @@ class Preferences(private val context: Context) { val set = safeInstance.getStringSet(key, setOf()) ?: setOf() return set.contains(value) } + + fun hasValue(key: String): Boolean { + val safeInstance = getInstance(context) + return safeInstance.contains(key) + } + + fun getValues(keys: Set): Map { + val safeInstance = getInstance(context) + return keys.associateWith { key -> + when (val value = safeInstance.all[key]) { + is String -> value + is Float -> value + is Boolean -> value + is Set<*> -> value + else -> null + } + } + } } \ No newline at end of file diff --git a/modules/expo-bluesky-swiss-army/ios/SharedPrefs/SharedPrefs.swift b/modules/expo-bluesky-swiss-army/ios/SharedPrefs/SharedPrefs.swift index fc573f84a2..8128a4b2e4 100644 --- a/modules/expo-bluesky-swiss-army/ios/SharedPrefs/SharedPrefs.swift +++ b/modules/expo-bluesky-swiss-army/ios/SharedPrefs/SharedPrefs.swift @@ -2,15 +2,15 @@ import Foundation public class SharedPrefs { public static let shared = SharedPrefs() - + private let defaults = UserDefaults(suiteName: "group.app.bsky") - + init() { if defaults == nil { NSLog("Failed to get user defaults for app group.") } } - + private func getDefaults(_ info: String = "(no info)") -> UserDefaults? { guard let defaults = self.defaults else { NSLog("Failed to get defaults for app group: \(info)") @@ -18,39 +18,39 @@ public class SharedPrefs { } return defaults } - + public func setValue(_ key: String, _ value: String?) { getDefaults(key)?.setValue(value, forKey: key) } - + public func setValue(_ key: String, _ value: Double?) { getDefaults(key)?.setValue(value, forKey: key) } - + public func setValue(_ key: String, _ value: Bool?) { getDefaults(key)?.setValue(value, forKey: key) } - + public func _setAnyValue(_ key: String, _ value: Any?) { getDefaults(key)?.setValue(value, forKey: key) } - + public func removeValue(_ key: String) { getDefaults(key)?.removeObject(forKey: key) } - + public func getString(_ key: String) -> String? { return getDefaults(key)?.string(forKey: key) } - + public func getNumber(_ key: String) -> Double? { return getDefaults(key)?.double(forKey: key) } - + public func getBool(_ key: String) -> Bool? { return getDefaults(key)?.bool(forKey: key) } - + public func addToSet(_ key: String, _ value: String) { var dict: [String:Bool]? if var currDict = getDefaults(key)?.dictionary(forKey: key) as? [String:Bool] { @@ -63,7 +63,7 @@ public class SharedPrefs { } getDefaults(key)?.setValue(dict, forKey: key) } - + public func removeFromSet(_ key: String, _ value: String) { guard var dict = getDefaults(key)?.dictionary(forKey: key) as? [String:Bool] else { return @@ -71,18 +71,18 @@ public class SharedPrefs { dict.removeValue(forKey: value) getDefaults(key)?.setValue(dict, forKey: key) } - + public func setContains(_ key: String, _ value: String) -> Bool { guard let dict = getDefaults(key)?.dictionary(forKey: key) as? [String:Bool] else { return false } return dict[value] == true } - + public func hasValue(_ key: String) -> Bool { return getDefaults(key)?.value(forKey: key) != nil } - + public func getValues(_ keys: [String]) -> [String:Any?]? { return getDefaults("keys:\(keys)")?.dictionaryWithValues(forKeys: keys) }