From 6bf568cb0876acea7c4ac2eb655679b01556c1ed Mon Sep 17 00:00:00 2001 From: Daniel Green Date: Fri, 4 Oct 2024 10:57:11 +0200 Subject: [PATCH 01/23] feat: Added buttons on alert dialog and initialization fragment manager --- .../main/kotlin/com/personalization/SDK.kt | 139 ++++++++++++------ .../api/managers/InAppNotificationManager.kt | 5 +- .../impl/InAppNotificationManagerImpl.kt | 41 +++--- .../view/DefaultAlertDialog.kt | 34 ++++- .../src/main/res/layout/alert_dialog.xml | 40 +++-- .../src/main/res/values/strings.xml | 2 +- .../sample/AbstractMainActivity.kt | 22 ++- 7 files changed, 196 insertions(+), 87 deletions(-) diff --git a/personalization-sdk/src/main/kotlin/com/personalization/SDK.kt b/personalization-sdk/src/main/kotlin/com/personalization/SDK.kt index ea0fe3e1..982d4768 100644 --- a/personalization-sdk/src/main/kotlin/com/personalization/SDK.kt +++ b/personalization-sdk/src/main/kotlin/com/personalization/SDK.kt @@ -4,6 +4,7 @@ import android.content.Context import android.os.Bundle import android.util.Log import androidx.core.util.Consumer +import androidx.fragment.app.FragmentManager import com.google.firebase.messaging.RemoteMessage import com.personalization.Params.InternalParameter import com.personalization.Params.TrackEvent @@ -35,6 +36,7 @@ open class SDK { internal lateinit var context: Context private lateinit var segment: String + lateinit var fragmentManager: FragmentManager private var onMessageListener: OnMessageListener? = null private var search: Search = Search(JSONObject()) @@ -107,8 +109,7 @@ open class SDK { sdkComponent.inject(this) initPreferencesUseCase.invoke( - context = context, - preferencesKey = preferencesKey + context = context, preferencesKey = preferencesKey ) this.context = context @@ -122,10 +123,7 @@ open class SDK { notificationHandler.initialize(context) initUserSettingsUseCase.invoke( - shopId = shopId, - shopSecretKey = shopSecretKey, - segment = segment, - stream = stream + shopId = shopId, shopSecretKey = shopSecretKey, segment = segment, stream = stream ) initNetworkUseCase.invoke( baseUrl = apiUrl @@ -153,6 +151,65 @@ open class SDK { storiesManager.showStories(context.mainLooper, code) } + fun initializeFragmentManager(fragmentManager: FragmentManager) { + this.fragmentManager = fragmentManager + } + + fun showAlertDialog( + title: String, + message: String, + buttonNegativeText: String, + buttonPositiveText: String, + onPositiveClick: () -> Unit, + onNegativeClick: () -> Unit + ) = inAppNotificationManager.showAlertDialog( + fragmentManager = fragmentManager, + title = title, + message = message, + buttonNegativeText = buttonNegativeText, + buttonPositiveText = buttonPositiveText, + onNegativeClick = onNegativeClick, + onPositiveClick = onPositiveClick, + ) + + fun showFullScreenDialog( + title: String, + message: String, + imageUrl: String, + buttonNegativeText: String, + buttonPositiveText: String, + onPositiveClick: () -> Unit, + onNegativeClick: () -> Unit + ) = inAppNotificationManager.showFullScreenDialog( + fragmentManager = fragmentManager, + title = title, + message = message, + imageUrl = imageUrl, + buttonNegativeText = buttonNegativeText, + buttonPositiveText = buttonPositiveText, + onNegativeClick = onNegativeClick, + onPositiveClick = onPositiveClick, + ) + + fun showBottomSheetDialog( + title: String, + message: String, + imageUrl: String?, + buttonPositiveText: String, + buttonNegativeText: String, + onPositiveClick: () -> Unit, + onNegativeClick: () -> Unit + ) = inAppNotificationManager.showBottomSheetDialog( + fragmentManager = fragmentManager, + title = title, + message = message, + imageUrl = imageUrl, + buttonNegativeText = buttonNegativeText, + buttonPositiveText = buttonPositiveText, + onNegativeClick = onNegativeClick, + onPositiveClick = onPositiveClick, + ) + /** * Triggers a story event * @@ -164,10 +221,7 @@ open class SDK { fun trackStory(event: String, code: String, storyId: Int, slideId: String) { if (::storiesManager.isInitialized) { storiesManager.trackStory( - event = event, - code = code, - storyId = storyId, - slideId = slideId + event = event, code = code, storyId = storyId, slideId = slideId ) } else { Log.i(TAG, "storiesManager is not initialized") @@ -186,8 +240,7 @@ open class SDK { /** * Return the session ID */ - fun getSid(): String = - getUserSettingsValueUseCase.getSid() + fun getSid(): String = getUserSettingsValueUseCase.getSid() /** * Returns the session ID @@ -212,10 +265,8 @@ open class SDK { * @param extras from data notification */ fun notificationClicked(extras: Bundle?) { - notificationHandler.notificationClicked( - extras = extras, - sendAsync = { method, params -> sendNetworkMethodUseCase.postAsync(method, params) } - ) + notificationHandler.notificationClicked(extras = extras, + sendAsync = { method, params -> sendNetworkMethodUseCase.postAsync(method, params) }) } /** @@ -262,8 +313,7 @@ open class SDK { ) fun setPushTokenNotification(token: String, listener: OnApiCallbackListener?) { registerManager.setPushTokenNotification( - token = token, - listener = listener + token = token, listener = listener ) } @@ -276,7 +326,8 @@ open class SDK { */ @Deprecated( "This class will be removed in future versions. Use searchManager.", - level = DeprecationLevel.WARNING, replaceWith = ReplaceWith( + level = DeprecationLevel.WARNING, + replaceWith = ReplaceWith( "searchManager.searchInstant(...) or searchManager.searchFull(...)" ) ) @@ -294,7 +345,8 @@ open class SDK { */ @Deprecated( "This class will be removed in future versions. Use searchManager.", - level = DeprecationLevel.WARNING, replaceWith = ReplaceWith( + level = DeprecationLevel.WARNING, + replaceWith = ReplaceWith( "searchManager.searchInstant(...) or searchManager.searchFull(...)" ) ) @@ -315,25 +367,24 @@ open class SDK { @Deprecated( "This class will be removed in future versions. Use searchManager.", - level = DeprecationLevel.WARNING, replaceWith = ReplaceWith( + level = DeprecationLevel.WARNING, + replaceWith = ReplaceWith( "searchManager.searchBlank(...)" ) ) fun searchBlank(listener: OnApiCallbackListener) { if (search != null) { if (search?.blank == null) { - getAsync( - BLANK_SEARCH_FIELD, - Params().build(), object : OnApiCallbackListener() { - override fun onSuccess(response: JSONObject?) { - search?.blank = response - listener.onSuccess(response) - } - - override fun onError(code: Int, msg: String?) { - listener.onError(code, msg) - } - }) + getAsync(BLANK_SEARCH_FIELD, Params().build(), object : OnApiCallbackListener() { + override fun onSuccess(response: JSONObject?) { + search?.blank = response + listener.onSuccess(response) + } + + override fun onError(code: Int, msg: String?) { + listener.onError(code, msg) + } + }) } else { listener.onSuccess(search?.blank) } @@ -350,7 +401,8 @@ open class SDK { */ @Deprecated( "This method will be removed in future versions. Use recommendationManager.", - level = DeprecationLevel.WARNING, replaceWith = ReplaceWith( + level = DeprecationLevel.WARNING, + replaceWith = ReplaceWith( "recommendationManager.getRecommendation(recommender_code, ...)" ) ) @@ -367,7 +419,8 @@ open class SDK { */ @Deprecated( "This method will be removed in future versions. Use recommendationManager.", - level = DeprecationLevel.WARNING, replaceWith = ReplaceWith( + level = DeprecationLevel.WARNING, + replaceWith = ReplaceWith( "recommendationManager.getRecommendation(code, ...)" ) ) @@ -383,7 +436,8 @@ open class SDK { */ @Deprecated( "This method will be removed in future versions.", - level = DeprecationLevel.WARNING, replaceWith = ReplaceWith( + level = DeprecationLevel.WARNING, + replaceWith = ReplaceWith( "trackEventManager.track(event, itemId)" ) ) @@ -400,7 +454,8 @@ open class SDK { */ @Deprecated( "This method will be removed in future versions.", - level = DeprecationLevel.WARNING, replaceWith = ReplaceWith( + level = DeprecationLevel.WARNING, + replaceWith = ReplaceWith( "trackEventManager.track(event, params, listener)" ) ) @@ -655,10 +710,7 @@ open class SDK { * @param phone */ fun addToSegment( - segmentId: String, - email: String?, - phone: String?, - listener: OnApiCallbackListener? = null + segmentId: String, email: String?, phone: String?, listener: OnApiCallbackListener? = null ) { segmentMethod(ADD_FIELD, segmentId, email, phone, listener) } @@ -671,10 +723,7 @@ open class SDK { * @param phone */ fun removeFromSegment( - segment_id: String, - email: String?, - phone: String?, - listener: OnApiCallbackListener? = null + segment_id: String, email: String?, phone: String?, listener: OnApiCallbackListener? = null ) { segmentMethod(REMOVE_FIELD, segment_id, email, phone, listener) } diff --git a/personalization-sdk/src/main/kotlin/com/personalization/api/managers/InAppNotificationManager.kt b/personalization-sdk/src/main/kotlin/com/personalization/api/managers/InAppNotificationManager.kt index b6ca12ab..1625d02a 100644 --- a/personalization-sdk/src/main/kotlin/com/personalization/api/managers/InAppNotificationManager.kt +++ b/personalization-sdk/src/main/kotlin/com/personalization/api/managers/InAppNotificationManager.kt @@ -9,7 +9,10 @@ interface InAppNotificationManager { fragmentManager: FragmentManager, title: String, message: String, - buttonText: String + buttonPositiveText: String, + buttonNegativeText: String, + onPositiveClick: () -> Unit, + onNegativeClick: () -> Unit ) fun showFullScreenDialog( 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 ccec8d5b..859f6528 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,9 +4,9 @@ import android.view.View import androidx.fragment.app.FragmentManager import com.personalization.api.managers.InAppNotificationManager import com.personalization.inAppNotification.view.BottomSheetDialog -import com.personalization.inAppNotification.view.SdkSnackbar import com.personalization.inAppNotification.view.DefaultAlertDialog import com.personalization.inAppNotification.view.FullScreenDialog +import com.personalization.inAppNotification.view.SdkSnackbar import javax.inject.Inject class InAppNotificationManagerImpl @Inject constructor() : InAppNotificationManager { @@ -15,13 +15,26 @@ class InAppNotificationManagerImpl @Inject constructor() : InAppNotificationMana fragmentManager: FragmentManager, title: String, message: String, - buttonText: String + buttonPositiveText: String, + buttonNegativeText: String, + onPositiveClick: () -> Unit, + onNegativeClick: () -> Unit ) { - DefaultAlertDialog.newInstance( + val dialog = DefaultAlertDialog.newInstance( title = title, message = message, - buttonText = buttonText - ).show( + buttonPositiveText = buttonPositiveText, + buttonNegativeText = buttonNegativeText, + ) + + dialog.setListener( + object : DefaultAlertDialog.AlertDialogListener { + override fun onPositiveButtonClick() = onPositiveClick() + override fun onNegativeButtonClick() = onNegativeClick() + } + ) + + dialog.show( /* manager = */ fragmentManager, /* tag = */ DefaultAlertDialog.TAG ) @@ -47,13 +60,8 @@ class InAppNotificationManagerImpl @Inject constructor() : InAppNotificationMana dialog.setListener( object : FullScreenDialog.FullScreenDialogListener { - override fun onPositiveButtonClick() { - onPositiveClick() - } - - override fun onNegativeButtonClick() { - onNegativeClick() - } + override fun onPositiveButtonClick() = onPositiveClick() + override fun onNegativeButtonClick() = onNegativeClick() } ) @@ -82,13 +90,8 @@ class InAppNotificationManagerImpl @Inject constructor() : InAppNotificationMana dialog.setListener( object : BottomSheetDialog.BottomSheetDialogListener { - override fun onPositiveButtonClick() { - onPositiveClick() - } - - override fun onNegativeButtonClick() { - onNegativeClick() - } + override fun onPositiveButtonClick() = onPositiveClick() + override fun onNegativeButtonClick() = onNegativeClick() } ) diff --git a/personalization-sdk/src/main/kotlin/com/personalization/inAppNotification/view/DefaultAlertDialog.kt b/personalization-sdk/src/main/kotlin/com/personalization/inAppNotification/view/DefaultAlertDialog.kt index 1e116951..88a9b7c1 100644 --- a/personalization-sdk/src/main/kotlin/com/personalization/inAppNotification/view/DefaultAlertDialog.kt +++ b/personalization-sdk/src/main/kotlin/com/personalization/inAppNotification/view/DefaultAlertDialog.kt @@ -8,6 +8,8 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.DialogFragment import com.personalization.databinding.AlertDialogBinding +import com.personalization.inAppNotification.view.FullScreenDialog.Companion +import com.personalization.inAppNotification.view.FullScreenDialog.FullScreenDialogListener class DefaultAlertDialog : DialogFragment() { @@ -15,6 +17,12 @@ class DefaultAlertDialog : DialogFragment() { AlertDialogBinding.inflate(layoutInflater) } + private var listener: AlertDialogListener? = null + + fun setListener(listener: AlertDialogListener) { + this.listener = listener + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -29,27 +37,43 @@ class DefaultAlertDialog : DialogFragment() { with(binding) { title.text = arguments?.getString(TITLE_KEY).orEmpty() message.text = arguments?.getString(MESSAGE_KEY).orEmpty() - button.text = arguments?.getString(BUTTON_TEXT_KEY).orEmpty() - button.setOnClickListener { dismiss() } + buttonAccept.text = arguments?.getString(BUTTON_POSITIVE_TEXT_KEY).orEmpty() + buttonDecline.text = arguments?.getString(BUTTON_NEGATIVE_TEXT_KEY).orEmpty() + buttonAccept.setOnClickListener { + listener?.onPositiveButtonClick() + dismiss() + } + buttonDecline.setOnClickListener { + listener?.onNegativeButtonClick() + dismiss() + } } } + interface AlertDialogListener { + fun onPositiveButtonClick() + fun onNegativeButtonClick() + } + companion object { const val TAG = "AlertDialog" const val TITLE_KEY = "TITLE_KEY" const val MESSAGE_KEY = "MESSAGE_KEY" - const val BUTTON_TEXT_KEY = "BUTTON_TEXT_KEY" + const val BUTTON_POSITIVE_TEXT_KEY = "BUTTON_POSITIVE_TEXT_KEY" + const val BUTTON_NEGATIVE_TEXT_KEY = "BUTTON_NEGATIVE_TEXT_KEY" fun newInstance( title: String, message: String, - buttonText: String + buttonPositiveText: String, + buttonNegativeText: String ): DefaultAlertDialog { val dialog = DefaultAlertDialog() val args = Bundle().apply { putString(TITLE_KEY, title) putString(MESSAGE_KEY, message) - putString(BUTTON_TEXT_KEY, buttonText) + putString(BUTTON_POSITIVE_TEXT_KEY, buttonPositiveText) + putString(BUTTON_NEGATIVE_TEXT_KEY, buttonNegativeText) } dialog.arguments = args return dialog diff --git a/personalization-sdk/src/main/res/layout/alert_dialog.xml b/personalization-sdk/src/main/res/layout/alert_dialog.xml index 2b7bcade..e44b05cf 100644 --- a/personalization-sdk/src/main/res/layout/alert_dialog.xml +++ b/personalization-sdk/src/main/res/layout/alert_dialog.xml @@ -27,15 +27,37 @@ android:gravity="center" android:text="@string/alert_dialog_message" /> -