From 5e8038754630349a6bb7b6ef6708d8a48b79548b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Stopi=C5=84ski?= Date: Wed, 3 Dec 2025 14:56:13 +0100 Subject: [PATCH 01/80] fix(ui): unexpected italic text style --- .../pushpushgo/inappmessages/ui/composables/common/Utils.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/Utils.kt b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/Utils.kt index ffc74c47..40563ff4 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/Utils.kt +++ b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/Utils.kt @@ -180,10 +180,10 @@ internal fun createFontFamily(message: InAppMessage): FontFamily { fontProvider = provider, weight = FontWeight(weight), style = - if (style == com.pushpushgo.inappmessages.model.FontStyle.NORMAL) { - FontStyle.Normal - } else { + if (style == com.pushpushgo.inappmessages.model.FontStyle.ITALIC) { FontStyle.Italic + } else { + FontStyle.Normal }, ) } From 81a2f38d17cd46661a442568f6d19a3203693114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Stopi=C5=84ski?= Date: Wed, 3 Dec 2025 15:47:33 +0100 Subject: [PATCH 02/80] fix(ui): close button --- .../ui/composables/common/MessageButton.kt | 31 ++++++++++++------- .../templates/BannerMessageTemplate.kt | 16 +++++----- .../templates/InAppMessageDefaultTemplate.kt | 18 +++++------ .../templates/ReviewForDiscountTemplate.kt | 16 +++++----- .../templates/RichMessageTemplate.kt | 16 ++++------ 5 files changed, 46 insertions(+), 51 deletions(-) diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageButton.kt b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageButton.kt index f7d75a60..d4b37404 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageButton.kt +++ b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageButton.kt @@ -2,10 +2,13 @@ package com.pushpushgo.inappmessages.ui.composables.common import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.material3.Button @@ -16,6 +19,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clipToBounds import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight @@ -112,17 +116,20 @@ internal fun CloseButton( ) { if (!style.closeIcon) return - IconButton( - onClick = onDismiss, - modifier = - modifier - .size(style.closeIconWidth.pxToDp), - ) { - Icon( - imageVector = Icons.Default.Close, - contentDescription = "Close", - tint = Color.fromHex(style.closeIconColor), - modifier = Modifier.size(style.closeIconWidth.pxToDp), - ) + Box(modifier = Modifier.width(30.pxToDp).height(30.pxToDp).clipToBounds()) { + IconButton( + modifier = + modifier + .size(style.closeIconWidth.pxToDp) + .align(Alignment.Center), + onClick = onDismiss, + ) { + Icon( + imageVector = Icons.Default.Close, + contentDescription = "Close", + tint = Color.fromHex(style.closeIconColor), + modifier = Modifier.size(style.closeIconWidth.pxToDp), + ) + } } } diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/BannerMessageTemplate.kt b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/BannerMessageTemplate.kt index da293a9f..6403694f 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/BannerMessageTemplate.kt +++ b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/BannerMessageTemplate.kt @@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.runtime.Composable @@ -15,6 +14,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp +import androidx.compose.ui.zIndex import coil.compose.AsyncImage import com.pushpushgo.inappmessages.model.InAppMessage import com.pushpushgo.inappmessages.model.InAppMessageAction @@ -50,14 +50,12 @@ internal fun TemplateBannerMessage( .padding(horizontal = 8.pxToDp, vertical = 4.pxToDp), ) { Box(modifier = Modifier.padding(if (message.style.border) message.style.borderWidth.pxToDp else 0.dp)) { - CloseButton( - style = message.style, - onDismiss = onDismiss, - modifier = - Modifier - .align(Alignment.TopEnd) - .offset(x = (-4 - message.style.borderWidth).dp, y = (2 + message.style.borderWidth).dp), - ) + Box(modifier = Modifier.align(Alignment.TopEnd).zIndex(1f)) { + CloseButton( + style = message.style, + onDismiss = onDismiss, + ) + } Box(modifier = Modifier.padding(parsePadding(message.layout.padding))) { Row( diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/InAppMessageDefaultTemplate.kt b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/InAppMessageDefaultTemplate.kt index 1ae13623..66159b0f 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/InAppMessageDefaultTemplate.kt +++ b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/InAppMessageDefaultTemplate.kt @@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults @@ -17,6 +16,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp +import androidx.compose.ui.zIndex import com.pushpushgo.inappmessages.model.InAppMessage import com.pushpushgo.inappmessages.model.InAppMessageAction import com.pushpushgo.inappmessages.ui.composables.common.CloseButton @@ -102,15 +102,11 @@ internal fun InAppMessageDefaultTemplate( } } - val closeButtonSize = message.style.closeIconWidth.pxToDp - val offset = (closeButtonSize / 4) - CloseButton( - style = message.style, - onDismiss = onDismiss, - modifier = - Modifier - .align(Alignment.TopEnd) - .offset(x = offset, y = -offset), - ) + Box(modifier = Modifier.align(Alignment.TopEnd).zIndex(1f)) { + CloseButton( + style = message.style, + onDismiss = onDismiss, + ) + } } } diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/ReviewForDiscountTemplate.kt b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/ReviewForDiscountTemplate.kt index 47a88c75..6ed5167e 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/ReviewForDiscountTemplate.kt +++ b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/ReviewForDiscountTemplate.kt @@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.runtime.Composable @@ -15,6 +14,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp +import androidx.compose.ui.zIndex import coil.compose.AsyncImage import com.pushpushgo.inappmessages.model.InAppMessage import com.pushpushgo.inappmessages.model.InAppMessageAction @@ -62,14 +62,12 @@ internal fun TemplateReviewForDiscount( ) { MessageCard(message, modifier = Modifier.fillMaxWidth()) { Box(modifier = Modifier.padding(if (message.style.border) message.style.borderWidth.pxToDp else 0.dp)) { - CloseButton( - message.style, - onDismiss, - modifier = - Modifier - .align(Alignment.TopEnd) - .offset(x = (-4 - message.style.borderWidth).dp, y = (2 + message.style.borderWidth).dp), - ) + Box(modifier = Modifier.align(Alignment.TopEnd).zIndex(1f)) { + CloseButton( + style = message.style, + onDismiss = onDismiss, + ) + } Row( modifier = diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/RichMessageTemplate.kt b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/RichMessageTemplate.kt index 34be83ec..d6a0a2c7 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/RichMessageTemplate.kt +++ b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/RichMessageTemplate.kt @@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -41,15 +40,12 @@ internal fun TemplateRichMessage( MessageCard(message, modifier = Modifier.fillMaxSize()) { Box(modifier = Modifier.padding(if (message.style.border) message.style.borderWidth.pxToDp else 0.dp)) { - CloseButton( - style = message.style, - onDismiss = onDismiss, - modifier = - Modifier - .align(Alignment.TopEnd) - .offset(x = (-4 - message.style.borderWidth).dp, y = (2 + message.style.borderWidth).dp) - .zIndex(1f), - ) + Box(modifier = Modifier.align(Alignment.TopEnd).zIndex(1f)) { + CloseButton( + style = message.style, + onDismiss = onDismiss, + ) + } Box( modifier = From 97b1513fa70fe1d3fa71d4a6eab757da34e15765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Stopi=C5=84ski?= Date: Tue, 9 Dec 2025 11:49:30 +0100 Subject: [PATCH 03/80] fix(ui): add emoji compat --- library-inappmessages/build.gradle.kts | 2 ++ library-inappmessages/src/main/AndroidManifest.xml | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/library-inappmessages/build.gradle.kts b/library-inappmessages/build.gradle.kts index bde5f66e..fe0d7588 100644 --- a/library-inappmessages/build.gradle.kts +++ b/library-inappmessages/build.gradle.kts @@ -71,6 +71,8 @@ dependencies { implementation(libs.compose.material.icons) implementation(libs.compose.runtime) implementation(libs.compose.ui.text.fonts) // Google Fonts + implementation("androidx.emoji2:emoji2:1.6.0") + implementation("androidx.emoji2:emoji2-bundled:1.6.0") // Image Loading implementation(libs.coil.compose) diff --git a/library-inappmessages/src/main/AndroidManifest.xml b/library-inappmessages/src/main/AndroidManifest.xml index 8bdb7e14..a1e42db5 100644 --- a/library-inappmessages/src/main/AndroidManifest.xml +++ b/library-inappmessages/src/main/AndroidManifest.xml @@ -1,4 +1,8 @@ - + + + From 8faa758497789f12cdf733a9ae5caf7e63d35195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Stopi=C5=84ski?= Date: Fri, 9 Jan 2026 12:51:11 +0100 Subject: [PATCH 04/80] refactor: restructure sdk layout * refactor: extract push module * refactor: extract inapp module * feat: initialize core module * feat(push): migrate from groovy to kotlin dsl * feat(inapp): use libs.versions file * feat(core): use libs.versions file * chore: ktlint & cleanup * feat: add PushSubscriptionProvider * feat: add common config * refactor: rename entrypoint classes * feat(inapp): add custom code handler, render inapps only on explicit call * feat(inapp): unify log tag * feat: reconfigure binary validator * refactor: CI * feat: improve notification permission check, improve inapp subscription request * fix(push/beacon): change exception type --- .editorconfig | 6 +- .github/actions/setup-ci.yml | 14 ++ .github/workflows/api-check.yml | 19 ++ .github/workflows/ci.yml | 24 ++ .github/workflows/deploy.yml | 33 --- .github/workflows/ktlint-check.yml | 24 -- .github/workflows/test.yml | 55 ----- build.gradle | 24 -- build.gradle.kts | 28 +++ {library-inappmessages => core}/.gitignore | 0 core/build.gradle.kts | 42 ++++ core/src/main/AndroidManifest.xml | 4 + .../com/pushpushgo/sdk/core/config/Config.kt | 27 +++ .../sdk/core/config/ConfigProvider.kt | 5 + .../sdk/core/config/ManifestConfigProvider.kt | 34 +++ .../push/NotificationPermissionProvider.kt | 27 +++ .../sdk/core/push/PushSubscriptionProvider.kt | 13 ++ gradle.properties | 8 +- gradle/libs.versions.toml | 125 +++++++++++ {sample-inapp => inapp}/.gitignore | 0 {library-inappmessages => inapp}/README.md | 0 inapp/api/inapp.api | 69 ++++++ .../build.gradle.kts | 76 +++---- inapp/sample/.gitignore | 1 + inapp/sample/build.gradle.kts | 76 +++++++ .../sample}/proguard-rules.pro | 0 .../sample/inapp}/ExampleInstrumentedTest.kt | 6 +- .../sample}/src/main/AndroidManifest.xml | 7 +- .../sdk/sample/inapp}/MainActivity.kt | 16 +- .../sdk/sample/inapp}/ui/MainNavHost.kt | 8 +- .../pushpushgo/sdk/sample/inapp}/ui/Screen.kt | 2 +- .../sample/inapp}/ui/screens/InfoScreen.kt | 9 +- .../sample/inapp}/ui/screens/MainScreen.kt | 9 +- .../sample/inapp}/ui/screens/OfferScreen.kt | 9 +- .../sdk/sample/inapp}/ui/theme/Color.kt | 2 +- .../sdk/sample/inapp}/ui/theme/Theme.kt | 2 +- .../sdk/sample/inapp}/ui/theme/Type.kt | 2 +- .../res/drawable/ic_launcher_background.xml | 0 .../res/drawable/ic_launcher_foreground.xml | 0 .../main/res/mipmap-anydpi/ic_launcher.xml | 0 .../res/mipmap-anydpi/ic_launcher_round.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin .../res/mipmap-hdpi/ic_launcher_round.webp | Bin .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin .../res/mipmap-mdpi/ic_launcher_round.webp | Bin .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin .../sample}/src/main/res/values/colors.xml | 0 .../sample}/src/main/res/values/strings.xml | 0 .../sample}/src/main/res/values/themes.xml | 0 .../sdk/sample/inapp}/ExampleUnitTest.kt | 6 +- .../src/main/AndroidManifest.xml | 0 .../com/pushpushgo/sdk/inapp/InAppMessages.kt | 203 +++++++++++++++++ .../sdk/inapp}/event/InAppMessageEvent.kt | 2 +- .../event/InAppMessageEventRepository.kt | 8 +- .../sdk/inapp}/manager/InAppMessageManager.kt | 9 +- .../inapp}/manager/InAppMessageManagerImpl.kt | 158 +++++++------ .../pushpushgo/sdk/inapp}/model/Alignment.kt | 2 +- .../sdk/inapp}/model/AnimationType.kt | 2 +- .../pushpushgo/sdk/inapp}/model/DisplayOn.kt | 2 +- .../sdk/inapp}/model/DisplayType.kt | 2 +- .../pushpushgo/sdk/inapp}/model/FontFamily.kt | 2 +- .../pushpushgo/sdk/inapp}/model/FontStyle.kt | 2 +- .../sdk/inapp}/model/InAppActionType.kt | 2 +- .../sdk/inapp}/model/InAppMessage.kt | 2 +- .../sdk/inapp}/model/InAppMessageAction.kt | 2 +- .../sdk/inapp}/model/InAppMessageAudience.kt | 2 +- .../inapp}/model/InAppMessageDescription.kt | 2 +- .../sdk/inapp}/model/InAppMessageImage.kt | 2 +- .../sdk/inapp}/model/InAppMessageLayout.kt | 2 +- .../sdk/inapp}/model/InAppMessageSettings.kt | 2 +- .../sdk/inapp}/model/InAppMessageStyle.kt | 2 +- .../sdk/inapp}/model/InAppMessageTitle.kt | 2 +- .../pushpushgo/sdk/inapp}/model/Placement.kt | 2 +- .../sdk/inapp}/model/ShowAgainType.kt | 2 +- .../pushpushgo/sdk/inapp}/model/TargetType.kt | 2 +- .../model/network/InAppMessagesResponse.kt | 4 +- .../pushpushgo/sdk/inapp}/network/InAppApi.kt | 6 +- .../sdk/inapp}/network/RetrofitProvider.kt | 6 +- .../persistence/InAppMessagePersistence.kt | 4 +- .../InAppMessagePersistenceImpl.kt | 24 +- .../repository/InAppMessageRepository.kt | 7 + .../repository/InAppMessageRepositoryImpl.kt | 29 ++- .../sdk/inapp/ui/CustomCodeHandler.kt | 5 + .../sdk/inapp}/ui/InAppMessageDisplayer.kt | 4 +- .../inapp}/ui/InAppMessageDisplayerImpl.kt | 108 ++++----- .../sdk/inapp}/ui/InAppUIController.kt | 28 +-- .../java/com/pushpushgo/sdk/inapp/ui/Route.kt | 11 + .../com/pushpushgo/sdk/inapp/ui/Trigger.kt | 6 + .../ui/composables/common/MessageButton.kt | 8 +- .../ui/composables/common/MessageCard.kt | 4 +- .../composables/common/MessageCardShadow.kt | 4 +- .../ui/composables/common/MessageImage.kt | 6 +- .../ui/composables/common/MessageText.kt | 8 +- .../sdk/inapp}/ui/composables/common/Utils.kt | 36 +-- .../templates/BannerMessageTemplate.kt | 26 +-- .../templates/InAppMessageDefaultTemplate.kt | 26 +-- .../templates/ReviewForDiscountTemplate.kt | 30 +-- .../templates/RichMessageTemplate.kt | 22 +- .../sdk/inapp}/utils/AutoCleanupManager.kt | 2 +- .../sdk/inapp}/utils/DeviceInfoProvider.kt | 6 +- .../sdk/inapp}/utils/InAppMessageHelper.kt | 12 +- .../sdk/inapp}/utils/ZonedDateTimeAdapter.kt | 2 +- .../src/main/res/anim/fade_in.xml | 0 .../src/main/res/values/font_certs.xml | 0 .../src/main/res/values/styles.xml | 0 .../pushpushgo/sdk/inapp}/ExampleUnitTest.kt | 6 +- library-inappmessages/consumer-rules.pro | 0 .../inappmessages/InAppMessagesSDK.kt | 207 ------------------ .../repository/InAppMessageRepository.kt | 7 - .../utils/PushNotificationStatusProvider.kt | 58 ----- .../utils/PushNotificationSubscriber.kt | 57 ----- library-no-op/build.gradle | 72 ------ library-no-op/src/main/AndroidManifest.xml | 1 - .../java/com/pushpushgo/sdk/BeaconBuilder.kt | 14 -- .../java/com/pushpushgo/sdk/PushPushGo.kt | 95 -------- .../pushpushgo/sdk/dto/PPGoNotification.kt | 9 - .../sdk/exception/PushPushException.kt | 5 - .../service/FcmMessagingServiceDelegate.kt | 14 -- .../service/HmsMessagingServiceDelegate.kt | 14 -- library/api/library.api | 120 ---------- library/build.gradle | 119 ---------- library/jacoco.gradle | 40 ---- .../sdk/bridge/PushSubscriptionManager.kt | 72 ------ .../java/com/pushpushgo/sdk/utils/LogUtils.kt | 25 --- .../sdk/utils/StringValidationExtension.kt | 15 -- .../utils/StringValidationExtensionKtTest.kt | 33 --- {library => push}/.gitignore | 0 .../library-no-op.api => push/api/push.api | 82 ++++--- push/build.gradle.kts | 104 +++++++++ {library => push}/ppgo-sdk.pro | 0 {sample => push/sample/firebase}/.gitignore | 0 push/sample/firebase/build.gradle.kts | 78 +++++++ .../sample/firebase}/google-services.json | 4 +- .../sample/firebase}/proguard-rules.pro | 0 .../firebase}/src/main/AndroidManifest.xml | 0 .../src/main/ic_launcher-playstore.png | Bin .../sample/push/firebase/MainApplication.kt | 18 ++ .../push/firebase/activity/BeaconActivity.kt | 88 ++++++++ .../push/firebase/activity/ClickActivity.kt | 26 +++ .../push/firebase/activity/MainActivity.kt | 123 +++++++++++ .../ic_stat_pushpushgo_default.xml | 0 .../ic_stat_pushpushgo_default.png | Bin .../ic_stat_pushpushgo_default.png | Bin .../ic_stat_pushpushgo_default.png | Bin .../ic_stat_pushpushgo_default.png | Bin .../src/main/res/layout/activity_beacon.xml | 0 .../src/main/res/layout/activity_click.xml | 0 .../src/main/res/layout/activity_main.xml | 0 .../firebase}/src/main/res/menu/menu_main.xml | 0 .../res/mipmap-anydpi-v26/ic_launcher.xml | 0 .../mipmap-anydpi-v26/ic_launcher_round.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../mipmap-hdpi/ic_launcher_foreground.png | Bin .../res/mipmap-hdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../mipmap-mdpi/ic_launcher_foreground.png | Bin .../res/mipmap-mdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../mipmap-xhdpi/ic_launcher_foreground.png | Bin .../res/mipmap-xhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin .../firebase}/src/main/res/values/colors.xml | 0 .../firebase}/src/main/res/values/dimens.xml | 0 .../firebase}/src/main/res/values/strings.xml | 0 .../firebase}/src/main/res/values/styles.xml | 0 {samplehms => push/sample/hms}/.gitignore | 0 .../sample/hms}/agconnect-services.json | 6 +- push/sample/hms/build.gradle.kts | 83 +++++++ .../sample/hms}/proguard-rules.pro | 0 .../sample/hms}/src/main/AndroidManifest.xml | 8 +- .../hms}/src/main/ic_launcher-playstore.png | Bin .../sdk/sample/push/hms/MainApplication.kt | 15 ++ .../push/hms/activity/BeaconActivity.kt | 88 ++++++++ .../sample/push/hms/activity/ClickActivity.kt | 26 +++ .../sample/push/hms/activity/MainActivity.kt | 93 ++++++++ .../ic_stat_pushpushgo_default.xml | 0 .../ic_stat_pushpushgo_default.png | Bin .../ic_stat_pushpushgo_default.png | Bin .../ic_stat_pushpushgo_default.png | Bin .../ic_stat_pushpushgo_default.png | Bin .../src/main/res/layout/activity_beacon.xml | 0 .../src/main/res/layout/activity_click.xml | 0 .../src/main/res/layout/activity_main.xml | 2 +- .../hms}/src/main/res/menu/menu_main.xml | 0 .../res/mipmap-anydpi-v26/ic_launcher.xml | 0 .../mipmap-anydpi-v26/ic_launcher_round.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../mipmap-hdpi/ic_launcher_foreground.png | Bin .../res/mipmap-hdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../mipmap-mdpi/ic_launcher_foreground.png | Bin .../res/mipmap-mdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../mipmap-xhdpi/ic_launcher_foreground.png | Bin .../res/mipmap-xhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin .../hms}/src/main/res/values/colors.xml | 0 .../hms}/src/main/res/values/dimens.xml | 0 .../hms}/src/main/res/values/strings.xml | 0 .../hms}/src/main/res/values/styles.xml | 0 {samplejava => push/sample/java}/.gitignore | 0 push/sample/java/build.gradle.kts | 72 ++++++ .../sample/java}/google-services.json | 4 +- .../sample/java}/proguard-rules.pro | 0 .../sample/java}/src/main/AndroidManifest.xml | 0 .../sample/push/java}/MainApplication.java | 9 +- .../push/java}/activity/MainActivity.java | 8 +- .../drawable-v24/ic_launcher_foreground.xml | 0 .../res/drawable/ic_launcher_background.xml | 0 .../src/main/res/layout/activity_main.xml | 0 .../java}/src/main/res/menu/menu_main.xml | 2 +- .../res/mipmap-anydpi-v26/ic_launcher.xml | 0 .../mipmap-anydpi-v26/ic_launcher_round.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../res/mipmap-hdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../res/mipmap-mdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../res/mipmap-xhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin .../java}/src/main/res/values/colors.xml | 0 .../java}/src/main/res/values/dimens.xml | 0 .../java}/src/main/res/values/strings.xml | 0 .../java}/src/main/res/values/styles.xml | 0 .../src/main/AndroidManifest.xml | 0 .../com/pushpushgo/sdk/push}/BeaconBuilder.kt | 12 +- .../sdk/push}/NotificationStatusChecker.kt | 43 ++-- .../pushpushgo/sdk/push/PushNotifications.kt | 189 +++++----------- .../pushpushgo/sdk/push}/data/BeaconTag.kt | 2 +- .../com/pushpushgo/sdk/push}/data/Event.kt | 2 +- .../com/pushpushgo/sdk/push}/data/Message.kt | 2 +- .../pushpushgo/sdk/push}/data/Notification.kt | 2 +- .../sdk/push}/data/NotificationMapper.kt | 4 +- .../com/pushpushgo/sdk/push}/data/Payload.kt | 2 +- .../pushpushgo/sdk/push}/di/NetworkModule.kt | 48 ++-- .../com/pushpushgo/sdk/push}/di/WorkModule.kt | 13 +- .../sdk/push}/dto/PPGoNotification.kt | 2 +- .../sdk/push}/exception/PushPushException.kt | 2 +- .../sdk/push}/network/ApiRepository.kt | 18 +- .../sdk/push}/network/ApiService.kt | 24 +- .../push}/network/SharedPreferencesHelper.kt | 32 ++- .../sdk/push}/network/data/TokenRequest.kt | 2 +- .../sdk/push}/network/data/TokenResponse.kt | 2 +- .../network/interceptor/RequestInterceptor.kt | 2 +- .../interceptor/ResponseInterceptor.kt | 6 +- .../sdk/push}/push/NotificationUtils.kt | 28 ++- .../pushpushgo/sdk/push}/push/PushMessage.kt | 2 +- .../push}/push/PushNotificationDelegate.kt | 59 +++-- .../push}/push/service/FcmMessagingService.kt | 2 +- .../service/FcmMessagingServiceDelegate.kt | 12 +- .../push}/push/service/HmsMessagingService.kt | 2 +- .../service/HmsMessagingServiceDelegate.kt | 12 +- .../DefaultPushSubscriptionProvider.kt | 25 +++ .../sdk/push}/utils/CollectionExtensions.kt | 2 +- .../com/pushpushgo/sdk/push/utils/LogUtils.kt | 25 +++ .../sdk/push}/utils/PendingIntentCompat.kt | 2 +- .../sdk/push}/utils/PlatformUtils.kt | 12 +- .../sdk/push}/utils/PushTokenUtils.kt | 2 +- .../sdk/push}/work/UploadDelegate.kt | 26 ++- .../sdk/push}/work/UploadManager.kt | 23 +- .../pushpushgo/sdk/push}/work/UploadWorker.kt | 6 +- .../ic_stat_pushpushgo_default.png | Bin .../ic_stat_pushpushgo_default.png | Bin .../ic_stat_pushpushgo_default.png | Bin .../ic_stat_pushpushgo_default.png | Bin .../src/main/res/values/colors.xml | 0 .../src/main/res/values/strings.xml | 0 .../pushpushgo/sdk/push}/BeaconBuilderTest.kt | 14 +- .../pushpushgo/sdk/push}/PushPushGoTest.kt | 22 +- sample-inapp/build.gradle.kts | 70 ------ sample-inapp/proguard-rules.pro | 21 -- sample/build.gradle | 72 ------ .../com/pushpushgo/sample/MainApplication.kt | 17 -- .../sample/activity/BeaconActivity.kt | 75 ------- .../sample/activity/ClickActivity.kt | 27 --- .../sample/activity/MainActivity.kt | 115 ---------- samplehms/build.gradle | 71 ------ .../com/pushpushgo/sample/MainApplication.kt | 14 -- .../sample/activity/BeaconActivity.kt | 74 ------- .../sample/activity/ClickActivity.kt | 27 --- .../sample/activity/MainActivity.kt | 93 -------- samplejava/build.gradle | 62 ------ settings.gradle | 87 -------- settings.gradle.kts | 33 +++ 302 files changed, 2391 insertions(+), 2738 deletions(-) create mode 100644 .github/actions/setup-ci.yml create mode 100644 .github/workflows/api-check.yml create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/deploy.yml delete mode 100644 .github/workflows/ktlint-check.yml delete mode 100644 .github/workflows/test.yml delete mode 100644 build.gradle create mode 100644 build.gradle.kts rename {library-inappmessages => core}/.gitignore (100%) create mode 100644 core/build.gradle.kts create mode 100644 core/src/main/AndroidManifest.xml create mode 100644 core/src/main/java/com/pushpushgo/sdk/core/config/Config.kt create mode 100644 core/src/main/java/com/pushpushgo/sdk/core/config/ConfigProvider.kt create mode 100644 core/src/main/java/com/pushpushgo/sdk/core/config/ManifestConfigProvider.kt create mode 100644 core/src/main/java/com/pushpushgo/sdk/core/push/NotificationPermissionProvider.kt create mode 100644 core/src/main/java/com/pushpushgo/sdk/core/push/PushSubscriptionProvider.kt create mode 100644 gradle/libs.versions.toml rename {sample-inapp => inapp}/.gitignore (100%) rename {library-inappmessages => inapp}/README.md (100%) create mode 100644 inapp/api/inapp.api rename {library-inappmessages => inapp}/build.gradle.kts (54%) create mode 100644 inapp/sample/.gitignore create mode 100644 inapp/sample/build.gradle.kts rename {library-inappmessages => inapp/sample}/proguard-rules.pro (100%) rename {sample-inapp/src/androidTest/java/com/pushpushgo/sample => inapp/sample/src/androidTest/java/com/pushpushgo/sdk/sample/inapp}/ExampleInstrumentedTest.kt (79%) rename {sample-inapp => inapp/sample}/src/main/AndroidManifest.xml (76%) rename {sample-inapp/src/main/java/com/pushpushgo/sample => inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp}/MainActivity.kt (65%) rename {sample-inapp/src/main/java/com/pushpushgo/sample => inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp}/ui/MainNavHost.kt (71%) rename {sample-inapp/src/main/java/com/pushpushgo/sample => inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp}/ui/Screen.kt (78%) rename {sample-inapp/src/main/java/com/pushpushgo/sample => inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp}/ui/screens/InfoScreen.kt (82%) rename {sample-inapp/src/main/java/com/pushpushgo/sample => inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp}/ui/screens/MainScreen.kt (84%) rename {sample-inapp/src/main/java/com/pushpushgo/sample => inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp}/ui/screens/OfferScreen.kt (82%) rename {sample-inapp/src/main/java/com/pushpushgo/sample => inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp}/ui/theme/Color.kt (83%) rename {sample-inapp/src/main/java/com/pushpushgo/sample => inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp}/ui/theme/Theme.kt (97%) rename {sample-inapp/src/main/java/com/pushpushgo/sample => inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp}/ui/theme/Type.kt (95%) rename {sample-inapp => inapp/sample}/src/main/res/drawable/ic_launcher_background.xml (100%) rename {sample-inapp => inapp/sample}/src/main/res/drawable/ic_launcher_foreground.xml (100%) rename {sample-inapp => inapp/sample}/src/main/res/mipmap-anydpi/ic_launcher.xml (100%) rename {sample-inapp => inapp/sample}/src/main/res/mipmap-anydpi/ic_launcher_round.xml (100%) rename {sample-inapp => inapp/sample}/src/main/res/mipmap-hdpi/ic_launcher.webp (100%) rename {sample-inapp => inapp/sample}/src/main/res/mipmap-hdpi/ic_launcher_round.webp (100%) rename {sample-inapp => inapp/sample}/src/main/res/mipmap-mdpi/ic_launcher.webp (100%) rename {sample-inapp => inapp/sample}/src/main/res/mipmap-mdpi/ic_launcher_round.webp (100%) rename {sample-inapp => inapp/sample}/src/main/res/mipmap-xhdpi/ic_launcher.webp (100%) rename {sample-inapp => inapp/sample}/src/main/res/mipmap-xhdpi/ic_launcher_round.webp (100%) rename {sample-inapp => inapp/sample}/src/main/res/mipmap-xxhdpi/ic_launcher.webp (100%) rename {sample-inapp => inapp/sample}/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp (100%) rename {sample-inapp => inapp/sample}/src/main/res/mipmap-xxxhdpi/ic_launcher.webp (100%) rename {sample-inapp => inapp/sample}/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp (100%) rename {sample-inapp => inapp/sample}/src/main/res/values/colors.xml (100%) rename {sample-inapp => inapp/sample}/src/main/res/values/strings.xml (100%) rename {sample-inapp => inapp/sample}/src/main/res/values/themes.xml (100%) rename {sample-inapp/src/test/java/com/pushpushgo/sample => inapp/sample/src/test/java/com/pushpushgo/sdk/sample/inapp}/ExampleUnitTest.kt (72%) rename {library-inappmessages => inapp}/src/main/AndroidManifest.xml (100%) create mode 100644 inapp/src/main/java/com/pushpushgo/sdk/inapp/InAppMessages.kt rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages/data => inapp/src/main/java/com/pushpushgo/sdk/inapp}/event/InAppMessageEvent.kt (76%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages/data => inapp/src/main/java/com/pushpushgo/sdk/inapp}/event/InAppMessageEventRepository.kt (72%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/manager/InAppMessageManager.kt (62%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/manager/InAppMessageManagerImpl.kt (71%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/Alignment.kt (86%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/AnimationType.kt (83%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/DisplayOn.kt (88%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/DisplayType.kt (83%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/FontFamily.kt (92%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/FontStyle.kt (86%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/InAppActionType.kt (87%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/InAppMessage.kt (98%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/InAppMessageAction.kt (95%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/InAppMessageAudience.kt (92%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/InAppMessageDescription.kt (92%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/InAppMessageImage.kt (88%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/InAppMessageLayout.kt (94%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/InAppMessageSettings.kt (95%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/InAppMessageStyle.kt (95%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/InAppMessageTitle.kt (92%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/Placement.kt (91%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/ShowAgainType.kt (84%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/TargetType.kt (82%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/model/network/InAppMessagesResponse.kt (77%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/network/InAppApi.kt (83%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/network/RetrofitProvider.kt (84%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/persistence/InAppMessagePersistence.kt (88%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/persistence/InAppMessagePersistenceImpl.kt (81%) create mode 100644 inapp/src/main/java/com/pushpushgo/sdk/inapp/repository/InAppMessageRepository.kt rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/repository/InAppMessageRepositoryImpl.kt (65%) create mode 100644 inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/CustomCodeHandler.kt rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/ui/InAppMessageDisplayer.kt (73%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/ui/InAppMessageDisplayerImpl.kt (79%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/ui/InAppUIController.kt (77%) create mode 100644 inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/Route.kt create mode 100644 inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/Trigger.kt rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/ui/composables/common/MessageButton.kt (94%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/ui/composables/common/MessageCard.kt (88%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/ui/composables/common/MessageCardShadow.kt (92%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/ui/composables/common/MessageImage.kt (82%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/ui/composables/common/MessageText.kt (88%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/ui/composables/common/Utils.kt (80%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/ui/composables/templates/BannerMessageTemplate.kt (82%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/ui/composables/templates/InAppMessageDefaultTemplate.kt (77%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/ui/composables/templates/ReviewForDiscountTemplate.kt (81%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/ui/composables/templates/RichMessageTemplate.kt (79%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/utils/AutoCleanupManager.kt (98%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/utils/DeviceInfoProvider.kt (77%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/utils/InAppMessageHelper.kt (91%) rename {library-inappmessages/src/main/java/com/pushpushgo/inappmessages => inapp/src/main/java/com/pushpushgo/sdk/inapp}/utils/ZonedDateTimeAdapter.kt (96%) rename {library-inappmessages => inapp}/src/main/res/anim/fade_in.xml (100%) rename {library-inappmessages => inapp}/src/main/res/values/font_certs.xml (100%) rename {library-inappmessages => inapp}/src/main/res/values/styles.xml (100%) rename {library-inappmessages/src/test/java/com/pushpushgo/inappmessages => inapp/src/test/java/com/pushpushgo/sdk/inapp}/ExampleUnitTest.kt (73%) delete mode 100644 library-inappmessages/consumer-rules.pro delete mode 100644 library-inappmessages/src/main/java/com/pushpushgo/inappmessages/InAppMessagesSDK.kt delete mode 100644 library-inappmessages/src/main/java/com/pushpushgo/inappmessages/repository/InAppMessageRepository.kt delete mode 100644 library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/PushNotificationStatusProvider.kt delete mode 100644 library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/PushNotificationSubscriber.kt delete mode 100644 library-no-op/build.gradle delete mode 100644 library-no-op/src/main/AndroidManifest.xml delete mode 100644 library-no-op/src/main/java/com/pushpushgo/sdk/BeaconBuilder.kt delete mode 100644 library-no-op/src/main/java/com/pushpushgo/sdk/PushPushGo.kt delete mode 100644 library-no-op/src/main/java/com/pushpushgo/sdk/dto/PPGoNotification.kt delete mode 100644 library-no-op/src/main/java/com/pushpushgo/sdk/exception/PushPushException.kt delete mode 100644 library-no-op/src/main/java/com/pushpushgo/sdk/push/service/FcmMessagingServiceDelegate.kt delete mode 100644 library-no-op/src/main/java/com/pushpushgo/sdk/push/service/HmsMessagingServiceDelegate.kt delete mode 100644 library/api/library.api delete mode 100644 library/build.gradle delete mode 100644 library/jacoco.gradle delete mode 100644 library/src/main/java/com/pushpushgo/sdk/bridge/PushSubscriptionManager.kt delete mode 100644 library/src/main/java/com/pushpushgo/sdk/utils/LogUtils.kt delete mode 100644 library/src/main/java/com/pushpushgo/sdk/utils/StringValidationExtension.kt delete mode 100644 library/src/test/java/com/pushpushgo/sdk/utils/StringValidationExtensionKtTest.kt rename {library => push}/.gitignore (100%) rename library-no-op/api/library-no-op.api => push/api/push.api (53%) create mode 100644 push/build.gradle.kts rename {library => push}/ppgo-sdk.pro (100%) rename {sample => push/sample/firebase}/.gitignore (100%) create mode 100644 push/sample/firebase/build.gradle.kts rename {samplejava => push/sample/firebase}/google-services.json (93%) rename {sample => push/sample/firebase}/proguard-rules.pro (100%) rename {sample => push/sample/firebase}/src/main/AndroidManifest.xml (100%) rename {sample => push/sample/firebase}/src/main/ic_launcher-playstore.png (100%) create mode 100644 push/sample/firebase/src/main/java/com/pushpushgo/sdk/sample/push/firebase/MainApplication.kt create mode 100644 push/sample/firebase/src/main/java/com/pushpushgo/sdk/sample/push/firebase/activity/BeaconActivity.kt create mode 100644 push/sample/firebase/src/main/java/com/pushpushgo/sdk/sample/push/firebase/activity/ClickActivity.kt create mode 100644 push/sample/firebase/src/main/java/com/pushpushgo/sdk/sample/push/firebase/activity/MainActivity.kt rename {sample => push/sample/firebase}/src/main/res/drawable-anydpi-v24/ic_stat_pushpushgo_default.xml (100%) rename {sample => push/sample/firebase}/src/main/res/drawable-hdpi/ic_stat_pushpushgo_default.png (100%) rename {sample => push/sample/firebase}/src/main/res/drawable-mdpi/ic_stat_pushpushgo_default.png (100%) rename {sample => push/sample/firebase}/src/main/res/drawable-xhdpi/ic_stat_pushpushgo_default.png (100%) rename {sample => push/sample/firebase}/src/main/res/drawable-xxhdpi/ic_stat_pushpushgo_default.png (100%) rename {sample => push/sample/firebase}/src/main/res/layout/activity_beacon.xml (100%) rename {sample => push/sample/firebase}/src/main/res/layout/activity_click.xml (100%) rename {sample => push/sample/firebase}/src/main/res/layout/activity_main.xml (100%) rename {sample => push/sample/firebase}/src/main/res/menu/menu_main.xml (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-anydpi-v26/ic_launcher.xml (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-hdpi/ic_launcher_foreground.png (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-hdpi/ic_launcher_round.png (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-mdpi/ic_launcher_foreground.png (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-mdpi/ic_launcher_round.png (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-xhdpi/ic_launcher_round.png (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-xxhdpi/ic_launcher_round.png (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png (100%) rename {sample => push/sample/firebase}/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png (100%) rename {sample => push/sample/firebase}/src/main/res/values/colors.xml (100%) rename {sample => push/sample/firebase}/src/main/res/values/dimens.xml (100%) rename {sample => push/sample/firebase}/src/main/res/values/strings.xml (100%) rename {sample => push/sample/firebase}/src/main/res/values/styles.xml (100%) rename {samplehms => push/sample/hms}/.gitignore (100%) rename {samplehms => push/sample/hms}/agconnect-services.json (87%) create mode 100644 push/sample/hms/build.gradle.kts rename {samplehms => push/sample/hms}/proguard-rules.pro (100%) rename {samplehms => push/sample/hms}/src/main/AndroidManifest.xml (85%) rename {samplehms => push/sample/hms}/src/main/ic_launcher-playstore.png (100%) create mode 100644 push/sample/hms/src/main/java/com/pushpushgo/sdk/sample/push/hms/MainApplication.kt create mode 100644 push/sample/hms/src/main/java/com/pushpushgo/sdk/sample/push/hms/activity/BeaconActivity.kt create mode 100644 push/sample/hms/src/main/java/com/pushpushgo/sdk/sample/push/hms/activity/ClickActivity.kt create mode 100644 push/sample/hms/src/main/java/com/pushpushgo/sdk/sample/push/hms/activity/MainActivity.kt rename {samplehms => push/sample/hms}/src/main/res/drawable-anydpi-v24/ic_stat_pushpushgo_default.xml (100%) rename {samplehms => push/sample/hms}/src/main/res/drawable-hdpi/ic_stat_pushpushgo_default.png (100%) rename {samplehms => push/sample/hms}/src/main/res/drawable-mdpi/ic_stat_pushpushgo_default.png (100%) rename {samplehms => push/sample/hms}/src/main/res/drawable-xhdpi/ic_stat_pushpushgo_default.png (100%) rename {samplehms => push/sample/hms}/src/main/res/drawable-xxhdpi/ic_stat_pushpushgo_default.png (100%) rename {samplehms => push/sample/hms}/src/main/res/layout/activity_beacon.xml (100%) rename {samplehms => push/sample/hms}/src/main/res/layout/activity_click.xml (100%) rename {samplehms => push/sample/hms}/src/main/res/layout/activity_main.xml (98%) rename {samplehms => push/sample/hms}/src/main/res/menu/menu_main.xml (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-anydpi-v26/ic_launcher.xml (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-hdpi/ic_launcher_foreground.png (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-hdpi/ic_launcher_round.png (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-mdpi/ic_launcher_foreground.png (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-mdpi/ic_launcher_round.png (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-xhdpi/ic_launcher_round.png (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-xxhdpi/ic_launcher_round.png (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png (100%) rename {samplehms => push/sample/hms}/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png (100%) rename {samplehms => push/sample/hms}/src/main/res/values/colors.xml (100%) rename {samplehms => push/sample/hms}/src/main/res/values/dimens.xml (100%) rename {samplehms => push/sample/hms}/src/main/res/values/strings.xml (100%) rename {samplehms => push/sample/hms}/src/main/res/values/styles.xml (100%) rename {samplejava => push/sample/java}/.gitignore (100%) create mode 100644 push/sample/java/build.gradle.kts rename {sample => push/sample/java}/google-services.json (93%) rename {samplejava => push/sample/java}/proguard-rules.pro (100%) rename {samplejava => push/sample/java}/src/main/AndroidManifest.xml (100%) rename {samplejava/src/main/java/com/pushpushgo/samplejava => push/sample/java/src/main/java/com/pushpushgo/sdk/sample/push/java}/MainApplication.java (79%) rename {samplejava/src/main/java/com/pushpushgo/samplejava => push/sample/java/src/main/java/com/pushpushgo/sdk/sample/push/java}/activity/MainActivity.java (85%) rename {samplejava => push/sample/java}/src/main/res/drawable-v24/ic_launcher_foreground.xml (100%) rename {samplejava => push/sample/java}/src/main/res/drawable/ic_launcher_background.xml (100%) rename {samplejava => push/sample/java}/src/main/res/layout/activity_main.xml (100%) rename {samplejava => push/sample/java}/src/main/res/menu/menu_main.xml (83%) rename {samplejava => push/sample/java}/src/main/res/mipmap-anydpi-v26/ic_launcher.xml (100%) rename {samplejava => push/sample/java}/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml (100%) rename {samplejava => push/sample/java}/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename {samplejava => push/sample/java}/src/main/res/mipmap-hdpi/ic_launcher_round.png (100%) rename {samplejava => push/sample/java}/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename {samplejava => push/sample/java}/src/main/res/mipmap-mdpi/ic_launcher_round.png (100%) rename {samplejava => push/sample/java}/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename {samplejava => push/sample/java}/src/main/res/mipmap-xhdpi/ic_launcher_round.png (100%) rename {samplejava => push/sample/java}/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename {samplejava => push/sample/java}/src/main/res/mipmap-xxhdpi/ic_launcher_round.png (100%) rename {samplejava => push/sample/java}/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename {samplejava => push/sample/java}/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png (100%) rename {samplejava => push/sample/java}/src/main/res/values/colors.xml (100%) rename {samplejava => push/sample/java}/src/main/res/values/dimens.xml (100%) rename {samplejava => push/sample/java}/src/main/res/values/strings.xml (100%) rename {samplejava => push/sample/java}/src/main/res/values/styles.xml (100%) rename {library => push}/src/main/AndroidManifest.xml (100%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/BeaconBuilder.kt (90%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/NotificationStatusChecker.kt (60%) rename library/src/main/java/com/pushpushgo/sdk/PushPushGo.kt => push/src/main/java/com/pushpushgo/sdk/push/PushNotifications.kt (63%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/data/BeaconTag.kt (77%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/data/Event.kt (91%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/data/Message.kt (89%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/data/Notification.kt (97%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/data/NotificationMapper.kt (72%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/data/Payload.kt (91%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/di/NetworkModule.kt (52%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/di/WorkModule.kt (61%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/dto/PPGoNotification.kt (81%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/exception/PushPushException.kt (73%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/network/ApiRepository.kt (88%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/network/ApiService.kt (78%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/network/SharedPreferencesHelper.kt (64%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/network/data/TokenRequest.kt (80%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/network/data/TokenResponse.kt (80%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/network/interceptor/RequestInterceptor.kt (93%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/network/interceptor/ResponseInterceptor.kt (82%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/push/NotificationUtils.kt (80%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/push/PushMessage.kt (86%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/push/PushNotificationDelegate.kt (83%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/push/service/FcmMessagingService.kt (92%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/push/service/FcmMessagingServiceDelegate.kt (77%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/push/service/HmsMessagingService.kt (92%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/push/service/HmsMessagingServiceDelegate.kt (79%) create mode 100644 push/src/main/java/com/pushpushgo/sdk/push/subscription/DefaultPushSubscriptionProvider.kt rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/utils/CollectionExtensions.kt (81%) create mode 100644 push/src/main/java/com/pushpushgo/sdk/push/utils/LogUtils.kt rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/utils/PendingIntentCompat.kt (86%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/utils/PlatformUtils.kt (60%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/utils/PushTokenUtils.kt (97%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/work/UploadDelegate.kt (57%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/work/UploadManager.kt (72%) rename {library/src/main/java/com/pushpushgo/sdk => push/src/main/java/com/pushpushgo/sdk/push}/work/UploadWorker.kt (89%) rename {library => push}/src/main/res/drawable-hdpi/ic_stat_pushpushgo_default.png (100%) rename {library => push}/src/main/res/drawable-mdpi/ic_stat_pushpushgo_default.png (100%) rename {library => push}/src/main/res/drawable-xhdpi/ic_stat_pushpushgo_default.png (100%) rename {library => push}/src/main/res/drawable-xxhdpi/ic_stat_pushpushgo_default.png (100%) rename {library => push}/src/main/res/values/colors.xml (100%) rename {library => push}/src/main/res/values/strings.xml (100%) rename {library/src/test/java/com/pushpushgo/sdk => push/src/test/java/com/pushpushgo/sdk/push}/BeaconBuilderTest.kt (94%) rename {library/src/test/java/com/pushpushgo/sdk => push/src/test/java/com/pushpushgo/sdk/push}/PushPushGoTest.kt (88%) delete mode 100644 sample-inapp/build.gradle.kts delete mode 100644 sample-inapp/proguard-rules.pro delete mode 100644 sample/build.gradle delete mode 100644 sample/src/main/java/com/pushpushgo/sample/MainApplication.kt delete mode 100644 sample/src/main/java/com/pushpushgo/sample/activity/BeaconActivity.kt delete mode 100644 sample/src/main/java/com/pushpushgo/sample/activity/ClickActivity.kt delete mode 100644 sample/src/main/java/com/pushpushgo/sample/activity/MainActivity.kt delete mode 100644 samplehms/build.gradle delete mode 100644 samplehms/src/main/java/com/pushpushgo/sample/MainApplication.kt delete mode 100644 samplehms/src/main/java/com/pushpushgo/sample/activity/BeaconActivity.kt delete mode 100644 samplehms/src/main/java/com/pushpushgo/sample/activity/ClickActivity.kt delete mode 100644 samplehms/src/main/java/com/pushpushgo/sample/activity/MainActivity.kt delete mode 100644 samplejava/build.gradle delete mode 100644 settings.gradle create mode 100644 settings.gradle.kts diff --git a/.editorconfig b/.editorconfig index d4903f32..6812b76d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,7 +5,7 @@ insert_final_newline=true indent_style=space indent_size=2 -[{*.kt, *.kts}] +[{*.kt,*.kts}] +ktlint_code_style = ktlint_official ktlint_standard_property-naming = disabled -ktlint_standard_no-wildcard-imports = disabled -ktlint_function_naming_ignore_when_annotated_with = Composable +ktlint_function_naming_ignore_when_annotated_with = Composable \ No newline at end of file diff --git a/.github/actions/setup-ci.yml b/.github/actions/setup-ci.yml new file mode 100644 index 00000000..c05f684c --- /dev/null +++ b/.github/actions/setup-ci.yml @@ -0,0 +1,14 @@ +name: Setup CI + +runs: + using: "composite" + steps: + - uses: actions/checkout@v6 + + - uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: 21 + cache: gradle + + - uses: gradle/wrapper-validation-action@v3 diff --git a/.github/workflows/api-check.yml b/.github/workflows/api-check.yml new file mode 100644 index 00000000..2093c0dd --- /dev/null +++ b/.github/workflows/api-check.yml @@ -0,0 +1,19 @@ +name: API Check + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + api-check: + name: Check public API compatibility + runs-on: ubuntu-latest + steps: + - uses: ./.github/actions/setup-ci + + - name: Check API compatibility + run: ./gradlew apiCheck --no-daemon --build-cache diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..90fa899e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,24 @@ +name: CI + +on: + push: + pull_request: + +jobs: + ktlint: + name: Ktlint + runs-on: ubuntu-latest + steps: + - uses: ./.github/actions/setup-ci + + - name: Run Ktlint + run: ./gradlew ktlintCheck --no-daemon + + tests: + name: Tests + runs-on: ubuntu-latest + steps: + - uses: ./.github/actions/setup-ci + + - name: Run tests + run: ./gradlew test --no-daemon --build-cache diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 44212d34..00000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Docs - -on: - push: - branches: [ master ] - -jobs: - docs: - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: fkirc/skip-duplicate-actions@master - - uses: actions/checkout@v3 - - uses: gradle/wrapper-validation-action@v1 - - uses: actions/setup-java@v3 - with: - distribution: 'zulu' - java-version: 17 - - uses: actions/cache@v3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }} - - name: Generate docs - run: ./gradlew :library:dokkaHtml - - name: Deploy to GitHub Pages - uses: JamesIves/github-pages-deploy-action@v4 - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BRANCH: docs - FOLDER: library/build/dokka/html - CLEAN: true diff --git a/.github/workflows/ktlint-check.yml b/.github/workflows/ktlint-check.yml deleted file mode 100644 index f8c484e6..00000000 --- a/.github/workflows/ktlint-check.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Ktlint Check - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - ktlint: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'zulu' - - - name: Run ktlint check - run: ./gradlew ktlintCheck diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 4e782bd4..00000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: Tests - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - - workflow_dispatch: - -jobs: - unit-tests: - name: Unit tests - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: fkirc/skip-duplicate-actions@master - - uses: actions/checkout@v3 - - uses: gradle/wrapper-validation-action@v1 - - uses: actions/setup-java@v3 - with: - distribution: 'zulu' - java-version: 17 - - uses: actions/cache@v3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }} - - name: Unit tests - run: | - ./gradlew :library:testDebug --stacktrace - - api-check: - name: API changes check - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: fkirc/skip-duplicate-actions@master - - uses: actions/checkout@v3 - - uses: gradle/wrapper-validation-action@v1 - - uses: actions/setup-java@v3 - with: - distribution: 'zulu' - java-version: 17 - - uses: actions/cache@v3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }} - - name: API changes check - run: | - ./gradlew :library:apiCheck --stacktrace - ./gradlew :library-no-op:apiCheck --stacktrace diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 8430daf3..00000000 --- a/build.gradle +++ /dev/null @@ -1,24 +0,0 @@ -buildscript { - repositories { - google() - gradlePluginPortal() - maven { url 'https://developer.huawei.com/repo/' } - } - dependencies { - classpath 'com.android.tools.build:gradle:8.13.0' - classpath "org.jetbrains.dokka:dokka-core:2.1.0" - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.0" - classpath 'com.google.gms:google-services:4.4.4' - classpath 'com.huawei.agconnect:agcp:1.9.1.303' - } -} - -allprojects { - repositories { - google() - mavenCentral() - maven { url "https://jitpack.io" } - maven { url "https://oss.sonatype.org/content/repositories/snapshots" } - maven { url 'https://developer.huawei.com/repo/' } - } -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..4ebee6d0 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + alias(libs.plugins.android.library) apply false + alias(libs.plugins.android.application) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.kotlin.compose) apply false + alias(libs.plugins.ksp) apply false + alias(libs.plugins.binary.validator) apply false + alias(libs.plugins.ktlint) apply false + alias(libs.plugins.google.services) apply false + id("com.huawei.agconnect") apply false +} + +buildscript { + dependencies { + classpath("com.android.tools.build:gradle:8.13.2") + classpath("com.huawei.agconnect:agcp:1.9.1.304") + } +} + +allprojects { + repositories { + google() + mavenCentral() + maven(url = "https://jitpack.io") + maven(url = "https://oss.sonatype.org/content/repositories/snapshots") + maven(url = "https://developer.huawei.com/repo/") + } +} diff --git a/library-inappmessages/.gitignore b/core/.gitignore similarity index 100% rename from library-inappmessages/.gitignore rename to core/.gitignore diff --git a/core/build.gradle.kts b/core/build.gradle.kts new file mode 100644 index 00000000..b080b0b0 --- /dev/null +++ b/core/build.gradle.kts @@ -0,0 +1,42 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion + +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.ktlint) +} + +android { + namespace = "com.pushpushgo.sdk.core" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + } + + buildTypes { + release { + isMinifyEnabled = false + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlin { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + languageVersion.set(KotlinVersion.KOTLIN_2_1) + apiVersion.set(KotlinVersion.KOTLIN_2_1) + } + } +} + +dependencies { + implementation(libs.androidx.core.ktx) + + testImplementation(libs.junit) +} diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml new file mode 100644 index 00000000..e1000761 --- /dev/null +++ b/core/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + diff --git a/core/src/main/java/com/pushpushgo/sdk/core/config/Config.kt b/core/src/main/java/com/pushpushgo/sdk/core/config/Config.kt new file mode 100644 index 00000000..ae4f5c22 --- /dev/null +++ b/core/src/main/java/com/pushpushgo/sdk/core/config/Config.kt @@ -0,0 +1,27 @@ +package com.pushpushgo.sdk.core.config + +class Config( + val projectId: String, + val apiKey: String, + apiUrl: String? = API_URL, + isDebug: Boolean? = false, +) { + val apiUrl: String = apiUrl ?: API_URL + val isDebug: Boolean = isDebug ?: false + + companion object { + private const val API_URL = "https://api.pushpushgo.com" + private val PROJECT_ID_REGEX = Regex("^[a-z0-9]{24}$") + private val API_KEY_REGEX = Regex("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + } + + init { + require(PROJECT_ID_REGEX.matches(this.projectId)) { + "Invalid project ID format! - $projectId" + } + + require(API_KEY_REGEX.matches(this.apiKey)) { + "Invalid API key format" + } + } +} diff --git a/core/src/main/java/com/pushpushgo/sdk/core/config/ConfigProvider.kt b/core/src/main/java/com/pushpushgo/sdk/core/config/ConfigProvider.kt new file mode 100644 index 00000000..5fea1bf1 --- /dev/null +++ b/core/src/main/java/com/pushpushgo/sdk/core/config/ConfigProvider.kt @@ -0,0 +1,5 @@ +package com.pushpushgo.sdk.core.config + +interface ConfigProvider { + fun provide(): Config +} diff --git a/core/src/main/java/com/pushpushgo/sdk/core/config/ManifestConfigProvider.kt b/core/src/main/java/com/pushpushgo/sdk/core/config/ManifestConfigProvider.kt new file mode 100644 index 00000000..c3ab0d89 --- /dev/null +++ b/core/src/main/java/com/pushpushgo/sdk/core/config/ManifestConfigProvider.kt @@ -0,0 +1,34 @@ +package com.pushpushgo.sdk.core.config + +import android.content.Context +import android.content.pm.PackageManager + +class ManifestConfigProvider( + private val context: Context, +) : ConfigProvider { + override fun provide(): Config { + val packageManager = context.packageManager + val metadata = + packageManager + .getApplicationInfo( + context.packageName, + PackageManager.GET_META_DATA, + ).metaData + + requireNotNull(metadata) { + "Missing metadata" + } + + return Config( + projectId = + metadata.getString( + "com.pushpushgo.projectId", + ) ?: throw IllegalStateException("Missing metadata: com.pushpushgo.projectId"), + apiKey = + metadata.getString("com.pushpushgo.apikey") ?: metadata.getString("com.pushpushgo.apiKey") + ?: throw IllegalStateException("Missing metadata: com.pushpushgo.apikey"), + apiUrl = metadata.getString("com.pushpushgo.apiUrl"), + isDebug = metadata.getBoolean("com.pushpushgo.isDebug"), + ) + } +} diff --git a/core/src/main/java/com/pushpushgo/sdk/core/push/NotificationPermissionProvider.kt b/core/src/main/java/com/pushpushgo/sdk/core/push/NotificationPermissionProvider.kt new file mode 100644 index 00000000..0d3d7ad9 --- /dev/null +++ b/core/src/main/java/com/pushpushgo/sdk/core/push/NotificationPermissionProvider.kt @@ -0,0 +1,27 @@ +package com.pushpushgo.sdk.core.push + +import android.Manifest +import android.content.Context +import android.content.pm.PackageManager +import android.os.Build +import androidx.core.app.NotificationManagerCompat +import androidx.core.content.ContextCompat + +object NotificationPermissionProvider { + fun canPostNotifications(context: Context): Boolean { + val manager = NotificationManagerCompat.from(context) + + if (!manager.areNotificationsEnabled()) { + return false + } + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { + return true + } + + return ContextCompat.checkSelfPermission( + context, + Manifest.permission.POST_NOTIFICATIONS, + ) == PackageManager.PERMISSION_GRANTED + } +} diff --git a/core/src/main/java/com/pushpushgo/sdk/core/push/PushSubscriptionProvider.kt b/core/src/main/java/com/pushpushgo/sdk/core/push/PushSubscriptionProvider.kt new file mode 100644 index 00000000..e780c8f1 --- /dev/null +++ b/core/src/main/java/com/pushpushgo/sdk/core/push/PushSubscriptionProvider.kt @@ -0,0 +1,13 @@ +package com.pushpushgo.sdk.core.push + +interface PushSubscriptionProvider { + suspend fun subscribe() + + suspend fun unsubscribe() + + fun isSubscribed(): Boolean + + fun getSubscriberId(): String? + + fun isNotificationChannelEnabled(): Boolean +} diff --git a/gradle.properties b/gradle.properties index f2dc0583..60781c37 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,8 @@ -org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" -XX:+UseParallelGC -kapt.include.compile.classpath=false +org.gradle.jvmargs=-Xmx2g -Dkotlin.daemon.jvm.options="-Xmx2g" -XX:+UseG1GC +org.gradle.parallel=true + kotlin.code.style=official +kotlin.explicitApi=strict + android.useAndroidX=true -android.enableJetifier=true android.nonTransitiveRClass=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..03c46280 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,125 @@ +[versions] +kotlin = "2.2.0" +agp = "8.13.2" +ksp = "2.2.0-2.0.2" +ktlint = "14.0.1" +binary-validator = "0.18.1" +google-services = "4.4.4" + +androidx-core = "1.17.0" +androidx-preference = "1.2.1" +androidx-appcompat = "1.7.1" +androidx-constraintlayout = "2.2.1" +lifecycle = "2.10.0" +navigation = "2.9.6" +work = "2.11.0" +activity-compose = "1.12.2" +emoji = "1.6.0" + +compose-bom = "2025.12.01" +compose-fonts = "1.10.0" +material = "1.13.0" + +coroutines = "1.10.2" +serialization = "1.9.0" + +retrofit = "2.11.0" +moshi = "1.15.2" +okhttp-bom = "4.12.0" +kodein = "7.30.0" +coil = "2.7.0" + +firebase-bom = "34.7.0" +hms-agconnect = "1.9.1.304" +hms-push = "6.13.0.300" +hms-update = "5.0.2.300" + +guava = "33.5.0-android" +timber = "5.0.1" +json = "20251224" + +junit = "4.13.2" +mockk = "1.14.7" +espresso = "3.7.0" +androidx-junit = "1.3.0" +robolectric = "4.16" + + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } +android-library = { id = "com.android.library", version.ref = "agp" } + +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } + +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } + +ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" } +binary-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binary-validator" } + +google-services = { id = "com.google.gms.google-services", version.ref = "google-services" } + + +[libraries] +androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core" } +androidx-preference = { module = "androidx.preference:preference-ktx", version.ref = "androidx-preference" } +androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" } +androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "androidx-constraintlayout" } +androidx-lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle" } + +androidx-navigation-runtime = { module = "androidx.navigation:navigation-runtime-ktx", version.ref = "navigation" } +androidx-navigation-common = { module = "androidx.navigation:navigation-common-ktx", version.ref = "navigation" } +androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigation" } +androidx-work-runtime = { module = "androidx.work:work-runtime-ktx", version.ref = "work" } +androidx-work-gcm = { module = "androidx.work:work-gcm", version.ref = "work" } + +androidx-emoji2 = { module = "androidx.emoji2:emoji2", version.ref = "emoji" } +androidx-emoji2-bundled = { module = "androidx.emoji2:emoji2-bundled", version.ref = "emoji" } + +compose-bom = { module = "androidx.compose:compose-bom", version.ref = "compose-bom" } +compose-activity = { module = "androidx.activity:activity-compose", version.ref = "activity-compose" } +compose-runtime = { module = "androidx.compose.runtime:runtime" } +compose-ui = { module = "androidx.compose.ui:ui" } +compose-ui-graphics = { module = "androidx.compose.ui:ui-graphics" } +compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" } +compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" } +compose-ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4" } +compose-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest" } +compose-ui-text-fonts = { module = "androidx.compose.ui:ui-text-google-fonts", version.ref = "compose-fonts" } +compose-material3 = { module = "androidx.compose.material3:material3" } +compose-material-icons = { module = "androidx.compose.material:material-icons-core" } + +material = { module = "com.google.android.material:material", version.ref = "material" } + +coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } +coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" } +coroutines-guava = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-guava", version.ref = "coroutines" } +coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } +kotlinx-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" } + +retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" } +retrofit-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofit" } +moshi-kotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "moshi" } +moshi-codegen = { module = "com.squareup.moshi:moshi-kotlin-codegen", version.ref = "moshi" } +moshi-adapters = { module = "com.squareup.moshi:moshi-adapters", version.ref = "moshi" } +okhttp-bom = { module = "com.squareup.okhttp3:okhttp-bom", version.ref = "okhttp-bom" } +okhttp-logging = { module = "com.squareup.okhttp3:logging-interceptor" } +kodein = { module = "org.kodein.di:kodein-di", version.ref = "kodein" } +coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" } + +firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebase-bom" } +firebase-messaging = { module = "com.google.firebase:firebase-messaging" } +hms-agconnect = { module = "com.huawei.agconnect:agconnect-core", version.ref = "hms-agconnect" } +hms-push = { module = "com.huawei.hms:push", version.ref = "hms-push" } +hms-update = { module = "com.huawei.hms:update", version.ref = "hms-update" } + +guava = { module = "com.google.guava:guava", version.ref = "guava" } +timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" } +json = { module = "org.json:json", version.ref = "json" } + +junit = { module = "junit:junit", version.ref = "junit" } +mockk = { module = "io.mockk:mockk", version.ref = "mockk" } +androidx-test-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-junit" } +espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" } +robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" } diff --git a/sample-inapp/.gitignore b/inapp/.gitignore similarity index 100% rename from sample-inapp/.gitignore rename to inapp/.gitignore diff --git a/library-inappmessages/README.md b/inapp/README.md similarity index 100% rename from library-inappmessages/README.md rename to inapp/README.md diff --git a/inapp/api/inapp.api b/inapp/api/inapp.api new file mode 100644 index 00000000..999ca5d4 --- /dev/null +++ b/inapp/api/inapp.api @@ -0,0 +1,69 @@ +public final class com/pushpushgo/sdk/inapp/BuildConfig { + public static final field BUILD_TYPE Ljava/lang/String; + public static final field DEBUG Z + public static final field LIBRARY_PACKAGE_NAME Ljava/lang/String; + public fun ()V +} + +public final class com/pushpushgo/sdk/inapp/InAppMessages { + public static final field $stable I + public static final field Companion Lcom/pushpushgo/sdk/inapp/InAppMessages$Companion; + public static final fun getInstance ()Lcom/pushpushgo/sdk/inapp/InAppMessages; + public static final fun initialize (Landroid/app/Application;Lcom/pushpushgo/sdk/core/config/Config;Lcom/pushpushgo/sdk/core/push/PushSubscriptionProvider;)Lcom/pushpushgo/sdk/inapp/InAppMessages; + public static final fun initialize (Landroid/app/Application;Lcom/pushpushgo/sdk/core/push/PushSubscriptionProvider;)Lcom/pushpushgo/sdk/inapp/InAppMessages; + public final fun showMessagesOnRoute (Lcom/pushpushgo/sdk/inapp/ui/Route;)V + public final fun showMessagesOnTrigger (Lcom/pushpushgo/sdk/inapp/ui/Trigger;)V +} + +public final class com/pushpushgo/sdk/inapp/InAppMessages$Companion { + public final fun getInstance ()Lcom/pushpushgo/sdk/inapp/InAppMessages; + public final fun initialize (Landroid/app/Application;Lcom/pushpushgo/sdk/core/config/Config;Lcom/pushpushgo/sdk/core/push/PushSubscriptionProvider;)Lcom/pushpushgo/sdk/inapp/InAppMessages; + public final fun initialize (Landroid/app/Application;Lcom/pushpushgo/sdk/core/push/PushSubscriptionProvider;)Lcom/pushpushgo/sdk/inapp/InAppMessages; + public static synthetic fun initialize$default (Lcom/pushpushgo/sdk/inapp/InAppMessages$Companion;Landroid/app/Application;Lcom/pushpushgo/sdk/core/config/Config;Lcom/pushpushgo/sdk/core/push/PushSubscriptionProvider;ILjava/lang/Object;)Lcom/pushpushgo/sdk/inapp/InAppMessages; + public static synthetic fun initialize$default (Lcom/pushpushgo/sdk/inapp/InAppMessages$Companion;Landroid/app/Application;Lcom/pushpushgo/sdk/core/push/PushSubscriptionProvider;ILjava/lang/Object;)Lcom/pushpushgo/sdk/inapp/InAppMessages; +} + +public abstract interface class com/pushpushgo/sdk/inapp/ui/CustomCodeHandler { + public abstract fun handle (Ljava/lang/String;)V +} + +public final class com/pushpushgo/sdk/inapp/ui/Route { + public static final field $stable I + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lcom/pushpushgo/sdk/inapp/ui/Route; + public static synthetic fun copy$default (Lcom/pushpushgo/sdk/inapp/ui/Route;Ljava/lang/String;ILjava/lang/Object;)Lcom/pushpushgo/sdk/inapp/ui/Route; + public fun equals (Ljava/lang/Object;)Z + public final fun getName ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/pushpushgo/sdk/inapp/ui/Trigger { + public static final field $stable I + public fun (Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/String;)Lcom/pushpushgo/sdk/inapp/ui/Trigger; + public static synthetic fun copy$default (Lcom/pushpushgo/sdk/inapp/ui/Trigger;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/pushpushgo/sdk/inapp/ui/Trigger; + public fun equals (Ljava/lang/Object;)Z + public final fun getKey ()Ljava/lang/String; + public final fun getValue ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class com/pushpushgo/sdk/inapp/utils/InAppMessageHelper { + public static final field $stable I + public static final field INSTANCE Lcom/pushpushgo/sdk/inapp/utils/InAppMessageHelper; + public final fun ObserveNavBackStack (Landroidx/navigation/NavBackStackEntry;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)V + public final fun ObserveNavigation (Ljava/lang/String;Landroidx/compose/runtime/Composer;I)V + public final fun createLifecycleObserver (Lkotlin/jvm/functions/Function0;)Landroidx/lifecycle/DefaultLifecycleObserver; + public final fun setupWithNavController (Landroidx/navigation/NavController;Lkotlin/jvm/functions/Function2;)Landroidx/navigation/NavController$OnDestinationChangedListener; + public static synthetic fun setupWithNavController$default (Lcom/pushpushgo/sdk/inapp/utils/InAppMessageHelper;Landroidx/navigation/NavController;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Landroidx/navigation/NavController$OnDestinationChangedListener; + public final fun showMessagesForFragment (Landroidx/fragment/app/Fragment;Ljava/lang/String;)V + public static synthetic fun showMessagesForFragment$default (Lcom/pushpushgo/sdk/inapp/utils/InAppMessageHelper;Landroidx/fragment/app/Fragment;Ljava/lang/String;ILjava/lang/Object;)V + public final fun showMessagesForScreen (Ljava/lang/String;)V +} + diff --git a/library-inappmessages/build.gradle.kts b/inapp/build.gradle.kts similarity index 54% rename from library-inappmessages/build.gradle.kts rename to inapp/build.gradle.kts index fe0d7588..54680ca8 100644 --- a/library-inappmessages/build.gradle.kts +++ b/inapp/build.gradle.kts @@ -2,46 +2,49 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.KotlinVersion plugins { - id("com.android.library") - id("org.jetbrains.kotlin.android") - id("com.google.devtools.ksp") version "2.2.0-2.0.2" - id("org.jetbrains.kotlin.plugin.serialization") version "2.2.0" - id("org.jetbrains.kotlin.plugin.compose") version "2.2.0" - id("org.jlleitschuh.gradle.ktlint") version "13.0.0" + alias(libs.plugins.android.library) + alias(libs.plugins.ksp) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.serialization) + alias(libs.plugins.kotlin.compose) + alias(libs.plugins.ktlint) + alias(libs.plugins.binary.validator) id("maven-publish") } android { - namespace = "com.pushpushgo.inappmessages" + namespace = "com.pushpushgo.sdk.inapp" compileSdk = 36 defaultConfig { minSdk = 26 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") } buildTypes { release { isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") } } + + buildFeatures { + buildConfig = true + compose = true + } + compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } + kotlin { compilerOptions { - jvmTarget = JvmTarget.fromTarget("17") - languageVersion = KotlinVersion.fromVersion("2.1") - apiVersion = KotlinVersion.fromVersion("2.1") + jvmTarget.set(JvmTarget.JVM_17) + languageVersion.set(KotlinVersion.KOTLIN_2_1) + apiVersion.set(KotlinVersion.KOTLIN_2_1) } } - buildFeatures { - compose = true - } publishing { singleVariant("release") { @@ -51,6 +54,10 @@ android { } dependencies { + if (System.getenv("JITPACK") == null) { + api(project(":core")) + } + // Core & Appcompat implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) @@ -71,50 +78,31 @@ dependencies { implementation(libs.compose.material.icons) implementation(libs.compose.runtime) implementation(libs.compose.ui.text.fonts) // Google Fonts - implementation("androidx.emoji2:emoji2:1.6.0") - implementation("androidx.emoji2:emoji2-bundled:1.6.0") + implementation(libs.androidx.emoji2) + implementation(libs.androidx.emoji2.bundled) // Image Loading implementation(libs.coil.compose) // Serialization - implementation(libs.moshi.kotlin) ksp(libs.moshi.codegen) + implementation(libs.moshi.kotlin) implementation(libs.kotlinx.serialization) // Networking implementation(libs.retrofit) implementation(libs.retrofit.moshi) implementation(platform(libs.okhttp.bom)) - implementation("com.squareup.okhttp3:logging-interceptor") + implementation(libs.okhttp.logging) // Testing - testImplementation("junit:junit:4.13.2") - testImplementation("io.mockk:mockk:1.14.5") + testImplementation(libs.junit) + testImplementation(libs.mockk) testImplementation(libs.coroutines.test) - androidTestImplementation("androidx.test.ext:junit:1.3.0") - androidTestImplementation("androidx.test.espresso:espresso-core:3.7.0") + androidTestImplementation(libs.androidx.test.junit) + androidTestImplementation(libs.espresso.core) } -tasks.register("androidSourcesJar") { - archiveClassifier.set("sources") - from( - android.sourceSets - .getByName("main") - .java.srcDirs, - ) -} - -publishing { - publications { - create("release") { - groupId = "com.pushpushgo" - artifactId = "inappmessages" - version = libs.versions.sdk.get() - - afterEvaluate { - from(components["release"]) - } - } - } +apiValidation { + ignoredProjects.add("sample") } diff --git a/inapp/sample/.gitignore b/inapp/sample/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/inapp/sample/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/inapp/sample/build.gradle.kts b/inapp/sample/build.gradle.kts new file mode 100644 index 00000000..1abb457f --- /dev/null +++ b/inapp/sample/build.gradle.kts @@ -0,0 +1,76 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) + alias(libs.plugins.ktlint) +} + +android { + namespace = "com.pushpushgo.sdk.sample.inapp" + compileSdk = 36 + + buildFeatures { + buildConfig = true + } + + defaultConfig { + applicationId = "com.pushpushgo.sdk.sample.inapp" + minSdk = 26 + targetSdk = 36 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + + manifestPlaceholders["PPG_PROJECT_ID"] = "" + manifestPlaceholders["PPG_API_KEY"] = "" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlin { + compilerOptions { + jvmTarget = JvmTarget.fromTarget("11") + } + } + buildFeatures { + compose = true + } +} + +dependencies { + implementation(project(":inapp")) + + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime) + implementation(libs.compose.activity) + + implementation(platform(libs.compose.bom)) + implementation(libs.compose.ui) + implementation(libs.compose.ui.graphics) + implementation(libs.compose.ui.tooling.preview) + implementation(libs.compose.material3) + + implementation(libs.androidx.navigation.runtime) + implementation(libs.androidx.navigation.compose) + + testImplementation(libs.junit) + + androidTestImplementation(libs.androidx.test.junit) + androidTestImplementation(libs.espresso.core) + androidTestImplementation(platform(libs.compose.bom)) + androidTestImplementation(libs.compose.ui.test.junit4) + + debugImplementation(libs.compose.ui.tooling) + debugImplementation(libs.compose.ui.test.manifest) +} diff --git a/library-inappmessages/proguard-rules.pro b/inapp/sample/proguard-rules.pro similarity index 100% rename from library-inappmessages/proguard-rules.pro rename to inapp/sample/proguard-rules.pro diff --git a/sample-inapp/src/androidTest/java/com/pushpushgo/sample/ExampleInstrumentedTest.kt b/inapp/sample/src/androidTest/java/com/pushpushgo/sdk/sample/inapp/ExampleInstrumentedTest.kt similarity index 79% rename from sample-inapp/src/androidTest/java/com/pushpushgo/sample/ExampleInstrumentedTest.kt rename to inapp/sample/src/androidTest/java/com/pushpushgo/sdk/sample/inapp/ExampleInstrumentedTest.kt index 68533708..53056a3c 100644 --- a/sample-inapp/src/androidTest/java/com/pushpushgo/sample/ExampleInstrumentedTest.kt +++ b/inapp/sample/src/androidTest/java/com/pushpushgo/sdk/sample/inapp/ExampleInstrumentedTest.kt @@ -1,8 +1,8 @@ -package com.pushpushgo.sample +package com.pushpushgo.sdk.sample.inapp import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry -import org.junit.Assert.* +import org.junit.Assert import org.junit.Test import org.junit.runner.RunWith @@ -17,6 +17,6 @@ class ExampleInstrumentedTest { fun useAppContext() { // Context of the app under test. val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.pushpushgo.sample", appContext.packageName) + Assert.assertEquals("com.pushpushgo.sample", appContext.packageName) } } diff --git a/sample-inapp/src/main/AndroidManifest.xml b/inapp/sample/src/main/AndroidManifest.xml similarity index 76% rename from sample-inapp/src/main/AndroidManifest.xml rename to inapp/sample/src/main/AndroidManifest.xml index 2ea82488..7da81ef4 100644 --- a/sample-inapp/src/main/AndroidManifest.xml +++ b/inapp/sample/src/main/AndroidManifest.xml @@ -11,9 +11,8 @@ android:supportsRtl="true" android:theme="@style/Theme.Androidsdk"> @@ -21,6 +20,10 @@ + + + + diff --git a/sample-inapp/src/main/java/com/pushpushgo/sample/MainActivity.kt b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/MainActivity.kt similarity index 65% rename from sample-inapp/src/main/java/com/pushpushgo/sample/MainActivity.kt rename to inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/MainActivity.kt index 3005c156..1c3e9d0c 100644 --- a/sample-inapp/src/main/java/com/pushpushgo/sample/MainActivity.kt +++ b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/MainActivity.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.sample +package com.pushpushgo.sdk.sample.inapp import android.os.Bundle import androidx.activity.ComponentActivity @@ -9,21 +9,15 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold import androidx.compose.ui.Modifier -import com.pushpushgo.inappmessages.InAppMessagesSDK -import com.pushpushgo.sample.ui.MainNavHost -import com.pushpushgo.sample.ui.theme.AndroidsdkTheme +import com.pushpushgo.sdk.inapp.InAppMessages +import com.pushpushgo.sdk.sample.inapp.ui.MainNavHost +import com.pushpushgo.sdk.sample.inapp.ui.theme.AndroidsdkTheme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - InAppMessagesSDK.initialize( - application = application, - projectId = BuildConfig.PPG_PROJECT_ID, - apiKey = BuildConfig.PPG_API_KEY, - debug = true, - baseUrl = "https://api.master1.qappg.co", - ) + InAppMessages.initialize(application) enableEdgeToEdge() setContent { diff --git a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/MainNavHost.kt b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/MainNavHost.kt similarity index 71% rename from sample-inapp/src/main/java/com/pushpushgo/sample/ui/MainNavHost.kt rename to inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/MainNavHost.kt index 4313bfe5..e30f0010 100644 --- a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/MainNavHost.kt +++ b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/MainNavHost.kt @@ -1,12 +1,12 @@ -package com.pushpushgo.sample.ui +package com.pushpushgo.sdk.sample.inapp.ui import androidx.compose.runtime.Composable import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController -import com.pushpushgo.sample.ui.screens.InfoScreen -import com.pushpushgo.sample.ui.screens.MainScreen -import com.pushpushgo.sample.ui.screens.OfferScreen +import com.pushpushgo.sdk.sample.inapp.ui.screens.InfoScreen +import com.pushpushgo.sdk.sample.inapp.ui.screens.MainScreen +import com.pushpushgo.sdk.sample.inapp.ui.screens.OfferScreen @Composable() internal fun MainNavHost() { diff --git a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/Screen.kt b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/Screen.kt similarity index 78% rename from sample-inapp/src/main/java/com/pushpushgo/sample/ui/Screen.kt rename to inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/Screen.kt index a7072ffb..5f2ff138 100644 --- a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/Screen.kt +++ b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/Screen.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.sample.ui +package com.pushpushgo.sdk.sample.inapp.ui sealed class Screen( val route: String, diff --git a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/screens/InfoScreen.kt b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/screens/InfoScreen.kt similarity index 82% rename from sample-inapp/src/main/java/com/pushpushgo/sample/ui/screens/InfoScreen.kt rename to inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/screens/InfoScreen.kt index 61d62041..d6e7872d 100644 --- a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/screens/InfoScreen.kt +++ b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/screens/InfoScreen.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.sample.ui.screens +package com.pushpushgo.sdk.sample.inapp.ui.screens import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -13,13 +13,14 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController -import com.pushpushgo.inappmessages.InAppMessagesSDK -import com.pushpushgo.sample.ui.Screen +import com.pushpushgo.sdk.inapp.InAppMessages +import com.pushpushgo.sdk.inapp.ui.Route +import com.pushpushgo.sdk.sample.inapp.ui.Screen @Composable internal fun InfoScreen(navController: NavHostController) { LaunchedEffect(Screen.Info.route) { - InAppMessagesSDK.getInstance().showActiveMessages(Screen.Info.route) + InAppMessages.getInstance().showMessagesOnRoute(Route(Screen.Info.route)) } Column( diff --git a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/screens/MainScreen.kt b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/screens/MainScreen.kt similarity index 84% rename from sample-inapp/src/main/java/com/pushpushgo/sample/ui/screens/MainScreen.kt rename to inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/screens/MainScreen.kt index c690f705..b7fa74b0 100644 --- a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/screens/MainScreen.kt +++ b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/screens/MainScreen.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.sample.ui.screens +package com.pushpushgo.sdk.sample.inapp.ui.screens import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -13,13 +13,14 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController -import com.pushpushgo.inappmessages.InAppMessagesSDK -import com.pushpushgo.sample.ui.Screen +import com.pushpushgo.sdk.inapp.InAppMessages +import com.pushpushgo.sdk.inapp.ui.Route +import com.pushpushgo.sdk.sample.inapp.ui.Screen @Composable internal fun MainScreen(navController: NavHostController) { LaunchedEffect(Screen.Main.route) { - InAppMessagesSDK.getInstance().showActiveMessages(Screen.Main.route) + InAppMessages.getInstance().showMessagesOnRoute(Route(Screen.Main.route)) } Column( diff --git a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/screens/OfferScreen.kt b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/screens/OfferScreen.kt similarity index 82% rename from sample-inapp/src/main/java/com/pushpushgo/sample/ui/screens/OfferScreen.kt rename to inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/screens/OfferScreen.kt index fa1fc440..317ef84b 100644 --- a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/screens/OfferScreen.kt +++ b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/screens/OfferScreen.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.sample.ui.screens +package com.pushpushgo.sdk.sample.inapp.ui.screens import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -13,13 +13,14 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController -import com.pushpushgo.inappmessages.InAppMessagesSDK -import com.pushpushgo.sample.ui.Screen +import com.pushpushgo.sdk.inapp.InAppMessages +import com.pushpushgo.sdk.inapp.ui.Route +import com.pushpushgo.sdk.sample.inapp.ui.Screen @Composable internal fun OfferScreen(navController: NavHostController) { LaunchedEffect(Screen.Offer.route) { - InAppMessagesSDK.getInstance().showActiveMessages(Screen.Offer.route) + InAppMessages.getInstance().showMessagesOnRoute(Route(Screen.Offer.route)) } Column( diff --git a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/theme/Color.kt b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/theme/Color.kt similarity index 83% rename from sample-inapp/src/main/java/com/pushpushgo/sample/ui/theme/Color.kt rename to inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/theme/Color.kt index a6a1b985..3f8373cc 100644 --- a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/theme/Color.kt +++ b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/theme/Color.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.sample.ui.theme +package com.pushpushgo.sdk.sample.inapp.ui.theme import androidx.compose.ui.graphics.Color diff --git a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/theme/Theme.kt b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/theme/Theme.kt similarity index 97% rename from sample-inapp/src/main/java/com/pushpushgo/sample/ui/theme/Theme.kt rename to inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/theme/Theme.kt index 887ccd2f..62d3a128 100644 --- a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/theme/Theme.kt +++ b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/theme/Theme.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.sample.ui.theme +package com.pushpushgo.sdk.sample.inapp.ui.theme import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme diff --git a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/theme/Type.kt b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/theme/Type.kt similarity index 95% rename from sample-inapp/src/main/java/com/pushpushgo/sample/ui/theme/Type.kt rename to inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/theme/Type.kt index 4adf0636..65a97314 100644 --- a/sample-inapp/src/main/java/com/pushpushgo/sample/ui/theme/Type.kt +++ b/inapp/sample/src/main/java/com/pushpushgo/sdk/sample/inapp/ui/theme/Type.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.sample.ui.theme +package com.pushpushgo.sdk.sample.inapp.ui.theme import androidx.compose.material3.Typography import androidx.compose.ui.text.TextStyle diff --git a/sample-inapp/src/main/res/drawable/ic_launcher_background.xml b/inapp/sample/src/main/res/drawable/ic_launcher_background.xml similarity index 100% rename from sample-inapp/src/main/res/drawable/ic_launcher_background.xml rename to inapp/sample/src/main/res/drawable/ic_launcher_background.xml diff --git a/sample-inapp/src/main/res/drawable/ic_launcher_foreground.xml b/inapp/sample/src/main/res/drawable/ic_launcher_foreground.xml similarity index 100% rename from sample-inapp/src/main/res/drawable/ic_launcher_foreground.xml rename to inapp/sample/src/main/res/drawable/ic_launcher_foreground.xml diff --git a/sample-inapp/src/main/res/mipmap-anydpi/ic_launcher.xml b/inapp/sample/src/main/res/mipmap-anydpi/ic_launcher.xml similarity index 100% rename from sample-inapp/src/main/res/mipmap-anydpi/ic_launcher.xml rename to inapp/sample/src/main/res/mipmap-anydpi/ic_launcher.xml diff --git a/sample-inapp/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/inapp/sample/src/main/res/mipmap-anydpi/ic_launcher_round.xml similarity index 100% rename from sample-inapp/src/main/res/mipmap-anydpi/ic_launcher_round.xml rename to inapp/sample/src/main/res/mipmap-anydpi/ic_launcher_round.xml diff --git a/sample-inapp/src/main/res/mipmap-hdpi/ic_launcher.webp b/inapp/sample/src/main/res/mipmap-hdpi/ic_launcher.webp similarity index 100% rename from sample-inapp/src/main/res/mipmap-hdpi/ic_launcher.webp rename to inapp/sample/src/main/res/mipmap-hdpi/ic_launcher.webp diff --git a/sample-inapp/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/inapp/sample/src/main/res/mipmap-hdpi/ic_launcher_round.webp similarity index 100% rename from sample-inapp/src/main/res/mipmap-hdpi/ic_launcher_round.webp rename to inapp/sample/src/main/res/mipmap-hdpi/ic_launcher_round.webp diff --git a/sample-inapp/src/main/res/mipmap-mdpi/ic_launcher.webp b/inapp/sample/src/main/res/mipmap-mdpi/ic_launcher.webp similarity index 100% rename from sample-inapp/src/main/res/mipmap-mdpi/ic_launcher.webp rename to inapp/sample/src/main/res/mipmap-mdpi/ic_launcher.webp diff --git a/sample-inapp/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/inapp/sample/src/main/res/mipmap-mdpi/ic_launcher_round.webp similarity index 100% rename from sample-inapp/src/main/res/mipmap-mdpi/ic_launcher_round.webp rename to inapp/sample/src/main/res/mipmap-mdpi/ic_launcher_round.webp diff --git a/sample-inapp/src/main/res/mipmap-xhdpi/ic_launcher.webp b/inapp/sample/src/main/res/mipmap-xhdpi/ic_launcher.webp similarity index 100% rename from sample-inapp/src/main/res/mipmap-xhdpi/ic_launcher.webp rename to inapp/sample/src/main/res/mipmap-xhdpi/ic_launcher.webp diff --git a/sample-inapp/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/inapp/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.webp similarity index 100% rename from sample-inapp/src/main/res/mipmap-xhdpi/ic_launcher_round.webp rename to inapp/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.webp diff --git a/sample-inapp/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/inapp/sample/src/main/res/mipmap-xxhdpi/ic_launcher.webp similarity index 100% rename from sample-inapp/src/main/res/mipmap-xxhdpi/ic_launcher.webp rename to inapp/sample/src/main/res/mipmap-xxhdpi/ic_launcher.webp diff --git a/sample-inapp/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/inapp/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp similarity index 100% rename from sample-inapp/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp rename to inapp/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp diff --git a/sample-inapp/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/inapp/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.webp similarity index 100% rename from sample-inapp/src/main/res/mipmap-xxxhdpi/ic_launcher.webp rename to inapp/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.webp diff --git a/sample-inapp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/inapp/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp similarity index 100% rename from sample-inapp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp rename to inapp/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp diff --git a/sample-inapp/src/main/res/values/colors.xml b/inapp/sample/src/main/res/values/colors.xml similarity index 100% rename from sample-inapp/src/main/res/values/colors.xml rename to inapp/sample/src/main/res/values/colors.xml diff --git a/sample-inapp/src/main/res/values/strings.xml b/inapp/sample/src/main/res/values/strings.xml similarity index 100% rename from sample-inapp/src/main/res/values/strings.xml rename to inapp/sample/src/main/res/values/strings.xml diff --git a/sample-inapp/src/main/res/values/themes.xml b/inapp/sample/src/main/res/values/themes.xml similarity index 100% rename from sample-inapp/src/main/res/values/themes.xml rename to inapp/sample/src/main/res/values/themes.xml diff --git a/sample-inapp/src/test/java/com/pushpushgo/sample/ExampleUnitTest.kt b/inapp/sample/src/test/java/com/pushpushgo/sdk/sample/inapp/ExampleUnitTest.kt similarity index 72% rename from sample-inapp/src/test/java/com/pushpushgo/sample/ExampleUnitTest.kt rename to inapp/sample/src/test/java/com/pushpushgo/sdk/sample/inapp/ExampleUnitTest.kt index 23e49c38..44516c50 100644 --- a/sample-inapp/src/test/java/com/pushpushgo/sample/ExampleUnitTest.kt +++ b/inapp/sample/src/test/java/com/pushpushgo/sdk/sample/inapp/ExampleUnitTest.kt @@ -1,6 +1,6 @@ -package com.pushpushgo.sample +package com.pushpushgo.sdk.sample.inapp -import org.junit.Assert.* +import org.junit.Assert import org.junit.Test /** @@ -11,6 +11,6 @@ import org.junit.Test class ExampleUnitTest { @Test fun addition_isCorrect() { - assertEquals(4, 2 + 2) + Assert.assertEquals(4, 2 + 2) } } diff --git a/library-inappmessages/src/main/AndroidManifest.xml b/inapp/src/main/AndroidManifest.xml similarity index 100% rename from library-inappmessages/src/main/AndroidManifest.xml rename to inapp/src/main/AndroidManifest.xml diff --git a/inapp/src/main/java/com/pushpushgo/sdk/inapp/InAppMessages.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/InAppMessages.kt new file mode 100644 index 00000000..194c6b2f --- /dev/null +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/InAppMessages.kt @@ -0,0 +1,203 @@ +package com.pushpushgo.sdk.inapp + +import android.app.Application +import android.util.Log +import com.pushpushgo.sdk.core.config.Config +import com.pushpushgo.sdk.core.config.ManifestConfigProvider +import com.pushpushgo.sdk.core.push.PushSubscriptionProvider +import com.pushpushgo.sdk.inapp.event.InAppMessageEvent +import com.pushpushgo.sdk.inapp.event.InAppMessageEventRepository +import com.pushpushgo.sdk.inapp.manager.InAppMessageManager +import com.pushpushgo.sdk.inapp.manager.InAppMessageManagerImpl +import com.pushpushgo.sdk.inapp.network.InAppEventApi +import com.pushpushgo.sdk.inapp.network.InAppListGetApi +import com.pushpushgo.sdk.inapp.network.RetrofitProvider +import com.pushpushgo.sdk.inapp.persistence.InAppMessagePersistenceImpl +import com.pushpushgo.sdk.inapp.repository.InAppMessageRepositoryImpl +import com.pushpushgo.sdk.inapp.ui.CustomCodeHandler +import com.pushpushgo.sdk.inapp.ui.InAppMessageDisplayer +import com.pushpushgo.sdk.inapp.ui.InAppMessageDisplayerImpl +import com.pushpushgo.sdk.inapp.ui.InAppUIController +import com.pushpushgo.sdk.inapp.ui.Route +import com.pushpushgo.sdk.inapp.ui.Trigger +import com.pushpushgo.sdk.inapp.utils.AutoCleanupManager +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import retrofit2.Retrofit + +class InAppMessages private constructor( + private val application: Application, + private val config: Config, + private val pushSubscriptionProvider: PushSubscriptionProvider? = null, + private val customCodeHandler: CustomCodeHandler? = null, +) { + private val retrofit: Retrofit by lazy { + RetrofitProvider.buildRetrofit(config.apiUrl) + } + private val api: InAppListGetApi by lazy { + retrofit.create(InAppListGetApi::class.java) + } + private val eventApi: InAppEventApi by lazy { + retrofit.create(InAppEventApi::class.java) + } + private val eventRepository by lazy { + InAppMessageEventRepository(eventApi, debug = config.isDebug) + } + + internal suspend fun dispatchInAppEvent( + action: String, + inAppId: String, + ) { + try { + eventRepository.sendEvent( + projectId = config.projectId, + token = config.apiKey, + event = InAppMessageEvent(action = action, inApp = inAppId), + ) + } catch (e: Exception) { + if (config.isDebug) { + Log.e(TAG, "Failed to send in-app event", e) + } + } + } + + private val sdkScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) + private val manager: InAppMessageManager + private val displayer: InAppMessageDisplayer + private val uiController: InAppUIController + private var autoCleanupManager: AutoCleanupManager? = null + + companion object { + internal const val TAG = "[PushPushGo:InAppMessages]" + + @Volatile + private var INSTANCE: InAppMessages? = null + + @JvmStatic + fun initialize( + application: Application, + pushSubscriptionProvider: PushSubscriptionProvider? = null, + ): InAppMessages = + INSTANCE ?: synchronized(this) { + INSTANCE ?: InAppMessages( + application = application, + config = ManifestConfigProvider(application).provide(), + pushSubscriptionProvider = pushSubscriptionProvider, + ).also { INSTANCE = it } + } + + @JvmStatic + fun initialize( + application: Application, + config: Config, + pushSubscriptionProvider: PushSubscriptionProvider? = null, + ): InAppMessages = + INSTANCE ?: synchronized(this) { + INSTANCE ?: InAppMessages( + application = application, + config = config, + pushSubscriptionProvider = pushSubscriptionProvider, + ).also { + INSTANCE = it + } + } + + @JvmStatic + fun getInstance(): InAppMessages = INSTANCE ?: throw IllegalStateException("InAppMessages SDK is not initialized!") + } + + init { + val persistence = InAppMessagePersistenceImpl(application, config.isDebug) + val repository = InAppMessageRepositoryImpl(api, config.projectId, config.apiKey, persistence, config.isDebug) + manager = + InAppMessageManagerImpl( + scope = sdkScope, + repository = repository, + persistence = persistence, + context = application, + debug = config.isDebug, + pushSubscriptionProvider = pushSubscriptionProvider, + ) + displayer = + InAppMessageDisplayerImpl( + persistence = persistence, + debug = config.isDebug, + onMessageDismissed = { + sdkScope.launch { + manager.refreshActiveMessages(manager.getRoute()) + } + }, + onMessageEvent = { eventType, message, ctaIndex -> + sdkScope.launch { + when (eventType) { + "show" -> dispatchInAppEvent("inapp.show", message.id) + "close" -> dispatchInAppEvent("inapp.close", message.id) + "cta" -> dispatchInAppEvent("inapp.cta.$ctaIndex", message.id) + } + } + }, + pushSubscriptionProvider = pushSubscriptionProvider, + customCodeHandler = customCodeHandler, + ) + uiController = InAppUIController(application, manager, displayer, config.isDebug) + + sdkScope.launch { + manager.initialize() + } + uiController.start() + + autoCleanupManager = + AutoCleanupManager( + application = application, + cleanupCallback = { cleanup() }, + ) + autoCleanupManager?.start() + } + + /** + * Cleans up resources used by the SDK + * This is called automatically after app is in background for a prolonged period, + * but can also be called manually from app's onDestroy() + */ + private fun cleanup() { + // Stop the auto-cleanup manager + autoCleanupManager?.stop() + autoCleanupManager = null + + uiController.stop() + displayer.cancelPendingMessages() + sdkScope.cancel() + } + + /** + * Shows all in-app messages that should be displayed automatically: + * - If currentRoute is null: shows all messages with trigger.type == APP_OPEN + * - If currentRoute is not null: shows all messages with trigger.type == ROUTE and trigger.route == currentRoute, and all with trigger.type == APP_OPEN + * + * Call this once on app start (with currentRoute = null), + * and on route/view change (with currentRoute = route name). + */ + fun showMessagesOnRoute(route: Route) { + sdkScope.launch { + manager.refreshActiveMessages(route) + } + } + + /** + * Shows in-app messages for a custom trigger. + * Only messages with trigger.type == CUSTOM_TRIGGER and matching key and value will be shown. + * Also doesn't cancel pending messages for APP_OPEN trigger. + */ + fun showMessagesOnTrigger(trigger: Trigger) { + sdkScope.launch { + val messageToShow = manager.trigger(trigger.key, trigger.value) + + if (messageToShow != null) { + uiController.displayCustomMessage(messageToShow) + } + } + } +} diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/data/event/InAppMessageEvent.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/event/InAppMessageEvent.kt similarity index 76% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/data/event/InAppMessageEvent.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/event/InAppMessageEvent.kt index 4dcd5442..de54f116 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/data/event/InAppMessageEvent.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/event/InAppMessageEvent.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.data.event +package com.pushpushgo.sdk.inapp.event import com.squareup.moshi.JsonClass diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/data/event/InAppMessageEventRepository.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/event/InAppMessageEventRepository.kt similarity index 72% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/data/event/InAppMessageEventRepository.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/event/InAppMessageEventRepository.kt index 60380dc2..b22ceb8c 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/data/event/InAppMessageEventRepository.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/event/InAppMessageEventRepository.kt @@ -1,7 +1,8 @@ -package com.pushpushgo.inappmessages.data.event +package com.pushpushgo.sdk.inapp.event import android.util.Log -import com.pushpushgo.inappmessages.network.InAppEventApi +import com.pushpushgo.sdk.inapp.InAppMessages +import com.pushpushgo.sdk.inapp.network.InAppEventApi import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -20,8 +21,9 @@ internal class InAppMessageEventRepository( val response = api.sendInAppEvent(token, projectId, event) if (!response.isSuccessful) { if (debug) { - Log.e("InAppEventRepo", "Failed to send event: ${response.code()} ${response.message()}") + Log.e(InAppMessages.TAG, "[EventRepository] Failed to send event: ${response.code()} ${response.message()}") } + throw HttpException(response) } } diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/manager/InAppMessageManager.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/manager/InAppMessageManager.kt similarity index 62% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/manager/InAppMessageManager.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/manager/InAppMessageManager.kt index e6dd7038..0c2d9f2f 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/manager/InAppMessageManager.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/manager/InAppMessageManager.kt @@ -1,6 +1,7 @@ -package com.pushpushgo.inappmessages.manager +package com.pushpushgo.sdk.inapp.manager -import com.pushpushgo.inappmessages.model.InAppMessage +import com.pushpushgo.sdk.inapp.model.InAppMessage +import com.pushpushgo.sdk.inapp.ui.Route import kotlinx.coroutines.flow.Flow internal interface InAppMessageManager { @@ -15,7 +16,9 @@ internal interface InAppMessageManager { fun getActiveMessages(): List - suspend fun refreshActiveMessages(route: String? = null) + fun getRoute(): Route? + + suspend fun refreshActiveMessages(route: Route?) suspend fun isMessageEligible(message: InAppMessage): Boolean } diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/manager/InAppMessageManagerImpl.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/manager/InAppMessageManagerImpl.kt similarity index 71% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/manager/InAppMessageManagerImpl.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/manager/InAppMessageManagerImpl.kt index 0b30793c..f3740aed 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/manager/InAppMessageManagerImpl.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/manager/InAppMessageManagerImpl.kt @@ -1,17 +1,21 @@ -package com.pushpushgo.inappmessages.manager +package com.pushpushgo.sdk.inapp.manager import android.content.Context import android.util.Log -import com.pushpushgo.inappmessages.model.DeviceType -import com.pushpushgo.inappmessages.model.InAppMessage -import com.pushpushgo.inappmessages.model.OSType -import com.pushpushgo.inappmessages.model.PlatformType -import com.pushpushgo.inappmessages.model.ShowAgainType -import com.pushpushgo.inappmessages.model.TriggerType -import com.pushpushgo.inappmessages.persistence.InAppMessagePersistence -import com.pushpushgo.inappmessages.repository.InAppMessageRepository -import com.pushpushgo.inappmessages.utils.DeviceInfoProvider -import com.pushpushgo.inappmessages.utils.PushNotificationStatusProvider +import com.pushpushgo.sdk.core.push.NotificationPermissionProvider +import com.pushpushgo.sdk.core.push.PushSubscriptionProvider +import com.pushpushgo.sdk.inapp.InAppMessages +import com.pushpushgo.sdk.inapp.model.DeviceType +import com.pushpushgo.sdk.inapp.model.InAppMessage +import com.pushpushgo.sdk.inapp.model.OSType +import com.pushpushgo.sdk.inapp.model.PlatformType +import com.pushpushgo.sdk.inapp.model.ShowAgainType +import com.pushpushgo.sdk.inapp.model.TriggerType +import com.pushpushgo.sdk.inapp.model.UserAudienceType +import com.pushpushgo.sdk.inapp.persistence.InAppMessagePersistence +import com.pushpushgo.sdk.inapp.repository.InAppMessageRepository +import com.pushpushgo.sdk.inapp.ui.Route +import com.pushpushgo.sdk.inapp.utils.DeviceInfoProvider import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -33,12 +37,8 @@ internal class InAppMessageManagerImpl( private val persistence: InAppMessagePersistence, private val context: Context, private val debug: Boolean = false, + private val pushSubscriptionProvider: PushSubscriptionProvider? = null, ) : InAppMessageManager { - // Provider for accessing push notification subscription status - private val notificationStatusProvider = PushNotificationStatusProvider(context) - - private val tag = "InAppMessageManager" - // Schedule refresh configuration private var scheduleRefreshJob: Job? = null private val scheduleRefreshInterval = 60_000L // Check schedules every minute @@ -52,7 +52,7 @@ internal class InAppMessageManagerImpl( @Volatile private var refreshJob: Job? = null - private var currentRoute: String? = null + private var currentRoute: Route? = null // Mutex to ensure atomic updates to activeMessages from refresh and trigger operations private val messagesUpdateMutex = Mutex() @@ -65,25 +65,21 @@ internal class InAppMessageManagerImpl( override suspend fun initialize() { try { if (debug) { - Log.d(tag, "Initializing InAppMessageManager...") + Log.d(InAppMessages.TAG, "[Manager] Initializing...") } // Fetch messages from API (with cache support) refreshMessagesFromApi() - // Build trigger map and refresh active messages - buildTriggerMap(allMessages) - refreshActiveMessages() - // Start periodic schedule checks startScheduleRefresh() if (debug) { - Log.d(tag, "InAppMessageManager initialized successfully") + Log.d(InAppMessages.TAG, "[Manager] initialized successfully") } } catch (e: Exception) { if (e is CancellationException) throw e - Log.e(tag, "Error initializing InAppMessageManager: ${e.message}", e) + Log.e(InAppMessages.TAG, "[Manager] Error initializing: ${e.message}", e) } } @@ -99,7 +95,7 @@ internal class InAppMessageManagerImpl( } if (debug) { - Log.d(tag, "Fetched ${messages.size} messages from API") + Log.d(InAppMessages.TAG, "[Manager] Fetched ${messages.size} messages from API") } // Update collections @@ -110,7 +106,7 @@ internal class InAppMessageManagerImpl( buildTriggerMap(messages) } catch (e: Exception) { if (e is CancellationException) throw e - Log.e(tag, "Error refreshing messages from API: ${e.message}", e) + Log.e(InAppMessages.TAG, "[Manager] śError refreshing messages from API: ${e.message}", e) } } @@ -133,7 +129,7 @@ internal class InAppMessageManagerImpl( // Don't block on refresh, just log and continue if there's an error try { if (debug) { - Log.d(tag, "Periodic refresh: fetching messages from API...") + Log.d(InAppMessages.TAG, "[Manager] Periodic refresh: fetching messages from API...") } // Refresh messages from API (with cache support via If-None-Match) @@ -142,11 +138,11 @@ internal class InAppMessageManagerImpl( // Then refresh active messages based on updated data refreshActiveMessages(currentRoute) } catch (e: Exception) { - Log.e(tag, "Error during periodic schedule refresh: ${e.message}") + Log.e(InAppMessages.TAG, "[Manager] Error during periodic schedule refresh: ${e.message}") } } } catch (e: Exception) { - Log.e(tag, "Schedule refresh job failed: ${e.message}") + Log.e(InAppMessages.TAG, "[Manager] Schedule refresh job failed: ${e.message}") } } } @@ -184,7 +180,7 @@ internal class InAppMessageManagerImpl( // 0. Check if message is enabled if (!message.enabled) { if (debug) { - Log.d(tag, "Message [${message.id}] is disabled - not eligible") + Log.d(InAppMessages.TAG, "[Manager] Message [${message.id}] is disabled - not eligible") } return@withContext false } @@ -196,7 +192,7 @@ internal class InAppMessageManagerImpl( ) ) { if (debug) { - Log.d(tag, "Message [${message.id}] permanently dismissed - not eligible") + Log.d(InAppMessages.TAG, "[Manager] Message [${message.id}] permanently dismissed - not eligible") } return@withContext false } @@ -204,17 +200,17 @@ internal class InAppMessageManagerImpl( // 2. Check schedule window (absolute check) if (!isInScheduleWindow(message)) { if (debug) { - Log.d(tag, "Message [${message.id}] outside schedule window - not eligible") + Log.d(InAppMessages.TAG, "[Manager] Message [${message.id}] outside schedule window - not eligible") } return@withContext false } // 3. Check user audience type - if (!notificationStatusProvider.matchesAudienceType(message.audience.userType)) { + if (!userMatchesAudienceType(message.audience.userType)) { if (debug) { Log.d( - tag, - "Message [${message.id}] audience mismatch (${message.audience.userType}) - not eligible", + InAppMessages.TAG, + "[Manager] Message [${message.id}] audience mismatch (${message.audience.userType}) - not eligible", ) } return@withContext false @@ -236,8 +232,8 @@ internal class InAppMessageManagerImpl( if (elapsedSinceLastDismissal < requiredCooldownMs) { if (debug) { Log.d( - tag, - "Message [${message.id}] in cooldown: ${elapsedSinceLastDismissal}ms/${requiredCooldownMs}ms", + InAppMessages.TAG, + "[Manager] Message [${message.id}] in cooldown: ${elapsedSinceLastDismissal}ms/${requiredCooldownMs}ms", ) } return@withContext false // Still in cooldown since last dismissal @@ -248,60 +244,47 @@ internal class InAppMessageManagerImpl( return@withContext true } - /** - * Refresh the list of active messages based on current conditions - * Filters messages by eligibility, schedule, device type, OS type, and expiration - */ - override suspend fun refreshActiveMessages(route: String?) { + override suspend fun refreshActiveMessages(route: Route?) { // If a new route is explicitly provided (on navigation), update the manager's internal state. - if (route != null) { - this.currentRoute = route - } - - // The route to use for this specific refresh operation is the one passed in, - // or the one we have stored if the call is for a generic refresh (e.g., on dismissal). - val effectiveRoute = route ?: this.currentRoute + this.currentRoute = route val newJob = scope.launch(Dispatchers.IO) { try { if (debug) { - Log.d(tag, "Refreshing active messages for route: ${effectiveRoute ?: "ENTER"}") + Log.d(InAppMessages.TAG, "[Manager] Refreshing active messages for route: ${route?.name}") } val eventBasedMessages = - allMessages.filter { msg -> - // CUSTOM_TRIGGER triggers are handled by the `trigger` method, not by general refresh. - if (msg.settings.triggerType == TriggerType.CUSTOM_TRIGGER) { - return@filter false - } - - val displayOnRules = msg.settings.displayOn + if (route != null) { + allMessages.filter { msg -> + // CUSTOM_TRIGGER triggers are handled by the `trigger` method, not by general refresh. + if (msg.settings.triggerType == TriggerType.CUSTOM_TRIGGER) { + return@filter false + } - if (displayOnRules.isEmpty()) { - return@filter true - } + val displayOnRules = msg.settings.displayOn - // Specific route rules exist. The message should only appear on these routes. + if (displayOnRules.isEmpty()) { + return@filter true + } - if (effectiveRoute == null) { - // If we're not on a specific route, don't show route-specific messages. - return@filter false - } + val (displayed, hidden) = displayOnRules.partition { it.display } + val isDisplayed = displayed.any { it.path == route.name } + val isHidden = hidden.any { it.path == route.name } - val (displayed, hidden) = displayOnRules.partition { it.display } - val isDisplayed = displayed.any { it.path == effectiveRoute } - val isHidden = hidden.any { it.path == effectiveRoute } + if (displayed.isEmpty() && !isHidden) { + return@filter true + } - if (displayed.isEmpty() && !isHidden) { - return@filter true - } + if (isDisplayed && !isHidden) { + return@filter true + } - if (isDisplayed && !isHidden) { - return@filter true + false } - - false + } else { + emptyList() } val initiallyFiltered = @@ -347,11 +330,11 @@ internal class InAppMessageManagerImpl( _messagesFlow.value = activeMessages.toList() if (debug) { - Log.d(tag, "Active messages refreshed: ${newActiveMessages.size} eligible messages") + Log.d(InAppMessages.TAG, "[Manager] Active messages refreshed: ${newActiveMessages.size} eligible messages") } } } catch (e: Exception) { - Log.e(tag, "Error refreshing active messages for route: ${effectiveRoute ?: "ENTER"}", e) + Log.e(InAppMessages.TAG, "[Manager] Error refreshing active messages for route: ${route?.name}", e) } } @@ -376,7 +359,7 @@ internal class InAppMessageManagerImpl( jobToWaitFor?.join() if (debug) { - Log.d(tag, "Triggering custom message: key='$key', value='$value'") + Log.d(InAppMessages.TAG, "[Manager] Triggering custom message: key='$key', value='$value'") } val potentialMessages = @@ -391,7 +374,7 @@ internal class InAppMessageManagerImpl( if (potentialMessages.isEmpty()) { if (debug) { - Log.d(tag, "No messages found for trigger key='$key', value='$value'") + Log.d(InAppMessages.TAG, "[Manager] No messages found for trigger key='$key', value='$value'") } return null } @@ -410,7 +393,7 @@ internal class InAppMessageManagerImpl( persistence.setFirstEligibleAt(msg.id, System.currentTimeMillis()) } if (debug) { - Log.d(tag, "Found eligible message [${msg.id}] for trigger '$key'") + Log.d(InAppMessages.TAG, "[Manager] Found eligible message [${msg.id}] for trigger '$key'") } return msg } @@ -443,6 +426,19 @@ internal class InAppMessageManagerImpl( return@withContext isInWindow } + private fun userMatchesAudienceType(audienceType: UserAudienceType): Boolean { + val isSubscribed = pushSubscriptionProvider?.isSubscribed() ?: false + val canPostNotifications = NotificationPermissionProvider.canPostNotifications(context) + val isNotificationChannelEnabled = pushSubscriptionProvider?.isNotificationChannelEnabled() ?: false + + return when (audienceType) { + UserAudienceType.ALL -> true + UserAudienceType.SUBSCRIBER -> isSubscribed && canPostNotifications && isNotificationChannelEnabled + UserAudienceType.NON_SUBSCRIBER -> !isSubscribed || !canPostNotifications || !isNotificationChannelEnabled + UserAudienceType.NOTIFICATIONS_BLOCKED -> !canPostNotifications || !isNotificationChannelEnabled + } + } + /** * Get the current list of active messages * This method returns the cached list of active messages from the most recent refresh @@ -451,4 +447,6 @@ internal class InAppMessageManagerImpl( * @return List of active messages that are eligible to be shown */ override fun getActiveMessages(): List = activeMessages.toList() + + override fun getRoute(): Route? = currentRoute } diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/Alignment.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/Alignment.kt similarity index 86% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/Alignment.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/Alignment.kt index 894b722e..d648a5b8 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/Alignment.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/Alignment.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/AnimationType.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/AnimationType.kt similarity index 83% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/AnimationType.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/AnimationType.kt index aef382d5..3c6e8009 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/AnimationType.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/AnimationType.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/DisplayOn.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/DisplayOn.kt similarity index 88% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/DisplayOn.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/DisplayOn.kt index cb59a2fe..890b83e2 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/DisplayOn.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/DisplayOn.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/DisplayType.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/DisplayType.kt similarity index 83% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/DisplayType.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/DisplayType.kt index 7d11aa4c..19755a00 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/DisplayType.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/DisplayType.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/FontFamily.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/FontFamily.kt similarity index 92% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/FontFamily.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/FontFamily.kt index 67e4b45e..71e6aad7 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/FontFamily.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/FontFamily.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/FontStyle.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/FontStyle.kt similarity index 86% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/FontStyle.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/FontStyle.kt index fccab4e2..7a0d062e 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/FontStyle.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/FontStyle.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppActionType.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppActionType.kt similarity index 87% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppActionType.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppActionType.kt index b2b6d1c4..70510e45 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppActionType.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppActionType.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessage.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessage.kt similarity index 98% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessage.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessage.kt index a0cfbd68..e1cffeda 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessage.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessage.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageAction.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageAction.kt similarity index 95% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageAction.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageAction.kt index 1b49e69b..fce7938f 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageAction.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageAction.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageAudience.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageAudience.kt similarity index 92% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageAudience.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageAudience.kt index c828f9e5..7f340dbe 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageAudience.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageAudience.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageDescription.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageDescription.kt similarity index 92% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageDescription.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageDescription.kt index 39b989d9..fed23c0d 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageDescription.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageDescription.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageImage.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageImage.kt similarity index 88% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageImage.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageImage.kt index dd32f019..4c36ef8f 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageImage.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageImage.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageLayout.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageLayout.kt similarity index 94% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageLayout.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageLayout.kt index c9a82ded..1a4d083a 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageLayout.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageLayout.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageSettings.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageSettings.kt similarity index 95% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageSettings.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageSettings.kt index cab9a1f5..56c325bb 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageSettings.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageSettings.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageStyle.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageStyle.kt similarity index 95% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageStyle.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageStyle.kt index c4348c21..204ee4c6 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageStyle.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageStyle.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageTitle.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageTitle.kt similarity index 92% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageTitle.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageTitle.kt index 53375d42..2fe920f0 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/InAppMessageTitle.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/InAppMessageTitle.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/Placement.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/Placement.kt similarity index 91% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/Placement.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/Placement.kt index 55a33fb9..b54adb6c 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/Placement.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/Placement.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/ShowAgainType.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/ShowAgainType.kt similarity index 84% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/ShowAgainType.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/ShowAgainType.kt index 703f8532..81bb7b9c 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/ShowAgainType.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/ShowAgainType.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/TargetType.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/TargetType.kt similarity index 82% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/TargetType.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/TargetType.kt index 1c980e96..94756c3a 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/TargetType.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/TargetType.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.model +package com.pushpushgo.sdk.inapp.model import com.squareup.moshi.Json diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/network/InAppMessagesResponse.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/network/InAppMessagesResponse.kt similarity index 77% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/network/InAppMessagesResponse.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/model/network/InAppMessagesResponse.kt index c8e8af35..fe5da43b 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/model/network/InAppMessagesResponse.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/model/network/InAppMessagesResponse.kt @@ -1,6 +1,6 @@ -package com.pushpushgo.inappmessages.model.network +package com.pushpushgo.sdk.inapp.model.network -import com.pushpushgo.inappmessages.model.InAppMessage +import com.pushpushgo.sdk.inapp.model.InAppMessage import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/network/InAppApi.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/network/InAppApi.kt similarity index 83% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/network/InAppApi.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/network/InAppApi.kt index d575f918..0ca1d14a 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/network/InAppApi.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/network/InAppApi.kt @@ -1,7 +1,7 @@ -package com.pushpushgo.inappmessages.network +package com.pushpushgo.sdk.inapp.network -import com.pushpushgo.inappmessages.data.event.InAppMessageEvent -import com.pushpushgo.inappmessages.model.network.InAppMessagesResponse +import com.pushpushgo.sdk.inapp.event.InAppMessageEvent +import com.pushpushgo.sdk.inapp.model.network.InAppMessagesResponse import retrofit2.Response import retrofit2.http.Body import retrofit2.http.GET diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/network/RetrofitProvider.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/network/RetrofitProvider.kt similarity index 84% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/network/RetrofitProvider.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/network/RetrofitProvider.kt index 5928f9c5..06876953 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/network/RetrofitProvider.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/network/RetrofitProvider.kt @@ -1,6 +1,6 @@ -package com.pushpushgo.inappmessages.network +package com.pushpushgo.sdk.inapp.network -import com.pushpushgo.inappmessages.utils.ZonedDateTimeAdapter +import com.pushpushgo.sdk.inapp.utils.ZonedDateTimeAdapter import com.squareup.moshi.Moshi import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import okhttp3.OkHttpClient @@ -22,7 +22,7 @@ internal object RetrofitProvider { val moshi = Moshi .Builder() - .add(ZonedDateTimeAdapter.FACTORY) + .add(ZonedDateTimeAdapter.Companion.FACTORY) .add(KotlinJsonAdapterFactory()) .build() diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/persistence/InAppMessagePersistence.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/persistence/InAppMessagePersistence.kt similarity index 88% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/persistence/InAppMessagePersistence.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/persistence/InAppMessagePersistence.kt index 2554fdd1..82b02d40 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/persistence/InAppMessagePersistence.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/persistence/InAppMessagePersistence.kt @@ -1,6 +1,6 @@ -package com.pushpushgo.inappmessages.persistence +package com.pushpushgo.sdk.inapp.persistence -import com.pushpushgo.inappmessages.model.InAppMessage +import com.pushpushgo.sdk.inapp.model.InAppMessage internal interface InAppMessagePersistence { fun isMessageDismissed(messageId: String): Boolean diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/persistence/InAppMessagePersistenceImpl.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/persistence/InAppMessagePersistenceImpl.kt similarity index 81% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/persistence/InAppMessagePersistenceImpl.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/persistence/InAppMessagePersistenceImpl.kt index 0a00c27c..c9602d30 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/persistence/InAppMessagePersistenceImpl.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/persistence/InAppMessagePersistenceImpl.kt @@ -1,11 +1,12 @@ -package com.pushpushgo.inappmessages.persistence +package com.pushpushgo.sdk.inapp.persistence import android.content.Context import android.content.SharedPreferences import android.util.Log import androidx.core.content.edit -import com.pushpushgo.inappmessages.model.InAppMessage -import com.pushpushgo.inappmessages.utils.ZonedDateTimeAdapter +import com.pushpushgo.sdk.inapp.InAppMessages +import com.pushpushgo.sdk.inapp.model.InAppMessage +import com.pushpushgo.sdk.inapp.utils.ZonedDateTimeAdapter import com.squareup.moshi.JsonAdapter import com.squareup.moshi.Moshi import com.squareup.moshi.Types @@ -17,7 +18,7 @@ internal class InAppMessagePersistenceImpl( private val moshi: Moshi = Moshi .Builder() - .add(ZonedDateTimeAdapter.FACTORY) + .add(ZonedDateTimeAdapter.Companion.FACTORY) .addLast(KotlinJsonAdapterFactory()) .build(), ) : InAppMessagePersistence { @@ -28,7 +29,6 @@ internal class InAppMessagePersistenceImpl( private val messagesAdapter: JsonAdapter> = moshi.adapter(listType) companion object { - private const val TAG = "InAppMsgPersistence" private const val KEY_ETAG = "etag" private const val KEY_CACHED_MESSAGES = "cached_messages" private const val KEY_CACHE_TIMESTAMP = "cache_timestamp" @@ -41,7 +41,7 @@ internal class InAppMessagePersistenceImpl( override fun markMessageDismissed(messageId: String) { if (debug) { - Log.d(TAG, "Marking message [$messageId] as dismissed") + Log.d(InAppMessages.TAG, "[Persistence] Marking message [$messageId] as dismissed") } prefs.edit { putBoolean("dismissed_$messageId", true) } setLastDismissedAt(messageId, System.currentTimeMillis()) @@ -87,14 +87,14 @@ internal class InAppMessagePersistenceImpl( return if (isExpired) { // Cache expired - clear and return null to force fresh fetch if (debug) { - Log.d(TAG, "Cache expired, clearing and forcing fresh fetch") + Log.d(InAppMessages.TAG, "[Persistence] Cache expired, clearing and forcing fresh fetch") } clearCache() null } else { val etag = prefs.getString(KEY_ETAG, null) if (debug) { - Log.d(TAG, "Retrieved stored ETag: ${etag ?: "none"}") + Log.d(InAppMessages.TAG, "[Persistence] Retrieved stored ETag: ${etag ?: "none"}") } etag } @@ -106,7 +106,7 @@ internal class InAppMessagePersistenceImpl( ) { val messagesJson = messagesAdapter.toJson(messages) if (debug) { - Log.d(TAG, "Saving cache: ETag=$etag, ${messages.size} messages") + Log.d(InAppMessages.TAG, "[Persistence] Saving cache: ETag=$etag, ${messages.size} messages") } prefs.edit { @@ -122,13 +122,13 @@ internal class InAppMessagePersistenceImpl( return try { val messages = messagesAdapter.fromJson(messagesJson) ?: emptyList() if (debug) { - Log.d(TAG, "Retrieved ${messages.size} cached messages") + Log.d(InAppMessages.TAG, "[Persistence] Retrieved ${messages.size} cached messages") } messages } catch (_: Exception) { // JSON parsing failed - clear cache and return null if (debug) { - Log.d(TAG, "Failed to parse cached messages, clearing cache") + Log.d(InAppMessages.TAG, "[Persistence] Failed to parse cached messages, clearing cache") } clearCache() null @@ -137,7 +137,7 @@ internal class InAppMessagePersistenceImpl( override fun clearCache() { if (debug) { - Log.d(TAG, "Clearing cache") + Log.d(InAppMessages.TAG, "[Persistence] Clearing cache") } prefs.edit { remove(KEY_ETAG) diff --git a/inapp/src/main/java/com/pushpushgo/sdk/inapp/repository/InAppMessageRepository.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/repository/InAppMessageRepository.kt new file mode 100644 index 00000000..aed72aec --- /dev/null +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/repository/InAppMessageRepository.kt @@ -0,0 +1,7 @@ +package com.pushpushgo.sdk.inapp.repository + +import com.pushpushgo.sdk.inapp.model.InAppMessage + +internal interface InAppMessageRepository { + suspend fun fetchMessages(): List +} diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/repository/InAppMessageRepositoryImpl.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/repository/InAppMessageRepositoryImpl.kt similarity index 65% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/repository/InAppMessageRepositoryImpl.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/repository/InAppMessageRepositoryImpl.kt index 104ce39f..889e97bc 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/repository/InAppMessageRepositoryImpl.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/repository/InAppMessageRepositoryImpl.kt @@ -1,9 +1,10 @@ -package com.pushpushgo.inappmessages.repository +package com.pushpushgo.sdk.inapp.repository import android.util.Log -import com.pushpushgo.inappmessages.model.InAppMessage -import com.pushpushgo.inappmessages.network.InAppListGetApi -import com.pushpushgo.inappmessages.persistence.InAppMessagePersistence +import com.pushpushgo.sdk.inapp.InAppMessages +import com.pushpushgo.sdk.inapp.model.InAppMessage +import com.pushpushgo.sdk.inapp.network.InAppListGetApi +import com.pushpushgo.sdk.inapp.persistence.InAppMessagePersistence import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -14,10 +15,6 @@ internal class InAppMessageRepositoryImpl( private val persistence: InAppMessagePersistence, private val debug: Boolean = false, ) : InAppMessageRepository { - companion object { - private const val TAG = "InAppMsgRepo" - } - override suspend fun fetchMessages(): List = try { withContext(Dispatchers.IO) { @@ -35,18 +32,18 @@ internal class InAppMessageRepositoryImpl( // Fresh data received val messages = response.body()?.data ?: emptyList() if (debug) { - Log.d(TAG, "Received fresh data: ${messages.size} messages") + Log.d(InAppMessages.TAG, "[Repository] Received fresh data: ${messages.size} messages") } // Save ETag and cache the payload val newETag = response.headers()["ETag"] if (newETag != null) { if (debug) { - Log.d(TAG, "Saving cache with ETag: $newETag") + Log.d(InAppMessages.TAG, "[Repository] Saving cache with ETag: $newETag") } persistence.saveCache(newETag, messages) } else { - Log.w(TAG, "No ETag header in response") + Log.w(InAppMessages.TAG, "[Repository] No ETag header in response") } messages @@ -55,33 +52,33 @@ internal class InAppMessageRepositoryImpl( 304 -> { // Data not modified - use cached messages if (debug) { - Log.d(TAG, "Received 304 Not Modified, using cached messages") + Log.d(InAppMessages.TAG, "[Repository] Received 304 Not Modified, using cached messages") } val cachedMessages = persistence.getCachedMessages() if (cachedMessages != null) { cachedMessages } else { - Log.w(TAG, "304 response but no cached messages found - clearing cache") + Log.w(InAppMessages.TAG, "[Repository] 304 response but no cached messages found - clearing cache") persistence.clearCache() emptyList() } } else -> { - Log.e(TAG, "Error fetching messages from API: ${response.code()}") + Log.e(InAppMessages.TAG, "[Repository] Error fetching messages from API: ${response.code()}") // On error, try to return cached messages if available val cachedMessages = persistence.getCachedMessages() if (debug && cachedMessages != null) { - Log.d(TAG, "API error, falling back to ${cachedMessages.size} cached messages") + Log.d(InAppMessages.TAG, "[Repository] API error, falling back to ${cachedMessages.size} cached messages") } cachedMessages ?: emptyList() } } } } catch (e: Exception) { - Log.e(TAG, "Exception fetching messages from API", e) + Log.e(InAppMessages.TAG, "[Repository] Exception fetching messages from API", e) // On network error, try to return cached messages if available val cachedMessages = persistence.getCachedMessages() diff --git a/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/CustomCodeHandler.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/CustomCodeHandler.kt new file mode 100644 index 00000000..092a057f --- /dev/null +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/CustomCodeHandler.kt @@ -0,0 +1,5 @@ +package com.pushpushgo.sdk.inapp.ui + +interface CustomCodeHandler { + fun handle(code: String) +} diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/InAppMessageDisplayer.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/InAppMessageDisplayer.kt similarity index 73% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/InAppMessageDisplayer.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/InAppMessageDisplayer.kt index 2cd46806..9522f7f5 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/InAppMessageDisplayer.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/InAppMessageDisplayer.kt @@ -1,7 +1,7 @@ -package com.pushpushgo.inappmessages.ui +package com.pushpushgo.sdk.inapp.ui import android.app.Activity -import com.pushpushgo.inappmessages.model.InAppMessage +import com.pushpushgo.sdk.inapp.model.InAppMessage internal interface InAppMessageDisplayer { fun showMessage( diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/InAppMessageDisplayerImpl.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/InAppMessageDisplayerImpl.kt similarity index 79% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/InAppMessageDisplayerImpl.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/InAppMessageDisplayerImpl.kt index 60cf7633..a3967267 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/InAppMessageDisplayerImpl.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/InAppMessageDisplayerImpl.kt @@ -1,9 +1,10 @@ -package com.pushpushgo.inappmessages.ui +package com.pushpushgo.sdk.inapp.ui import android.app.Activity import android.app.Dialog import android.content.Context import android.content.Intent +import android.graphics.Color import android.util.Log import android.view.Gravity import android.view.ViewGroup @@ -12,21 +13,23 @@ import android.widget.Toast import androidx.compose.ui.platform.ComposeView import androidx.core.graphics.drawable.toDrawable import androidx.core.net.toUri +import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.setViewTreeLifecycleOwner +import androidx.savedstate.SavedStateRegistryOwner import androidx.savedstate.setViewTreeSavedStateRegistryOwner -import com.pushpushgo.inappmessages.R -import com.pushpushgo.inappmessages.model.AnimationType -import com.pushpushgo.inappmessages.model.InAppActionType -import com.pushpushgo.inappmessages.model.InAppMessage -import com.pushpushgo.inappmessages.model.InAppMessageAction -import com.pushpushgo.inappmessages.model.ShowAgainType -import com.pushpushgo.inappmessages.persistence.InAppMessagePersistence -import com.pushpushgo.inappmessages.ui.composables.templates.InAppMessageDefaultTemplate -import com.pushpushgo.inappmessages.ui.composables.templates.TemplateBannerMessage -import com.pushpushgo.inappmessages.ui.composables.templates.TemplateReviewForDiscount -import com.pushpushgo.inappmessages.ui.composables.templates.TemplateRichMessage -import com.pushpushgo.inappmessages.utils.DefaultPushNotificationSubscriber -import com.pushpushgo.inappmessages.utils.PushNotificationSubscriber +import com.pushpushgo.sdk.core.push.PushSubscriptionProvider +import com.pushpushgo.sdk.inapp.InAppMessages +import com.pushpushgo.sdk.inapp.R +import com.pushpushgo.sdk.inapp.model.AnimationType +import com.pushpushgo.sdk.inapp.model.InAppActionType +import com.pushpushgo.sdk.inapp.model.InAppMessage +import com.pushpushgo.sdk.inapp.model.InAppMessageAction +import com.pushpushgo.sdk.inapp.model.ShowAgainType +import com.pushpushgo.sdk.inapp.persistence.InAppMessagePersistence +import com.pushpushgo.sdk.inapp.ui.composables.templates.InAppMessageDefaultTemplate +import com.pushpushgo.sdk.inapp.ui.composables.templates.TemplateBannerMessage +import com.pushpushgo.sdk.inapp.ui.composables.templates.TemplateReviewForDiscount +import com.pushpushgo.sdk.inapp.ui.composables.templates.TemplateRichMessage import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -34,6 +37,7 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import java.lang.ref.WeakReference import java.util.concurrent.CancellationException @@ -44,12 +48,10 @@ internal class InAppMessageDisplayerImpl( private val debug: Boolean = false, private val onMessageDismissed: () -> Unit, private val onMessageEvent: (eventType: String, message: InAppMessage, ctaIndex: Int?) -> Unit = { _, _, _ -> }, - private var onJsAction: ((jsCall: String) -> Unit)? = null, - private var subscriptionHandler: PushNotificationSubscriber = DefaultPushNotificationSubscriber(), + private val pushSubscriptionProvider: PushSubscriptionProvider? = null, + private val customCodeHandler: CustomCodeHandler? = null, ) : InAppMessageDisplayer, CoroutineScope { - private val tag = "InAppMsgDisplayer" - // Coroutine context and job for managing message display jobs private val job = SupervisorJob() override val coroutineContext: CoroutineContext @@ -76,7 +78,7 @@ internal class InAppMessageDisplayerImpl( if (delaySec > 0) { val delayMs = delaySec * 1000L if (debug) { - Log.d(tag, "Scheduling message [${message.id}] with ${delayMs}ms delay") + Log.d(InAppMessages.TAG, "[Displayer] Scheduling message [${message.id}] with ${delayMs}ms delay") } val activityRef = WeakReference(activity) @@ -103,11 +105,11 @@ internal class InAppMessageDisplayerImpl( } catch (t: Throwable) { if (t is CancellationException) { if (debug) { - Log.d(tag, "Message [${message.id}] display cancelled") + Log.d(InAppMessages.TAG, "[Displayer] Message [${message.id}] display cancelled") } throw t } - Log.e(tag, "Failed to display message ${message.id}", t) + Log.e(InAppMessages.TAG, "[Displayer] Failed to display message ${message.id}", t) } finally { // Always remove the job from the map when it's done. // This check prevents a race condition where a new job for the same ID is added @@ -120,7 +122,7 @@ internal class InAppMessageDisplayerImpl( pendingMessageJobs[message.id] = message to newJob } else { if (debug) { - Log.d(tag, "Showing message [${message.id}] immediately") + Log.d(InAppMessages.TAG, "[Displayer] Showing message [${message.id}] immediately") } launch { if (shouldBeDisplayed(message)) { @@ -152,7 +154,7 @@ internal class InAppMessageDisplayerImpl( -> R.style.InAppMessageDialog_Banner else -> { - Log.w(tag, "Unsupported template: ${message.template}, no container style defined.") + Log.w(InAppMessages.TAG, "[Displayer] Unsupported template: ${message.template}, no container style defined.") null } } @@ -167,7 +169,10 @@ internal class InAppMessageDisplayerImpl( return } if (debug) { - Log.d(tag, "Cancelling ${pendingMessageJobs.size} pending message jobs (activity paused: $isActivityPaused)") + Log.d( + InAppMessages.TAG, + "[Displayer] Cancelling ${pendingMessageJobs.size} pending message jobs (activity paused: $isActivityPaused)", + ) } // Create a copy of the values to avoid ConcurrentModificationException @@ -189,7 +194,7 @@ internal class InAppMessageDisplayerImpl( override fun dismissMessage(message: InAppMessage) { if (debug) { - Log.d(tag, "Dismissing message [${message.id}]") + Log.d(InAppMessages.TAG, "[Displayer] Dismissing message [${message.id}]") } dismissMessageInternal(message, sendCloseEvent = true) } @@ -260,7 +265,7 @@ internal class InAppMessageDisplayerImpl( // Handle overlay property - set window background explicitly based on overlay setting window?.setBackgroundDrawable( - android.graphics.Color.TRANSPARENT + Color.TRANSPARENT .toDrawable(), ) @@ -323,8 +328,8 @@ internal class InAppMessageDisplayerImpl( // This is crucial for Jetpack Compose to work correctly in a Dialog or any view // that is not directly part of the Activity's main content view, as it allows // the composable to observe LiveData, use ViewModels, and save instance state. - setViewTreeLifecycleOwner(activity as? androidx.lifecycle.LifecycleOwner) - setViewTreeSavedStateRegistryOwner(activity as? androidx.savedstate.SavedStateRegistryOwner) + setViewTreeLifecycleOwner(activity as? LifecycleOwner) + setViewTreeSavedStateRegistryOwner(activity as? SavedStateRegistryOwner) layoutParams = FrameLayout @@ -385,26 +390,6 @@ internal class InAppMessageDisplayerImpl( } } - /** - * Sets a handler for code from actions. - * This method allows updating the code action handler after initialization. - * - * @param handler Function that takes button action code string and processes it - */ - internal fun setJsActionHandler(handler: (jsCall: String) -> Unit) { - this.onJsAction = handler - } - - /** - * Sets a handler for subscription requests. - * This will be called when a SUBSCRIBE action button is clicked. - * - * @param handler The PushNotificationSubscriber implementation - */ - internal fun setSubscriptionHandler(handler: PushNotificationSubscriber) { - this.subscriptionHandler = handler - } - private fun handleAction( context: Context, action: InAppMessageAction, @@ -418,25 +403,26 @@ internal class InAppMessageDisplayerImpl( addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }, ) - } ?: Log.e(tag, "URL is null or empty in REDIRECT action") + } ?: Log.e(InAppMessages.TAG, "[Displayer] URL is null or empty in REDIRECT action") } InAppActionType.JS -> { - action.call?.takeIf { it.isNotEmpty() }?.let { jsCall -> - onJsAction?.invoke(jsCall) ?: run { - Log.w(tag, "No JS action handler provided for call: $jsCall") - } - } ?: Log.e(tag, "JS call value is null or empty") + action.call?.takeIf { it.isNotEmpty() }?.let { code -> + customCodeHandler?.handle(code) + } ?: Log.e(InAppMessages.TAG, "[Displayer] Custom code is null or empty") } InAppActionType.SUBSCRIBE -> { - val success = - try { - subscriptionHandler.requestSubscription(context) - } catch (e: Exception) { - Log.e(tag, "Error processing subscription request", e) - false + try { + runBlocking { + pushSubscriptionProvider?.subscribe() } + } catch (e: Exception) { + Log.e(InAppMessages.TAG, "[Displayer] Error processing subscription request", e) + false + } + + val success = pushSubscriptionProvider?.isSubscribed() ?: false if (success) { Toast @@ -461,7 +447,7 @@ internal class InAppMessageDisplayerImpl( } } } catch (e: Exception) { - Log.e(tag, "Failed to handle action", e) + Log.e(InAppMessages.TAG, "[Displayer] Failed to handle action", e) Toast.makeText(context, "Error performing action", Toast.LENGTH_SHORT).show() } } diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/InAppUIController.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/InAppUIController.kt similarity index 77% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/InAppUIController.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/InAppUIController.kt index 504895d2..9ad79f46 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/InAppUIController.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/InAppUIController.kt @@ -1,11 +1,12 @@ -package com.pushpushgo.inappmessages.ui +package com.pushpushgo.sdk.inapp.ui import android.app.Activity import android.app.Application import android.os.Bundle import android.util.Log -import com.pushpushgo.inappmessages.manager.InAppMessageManager -import com.pushpushgo.inappmessages.model.InAppMessage +import com.pushpushgo.sdk.inapp.InAppMessages +import com.pushpushgo.sdk.inapp.manager.InAppMessageManager +import com.pushpushgo.sdk.inapp.model.InAppMessage import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -23,8 +24,6 @@ internal class InAppUIController( private val debug: Boolean = false, ) : Application.ActivityLifecycleCallbacks, CoroutineScope { - private val tag = "InAppUIController" - private val job = SupervisorJob() override val coroutineContext = Dispatchers.Main + job @@ -33,7 +32,7 @@ internal class InAppUIController( fun start() { if (debug) { - Log.d(tag, "Starting InApp UI Controller") + Log.d(InAppMessages.TAG, "[UIController] Starting") } application.registerActivityLifecycleCallbacks(this) observeMessages() @@ -47,7 +46,7 @@ internal class InAppUIController( private fun observeMessages() { if (debug) { - Log.d(tag, "Starting to observe messages flow") + Log.d(InAppMessages.TAG, "[UIController] Starting to observe messages flow") } messageSubscription?.cancel() messageSubscription = @@ -57,20 +56,23 @@ internal class InAppUIController( val activity = currentActivity.get() if (activity == null || activity.isFinishing) { if (debug) { - Log.d(tag, "No current activity available, skipping message display") + Log.d(InAppMessages.TAG, "[UIController] No current activity available, skipping message display") } return@onEach } if (messages.isNotEmpty()) { if (debug) { - Log.d(tag, "Displaying message from flow: [${messages.first().id}] (${messages.size} total messages available)") + Log.d( + InAppMessages.TAG, + "[UIController] Displaying message from flow: [${messages.first().id}] (${messages.size} total messages available)", + ) } val highestPriorityMessage = messages.first() displayer.showMessage(activity, highestPriorityMessage) } else { if (debug) { - Log.d(tag, "No messages to display") + Log.d(InAppMessages.TAG, "[UIController] No messages to display") } displayer.cancelPendingMessages(isActivityPaused = false) } @@ -79,12 +81,12 @@ internal class InAppUIController( override fun onActivityResumed(activity: Activity) { if (debug) { - Log.d(tag, "Activity resumed: ${activity.javaClass.simpleName}") + Log.d(InAppMessages.TAG, "[UIController] Activity resumed: ${activity.javaClass.simpleName}") } currentActivity = WeakReference(activity) launch { - manager.refreshActiveMessages() + manager.refreshActiveMessages(manager.getRoute()) // Force display of available messages after activity resume // This handles the case where distinctUntilChanged() blocks emission // of the same message list after permission for push notifications changes @@ -99,7 +101,7 @@ internal class InAppUIController( override fun onActivityPaused(activity: Activity) { if (currentActivity.get() == activity) { if (debug) { - Log.d(tag, "Activity paused, cancelling pending messages") + Log.d(InAppMessages.TAG, "[UIController] Activity paused, cancelling pending messages") } currentActivity.clear() } diff --git a/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/Route.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/Route.kt new file mode 100644 index 00000000..482ef2ec --- /dev/null +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/Route.kt @@ -0,0 +1,11 @@ +package com.pushpushgo.sdk.inapp.ui + +data class Route( + val name: String, +) { + init { + require(name.isNotBlank()) { + "Route name must not me empty" + } + } +} diff --git a/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/Trigger.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/Trigger.kt new file mode 100644 index 00000000..81ccde66 --- /dev/null +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/Trigger.kt @@ -0,0 +1,6 @@ +package com.pushpushgo.sdk.inapp.ui + +data class Trigger( + val key: String, + val value: String? = null, +) diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageButton.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageButton.kt similarity index 94% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageButton.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageButton.kt index d4b37404..a9d36f4b 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageButton.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageButton.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.ui.composables.common +package com.pushpushgo.sdk.inapp.ui.composables.common import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.Arrangement @@ -28,9 +28,9 @@ import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.em -import com.pushpushgo.inappmessages.model.FontStyle -import com.pushpushgo.inappmessages.model.InAppMessageAction -import com.pushpushgo.inappmessages.model.InAppMessageStyle +import com.pushpushgo.sdk.inapp.model.FontStyle +import com.pushpushgo.sdk.inapp.model.InAppMessageAction +import com.pushpushgo.sdk.inapp.model.InAppMessageStyle @Composable internal fun MessageButtons( diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageCard.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageCard.kt similarity index 88% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageCard.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageCard.kt index 78978d62..139c2c4d 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageCard.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageCard.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.ui.composables.common +package com.pushpushgo.sdk.inapp.ui.composables.common import androidx.compose.foundation.BorderStroke import androidx.compose.material3.Card @@ -6,7 +6,7 @@ import androidx.compose.material3.CardDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import com.pushpushgo.inappmessages.model.InAppMessage +import com.pushpushgo.sdk.inapp.model.InAppMessage @Composable internal fun MessageCard( diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageCardShadow.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageCardShadow.kt similarity index 92% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageCardShadow.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageCardShadow.kt index 4f654036..1c41b366 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageCardShadow.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageCardShadow.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.ui.composables.common +package com.pushpushgo.sdk.inapp.ui.composables.common import android.graphics.BlurMaskFilter import androidx.compose.foundation.layout.Box @@ -9,7 +9,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Paint import androidx.compose.ui.graphics.nativeCanvas import androidx.compose.ui.graphics.toArgb -import com.pushpushgo.inappmessages.model.InAppMessage +import com.pushpushgo.sdk.inapp.model.InAppMessage @Composable internal fun MessageCardShadow( diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageImage.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageImage.kt similarity index 82% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageImage.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageImage.kt index 6595ce99..8638b231 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageImage.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageImage.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.ui.composables.common +package com.pushpushgo.sdk.inapp.ui.composables.common import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth @@ -8,8 +8,8 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import coil.compose.AsyncImage -import com.pushpushgo.inappmessages.model.InAppMessageImage -import com.pushpushgo.inappmessages.model.InAppMessageStyle +import com.pushpushgo.sdk.inapp.model.InAppMessageImage +import com.pushpushgo.sdk.inapp.model.InAppMessageStyle @Composable internal fun MessageImage( diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageText.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageText.kt similarity index 88% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageText.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageText.kt index 812e86c7..17bad897 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/MessageText.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/MessageText.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.ui.composables.common +package com.pushpushgo.sdk.inapp.ui.composables.common import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.Text @@ -9,9 +9,9 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextDecoration -import com.pushpushgo.inappmessages.model.FontStyle -import com.pushpushgo.inappmessages.model.InAppMessageDescription -import com.pushpushgo.inappmessages.model.InAppMessageTitle +import com.pushpushgo.sdk.inapp.model.FontStyle +import com.pushpushgo.sdk.inapp.model.InAppMessageDescription +import com.pushpushgo.sdk.inapp.model.InAppMessageTitle @Composable internal fun MessageTitle( diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/Utils.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/Utils.kt similarity index 80% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/Utils.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/Utils.kt index 40563ff4..e282f806 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/common/Utils.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/common/Utils.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.ui.composables.common +package com.pushpushgo.sdk.inapp.ui.composables.common import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.calculateEndPadding @@ -19,12 +19,12 @@ import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.core.graphics.toColorInt -import com.pushpushgo.inappmessages.R -import com.pushpushgo.inappmessages.model.InAppMessage -import com.pushpushgo.inappmessages.model.InAppMessageAction -import com.pushpushgo.inappmessages.model.InAppMessageDescription -import com.pushpushgo.inappmessages.model.InAppMessageStyle -import com.pushpushgo.inappmessages.model.InAppMessageTitle +import com.pushpushgo.sdk.inapp.R +import com.pushpushgo.sdk.inapp.model.InAppMessage +import com.pushpushgo.sdk.inapp.model.InAppMessageAction +import com.pushpushgo.sdk.inapp.model.InAppMessageDescription +import com.pushpushgo.sdk.inapp.model.InAppMessageStyle +import com.pushpushgo.sdk.inapp.model.InAppMessageTitle internal fun Color.Companion.fromHex(hex: String): Color = try { @@ -148,16 +148,16 @@ internal fun createFontFamily(message: InAppMessage): FontFamily { val fontName = when (message.style.fontFamily) { - com.pushpushgo.inappmessages.model.FontFamily.ROBOTO -> "Roboto" - com.pushpushgo.inappmessages.model.FontFamily.OPEN_SANS -> "Open Sans" - com.pushpushgo.inappmessages.model.FontFamily.MONTSERRAT -> "Montserrat" - com.pushpushgo.inappmessages.model.FontFamily.INTER -> "Inter" - com.pushpushgo.inappmessages.model.FontFamily.POPPINS -> "Poppins" - com.pushpushgo.inappmessages.model.FontFamily.LATO -> "Lato" - com.pushpushgo.inappmessages.model.FontFamily.PLAYFAIR_DISPLAY -> "Playfair Display" - com.pushpushgo.inappmessages.model.FontFamily.FIRA_SANS -> "Fira Sans" - com.pushpushgo.inappmessages.model.FontFamily.ARIAL -> "Roboto" - com.pushpushgo.inappmessages.model.FontFamily.GEORGIA -> "Gelasio" + com.pushpushgo.sdk.inapp.model.FontFamily.ROBOTO -> "Roboto" + com.pushpushgo.sdk.inapp.model.FontFamily.OPEN_SANS -> "Open Sans" + com.pushpushgo.sdk.inapp.model.FontFamily.MONTSERRAT -> "Montserrat" + com.pushpushgo.sdk.inapp.model.FontFamily.INTER -> "Inter" + com.pushpushgo.sdk.inapp.model.FontFamily.POPPINS -> "Poppins" + com.pushpushgo.sdk.inapp.model.FontFamily.LATO -> "Lato" + com.pushpushgo.sdk.inapp.model.FontFamily.PLAYFAIR_DISPLAY -> "Playfair Display" + com.pushpushgo.sdk.inapp.model.FontFamily.FIRA_SANS -> "Fira Sans" + com.pushpushgo.sdk.inapp.model.FontFamily.ARIAL -> "Roboto" + com.pushpushgo.sdk.inapp.model.FontFamily.GEORGIA -> "Gelasio" } val fontWeights = @@ -180,7 +180,7 @@ internal fun createFontFamily(message: InAppMessage): FontFamily { fontProvider = provider, weight = FontWeight(weight), style = - if (style == com.pushpushgo.inappmessages.model.FontStyle.ITALIC) { + if (style == com.pushpushgo.sdk.inapp.model.FontStyle.ITALIC) { FontStyle.Italic } else { FontStyle.Normal diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/BannerMessageTemplate.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/templates/BannerMessageTemplate.kt similarity index 82% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/BannerMessageTemplate.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/templates/BannerMessageTemplate.kt index 6403694f..673bacb9 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/BannerMessageTemplate.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/templates/BannerMessageTemplate.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.ui.composables.templates +package com.pushpushgo.sdk.inapp.ui.composables.templates import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -16,17 +16,17 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import coil.compose.AsyncImage -import com.pushpushgo.inappmessages.model.InAppMessage -import com.pushpushgo.inappmessages.model.InAppMessageAction -import com.pushpushgo.inappmessages.ui.composables.common.CloseButton -import com.pushpushgo.inappmessages.ui.composables.common.MessageButton -import com.pushpushgo.inappmessages.ui.composables.common.MessageCard -import com.pushpushgo.inappmessages.ui.composables.common.MessageCardShadow -import com.pushpushgo.inappmessages.ui.composables.common.MessageDescription -import com.pushpushgo.inappmessages.ui.composables.common.MessageTitle -import com.pushpushgo.inappmessages.ui.composables.common.createFontFamily -import com.pushpushgo.inappmessages.ui.composables.common.parsePadding -import com.pushpushgo.inappmessages.ui.composables.common.pxToDp +import com.pushpushgo.sdk.inapp.model.InAppMessage +import com.pushpushgo.sdk.inapp.model.InAppMessageAction +import com.pushpushgo.sdk.inapp.ui.composables.common.CloseButton +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageButton +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageCard +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageCardShadow +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageDescription +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageTitle +import com.pushpushgo.sdk.inapp.ui.composables.common.createFontFamily +import com.pushpushgo.sdk.inapp.ui.composables.common.parsePadding +import com.pushpushgo.sdk.inapp.ui.composables.common.pxToDp /** * Banner-style message template for: @@ -57,7 +57,7 @@ internal fun TemplateBannerMessage( ) } - Box(modifier = Modifier.padding(parsePadding(message.layout.padding))) { + Box(modifier = Modifier.Companion.padding(parsePadding(message.layout.padding))) { Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/InAppMessageDefaultTemplate.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/templates/InAppMessageDefaultTemplate.kt similarity index 77% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/InAppMessageDefaultTemplate.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/templates/InAppMessageDefaultTemplate.kt index 66159b0f..cdcb9fa5 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/InAppMessageDefaultTemplate.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/templates/InAppMessageDefaultTemplate.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.ui.composables.templates +package com.pushpushgo.sdk.inapp.ui.composables.templates import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.Arrangement @@ -17,17 +17,17 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex -import com.pushpushgo.inappmessages.model.InAppMessage -import com.pushpushgo.inappmessages.model.InAppMessageAction -import com.pushpushgo.inappmessages.ui.composables.common.CloseButton -import com.pushpushgo.inappmessages.ui.composables.common.MessageButtons -import com.pushpushgo.inappmessages.ui.composables.common.MessageDescription -import com.pushpushgo.inappmessages.ui.composables.common.MessageImage -import com.pushpushgo.inappmessages.ui.composables.common.MessageTitle -import com.pushpushgo.inappmessages.ui.composables.common.fromHex -import com.pushpushgo.inappmessages.ui.composables.common.parseBorderRadius -import com.pushpushgo.inappmessages.ui.composables.common.parsePadding -import com.pushpushgo.inappmessages.ui.composables.common.pxToDp +import com.pushpushgo.sdk.inapp.model.InAppMessage +import com.pushpushgo.sdk.inapp.model.InAppMessageAction +import com.pushpushgo.sdk.inapp.ui.composables.common.CloseButton +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageButtons +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageDescription +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageImage +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageTitle +import com.pushpushgo.sdk.inapp.ui.composables.common.fromHex +import com.pushpushgo.sdk.inapp.ui.composables.common.parseBorderRadius +import com.pushpushgo.sdk.inapp.ui.composables.common.parsePadding +import com.pushpushgo.sdk.inapp.ui.composables.common.pxToDp @Composable internal fun InAppMessageDefaultTemplate( @@ -53,7 +53,7 @@ internal fun InAppMessageDefaultTemplate( shape = borderRadius, colors = CardDefaults.cardColors( - containerColor = Color.fromHex(message.style.backgroundColor), + containerColor = Color.Companion.fromHex(message.style.backgroundColor), ), border = if (message.style.border) { diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/ReviewForDiscountTemplate.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/templates/ReviewForDiscountTemplate.kt similarity index 81% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/ReviewForDiscountTemplate.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/templates/ReviewForDiscountTemplate.kt index 6ed5167e..06bd7659 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/ReviewForDiscountTemplate.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/templates/ReviewForDiscountTemplate.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.ui.composables.templates +package com.pushpushgo.sdk.inapp.ui.composables.templates import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -16,19 +16,19 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import coil.compose.AsyncImage -import com.pushpushgo.inappmessages.model.InAppMessage -import com.pushpushgo.inappmessages.model.InAppMessageAction -import com.pushpushgo.inappmessages.model.Placement -import com.pushpushgo.inappmessages.ui.composables.common.CloseButton -import com.pushpushgo.inappmessages.ui.composables.common.MessageButton -import com.pushpushgo.inappmessages.ui.composables.common.MessageCard -import com.pushpushgo.inappmessages.ui.composables.common.MessageCardShadow -import com.pushpushgo.inappmessages.ui.composables.common.MessageDescription -import com.pushpushgo.inappmessages.ui.composables.common.MessageTitle -import com.pushpushgo.inappmessages.ui.composables.common.add -import com.pushpushgo.inappmessages.ui.composables.common.createFontFamily -import com.pushpushgo.inappmessages.ui.composables.common.parsePadding -import com.pushpushgo.inappmessages.ui.composables.common.pxToDp +import com.pushpushgo.sdk.inapp.model.InAppMessage +import com.pushpushgo.sdk.inapp.model.InAppMessageAction +import com.pushpushgo.sdk.inapp.model.Placement +import com.pushpushgo.sdk.inapp.ui.composables.common.CloseButton +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageButton +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageCard +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageCardShadow +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageDescription +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageTitle +import com.pushpushgo.sdk.inapp.ui.composables.common.add +import com.pushpushgo.sdk.inapp.ui.composables.common.createFontFamily +import com.pushpushgo.sdk.inapp.ui.composables.common.parsePadding +import com.pushpushgo.sdk.inapp.ui.composables.common.pxToDp /** * Banner-style message template for: @@ -98,7 +98,7 @@ internal fun TemplateReviewForDiscount( Row( modifier = - Modifier + Modifier.Companion .padding(parsePadding(message.layout.paddingBody)) .weight(1f), ) { diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/RichMessageTemplate.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/templates/RichMessageTemplate.kt similarity index 79% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/RichMessageTemplate.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/templates/RichMessageTemplate.kt index d6a0a2c7..b52516fe 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/ui/composables/templates/RichMessageTemplate.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/ui/composables/templates/RichMessageTemplate.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.ui.composables.templates +package com.pushpushgo.sdk.inapp.ui.composables.templates import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -15,16 +15,16 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import coil.compose.AsyncImage -import com.pushpushgo.inappmessages.model.InAppMessage -import com.pushpushgo.inappmessages.model.InAppMessageAction -import com.pushpushgo.inappmessages.ui.composables.common.CloseButton -import com.pushpushgo.inappmessages.ui.composables.common.MessageButtons -import com.pushpushgo.inappmessages.ui.composables.common.MessageCard -import com.pushpushgo.inappmessages.ui.composables.common.MessageDescription -import com.pushpushgo.inappmessages.ui.composables.common.MessageTitle -import com.pushpushgo.inappmessages.ui.composables.common.createFontFamily -import com.pushpushgo.inappmessages.ui.composables.common.parsePadding -import com.pushpushgo.inappmessages.ui.composables.common.pxToDp +import com.pushpushgo.sdk.inapp.model.InAppMessage +import com.pushpushgo.sdk.inapp.model.InAppMessageAction +import com.pushpushgo.sdk.inapp.ui.composables.common.CloseButton +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageButtons +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageCard +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageDescription +import com.pushpushgo.sdk.inapp.ui.composables.common.MessageTitle +import com.pushpushgo.sdk.inapp.ui.composables.common.createFontFamily +import com.pushpushgo.sdk.inapp.ui.composables.common.parsePadding +import com.pushpushgo.sdk.inapp.ui.composables.common.pxToDp /** * Banner-style message template for: diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/AutoCleanupManager.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/utils/AutoCleanupManager.kt similarity index 98% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/AutoCleanupManager.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/utils/AutoCleanupManager.kt index a2df9233..99bedc72 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/AutoCleanupManager.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/utils/AutoCleanupManager.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.utils +package com.pushpushgo.sdk.inapp.utils import android.app.Activity import android.app.Application diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/DeviceInfoProvider.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/utils/DeviceInfoProvider.kt similarity index 77% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/DeviceInfoProvider.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/utils/DeviceInfoProvider.kt index 56282efb..f82567a1 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/DeviceInfoProvider.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/utils/DeviceInfoProvider.kt @@ -1,9 +1,9 @@ -package com.pushpushgo.inappmessages.utils +package com.pushpushgo.sdk.inapp.utils import android.content.Context import android.content.res.Configuration -import com.pushpushgo.inappmessages.model.DeviceType -import com.pushpushgo.inappmessages.model.OSType +import com.pushpushgo.sdk.inapp.model.DeviceType +import com.pushpushgo.sdk.inapp.model.OSType internal object DeviceInfoProvider { fun getCurrentDeviceType(context: Context): DeviceType { diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/InAppMessageHelper.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/utils/InAppMessageHelper.kt similarity index 91% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/InAppMessageHelper.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/utils/InAppMessageHelper.kt index 8cd9b128..d4a3d3c5 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/InAppMessageHelper.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/utils/InAppMessageHelper.kt @@ -1,12 +1,14 @@ -package com.pushpushgo.inappmessages.utils +package com.pushpushgo.sdk.inapp.utils import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.fragment.app.Fragment import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner +import androidx.navigation.NavBackStackEntry import androidx.navigation.NavController -import com.pushpushgo.inappmessages.InAppMessagesSDK +import com.pushpushgo.sdk.inapp.InAppMessages +import com.pushpushgo.sdk.inapp.ui.Route /** * Helper class that simplifies in-app message integration across different UI frameworks. @@ -20,7 +22,7 @@ object InAppMessageHelper { * @param screenName The name of the current screen/route */ fun showMessagesForScreen(screenName: String) { - InAppMessagesSDK.getInstance().showActiveMessages(screenName) + InAppMessages.getInstance().showMessagesOnRoute(Route(screenName)) } /** @@ -109,8 +111,8 @@ object InAppMessageHelper { */ @Composable fun ObserveNavBackStack( - navBackStackEntry: androidx.navigation.NavBackStackEntry?, - routeProvider: (androidx.navigation.NavBackStackEntry?) -> String? = { it?.destination?.route }, + navBackStackEntry: NavBackStackEntry?, + routeProvider: (NavBackStackEntry?) -> String? = { it?.destination?.route }, ) { val currentRoute = routeProvider(navBackStackEntry) ObserveNavigation(currentRoute) diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/ZonedDateTimeAdapter.kt b/inapp/src/main/java/com/pushpushgo/sdk/inapp/utils/ZonedDateTimeAdapter.kt similarity index 96% rename from library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/ZonedDateTimeAdapter.kt rename to inapp/src/main/java/com/pushpushgo/sdk/inapp/utils/ZonedDateTimeAdapter.kt index 403faf3e..a891ac9f 100644 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/ZonedDateTimeAdapter.kt +++ b/inapp/src/main/java/com/pushpushgo/sdk/inapp/utils/ZonedDateTimeAdapter.kt @@ -1,4 +1,4 @@ -package com.pushpushgo.inappmessages.utils +package com.pushpushgo.sdk.inapp.utils import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonReader diff --git a/library-inappmessages/src/main/res/anim/fade_in.xml b/inapp/src/main/res/anim/fade_in.xml similarity index 100% rename from library-inappmessages/src/main/res/anim/fade_in.xml rename to inapp/src/main/res/anim/fade_in.xml diff --git a/library-inappmessages/src/main/res/values/font_certs.xml b/inapp/src/main/res/values/font_certs.xml similarity index 100% rename from library-inappmessages/src/main/res/values/font_certs.xml rename to inapp/src/main/res/values/font_certs.xml diff --git a/library-inappmessages/src/main/res/values/styles.xml b/inapp/src/main/res/values/styles.xml similarity index 100% rename from library-inappmessages/src/main/res/values/styles.xml rename to inapp/src/main/res/values/styles.xml diff --git a/library-inappmessages/src/test/java/com/pushpushgo/inappmessages/ExampleUnitTest.kt b/inapp/src/test/java/com/pushpushgo/sdk/inapp/ExampleUnitTest.kt similarity index 73% rename from library-inappmessages/src/test/java/com/pushpushgo/inappmessages/ExampleUnitTest.kt rename to inapp/src/test/java/com/pushpushgo/sdk/inapp/ExampleUnitTest.kt index 58d0975d..f1fb9951 100644 --- a/library-inappmessages/src/test/java/com/pushpushgo/inappmessages/ExampleUnitTest.kt +++ b/inapp/src/test/java/com/pushpushgo/sdk/inapp/ExampleUnitTest.kt @@ -1,6 +1,6 @@ -package com.pushpushgo.inappmessages +package com.pushpushgo.sdk.inapp -import org.junit.Assert.* +import org.junit.Assert import org.junit.Test /** @@ -11,6 +11,6 @@ import org.junit.Test class ExampleUnitTest { @Test fun addition_isCorrect() { - assertEquals(4, 2 + 2) + Assert.assertEquals(4, 2 + 2) } } diff --git a/library-inappmessages/consumer-rules.pro b/library-inappmessages/consumer-rules.pro deleted file mode 100644 index e69de29b..00000000 diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/InAppMessagesSDK.kt b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/InAppMessagesSDK.kt deleted file mode 100644 index 782f587f..00000000 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/InAppMessagesSDK.kt +++ /dev/null @@ -1,207 +0,0 @@ -package com.pushpushgo.inappmessages - -import android.app.Application -import android.util.Log -import com.pushpushgo.inappmessages.data.event.InAppMessageEvent -import com.pushpushgo.inappmessages.data.event.InAppMessageEventRepository -import com.pushpushgo.inappmessages.manager.InAppMessageManager -import com.pushpushgo.inappmessages.manager.InAppMessageManagerImpl -import com.pushpushgo.inappmessages.network.InAppEventApi -import com.pushpushgo.inappmessages.network.InAppListGetApi -import com.pushpushgo.inappmessages.network.RetrofitProvider -import com.pushpushgo.inappmessages.persistence.InAppMessagePersistenceImpl -import com.pushpushgo.inappmessages.repository.InAppMessageRepositoryImpl -import com.pushpushgo.inappmessages.ui.InAppMessageDisplayer -import com.pushpushgo.inappmessages.ui.InAppMessageDisplayerImpl -import com.pushpushgo.inappmessages.ui.InAppUIController -import com.pushpushgo.inappmessages.utils.AutoCleanupManager -import com.pushpushgo.inappmessages.utils.DefaultPushNotificationSubscriber -import com.pushpushgo.inappmessages.utils.PushNotificationSubscriber -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.cancel -import kotlinx.coroutines.launch -import retrofit2.Retrofit - -class InAppMessagesSDK private constructor( - private val application: Application, - private val projectId: String, - private val apiKey: String, - private val debug: Boolean = false, - private val baseUrl: String? = null, - private var pushNotificationSubscriber: PushNotificationSubscriber = DefaultPushNotificationSubscriber(), -) { - // --- Retrofit & APIs --- - private val retrofit: Retrofit by lazy { - RetrofitProvider.buildRetrofit(baseUrl ?: "https://api.pushpushgo.com/") - } - private val api: InAppListGetApi by lazy { - retrofit.create(InAppListGetApi::class.java) - } - private val eventApi: InAppEventApi by lazy { - retrofit.create(InAppEventApi::class.java) - } - private val eventRepository by lazy { - InAppMessageEventRepository(eventApi, debug = debug) - } - - internal suspend fun dispatchInAppEvent( - action: String, - inAppId: String, - ) { - try { - eventRepository.sendEvent( - token = apiKey, - projectId = projectId, - event = InAppMessageEvent(action = action, inApp = inAppId), - ) - } catch (e: Exception) { - if (debug) { - Log.e(tag, "Failed to send in-app event", e) - } - } - } - - private val tag = "InAppMessagesSDK" - private val sdkScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) - private val manager: InAppMessageManager - private val displayer: InAppMessageDisplayer - private val uiController: InAppUIController - private var autoCleanupManager: AutoCleanupManager? = null - - companion object { - @Volatile - private var INSTANCE: InAppMessagesSDK? = null - - @JvmStatic - fun initialize( - application: Application, - projectId: String, - apiKey: String, - debug: Boolean = false, - baseUrl: String? = null, - pushNotificationSubscriber: PushNotificationSubscriber? = null, - ): InAppMessagesSDK = - INSTANCE ?: synchronized(this) { - INSTANCE ?: InAppMessagesSDK( - application, - projectId, - apiKey, - debug, - baseUrl, - pushNotificationSubscriber ?: DefaultPushNotificationSubscriber(), - ).also { - INSTANCE = it - } - } - - @JvmStatic - fun getInstance(): InAppMessagesSDK = INSTANCE ?: throw IllegalStateException("InAppMessagesSDK is not initialized!") - } - - init { - val persistence = InAppMessagePersistenceImpl(application, debug) - val repository = InAppMessageRepositoryImpl(api, projectId, apiKey, persistence, debug) - manager = InAppMessageManagerImpl(sdkScope, repository, persistence, application, debug) - displayer = - InAppMessageDisplayerImpl( - persistence, - debug, - onMessageDismissed = { showActiveMessages() }, - onMessageEvent = { eventType, message, ctaIndex -> - sdkScope.launch { - when (eventType) { - "show" -> dispatchInAppEvent("inapp.show", message.id) - "close" -> dispatchInAppEvent("inapp.close", message.id) - "cta" -> dispatchInAppEvent("inapp.cta.$ctaIndex", message.id) - } - } - }, - ) - uiController = InAppUIController(application, manager, displayer, debug) - - sdkScope.launch { - manager.initialize() - } - uiController.start() - - autoCleanupManager = - AutoCleanupManager( - application = application, - cleanupCallback = { cleanup() }, - ) - autoCleanupManager?.start() - } - - /** - * Cleans up resources used by the SDK - * This is called automatically after app is in background for a prolonged period, - * but can also be called manually from app's onDestroy() - */ - private fun cleanup() { - // Stop the auto-cleanup manager - autoCleanupManager?.stop() - autoCleanupManager = null - - uiController.stop() - displayer.cancelPendingMessages() - sdkScope.cancel() - } - - /** - * Shows all in-app messages that should be displayed automatically: - * - If currentRoute is null: shows all messages with trigger.type == APP_OPEN - * - If currentRoute is not null: shows all messages with trigger.type == ROUTE and trigger.route == currentRoute, and all with trigger.type == APP_OPEN - * - * Call this once on app start (with currentRoute = null), - * and on route/view change (with currentRoute = route name). - */ - fun showActiveMessages(currentRoute: String? = null) { - sdkScope.launch { - manager.refreshActiveMessages(currentRoute) - } - } - - /** - * Shows in-app messages for a custom trigger. - * Only messages with trigger.type == CUSTOM_TRIGGER and matching key and value will be shown. - * Also doesn't cancel pending messages for APP_OPEN trigger. - */ - fun showMessagesOnTrigger( - key: String, - value: String, - ) { - sdkScope.launch { - val messageToShow = manager.trigger(key, value) - if (messageToShow != null) { - uiController.displayCustomMessage(messageToShow) - } - } - } - - /** - * Sets a handler for code actions from in-app messages. - * When an in-app message with action type JS is clicked, the handler will be called with the given code. - * - * @param handler Function that takes a action button code string and processes it - */ - fun setJsActionHandler(handler: (jsCall: String) -> Unit) { - (displayer as? InAppMessageDisplayerImpl)?.setJsActionHandler(handler) - } - - /** - * Sets a custom implementation for handling subscription requests. - * This will be called when an in-app message with a SUBSCRIBE action button is clicked. - * - * By default, this SDK attempts to use reflection to find and call the PushPushGo SDK. - * You only need to provide a custom implementation if you're using a different push service - * or have special requirements. - * - * @param subscriber The PushNotificationSubscriber implementation - */ - fun setPushNotificationSubscriber(subscriber: PushNotificationSubscriber) { - this.pushNotificationSubscriber = subscriber - (displayer as? InAppMessageDisplayerImpl)?.setSubscriptionHandler(subscriber) - } -} diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/repository/InAppMessageRepository.kt b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/repository/InAppMessageRepository.kt deleted file mode 100644 index 16445e8e..00000000 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/repository/InAppMessageRepository.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.pushpushgo.inappmessages.repository - -import com.pushpushgo.inappmessages.model.InAppMessage - -internal interface InAppMessageRepository { - suspend fun fetchMessages(): List -} diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/PushNotificationStatusProvider.kt b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/PushNotificationStatusProvider.kt deleted file mode 100644 index 2e522568..00000000 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/PushNotificationStatusProvider.kt +++ /dev/null @@ -1,58 +0,0 @@ -package com.pushpushgo.inappmessages.utils - -import android.content.Context -import android.content.SharedPreferences -import androidx.preference.PreferenceManager -import com.pushpushgo.inappmessages.model.UserAudienceType - -/** - * Utility class for accessing push notification subscription state - * from the PushPushGo SDK's SharedPreferences. - * - * This provides a bridge to the push notification SDK without creating a direct dependency. - */ -internal class PushNotificationStatusProvider( - private val context: Context, -) { - companion object { - // These constants match the ones in PushPushGo SDK's SharedPreferencesHelper - private const val IS_SUBSCRIBED = "_PushPushGoSDK_is_subscribed_" - private const val ARE_NOTIFICATIONS_BLOCKED = "_PushPushGoSDK_notifications_blocked_" - } - - private val sharedPreferences: SharedPreferences by lazy { - PreferenceManager.getDefaultSharedPreferences(context) - } - - /** - * Checks if the user is currently subscribed to push notifications - * by reading directly from the PushPushGo SDK's SharedPreferences - * - * @return true if subscribed (defaults to false if not found) - */ - fun isSubscribed(): Boolean { - val result = sharedPreferences.getBoolean(IS_SUBSCRIBED, false) - return result - } - - /** - * Checks if notifications are blocked for the current user - * - * @return true if notifications are blocked (defaults to false if not found) - */ - fun isNotificationsBlocked(): Boolean = sharedPreferences.getBoolean(ARE_NOTIFICATIONS_BLOCKED, false) - - /** - * Utility method to check if a user matches the given audience type - * - * @param audienceType The audience type to check against - * @return true if the current user matches the specified audience type - */ - fun matchesAudienceType(audienceType: UserAudienceType): Boolean = - when (audienceType) { - UserAudienceType.ALL -> true - UserAudienceType.SUBSCRIBER -> isSubscribed() && !isNotificationsBlocked() - UserAudienceType.NON_SUBSCRIBER -> !isSubscribed() || isNotificationsBlocked() - UserAudienceType.NOTIFICATIONS_BLOCKED -> isNotificationsBlocked() - } -} diff --git a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/PushNotificationSubscriber.kt b/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/PushNotificationSubscriber.kt deleted file mode 100644 index 64cb7db7..00000000 --- a/library-inappmessages/src/main/java/com/pushpushgo/inappmessages/utils/PushNotificationSubscriber.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.pushpushgo.inappmessages.utils - -import android.content.Context -import android.util.Log -import java.lang.reflect.InvocationTargetException - -/** - * Interface for requesting push notification subscription. - * This provides a clean way for the in-app messages to trigger a subscription request - * without directly depending on the push notification SDK. - */ -interface PushNotificationSubscriber { - /** - * Request user to subscribe to push notifications - * - * @param context Android context - * @return true if the subscription request was successfully initiated - */ - fun requestSubscription(context: Context): Boolean -} - -/** - * Default implementation that attempts to find the PushPushGoSubscriptionManager - * in the push notifications SDK using reflection. - * - * This provides automatic integration between the in-app messages library and - * the push notifications SDK without creating direct compile-time dependencies. - */ -internal class DefaultPushNotificationSubscriber : PushNotificationSubscriber { - companion object { - private const val TAG = "DefaultPushSubscriber" - private const val BRIDGE_CLASS = "com.pushpushgo.sdk.bridge.PushPushGoSubscriptionBridgeManager" - } - - override fun requestSubscription(context: Context): Boolean { - try { - // Try to find the PushPushGoSubscriptionManager class - val managerClass = Class.forName(BRIDGE_CLASS) - - // Create a new instance of the manager - val manager = managerClass.getDeclaredConstructor().newInstance() - - // Call the requestSubscription method - val method = managerClass.getMethod("requestSubscription", Context::class.java) - return method.invoke(manager, context) as Boolean - } catch (e: ClassNotFoundException) { - Log.e(TAG, "PushPushGoSubscriptionManager not found. Make sure the push notifications SDK is included", e) - } catch (e: InvocationTargetException) { - Log.e(TAG, "Error calling requestSubscription", e.targetException) - } catch (e: Exception) { - Log.e(TAG, "Error requesting subscription", e) - } - - Log.w(TAG, "Subscription requested but could not be processed automatically") - return false - } -} diff --git a/library-no-op/build.gradle b/library-no-op/build.gradle deleted file mode 100644 index fa9ae3ac..00000000 --- a/library-no-op/build.gradle +++ /dev/null @@ -1,72 +0,0 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - -plugins { - id 'com.android.library' - id 'kotlin-android' - id 'maven-publish' - alias(libs.plugins.validator) -} - -android { - compileSdk 36 - - namespace 'com.pushpushgo.sdk' - defaultConfig { - minSdkVersion 21 - targetSdkVersion 36 - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - buildFeatures { - buildConfig true - } - compileOptions { - sourceCompatibility JavaLanguageVersion.of(17) - targetCompatibility JavaLanguageVersion.of(17) - } - - kotlin { - compilerOptions { - jvmTarget = JvmTarget.fromTarget("17") - } - } - - publishing { - singleVariant("release") { - withSourcesJar() - } - } -} - -dependencies { - compileOnly libs.hms.push - - compileOnly platform(libs.firebase.bom) - compileOnly 'com.google.firebase:firebase-messaging' - - api "com.google.guava:guava:33.4.8-android" -} - -tasks.register('androidSourcesJar', Jar) { - archiveClassifier.set('sources') - from android.sourceSets.main.java.srcDirs -} - -publishing { - publications { - release(MavenPublication) { - groupId = 'com.pushpushgo' - artifactId = 'sdk-no-op' - version = libs.versions.sdk.get() - - afterEvaluate { - from components.release - } - } - } -} diff --git a/library-no-op/src/main/AndroidManifest.xml b/library-no-op/src/main/AndroidManifest.xml deleted file mode 100644 index cc947c56..00000000 --- a/library-no-op/src/main/AndroidManifest.xml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/library-no-op/src/main/java/com/pushpushgo/sdk/BeaconBuilder.kt b/library-no-op/src/main/java/com/pushpushgo/sdk/BeaconBuilder.kt deleted file mode 100644 index 4271dc0e..00000000 --- a/library-no-op/src/main/java/com/pushpushgo/sdk/BeaconBuilder.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.pushpushgo.sdk - -@Suppress("unused", "UNUSED_PARAMETER") -class BeaconBuilder internal constructor() { - @JvmOverloads - fun appendTag(tag: String, label: String = "default", strategy: String = "append", ttl: Int = 0): BeaconBuilder = this - fun getTags(): MutableList> = mutableListOf() - fun getTagsToDelete(): MutableList = mutableListOf() - fun removeTag(vararg name: String): BeaconBuilder = this - fun send() = Unit - fun set(key: String, value: Any): BeaconBuilder = this - fun setCustomId(id: Int?): BeaconBuilder = this - fun setCustomId(id: String?): BeaconBuilder = this -} diff --git a/library-no-op/src/main/java/com/pushpushgo/sdk/PushPushGo.kt b/library-no-op/src/main/java/com/pushpushgo/sdk/PushPushGo.kt deleted file mode 100644 index 511c955b..00000000 --- a/library-no-op/src/main/java/com/pushpushgo/sdk/PushPushGo.kt +++ /dev/null @@ -1,95 +0,0 @@ -package com.pushpushgo.sdk - -import android.app.Application -import android.content.Context -import android.content.Intent -import com.google.common.util.concurrent.Futures -import com.google.common.util.concurrent.ListenableFuture -import com.pushpushgo.sdk.BuildConfig.DEBUG -import com.pushpushgo.sdk.dto.PPGoNotification -import com.pushpushgo.sdk.exception.PushPushException - -@Suppress("unused", "UNUSED_PARAMETER") -class PushPushGo private constructor( - private val application: Application, - private val apiKey: String, - private val projectId: String, - private val isProduction: Boolean, - private val isNetworkDebug: Boolean, - private val customBaseUrl: String? -) { - - companion object { - const val VERSION = "NO-OP" - - private var INSTANCE: PushPushGo? = null - - fun isInitialized(): Boolean = INSTANCE != null - - @JvmStatic - fun getInstance(): PushPushGo = - INSTANCE ?: throw PushPushException("You have to initialize PushPushGo with context first!") - - @JvmStatic - fun getInstance(application: Application) = INSTANCE ?: synchronized(this) { - INSTANCE ?: PushPushGo(application, "", "", true, DEBUG, null).also { INSTANCE = it } - } - - @JvmStatic - @JvmOverloads - fun getInstance( - application: Application, apiKey: String, projectId: String, isProduction: Boolean, isDebug: Boolean = false, customBaseUrl: String?, - ): PushPushGo { - if (INSTANCE == null) { - INSTANCE = PushPushGo(application, apiKey, projectId, isProduction, isDebug, customBaseUrl) - } - return INSTANCE as PushPushGo - } - } - - var defaultIsSubscribed: Boolean = false - - var notificationHandler: NotificationHandler = { _, _ -> } - - var onInvalidProjectIdHandler: InvalidProjectIdHandler = { _, _, _ -> } - - fun createBeacon(): BeaconBuilder = BeaconBuilder() - - fun getApiKey(): String = apiKey - - fun getNotificationDetails(notificationIntent: Intent?): PPGoNotification? = null - - fun getNotificationDetails(notificationData: Map): PPGoNotification? = null - - fun getProjectId(): String = projectId - - fun getSubscriberId(): String = "" - - fun getPushToken(): ListenableFuture = Futures.immediateFuture("null") - - fun handleBackgroundNotificationClick(intent: Intent?) = Unit - - fun isPPGoPush(notificationIntent: Intent?): Boolean = false - - fun isPPGoPush(notificationData: Map): Boolean = false - - fun isSubscribed(): Boolean = false - - fun migrateToNewProject(newProjectId: String, newProjectToken: String): ListenableFuture = - Futures.immediateFuture(this) - - fun areNotificationsEnabled(): Boolean = false - - fun registerSubscriber() = Unit - - fun createSubscriber(): ListenableFuture = Futures.immediateFuture("") - - fun unregisterSubscriber() = Unit - - fun unregisterSubscriber(projectId: String, projectToken: String, subscriberId: String): ListenableFuture = - Futures.immediateFuture(Unit) -} - -typealias NotificationHandler = (context: Context, url: String) -> Unit - -typealias InvalidProjectIdHandler = (pushProjectId: String, pushSubscriberId: String, currentProjectId: String) -> Unit diff --git a/library-no-op/src/main/java/com/pushpushgo/sdk/dto/PPGoNotification.kt b/library-no-op/src/main/java/com/pushpushgo/sdk/dto/PPGoNotification.kt deleted file mode 100644 index ca299871..00000000 --- a/library-no-op/src/main/java/com/pushpushgo/sdk/dto/PPGoNotification.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.pushpushgo.sdk.dto - -data class PPGoNotification( - val title: String?, - val body: String?, - val priority: Int = 0, - val campaignId: String, - val redirectLink: String?, -) diff --git a/library-no-op/src/main/java/com/pushpushgo/sdk/exception/PushPushException.kt b/library-no-op/src/main/java/com/pushpushgo/sdk/exception/PushPushException.kt deleted file mode 100644 index 29461f4b..00000000 --- a/library-no-op/src/main/java/com/pushpushgo/sdk/exception/PushPushException.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.pushpushgo.sdk.exception - -import java.io.IOException - -class PushPushException internal constructor(message: String) : IOException(message) diff --git a/library-no-op/src/main/java/com/pushpushgo/sdk/push/service/FcmMessagingServiceDelegate.kt b/library-no-op/src/main/java/com/pushpushgo/sdk/push/service/FcmMessagingServiceDelegate.kt deleted file mode 100644 index da613d91..00000000 --- a/library-no-op/src/main/java/com/pushpushgo/sdk/push/service/FcmMessagingServiceDelegate.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.pushpushgo.sdk.push.service - -import android.content.Context -import com.google.firebase.messaging.RemoteMessage - -@Suppress("unused", "UNUSED_PARAMETER") -class FcmMessagingServiceDelegate(private val context: Context) { - - fun onDestroy() = Unit - - fun onMessageReceived(remoteMessage: RemoteMessage) = Unit - - fun onNewToken(token: String) = Unit -} diff --git a/library-no-op/src/main/java/com/pushpushgo/sdk/push/service/HmsMessagingServiceDelegate.kt b/library-no-op/src/main/java/com/pushpushgo/sdk/push/service/HmsMessagingServiceDelegate.kt deleted file mode 100644 index 6691ca50..00000000 --- a/library-no-op/src/main/java/com/pushpushgo/sdk/push/service/HmsMessagingServiceDelegate.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.pushpushgo.sdk.push.service - -import android.content.Context -import com.huawei.hms.push.RemoteMessage - -@Suppress("unused", "UNUSED_PARAMETER") -class HmsMessagingServiceDelegate(private val context: Context) { - - fun onDestroy() = Unit - - fun onMessageReceived(remoteMessage: RemoteMessage) = Unit - - fun onNewToken(token: String) = Unit -} diff --git a/library/api/library.api b/library/api/library.api deleted file mode 100644 index bd2daca1..00000000 --- a/library/api/library.api +++ /dev/null @@ -1,120 +0,0 @@ -public final class com/pushpushgo/sdk/BeaconBuilder { - public final fun appendTag (Ljava/lang/String;)Lcom/pushpushgo/sdk/BeaconBuilder; - public final fun appendTag (Ljava/lang/String;Ljava/lang/String;)Lcom/pushpushgo/sdk/BeaconBuilder; - public final fun appendTag (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/pushpushgo/sdk/BeaconBuilder; - public final fun appendTag (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Lcom/pushpushgo/sdk/BeaconBuilder; - public static synthetic fun appendTag$default (Lcom/pushpushgo/sdk/BeaconBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IILjava/lang/Object;)Lcom/pushpushgo/sdk/BeaconBuilder; - public final fun getTags ()Ljava/util/List; - public final fun getTagsToDelete ()Ljava/util/List; - public final fun removeTag ([Ljava/lang/String;)Lcom/pushpushgo/sdk/BeaconBuilder; - public final fun removeTags (Ljava/util/Map;)Lcom/pushpushgo/sdk/BeaconBuilder; - public final fun send ()V - public final fun set (Ljava/lang/String;Ljava/lang/Object;)Lcom/pushpushgo/sdk/BeaconBuilder; - public final fun setCustomId (Ljava/lang/Integer;)Lcom/pushpushgo/sdk/BeaconBuilder; - public final fun setCustomId (Ljava/lang/String;)Lcom/pushpushgo/sdk/BeaconBuilder; -} - -public final class com/pushpushgo/sdk/BuildConfig { - public static final field BUILD_TYPE Ljava/lang/String; - public static final field DEBUG Z - public static final field LIBRARY_PACKAGE_NAME Ljava/lang/String; - public fun ()V -} - -public final class com/pushpushgo/sdk/PushPushGo { - public static final field Companion Lcom/pushpushgo/sdk/PushPushGo$Companion; - public static final field VERSION Ljava/lang/String; - public synthetic fun (Landroid/app/Application;Ljava/lang/String;Ljava/lang/String;ZZLjava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun areNotificationsEnabled ()Z - public final fun createBeacon ()Lcom/pushpushgo/sdk/BeaconBuilder; - public final fun createSubscriber ()Lcom/google/common/util/concurrent/ListenableFuture; - public final fun getApiKey ()Ljava/lang/String; - public final fun getCustomClickIntentFlags ()I - public final fun getDefaultIsSubscribed ()Z - public static final fun getInstance ()Lcom/pushpushgo/sdk/PushPushGo; - public static final fun getInstance (Landroid/app/Application;)Lcom/pushpushgo/sdk/PushPushGo; - public static final fun getInstance (Landroid/app/Application;Ljava/lang/String;Ljava/lang/String;Z)Lcom/pushpushgo/sdk/PushPushGo; - public static final fun getInstance (Landroid/app/Application;Ljava/lang/String;Ljava/lang/String;ZZ)Lcom/pushpushgo/sdk/PushPushGo; - public static final fun getInstance (Landroid/app/Application;Ljava/lang/String;Ljava/lang/String;ZZLjava/lang/String;)Lcom/pushpushgo/sdk/PushPushGo; - public final fun getNotificationDetails (Landroid/content/Intent;)Lcom/pushpushgo/sdk/dto/PPGoNotification; - public final fun getNotificationDetails (Ljava/util/Map;)Lcom/pushpushgo/sdk/dto/PPGoNotification; - public final fun getNotificationHandler ()Lkotlin/jvm/functions/Function3; - public final fun getOnInvalidProjectIdHandler ()Lkotlin/jvm/functions/Function3; - public final fun getProjectId ()Ljava/lang/String; - public final fun getPushToken ()Lcom/google/common/util/concurrent/ListenableFuture; - public final fun getSubscriberId ()Ljava/lang/String; - public final fun handleBackgroundNotificationClick (Landroid/content/Intent;I)V - public static synthetic fun handleBackgroundNotificationClick$default (Lcom/pushpushgo/sdk/PushPushGo;Landroid/content/Intent;IILjava/lang/Object;)V - public final fun isPPGoPush (Landroid/content/Intent;)Z - public final fun isPPGoPush (Ljava/util/Map;)Z - public final fun isSubscribed ()Z - public final fun migrateToNewProject (Ljava/lang/String;Ljava/lang/String;)Lcom/google/common/util/concurrent/ListenableFuture; - public final fun registerSubscriber ()V - public final fun setCustomClickIntentFlags (I)V - public final fun setDefaultIsSubscribed (Z)V - public final fun setNotificationHandler (Lkotlin/jvm/functions/Function3;)V - public final fun setOnInvalidProjectIdHandler (Lkotlin/jvm/functions/Function3;)V - public final fun unregisterSubscriber ()V - public final fun unregisterSubscriber (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/google/common/util/concurrent/ListenableFuture; -} - -public final class com/pushpushgo/sdk/PushPushGo$Companion { - public final fun getInstance ()Lcom/pushpushgo/sdk/PushPushGo; - public final fun getInstance (Landroid/app/Application;)Lcom/pushpushgo/sdk/PushPushGo; - public final fun getInstance (Landroid/app/Application;Ljava/lang/String;Ljava/lang/String;Z)Lcom/pushpushgo/sdk/PushPushGo; - public final fun getInstance (Landroid/app/Application;Ljava/lang/String;Ljava/lang/String;ZZ)Lcom/pushpushgo/sdk/PushPushGo; - public final fun getInstance (Landroid/app/Application;Ljava/lang/String;Ljava/lang/String;ZZLjava/lang/String;)Lcom/pushpushgo/sdk/PushPushGo; - public static synthetic fun getInstance$default (Lcom/pushpushgo/sdk/PushPushGo$Companion;Landroid/app/Application;Ljava/lang/String;Ljava/lang/String;ZZLjava/lang/String;ILjava/lang/Object;)Lcom/pushpushgo/sdk/PushPushGo; - public final fun isInitialized ()Z -} - -public final class com/pushpushgo/sdk/bridge/PushPushGoSubscriptionBridgeManager : com/pushpushgo/sdk/bridge/PushSubscriptionBridgeManager { - public static final field Companion Lcom/pushpushgo/sdk/bridge/PushPushGoSubscriptionBridgeManager$Companion; - public fun ()V - public fun requestSubscription (Landroid/content/Context;)Z -} - -public final class com/pushpushgo/sdk/bridge/PushPushGoSubscriptionBridgeManager$Companion { -} - -public abstract interface class com/pushpushgo/sdk/bridge/PushSubscriptionBridgeManager { - public abstract fun requestSubscription (Landroid/content/Context;)Z -} - -public final class com/pushpushgo/sdk/dto/PPGoNotification { - public fun (Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun component1 ()Ljava/lang/String; - public final fun component2 ()Ljava/lang/String; - public final fun component3 ()I - public final fun component4 ()Ljava/lang/String; - public final fun component5 ()Ljava/lang/String; - public final fun copy (Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Lcom/pushpushgo/sdk/dto/PPGoNotification; - public static synthetic fun copy$default (Lcom/pushpushgo/sdk/dto/PPGoNotification;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/pushpushgo/sdk/dto/PPGoNotification; - public fun equals (Ljava/lang/Object;)Z - public final fun getBody ()Ljava/lang/String; - public final fun getCampaignId ()Ljava/lang/String; - public final fun getPriority ()I - public final fun getRedirectLink ()Ljava/lang/String; - public final fun getTitle ()Ljava/lang/String; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class com/pushpushgo/sdk/exception/PushPushException : java/io/IOException { -} - -public final class com/pushpushgo/sdk/push/service/FcmMessagingServiceDelegate { - public fun (Landroid/content/Context;)V - public final fun onDestroy ()V - public final fun onMessageReceived (Lcom/google/firebase/messaging/RemoteMessage;)V - public final fun onNewToken (Ljava/lang/String;)V -} - -public final class com/pushpushgo/sdk/push/service/HmsMessagingServiceDelegate { - public fun (Landroid/content/Context;)V - public final fun onDestroy ()V - public final fun onMessageReceived (Lcom/huawei/hms/push/RemoteMessage;)V - public final fun onNewToken (Ljava/lang/String;)V -} - diff --git a/library/build.gradle b/library/build.gradle deleted file mode 100644 index 92c132b7..00000000 --- a/library/build.gradle +++ /dev/null @@ -1,119 +0,0 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.dsl.KotlinVersion - -plugins { - id 'com.android.library' - id 'kotlin-android' - id 'maven-publish' - id('com.google.devtools.ksp').version('2.2.0-2.0.2') - alias(libs.plugins.dokka) - alias(libs.plugins.validator) - alias(libs.plugins.ktlint) -} - -apply from: 'jacoco.gradle' - -tasks.named("dokkaHtml") { - moduleName.set("PushPushGo SDK") -} - -android { - namespace 'com.pushpushgo.sdk' - compileSdk 36 - - defaultConfig { - minSdk 23 - targetSdk 36 - - consumerProguardFiles("ppgo-sdk.pro") - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - - buildTypes { - release { - minifyEnabled false - } - } - buildFeatures { - buildConfig true - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_17 - targetCompatibility JavaVersion.VERSION_17 - } - kotlin { - compilerOptions { - jvmTarget = JvmTarget.fromTarget("17") - languageVersion = KotlinVersion.fromVersion("2.1") - apiVersion = KotlinVersion.fromVersion("2.1") - } - } - - testOptions { - unitTests { - includeAndroidResources = true - } - } - publishing { - singleVariant("release") { - withSourcesJar() - } - } -} - -dependencies { - implementation libs.androidx.core.ktx - implementation libs.androidx.preference - - implementation libs.kodein - - implementation libs.coroutines.core - implementation libs.coroutines.android - implementation libs.coroutines.guava - - implementation libs.retrofit - implementation libs.retrofit.moshi - implementation platform(libs.okhttp.bom) - implementation 'com.squareup.okhttp3:logging-interceptor' - - implementation libs.moshi.kotlin - ksp libs.moshi.codegen - implementation libs.moshi.adapters - - implementation libs.androidx.work.runtime - implementation libs.androidx.work.gcm - - compileOnly platform(libs.firebase.bom) - compileOnly 'com.google.firebase:firebase-messaging' - - compileOnly libs.hms.push - - // testing - testImplementation 'junit:junit:4.13.2' - testImplementation 'io.mockk:mockk:1.14.5' - testImplementation 'org.json:json:20250517' - testImplementation 'androidx.test.ext:junit-ktx:1.3.0' - testImplementation 'org.robolectric:robolectric:4.15.1' - - testImplementation platform(libs.firebase.bom) - testImplementation 'com.google.firebase:firebase-messaging' -} - -tasks.register('androidSourcesJar', Jar) { - archiveClassifier.set('sources') - from android.sourceSets.main.java.srcDirs -} - -publishing { - publications { - release(MavenPublication) { - groupId = 'com.pushpushgo' - artifactId = 'sdk' - version = libs.versions.sdk.get() - - afterEvaluate { - from components.release - } - } - } -} diff --git a/library/jacoco.gradle b/library/jacoco.gradle deleted file mode 100644 index 2e76184f..00000000 --- a/library/jacoco.gradle +++ /dev/null @@ -1,40 +0,0 @@ -apply plugin: "jacoco" - -jacoco { - toolVersion "0.8.11" - reportsDirectory.set(layout.buildDirectory.dir('reports')) -} - -tasks.register('jacocoTestReport', JacocoReport) { - group = "Reporting" - description = "Generate Jacoco coverage reports" - - reports { - xml.required.set(true) - html.required.set(true) - } - - def excludes = [ - '**/R.class', - '**/R$*.class', - '**/BuildConfig.*', - '**/*Test*.*', - '**/*JsonAdapter.*' - ] - - classDirectories.setFrom(fileTree( - dir: "$buildDir/intermediates/classes/debug", - excludes: excludes - ) + fileTree( - dir: "$buildDir/tmp/kotlin-classes/debug", - excludes: excludes - )) - - sourceDirectories.setFrom(files([ - "src/main/java" - ])) - executionData.setFrom(fileTree( - dir: project.projectDir, - includes: ["**/*.exec", "**/*.ec"] - )) -} diff --git a/library/src/main/java/com/pushpushgo/sdk/bridge/PushSubscriptionManager.kt b/library/src/main/java/com/pushpushgo/sdk/bridge/PushSubscriptionManager.kt deleted file mode 100644 index 4aba394d..00000000 --- a/library/src/main/java/com/pushpushgo/sdk/bridge/PushSubscriptionManager.kt +++ /dev/null @@ -1,72 +0,0 @@ -package com.pushpushgo.sdk.bridge - -import android.Manifest -import android.app.Activity -import android.content.Context -import android.content.pm.PackageManager -import android.os.Build -import android.util.Log -import androidx.core.app.ActivityCompat -import androidx.core.content.ContextCompat -import com.pushpushgo.sdk.PushPushGo -import com.pushpushgo.sdk.push.areNotificationsEnabled - -/** - * Bridge interface that allows other components (in-app messages library) - * to request push notification subscription without creating direct dependencies. - */ -interface PushSubscriptionBridgeManager { - /** - * Request user to subscribe to push notifications - * - * @param context Android context - * @return true if the subscription request was successfully initiated - */ - fun requestSubscription(context: Context): Boolean -} - -class PushPushGoSubscriptionBridgeManager : PushSubscriptionBridgeManager { - companion object { - private const val TAG = "PushSubscriptionManager" - private const val NOTIFICATION_PERMISSION_REQUEST_CODE = 1001 - } - - override fun requestSubscription(context: Context): Boolean { - try { - if (!PushPushGo.isInitialized()) { - Log.e(TAG, "PushPushGo SDK is not initialized") - return false - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - if (ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) - != PackageManager.PERMISSION_GRANTED - ) { - if (context is Activity) { - Log.d(TAG, "Requesting POST_NOTIFICATIONS permission") - ActivityCompat.requestPermissions( - context, - arrayOf(Manifest.permission.POST_NOTIFICATIONS), - NOTIFICATION_PERMISSION_REQUEST_CODE, - ) - } else { - Log.w(TAG, "Cannot request permission: context is not an Activity") - return false - } - } - } - - val pushSdk = PushPushGo.getInstance() - Log.d(TAG, "Requesting push notification subscription") - pushSdk.registerSubscriber() - - val notificationsEnabled = areNotificationsEnabled(context) - Log.d(TAG, "Notifications enabled after registration: $notificationsEnabled") - - return notificationsEnabled - } catch (e: Exception) { - Log.e(TAG, "Error requesting subscription", e) - return false - } - } -} diff --git a/library/src/main/java/com/pushpushgo/sdk/utils/LogUtils.kt b/library/src/main/java/com/pushpushgo/sdk/utils/LogUtils.kt deleted file mode 100644 index 6f8a1bad..00000000 --- a/library/src/main/java/com/pushpushgo/sdk/utils/LogUtils.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.pushpushgo.sdk.utils - -import android.util.Log -import com.pushpushgo.sdk.PushPushGo - -internal fun logDebug(text: String) { - if (!PushPushGo.getInstance().isDebug) return - - Log.d(PushPushGo.TAG, text) -} - -internal fun logWarning(text: String) { - Log.w(PushPushGo.TAG, text) -} - -internal fun logError( - text: String, - exception: Throwable? = null, -) { - Log.e(PushPushGo.TAG, text, exception) -} - -internal fun logError(exception: Throwable?) { - Log.e(PushPushGo.TAG, exception?.message, exception) -} diff --git a/library/src/main/java/com/pushpushgo/sdk/utils/StringValidationExtension.kt b/library/src/main/java/com/pushpushgo/sdk/utils/StringValidationExtension.kt deleted file mode 100644 index 9c361200..00000000 --- a/library/src/main/java/com/pushpushgo/sdk/utils/StringValidationExtension.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.pushpushgo.sdk.utils - -import com.pushpushgo.sdk.exception.PushPushException - -internal fun validateApiKey(apiKey: String) { - if (!"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$".toRegex().matches(apiKey)) { - throw PushPushException("Invalid API key! Current API key: `$apiKey`") - } -} - -internal fun validateProjectId(projectId: String) { - if (!"[a-z0-9]{24}".toRegex().matches(projectId)) { - throw PushPushException("Invalid project ID! Current project ID: `$projectId`") - } -} diff --git a/library/src/test/java/com/pushpushgo/sdk/utils/StringValidationExtensionKtTest.kt b/library/src/test/java/com/pushpushgo/sdk/utils/StringValidationExtensionKtTest.kt deleted file mode 100644 index 3a69e8f2..00000000 --- a/library/src/test/java/com/pushpushgo/sdk/utils/StringValidationExtensionKtTest.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.pushpushgo.sdk.utils - -import org.junit.Assert.assertEquals -import org.junit.Assert.assertTrue -import org.junit.Test - -class StringValidationExtensionKtTest { - @Test - fun `check valid api key`() { - val result = runCatching { validateApiKey("57118b49-eb83-4de4-aea9-872144b443fc") } - assertTrue(result.isSuccess) - } - - @Test - fun `check invalid api key`() { - val result = runCatching { validateApiKey("empty1") } - assertTrue(result.isFailure) - assertEquals("Invalid API key! Current API key: `empty1`", result.exceptionOrNull()?.message) - } - - @Test - fun `check valid project id`() { - val result = kotlin.runCatching { validateProjectId("5d411352784425000bd02a15") } - assertTrue(result.isSuccess) - } - - @Test - fun `check invalid project id`() { - val result = runCatching { validateProjectId("empty2") } - assertTrue(result.isFailure) - assertEquals("Invalid project ID! Current project ID: `empty2`", result.exceptionOrNull()?.message) - } -} diff --git a/library/.gitignore b/push/.gitignore similarity index 100% rename from library/.gitignore rename to push/.gitignore diff --git a/library-no-op/api/library-no-op.api b/push/api/push.api similarity index 53% rename from library-no-op/api/library-no-op.api rename to push/api/push.api index d4bc9725..b0ffdfd0 100644 --- a/library-no-op/api/library-no-op.api +++ b/push/api/push.api @@ -1,68 +1,70 @@ -public final class com/pushpushgo/sdk/BeaconBuilder { - public final fun appendTag (Ljava/lang/String;)Lcom/pushpushgo/sdk/BeaconBuilder; - public final fun appendTag (Ljava/lang/String;Ljava/lang/String;)Lcom/pushpushgo/sdk/BeaconBuilder; - public final fun appendTag (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/pushpushgo/sdk/BeaconBuilder; - public final fun appendTag (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Lcom/pushpushgo/sdk/BeaconBuilder; - public static synthetic fun appendTag$default (Lcom/pushpushgo/sdk/BeaconBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IILjava/lang/Object;)Lcom/pushpushgo/sdk/BeaconBuilder; +public final class com/pushpushgo/sdk/push/BeaconBuilder { + public final fun appendTag (Ljava/lang/String;)Lcom/pushpushgo/sdk/push/BeaconBuilder; + public final fun appendTag (Ljava/lang/String;Ljava/lang/String;)Lcom/pushpushgo/sdk/push/BeaconBuilder; + public final fun appendTag (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/pushpushgo/sdk/push/BeaconBuilder; + public final fun appendTag (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Lcom/pushpushgo/sdk/push/BeaconBuilder; + public static synthetic fun appendTag$default (Lcom/pushpushgo/sdk/push/BeaconBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IILjava/lang/Object;)Lcom/pushpushgo/sdk/push/BeaconBuilder; public final fun getTags ()Ljava/util/List; public final fun getTagsToDelete ()Ljava/util/List; - public final fun removeTag ([Ljava/lang/String;)Lcom/pushpushgo/sdk/BeaconBuilder; + public final fun removeTag ([Ljava/lang/String;)Lcom/pushpushgo/sdk/push/BeaconBuilder; + public final fun removeTags (Ljava/util/Map;)Lcom/pushpushgo/sdk/push/BeaconBuilder; public final fun send ()V - public final fun set (Ljava/lang/String;Ljava/lang/Object;)Lcom/pushpushgo/sdk/BeaconBuilder; - public final fun setCustomId (Ljava/lang/Integer;)Lcom/pushpushgo/sdk/BeaconBuilder; - public final fun setCustomId (Ljava/lang/String;)Lcom/pushpushgo/sdk/BeaconBuilder; + public final fun set (Ljava/lang/String;Ljava/lang/Object;)Lcom/pushpushgo/sdk/push/BeaconBuilder; + public final fun setCustomId (Ljava/lang/Integer;)Lcom/pushpushgo/sdk/push/BeaconBuilder; + public final fun setCustomId (Ljava/lang/String;)Lcom/pushpushgo/sdk/push/BeaconBuilder; } -public final class com/pushpushgo/sdk/BuildConfig { +public final class com/pushpushgo/sdk/push/BuildConfig { public static final field BUILD_TYPE Ljava/lang/String; public static final field DEBUG Z public static final field LIBRARY_PACKAGE_NAME Ljava/lang/String; public fun ()V } -public final class com/pushpushgo/sdk/PushPushGo { - public static final field Companion Lcom/pushpushgo/sdk/PushPushGo$Companion; +public final class com/pushpushgo/sdk/push/PushNotifications { + public static final field Companion Lcom/pushpushgo/sdk/push/PushNotifications$Companion; public static final field VERSION Ljava/lang/String; - public synthetic fun (Landroid/app/Application;Ljava/lang/String;Ljava/lang/String;ZZLjava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (Landroid/app/Application;Lcom/pushpushgo/sdk/core/config/Config;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun areNotificationsEnabled ()Z - public final fun createBeacon ()Lcom/pushpushgo/sdk/BeaconBuilder; + public final fun createBeacon ()Lcom/pushpushgo/sdk/push/BeaconBuilder; public final fun createSubscriber ()Lcom/google/common/util/concurrent/ListenableFuture; public final fun getApiKey ()Ljava/lang/String; + public final fun getCustomClickIntentFlags ()I public final fun getDefaultIsSubscribed ()Z - public static final fun getInstance ()Lcom/pushpushgo/sdk/PushPushGo; - public static final fun getInstance (Landroid/app/Application;)Lcom/pushpushgo/sdk/PushPushGo; - public static final fun getInstance (Landroid/app/Application;Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;)Lcom/pushpushgo/sdk/PushPushGo; - public static final fun getInstance (Landroid/app/Application;Ljava/lang/String;Ljava/lang/String;ZZLjava/lang/String;)Lcom/pushpushgo/sdk/PushPushGo; - public final fun getNotificationDetails (Landroid/content/Intent;)Lcom/pushpushgo/sdk/dto/PPGoNotification; - public final fun getNotificationDetails (Ljava/util/Map;)Lcom/pushpushgo/sdk/dto/PPGoNotification; - public final fun getNotificationHandler ()Lkotlin/jvm/functions/Function2; + public static final fun getInstance ()Lcom/pushpushgo/sdk/push/PushNotifications; + public final fun getNotificationDetails (Landroid/content/Intent;)Lcom/pushpushgo/sdk/push/dto/PPGoNotification; + public final fun getNotificationDetails (Ljava/util/Map;)Lcom/pushpushgo/sdk/push/dto/PPGoNotification; + public final fun getNotificationHandler ()Lkotlin/jvm/functions/Function3; public final fun getOnInvalidProjectIdHandler ()Lkotlin/jvm/functions/Function3; public final fun getProjectId ()Ljava/lang/String; + public final fun getPushSubscriptionProvider ()Lcom/pushpushgo/sdk/core/push/PushSubscriptionProvider; public final fun getPushToken ()Lcom/google/common/util/concurrent/ListenableFuture; public final fun getSubscriberId ()Ljava/lang/String; - public final fun handleBackgroundNotificationClick (Landroid/content/Intent;)V + public final fun handleBackgroundNotificationClick (Landroid/content/Intent;I)V + public static synthetic fun handleBackgroundNotificationClick$default (Lcom/pushpushgo/sdk/push/PushNotifications;Landroid/content/Intent;IILjava/lang/Object;)V + public static final fun initialize (Landroid/app/Application;)Lcom/pushpushgo/sdk/push/PushNotifications; + public static final fun initialize (Landroid/app/Application;Lcom/pushpushgo/sdk/core/config/Config;)Lcom/pushpushgo/sdk/push/PushNotifications; public final fun isPPGoPush (Landroid/content/Intent;)Z public final fun isPPGoPush (Ljava/util/Map;)Z public final fun isSubscribed ()Z public final fun migrateToNewProject (Ljava/lang/String;Ljava/lang/String;)Lcom/google/common/util/concurrent/ListenableFuture; public final fun registerSubscriber ()V + public final fun setCustomClickIntentFlags (I)V public final fun setDefaultIsSubscribed (Z)V - public final fun setNotificationHandler (Lkotlin/jvm/functions/Function2;)V + public final fun setNotificationHandler (Lkotlin/jvm/functions/Function3;)V public final fun setOnInvalidProjectIdHandler (Lkotlin/jvm/functions/Function3;)V public final fun unregisterSubscriber ()V public final fun unregisterSubscriber (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/google/common/util/concurrent/ListenableFuture; } -public final class com/pushpushgo/sdk/PushPushGo$Companion { - public final fun getInstance ()Lcom/pushpushgo/sdk/PushPushGo; - public final fun getInstance (Landroid/app/Application;)Lcom/pushpushgo/sdk/PushPushGo; - public final fun getInstance (Landroid/app/Application;Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;)Lcom/pushpushgo/sdk/PushPushGo; - public final fun getInstance (Landroid/app/Application;Ljava/lang/String;Ljava/lang/String;ZZLjava/lang/String;)Lcom/pushpushgo/sdk/PushPushGo; - public static synthetic fun getInstance$default (Lcom/pushpushgo/sdk/PushPushGo$Companion;Landroid/app/Application;Ljava/lang/String;Ljava/lang/String;ZZLjava/lang/String;ILjava/lang/Object;)Lcom/pushpushgo/sdk/PushPushGo; +public final class com/pushpushgo/sdk/push/PushNotifications$Companion { + public final fun getInstance ()Lcom/pushpushgo/sdk/push/PushNotifications; + public final fun initialize (Landroid/app/Application;)Lcom/pushpushgo/sdk/push/PushNotifications; + public final fun initialize (Landroid/app/Application;Lcom/pushpushgo/sdk/core/config/Config;)Lcom/pushpushgo/sdk/push/PushNotifications; public final fun isInitialized ()Z } -public final class com/pushpushgo/sdk/dto/PPGoNotification { +public final class com/pushpushgo/sdk/push/dto/PPGoNotification { public fun (Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V public synthetic fun (Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/String; @@ -70,8 +72,8 @@ public final class com/pushpushgo/sdk/dto/PPGoNotification { public final fun component3 ()I public final fun component4 ()Ljava/lang/String; public final fun component5 ()Ljava/lang/String; - public final fun copy (Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Lcom/pushpushgo/sdk/dto/PPGoNotification; - public static synthetic fun copy$default (Lcom/pushpushgo/sdk/dto/PPGoNotification;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/pushpushgo/sdk/dto/PPGoNotification; + public final fun copy (Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Lcom/pushpushgo/sdk/push/dto/PPGoNotification; + public static synthetic fun copy$default (Lcom/pushpushgo/sdk/push/dto/PPGoNotification;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/pushpushgo/sdk/push/dto/PPGoNotification; public fun equals (Ljava/lang/Object;)Z public final fun getBody ()Ljava/lang/String; public final fun getCampaignId ()Ljava/lang/String; @@ -82,20 +84,28 @@ public final class com/pushpushgo/sdk/dto/PPGoNotification { public fun toString ()Ljava/lang/String; } -public final class com/pushpushgo/sdk/exception/PushPushException : java/io/IOException { +public final class com/pushpushgo/sdk/push/exception/PushPushException : java/io/IOException { } -public final class com/pushpushgo/sdk/push/service/FcmMessagingServiceDelegate { +public final class com/pushpushgo/sdk/push/push/service/FcmMessagingServiceDelegate { public fun (Landroid/content/Context;)V public final fun onDestroy ()V public final fun onMessageReceived (Lcom/google/firebase/messaging/RemoteMessage;)V public final fun onNewToken (Ljava/lang/String;)V } -public final class com/pushpushgo/sdk/push/service/HmsMessagingServiceDelegate { +public final class com/pushpushgo/sdk/push/push/service/HmsMessagingServiceDelegate { public fun (Landroid/content/Context;)V public final fun onDestroy ()V public final fun onMessageReceived (Lcom/huawei/hms/push/RemoteMessage;)V public final fun onNewToken (Ljava/lang/String;)V } +public final class com/pushpushgo/sdk/push/subscription/DefaultPushSubscriptionProvider : com/pushpushgo/sdk/core/push/PushSubscriptionProvider { + public fun getSubscriberId ()Ljava/lang/String; + public fun isNotificationChannelEnabled ()Z + public fun isSubscribed ()Z + public fun subscribe (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun unsubscribe (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + diff --git a/push/build.gradle.kts b/push/build.gradle.kts new file mode 100644 index 00000000..fe63dfc1 --- /dev/null +++ b/push/build.gradle.kts @@ -0,0 +1,104 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion + +plugins { + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.ksp) + alias(libs.plugins.binary.validator) + alias(libs.plugins.ktlint) + id("maven-publish") +} + +android { + namespace = "com.pushpushgo.sdk.push" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + consumerProguardFiles("ppgo-sdk.pro") + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + } + } + + buildFeatures { + buildConfig = true + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlin { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + languageVersion.set(KotlinVersion.KOTLIN_2_1) + apiVersion.set(KotlinVersion.KOTLIN_2_1) + } + } + + testOptions { + unitTests { + isIncludeAndroidResources = true + } + } + + publishing { + singleVariant("release") { + withSourcesJar() + } + } +} + +dependencies { + if (System.getenv("JITPACK") == null) { + api(project(":core")) + } + + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.preference) + + implementation(libs.kodein) + + implementation(libs.coroutines.core) + implementation(libs.coroutines.android) + implementation(libs.coroutines.guava) + + implementation(libs.retrofit) + implementation(libs.retrofit.moshi) + + implementation(platform(libs.okhttp.bom)) + implementation(libs.okhttp.logging) + + ksp(libs.moshi.codegen) + implementation(libs.moshi.kotlin) + implementation(libs.moshi.adapters) + + implementation(libs.androidx.work.runtime) + implementation(libs.androidx.work.gcm) + + compileOnly(platform(libs.firebase.bom)) + compileOnly(libs.firebase.messaging) + + compileOnly(libs.hms.push) + + testImplementation(libs.junit) + testImplementation(libs.mockk) + testImplementation(libs.json) + testImplementation(libs.androidx.test.junit) + testImplementation(libs.robolectric) + + testImplementation(platform(libs.firebase.bom)) + testImplementation(libs.firebase.messaging) +} + +apiValidation { + ignoredProjects.addAll(listOf("firebase", "hms", "java")) +} diff --git a/library/ppgo-sdk.pro b/push/ppgo-sdk.pro similarity index 100% rename from library/ppgo-sdk.pro rename to push/ppgo-sdk.pro diff --git a/sample/.gitignore b/push/sample/firebase/.gitignore similarity index 100% rename from sample/.gitignore rename to push/sample/firebase/.gitignore diff --git a/push/sample/firebase/build.gradle.kts b/push/sample/firebase/build.gradle.kts new file mode 100644 index 00000000..6b6b950b --- /dev/null +++ b/push/sample/firebase/build.gradle.kts @@ -0,0 +1,78 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.google.services) + alias(libs.plugins.ktlint) +} + +android { + namespace = "com.pushpushgo.sdk.sample.push.firebase" + compileSdk = 36 + + defaultConfig { + minSdk = 23 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + signingConfigs { + create("release") { + storeFile = file("../../../keystore.jks") + storePassword = "demo123" + keyAlias = "key0" + keyPassword = "demo123" + } + + getByName("debug") { + storeFile = file("../../../keystore.jks") + storePassword = "demo123" + keyAlias = "key0" + keyPassword = "demo123" + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlin { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + } + } + + buildTypes { + release { + isMinifyEnabled = true + isShrinkResources = true + + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro", + ) + + signingConfig = signingConfigs.getByName("release") + } + + debug { + signingConfig = signingConfigs.getByName("debug") + } + } +} + +dependencies { + implementation(project(":push")) + + implementation(libs.timber) + implementation(libs.guava) + + implementation(libs.androidx.appcompat) + implementation(libs.androidx.constraintlayout) + implementation(libs.androidx.lifecycle.runtime) + + implementation(platform(libs.firebase.bom)) + implementation(libs.firebase.messaging) +} diff --git a/samplejava/google-services.json b/push/sample/firebase/google-services.json similarity index 93% rename from samplejava/google-services.json rename to push/sample/firebase/google-services.json index c5e82a9c..53f7dec9 100644 --- a/samplejava/google-services.json +++ b/push/sample/firebase/google-services.json @@ -10,7 +10,7 @@ "client_info": { "mobilesdk_app_id": "1:120314134586:android:01615cfde51b13c2393503", "android_client_info": { - "package_name": "com.pushpushgo.samplejava" + "package_name": "com.pushpushgo.sdk.sample.push.firebase" } }, "oauth_client": [ @@ -37,4 +37,4 @@ } ], "configuration_version": "1" -} \ No newline at end of file +} diff --git a/sample/proguard-rules.pro b/push/sample/firebase/proguard-rules.pro similarity index 100% rename from sample/proguard-rules.pro rename to push/sample/firebase/proguard-rules.pro diff --git a/sample/src/main/AndroidManifest.xml b/push/sample/firebase/src/main/AndroidManifest.xml similarity index 100% rename from sample/src/main/AndroidManifest.xml rename to push/sample/firebase/src/main/AndroidManifest.xml diff --git a/sample/src/main/ic_launcher-playstore.png b/push/sample/firebase/src/main/ic_launcher-playstore.png similarity index 100% rename from sample/src/main/ic_launcher-playstore.png rename to push/sample/firebase/src/main/ic_launcher-playstore.png diff --git a/push/sample/firebase/src/main/java/com/pushpushgo/sdk/sample/push/firebase/MainApplication.kt b/push/sample/firebase/src/main/java/com/pushpushgo/sdk/sample/push/firebase/MainApplication.kt new file mode 100644 index 00000000..5935a8bf --- /dev/null +++ b/push/sample/firebase/src/main/java/com/pushpushgo/sdk/sample/push/firebase/MainApplication.kt @@ -0,0 +1,18 @@ +package com.pushpushgo.sdk.sample.push.firebase + +import android.app.Application +import android.content.Intent +import com.pushpushgo.sdk.push.PushNotifications +import timber.log.Timber + +class MainApplication : Application() { + override fun onCreate() { + super.onCreate() + + Timber.plant(Timber.DebugTree()) + + PushNotifications + .initialize(this) + .setCustomClickIntentFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) + } +} diff --git a/push/sample/firebase/src/main/java/com/pushpushgo/sdk/sample/push/firebase/activity/BeaconActivity.kt b/push/sample/firebase/src/main/java/com/pushpushgo/sdk/sample/push/firebase/activity/BeaconActivity.kt new file mode 100644 index 00000000..0a033efe --- /dev/null +++ b/push/sample/firebase/src/main/java/com/pushpushgo/sdk/sample/push/firebase/activity/BeaconActivity.kt @@ -0,0 +1,88 @@ +package com.pushpushgo.sdk.sample.push.firebase.activity + +import android.annotation.SuppressLint +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.widget.Button +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import com.pushpushgo.sdk.push.PushNotifications +import com.pushpushgo.sdk.sample.push.firebase.R +import timber.log.Timber +import java.text.SimpleDateFormat +import java.util.Date + +class BeaconActivity : AppCompatActivity(R.layout.activity_beacon) { + private val ppg by lazy { PushNotifications.getInstance() } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + Timber.plant( + object : Timber.Tree() { + @SuppressLint("SetTextI18n", "SimpleDateFormat") + override fun log( + priority: Int, + tag: String?, + message: String, + t: Throwable?, + ) { + if (priority > Log.VERBOSE) { + with(findViewById(R.id.logs)) { + post { text = "${SimpleDateFormat("HH:mm:ss").format(Date())}: $message\n$text" } + } + } + } + }, + ) + + findViewById