diff --git a/personalization-sdk/src/main/kotlin/com/personalization/features/inAppNotification/impl/InAppNotificationManagerImpl.kt b/personalization-sdk/src/main/kotlin/com/personalization/features/inAppNotification/impl/InAppNotificationManagerImpl.kt index 5337197f..8e5ff003 100644 --- a/personalization-sdk/src/main/kotlin/com/personalization/features/inAppNotification/impl/InAppNotificationManagerImpl.kt +++ b/personalization-sdk/src/main/kotlin/com/personalization/features/inAppNotification/impl/InAppNotificationManagerImpl.kt @@ -4,7 +4,11 @@ import android.app.Activity import android.content.Context import android.content.Intent import android.net.Uri +import android.os.Build +import android.provider.Settings import android.view.View +import android.widget.Toast +import androidx.core.app.NotificationManagerCompat import androidx.core.content.ContextCompat import androidx.fragment.app.FragmentManager import com.personalization.R @@ -14,6 +18,7 @@ import com.personalization.inAppNotification.view.component.dialog.AlertDialog import com.personalization.inAppNotification.view.component.dialog.BottomSheetDialog import com.personalization.inAppNotification.view.component.dialog.FullScreenDialog import com.personalization.inAppNotification.view.component.snackbar.Snackbar +import com.personalization.sdk.data.models.dto.popUp.DialogDataDto import com.personalization.sdk.data.models.dto.popUp.PopupDto import com.personalization.sdk.data.models.dto.popUp.Position import com.personalization.ui.click.NotificationClickListener @@ -29,76 +34,76 @@ class InAppNotificationManagerImpl @Inject constructor( this.fragmentManager = fragmentManager } - private fun openUrlInBrowser(url: String?) { - if (url.isNullOrEmpty()) { - EmptyFieldError( - tag = TAG, - functionName = FUNC_OPENING_BROWSER, - ) - return - } - - try { - val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) - if (context !is Activity) { - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - context.startActivity(intent) - } catch (exception: Exception) { - exception.printStackTrace() - } + override fun shopPopUp(popupDto: PopupDto) { + val dialogData = extractDialogData(popupDto) + showDialog(dialogData) } - override fun shopPopUp(popupDto: PopupDto) { + private fun extractDialogData(popupDto: PopupDto): DialogDataDto { val deepLink = popupDto.popupActions?.link?.linkAndroid ?: popupDto.popupActions?.link?.linkWeb val buttonPositiveColor = ContextCompat.getColor(context, R.color.buttonAcceptColor) val buttonNegativeColor = ContextCompat.getColor(context, R.color.colorGray) + val buttonSubscription = popupDto.popupActions?.pushSubscribe?.buttonText val buttonNegativeText = popupDto.popupActions?.close?.buttonText - val buttonPositiveText = popupDto.popupActions?.link?.buttonText + val buttonPositiveText = buttonSubscription ?: popupDto.popupActions?.link?.buttonText val imageUrl: String? = popupDto.components?.image val title: String? = popupDto.components?.header val message: String? = popupDto.components?.text val position: Position = popupDto.position - when (position) { + val onPositiveClick = if (buttonSubscription != null) { + { requestPushNotifications() } + } else { + { openUrlInBrowser(url = deepLink) } + } + + return DialogDataDto( + title = title.orEmpty(), + message = message.orEmpty(), + imageUrl = imageUrl.orEmpty(), + buttonPositiveColor = buttonPositiveColor, + buttonNegativeColor = buttonNegativeColor, + buttonPositiveText = buttonPositiveText.orEmpty(), + buttonNegativeText = buttonNegativeText.orEmpty(), + onPositiveClick = onPositiveClick, + position = position + ) + } + + private fun showDialog(dialogData: DialogDataDto) { + when (dialogData.position) { Position.CENTERED -> showAlertDialog( - title = title.orEmpty(), - message = message.orEmpty(), - imageUrl = imageUrl.orEmpty(), - buttonPositiveColor = buttonPositiveColor, - buttonNegativeColor = buttonNegativeColor, - buttonPositiveText = buttonPositiveText.orEmpty(), - buttonNegativeText = buttonNegativeText.orEmpty(), - onPositiveClick = { - openUrlInBrowser(url = deepLink) - } + title = dialogData.title, + message = dialogData.message, + imageUrl = dialogData.imageUrl, + buttonPositiveColor = dialogData.buttonPositiveColor, + buttonNegativeColor = dialogData.buttonNegativeColor, + buttonPositiveText = dialogData.buttonPositiveText, + buttonNegativeText = dialogData.buttonNegativeText, + onPositiveClick = dialogData.onPositiveClick ) Position.BOTTOM -> showBottomSheetDialog( - title = title.orEmpty(), - message = message.orEmpty(), - imageUrl = imageUrl.orEmpty(), - buttonPositiveColor = buttonPositiveColor, - buttonNegativeColor = buttonNegativeColor, - buttonPositiveText = buttonPositiveText.orEmpty(), - buttonNegativeText = buttonNegativeText.orEmpty(), - onPositiveClick = { - openUrlInBrowser(url = deepLink) - } + title = dialogData.title, + message = dialogData.message, + imageUrl = dialogData.imageUrl, + buttonPositiveColor = dialogData.buttonPositiveColor, + buttonNegativeColor = dialogData.buttonNegativeColor, + buttonPositiveText = dialogData.buttonPositiveText, + buttonNegativeText = dialogData.buttonNegativeText, + onPositiveClick = dialogData.onPositiveClick ) else -> showFullScreenDialog( - title = title.orEmpty(), - message = message.orEmpty(), - imageUrl = imageUrl.orEmpty(), - buttonPositiveColor = buttonPositiveColor, - buttonNegativeColor = buttonNegativeColor, - buttonPositiveText = buttonPositiveText.orEmpty(), - buttonNegativeText = buttonNegativeText.orEmpty(), - onPositiveClick = { - openUrlInBrowser(url = deepLink) - } + title = dialogData.title, + message = dialogData.message, + imageUrl = dialogData.imageUrl, + buttonPositiveColor = dialogData.buttonPositiveColor, + buttonNegativeColor = dialogData.buttonNegativeColor, + buttonPositiveText = dialogData.buttonPositiveText, + buttonNegativeText = dialogData.buttonNegativeText, + onPositiveClick = dialogData.onPositiveClick ) } } @@ -225,6 +230,52 @@ class InAppNotificationManagerImpl @Inject constructor( ) } + private fun openUrlInBrowser(url: String?) { + if (url.isNullOrEmpty()) { + EmptyFieldError( + tag = TAG, + functionName = FUNC_OPENING_BROWSER, + ) + return + } + + try { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + if (context !is Activity) { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } + context.startActivity(intent) + } catch (exception: Exception) { + exception.printStackTrace() + } + } + + private fun requestPushNotifications() { + val notificationManager = NotificationManagerCompat.from(context) + if (!notificationManager.areNotificationsEnabled()) { + val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply { + putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName) + } + } else { + Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.parse("package:${context.packageName}") + } + } + + if (context !is Activity) { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } + context.startActivity(intent) + } else { + Toast.makeText( + /* context = */ context, + /* text = */ context.getText(R.string.has_notification_permission_message), + /* duration = */ Toast.LENGTH_SHORT + ).show() + } + } + companion object { private const val TAG = "InAppNotificationManagerImpl" private const val FUNC_OPENING_BROWSER = "openUrlInBrowser" diff --git a/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/mappers/popup/action/PopupActionsMapper.kt b/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/mappers/popup/action/PopupActionsMapper.kt index 9c30afe2..60030c31 100644 --- a/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/mappers/popup/action/PopupActionsMapper.kt +++ b/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/mappers/popup/action/PopupActionsMapper.kt @@ -5,6 +5,7 @@ import com.personalization.sdk.data.mappers.popup.link.LinkMapper import com.personalization.sdk.data.models.dto.popUp.PopupActions import com.personalization.sdk.data.models.params.SdkInitializationParams.PARAM_CLOSE import com.personalization.sdk.data.models.params.SdkInitializationParams.PARAM_LINK +import com.personalization.sdk.data.models.params.SdkInitializationParams.PARAM_PUSH_SUBSCRIPTION import com.personalization.sdk.data.models.params.SdkInitializationParams.TAG import org.json.JSONObject @@ -12,7 +13,9 @@ object PopupActionsMapper { fun map(json: JSONObject): PopupActions? = try { PopupActions( link = json.optJSONObject(PARAM_LINK)?.let { LinkMapper.map(it) }, - close = json.optJSONObject(PARAM_CLOSE)?.let { CloseActionMapper.map(it) } + close = json.optJSONObject(PARAM_CLOSE)?.let { CloseActionMapper.map(it) }, + pushSubscribe = json.optJSONObject(PARAM_PUSH_SUBSCRIPTION) + ?.let { PushSubscriptionMapper.map(it) } ) } catch (exception: Exception) { JsonResponseErrorHandler(TAG, null).logError( diff --git a/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/mappers/popup/action/PushSubscriptionMapper.kt b/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/mappers/popup/action/PushSubscriptionMapper.kt new file mode 100644 index 00000000..56f346bb --- /dev/null +++ b/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/mappers/popup/action/PushSubscriptionMapper.kt @@ -0,0 +1,11 @@ +package com.personalization.sdk.data.mappers.popup.action + +import com.personalization.sdk.data.models.dto.popUp.PushSubscribe +import com.personalization.sdk.data.models.params.SdkInitializationParams.PARAM_BUTTON_TEXT +import org.json.JSONObject + +object PushSubscriptionMapper { + fun map(json: JSONObject): PushSubscribe = PushSubscribe( + buttonText = json.optString(PARAM_BUTTON_TEXT) + ) +} diff --git a/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/models/dto/popUp/DialogDataDto.kt b/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/models/dto/popUp/DialogDataDto.kt new file mode 100644 index 00000000..5ee7f2ad --- /dev/null +++ b/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/models/dto/popUp/DialogDataDto.kt @@ -0,0 +1,13 @@ +package com.personalization.sdk.data.models.dto.popUp + +data class DialogDataDto( + val title: String, + val message: String, + val imageUrl: String, + val buttonPositiveColor: Int, + val buttonNegativeColor: Int, + val buttonPositiveText: String, + val buttonNegativeText: String, + val onPositiveClick: () -> Unit, + val position: Position +) diff --git a/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/models/dto/popUp/PopupActions.kt b/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/models/dto/popUp/PopupActions.kt index c4fb4a7c..098025ca 100644 --- a/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/models/dto/popUp/PopupActions.kt +++ b/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/models/dto/popUp/PopupActions.kt @@ -2,5 +2,6 @@ package com.personalization.sdk.data.models.dto.popUp data class PopupActions( val link: Link?, - val close: CloseAction? + val close: CloseAction?, + val pushSubscribe: PushSubscribe? ) diff --git a/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/models/dto/popUp/PushSubscribe.kt b/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/models/dto/popUp/PushSubscribe.kt new file mode 100644 index 00000000..522ccfb8 --- /dev/null +++ b/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/models/dto/popUp/PushSubscribe.kt @@ -0,0 +1,5 @@ +package com.personalization.sdk.data.models.dto.popUp + +data class PushSubscribe( + val buttonText: String? +) diff --git a/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/models/params/SdkInitializationParams.kt b/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/models/params/SdkInitializationParams.kt index 685f9a2f..aacd27c9 100644 --- a/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/models/params/SdkInitializationParams.kt +++ b/personalization-sdk/src/main/kotlin/com/personalization/sdk/data/models/params/SdkInitializationParams.kt @@ -24,6 +24,7 @@ object SdkInitializationParams { const val PARAM_BUTTON_TEXT = "button_text" const val PARAM_LINK_ANDROID = "link_android" const val PARAM_CLOSE = "close" + const val PARAM_PUSH_SUBSCRIPTION = "system_mobile_push_subscribe" const val PARAM_DID = "did" const val PARAM_SEANCE = "seance" const val PARAM_CURRENCY = "currency" diff --git a/personalization-sdk/src/main/res/values-ru/strings.xml b/personalization-sdk/src/main/res/values-ru/strings.xml index 9b02b0f1..cac0144c 100644 --- a/personalization-sdk/src/main/res/values-ru/strings.xml +++ b/personalization-sdk/src/main/res/values-ru/strings.xml @@ -12,5 +12,6 @@ Pizza ipsum dolor meat lovers buffalo. Garlic sauce party sautéed ipsum cheese. Meatball mayo extra peppers Chicago spinach olives. Philly black crust pineapple steak ranch large large. Chicken hand pie tossed pan mushrooms large Bianca deep. Mozzarella roll string party mouth style lovers Hawaiian pan. Ricotta mayo red pizza fresh style string string. Broccoli meatball wing cheese sautéed. Peppers ipsum Aussie cheese olives Philly Hawaiian Aussie cheese personal. Pork dolor sausage bell mozzarella pepperoni thin deep mushrooms. Error loading images. Invalid notification data. + Notifications are already enabled \ No newline at end of file diff --git a/personalization-sdk/src/main/res/values/strings.xml b/personalization-sdk/src/main/res/values/strings.xml index 81778c9e..441ddf8b 100644 --- a/personalization-sdk/src/main/res/values/strings.xml +++ b/personalization-sdk/src/main/res/values/strings.xml @@ -24,5 +24,6 @@ Pizza ipsum dolor meat lovers buffalo. Garlic sauce party sautéed ipsum cheese. Meatball mayo extra peppers Chicago spinach olives. Philly black crust pineapple steak ranch large large. Chicken hand pie tossed pan mushrooms large Bianca deep. Mozzarella roll string party mouth style lovers Hawaiian pan. Ricotta mayo red pizza fresh style string string. Broccoli meatball wing cheese sautéed. Peppers ipsum Aussie cheese olives Philly Hawaiian Aussie cheese personal. Pork dolor sausage bell mozzarella pepperoni thin deep mushrooms. Error loading images. Invalid notification data. + Notifications are already enabled