From dd34cd08dfb87bb1b3417784e9264a56935519be Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Thu, 8 Aug 2024 11:39:12 +0200 Subject: [PATCH 1/2] feat: add locale to request context (#32) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Damian Jäger <25776715+DamianJaeger@users.noreply.github.com> --- .gitignore | 47 ++++++++---- README.md | 19 +++-- .../java/app/kula/onlaunch/client/OnLaunch.kt | 72 +++---------------- .../onlaunch/client/OnLaunchConfiguration.kt | 57 +++++++++++++++ .../client/OnLaunchConfigurationBulder.kt | 69 ++++++++++++++++++ .../onlaunch/client/data/api/OnLaunchApi.kt | 3 + .../app/kula/onlaunch/sample/SampleApp.kt | 2 +- 7 files changed, 186 insertions(+), 83 deletions(-) create mode 100644 client/src/main/java/app/kula/onlaunch/client/OnLaunchConfiguration.kt create mode 100644 client/src/main/java/app/kula/onlaunch/client/OnLaunchConfigurationBulder.kt diff --git a/.gitignore b/.gitignore index aa724b7..435ea76 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,36 @@ +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Log/OS Files +*.log + +# Android Studio generated files and folders +captures/ +.externalNativeBuild/ +.cxx/ +*.apk +output.json + +# IntelliJ *.iml -.gradle -/local.properties -/.idea/caches -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -/.idea/navEditor.xml -/.idea/assetWizardSettings.xml +.idea/ +misc.xml +deploymentTargetDropDown.xml +render.experimental.xml + +# Keystore files +*.jks +*.keystore + +# Google Services (e.g. APIs or Firebase) +google-services.json + +# Android Profiling +*.hprof + +# macOS .DS_Store -/build -/captures -.externalNativeBuild -.cxx -local.properties diff --git a/README.md b/README.md index 1abf85a..83c82c4 100644 --- a/README.md +++ b/README.md @@ -63,12 +63,19 @@ override fun onResume() { The OnLaunch Android client provides a couple of configuration options: -| Name | Description | Default | -|---------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------| -| `publicKey` | Public key used to authenticate with the API | | -| `baseUrl` | Base URL where the OnLaunch API is hosted at. Change this to point to your self-hosted instance of the OnLaunch server. | `https://onlaunch.kula.app/api/` | -| `shouldCheckOnInit` | Flag indicating if the client should check for new messages immediately after it has been initialized. | `true` | -| `useInAppUpdates` | Set to `true` to use Google Play In-App Updates to check for available updates. When using Google Play In-App Updates you accept the Google Play Terms of Service. See https://developer.android.com/guide/playcore/in-app-updates | `false` | +| Name | Description | Default | +|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------| +| `publicKey` | Public key used to authenticate with the API. | | +| `baseUrl` | Base URL where the OnLaunch API is hosted at. Change this to point to your self-hosted instance of the OnLaunch server. | `https://onlaunch.kula.app/api/` | +| `shouldCheckOnInit` | Flag indicating if the client should check for new messages immediately after it has been initialized. | `true` | +| `useInAppUpdates` | Set to `true` to use Google Play In-App Updates to check for available updates. When using Google Play In-App Updates you accept the Google Play Terms of Service. See https://developer.android.com/guide/playcore/in-app-updates | `false` | +| `appStoreUrl` | URL to the app store where the app can be updated. Used to open the app store. The package name in the default value is NOT the `packageName` parameter, but the package name provided by the `Context`. | `https://play.google.com/store/apps/details?id=` | +| `packageName` | The package name of the app. Used by server-side rule evaluation. | Package name defined in the context | +| `versionCode` | The version code of the app. Used by server-side rule evaluation. | Version code defined in the package manager context | +| `versionName` | The version name of the app. Used by server-side rule evaluation. | Version name defined in the package manager context | +| `locale` | The locale of the app. Used by server-side rule evaluation. | Locale defined in `context.resources.configuration.locale`, i.e. `en_US` | +| `localeLanguageCode` | The language code of the locale. Used by server-side rule evaluation. | Language code defined in `context.resources.configuration.locale`, i.e. `en` | +| `localeRegionCode` | The region code of the locale. Used by server-side rule evaluation. | Region code defined in `context.resources.configuration.locale`, i.e. `US` | # Contributing Guide diff --git a/client/src/main/java/app/kula/onlaunch/client/OnLaunch.kt b/client/src/main/java/app/kula/onlaunch/client/OnLaunch.kt index d6e3c00..f7c4cb2 100644 --- a/client/src/main/java/app/kula/onlaunch/client/OnLaunch.kt +++ b/client/src/main/java/app/kula/onlaunch/client/OnLaunch.kt @@ -3,6 +3,7 @@ package app.kula.onlaunch.client import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent +import android.os.Build import android.util.Log import app.kula.onlaunch.client.data.api.OnLaunchApi import app.kula.onlaunch.client.data.dtos.toMessages @@ -10,11 +11,8 @@ import app.kula.onlaunch.client.data.local.OnLaunchDataStore import app.kula.onlaunch.client.ui.OnLaunchActivity import com.google.android.play.core.appupdate.AppUpdateManagerFactory import com.google.android.play.core.install.model.UpdateAvailability -import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch -import kotlinx.coroutines.plus import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import kotlin.coroutines.resume @@ -63,8 +61,11 @@ object OnLaunch { versionCode = config.versionCode.toString(), versionName = config.versionName, platformName = "android", - platformVersion = android.os.Build.VERSION.SDK_INT.toString(), + platformVersion = Build.VERSION.SDK_INT.toString(), updateAvailable = if (config.useInAppUpdates) checkUpdateAvailable(context = context) else null, + locale = config.locale, + localeLanguageCode = config.localeLanguageCode, + localeRegionCode = config.localeRegionCode, ).toMessages() val dismissedIds = dataStore.getDismissedMessageIds() @@ -128,7 +129,7 @@ object OnLaunch { } } -private data class OnLaunchConfig( +internal data class OnLaunchConfig( val baseUrl: String, val publicKey: String, val shouldCheckOnInit: Boolean, @@ -138,62 +139,7 @@ private data class OnLaunchConfig( val versionName: String, val useInAppUpdates: Boolean, val appStoreUrl: String, + val locale: String, + val localeLanguageCode: String, + val localeRegionCode: String, ) - -interface OnLaunchConfiguration { - var baseUrl: String? - var publicKey: String? - - /** - * If set to true, OnLaunch will check for messages on initialization. - * - * Defaults to true - */ - var shouldCheckOnInit: Boolean? - var packageName: String? - var versionCode: Long? - var versionName: String? - var appStoreUrl: String? - - /** - * Set to true to use Google Play In-App Updates to check for available updates. - * When using Google Play In-App Updates you have to accept the Google Play Terms of Service. - * - * Defaults to false. - * @see https://developer.android.com/guide/playcore/in-app-updates - */ - var useInAppUpdates: Boolean? -} - -private class OnLaunchConfigurationBuilder : OnLaunchConfiguration { - override var baseUrl: String? = null - override var publicKey: String? = null - override var shouldCheckOnInit: Boolean? = null - override var packageName: String? = null - override var versionCode: Long? = null - override var versionName: String? = null - override var useInAppUpdates: Boolean? = null - override var appStoreUrl: String? = null - - fun getConfig(context: Context) = OnLaunchConfig( - baseUrl = baseUrl ?: "https://onlaunch.kula.app/api/", - publicKey = publicKey - ?: throw IllegalArgumentException("Failed to initialize OnLaunch: publicKey not set"), - shouldCheckOnInit = shouldCheckOnInit ?: true, - scope = (MainScope() + CoroutineExceptionHandler { _, throwable -> - Log.e(OnLaunch.LOG_TAG, throwable.message, throwable) - }), - versionCode = versionCode ?: context.packageManager.getPackageInfo( - context.packageName, - 0 - ).versionCode.toLong(), - versionName = versionName ?: context.packageManager.getPackageInfo( - context.packageName, - 0 - ).versionName, - packageName = packageName ?: context.packageName, - useInAppUpdates = useInAppUpdates ?: false, - appStoreUrl = appStoreUrl - ?: "https://play.google.com/store/apps/details?id=${context.packageName}", - ) -} diff --git a/client/src/main/java/app/kula/onlaunch/client/OnLaunchConfiguration.kt b/client/src/main/java/app/kula/onlaunch/client/OnLaunchConfiguration.kt new file mode 100644 index 0000000..67922be --- /dev/null +++ b/client/src/main/java/app/kula/onlaunch/client/OnLaunchConfiguration.kt @@ -0,0 +1,57 @@ +package app.kula.onlaunch.client + +import android.content.Context + +interface OnLaunchConfiguration { + /** + * Base URL where the OnLaunch API is hosted at. Change this to point to your self-hosted instance of the OnLaunch server. + * + * Defaults to `https://onlaunch.kula.app/api/` + */ + var baseUrl: String? + + /** Public key used to authenticate with the API */ + var publicKey: String? + + /** + * If set to true, OnLaunch will check for messages on initialization. + * + * Defaults to `true` + */ + var shouldCheckOnInit: Boolean? + + /** The package name of the app. Used by server-side rule evaluation. */ + var packageName: String? + + /** The version code of the app. Used by server-side rule evaluation. */ + var versionCode: Long? + + /** The version name of the app. Used by server-side rule evaluation. */ + var versionName: String? + + /** + * URL to the app store where the app can be updated. Used to open the app store. + * The package name in the default value is NOT the `packageName` parameter, but the package name provided by the [Context]. + * + * Defaults to `https://play.google.com/store/apps/details?id=` + */ + var appStoreUrl: String? + + /** + * Set to true to use Google Play In-App Updates to check for available updates. + * When using Google Play In-App Updates you have to accept the Google Play Terms of Service. + * + * Defaults to `false` + * @see https://developer.android.com/guide/playcore/in-app-updates + */ + var useInAppUpdates: Boolean? + + /** The locale of the app. Used by server-side rule evaluation. */ + var locale: String? + + /** The language code of the locale. Used by server-side rule evaluation. */ + var localeLanguageCode: String? + + /** The region code of the locale. Used by server-side rule evaluation. */ + var localeRegionCode: String? +} diff --git a/client/src/main/java/app/kula/onlaunch/client/OnLaunchConfigurationBulder.kt b/client/src/main/java/app/kula/onlaunch/client/OnLaunchConfigurationBulder.kt new file mode 100644 index 0000000..8137688 --- /dev/null +++ b/client/src/main/java/app/kula/onlaunch/client/OnLaunchConfigurationBulder.kt @@ -0,0 +1,69 @@ +package app.kula.onlaunch.client + +import android.content.Context +import android.os.Build +import android.util.Log +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.plus +import java.util.Locale + +internal class OnLaunchConfigurationBuilder : OnLaunchConfiguration { + override var baseUrl: String? = null + override var publicKey: String? = null + override var shouldCheckOnInit: Boolean? = null + override var packageName: String? = null + override var versionCode: Long? = null + override var versionName: String? = null + override var useInAppUpdates: Boolean? = null + override var appStoreUrl: String? = null + override var locale: String? = null + override var localeLanguageCode: String? = null + override var localeRegionCode: String? = null + + internal fun getConfig(context: Context) = OnLaunchConfig( + baseUrl = baseUrl ?: "https://onlaunch.kula.app/api/", + publicKey = publicKey + ?: throw IllegalArgumentException("Failed to initialize OnLaunch: publicKey not set"), + shouldCheckOnInit = shouldCheckOnInit ?: true, + scope = (MainScope() + CoroutineExceptionHandler { _, throwable -> + Log.e(OnLaunch.LOG_TAG, throwable.message, throwable) + }), + versionCode = versionCode ?: getVersionCode(context), + versionName = versionName ?: context.packageManager.getPackageInfo( + context.packageName, + 0 + ).versionName, + packageName = packageName ?: context.packageName, + useInAppUpdates = useInAppUpdates ?: false, + appStoreUrl = appStoreUrl + ?: "https://play.google.com/store/apps/details?id=${context.packageName}", + locale = locale ?: getLocale(context).toString(), + localeLanguageCode = localeLanguageCode ?: getLocale(context).language, + localeRegionCode = localeRegionCode ?: getLocale(context).country + ) + + private fun getVersionCode(context: Context): Long { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + context.packageManager.getPackageInfo( + context.packageName, + 0 + ).longVersionCode + } else { + @Suppress("DEPRECATION") + context.packageManager.getPackageInfo( + context.packageName, + 0 + ).versionCode.toLong() + } + } + + private fun getLocale(context: Context): Locale { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + context.resources.configuration.locales[0] + } else { + @Suppress("DEPRECATION") + context.resources.configuration.locale + } + } +} diff --git a/client/src/main/java/app/kula/onlaunch/client/data/api/OnLaunchApi.kt b/client/src/main/java/app/kula/onlaunch/client/data/api/OnLaunchApi.kt index d72ae9f..0fb9725 100644 --- a/client/src/main/java/app/kula/onlaunch/client/data/api/OnLaunchApi.kt +++ b/client/src/main/java/app/kula/onlaunch/client/data/api/OnLaunchApi.kt @@ -8,6 +8,9 @@ internal interface OnLaunchApi { @GET("v0.2/messages") suspend fun getMessages( @Header("x-api-key") publicKey: String, + @Header("X-ONLAUNCH-LOCALE") locale: String, + @Header("X-ONLAUNCH-LOCALE-LANGUAGE-CODE") localeLanguageCode: String, + @Header("X-ONLAUNCH-LOCALE-REGION-CODE") localeRegionCode: String, @Header("X-ONLAUNCH-VERSION-CODE") versionCode: String, @Header("X-ONLAUNCH-VERSION-NAME") versionName: String, @Header("X-ONLAUNCH-PACKAGE-NAME") packageName: String, diff --git a/sample/src/main/java/app/kula/onlaunch/sample/SampleApp.kt b/sample/src/main/java/app/kula/onlaunch/sample/SampleApp.kt index 5df0ffa..da3483b 100644 --- a/sample/src/main/java/app/kula/onlaunch/sample/SampleApp.kt +++ b/sample/src/main/java/app/kula/onlaunch/sample/SampleApp.kt @@ -8,7 +8,7 @@ class SampleApp : Application() { super.onCreate() OnLaunch.init(this) { - publicKey = "" + publicKey = "K2UX4fVPFyixVaeLn8Fky_uWhjMr-frADqKqpOCZW2c" } } } From 5be84e9c274258d94e66423871094d05fd932d31 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 09:49:17 +0000 Subject: [PATCH 2/2] chore(deps): update plugin io.github.gradle-nexus.publish-plugin to v2 (#43) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | io.github.gradle-nexus.publish-plugin | `1.3.0` -> `2.0.0` | [![age](https://developer.mend.io/api/mc/badges/age/maven/io.github.gradle-nexus.publish-plugin/2.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/io.github.gradle-nexus.publish-plugin/2.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/io.github.gradle-nexus.publish-plugin/1.3.0/2.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/io.github.gradle-nexus.publish-plugin/1.3.0/2.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View the [repository job log](https://developer.mend.io/github/kula-app/OnLaunch-Android-Client). --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 47e2b8d..6091d39 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ plugins { id("com.android.application") version "7.4.2" apply false id("com.android.library") version "7.4.2" apply false id("org.jetbrains.kotlin.android") version "1.8.10" apply false - id("io.github.gradle-nexus.publish-plugin") version "1.3.0" + id("io.github.gradle-nexus.publish-plugin") version "2.0.0" } ext["ossrhUsername"] = ""