From 2b1f4475ccb1cfd663e43f998b5e6d1948567ebd Mon Sep 17 00:00:00 2001 From: Davit Dolmazyan Date: Thu, 26 Sep 2024 23:57:59 +0300 Subject: [PATCH] Implement EngagementLauncher business logic - Remove all the configurations in favor of ConfigurationManager - Get rid of configurations passed through Activity extras - Move extra keys to internal class - Make activities internal - Minor refactoring --- .../java/com/glia/exampleapp/Application.java | 39 -- .../com/glia/exampleapp/ChatFragment.java | 65 ---- .../java/com/glia/exampleapp/MainFragment.kt | 118 ++---- .../main/java/com/glia/exampleapp/Utils.java | 18 - app/src/main/res/layout/chat_fragment.xml | 7 - app/src/main/res/navigation/nav_graph.xml | 8 - .../main/res/raw/sample_unified_config.json | 364 +++++++++++++++--- .../java/com/glia/widgets/CallActivityTest.kt | 16 +- .../glia/widgets/call/CallStateHelper.java | 2 - .../java/com/glia/widgets/GliaWidgets.java | 97 +---- .../src/main/java/com/glia/widgets/UiTheme.kt | 16 - .../com/glia/widgets/call/CallActivity.kt | 53 +-- .../call/CallActivityConfigurationHelper.kt | 18 - .../glia/widgets/call/CallConfiguration.kt | 13 - .../com/glia/widgets/call/CallContract.kt | 12 +- .../com/glia/widgets/call/CallController.kt | 40 +- .../java/com/glia/widgets/call/CallState.java | 37 +- .../java/com/glia/widgets/call/CallView.kt | 34 +- .../callvisualizer/EndScreenSharingView.kt | 17 +- .../com/glia/widgets/chat/ChatActivity.kt | 64 +-- .../com/glia/widgets/chat/ChatContract.kt | 5 +- .../java/com/glia/widgets/chat/ChatManager.kt | 16 +- .../java/com/glia/widgets/chat/ChatType.kt | 14 +- .../java/com/glia/widgets/chat/ChatView.kt | 71 +--- .../holder/OperatorStatusViewHolder.kt | 24 +- .../widgets/chat/controller/ChatController.kt | 21 +- .../com/glia/widgets/chat/model/ChatItems.kt | 12 +- .../com/glia/widgets/chat/model/ChatState.kt | 8 +- .../domain/IsDisplayBubbleInsideAppUseCase.kt | 8 +- .../IsDisplayBubbleOutsideAppUseCase.kt | 8 +- .../chathead/domain/IsDisplayBubbleUseCase.kt | 4 +- .../configuration/EngagementConfiguration.kt | 35 -- .../GliaSdkConfigurationManager.java | 110 ------ ...owOverlayPermissionRequestDialogUseCase.kt | 6 +- .../GliaEngagementConfigRepository.kt | 4 +- .../domain/SetEngagementConfigUseCase.kt | 3 +- .../widgets/core/queue/GliaQueueRepository.kt | 2 +- ...ilableQueueIdsForSecureMessagingUseCase.kt | 1 + .../glia/widgets/di/ControllerFactory.java | 11 +- .../java/com/glia/widgets/di/Dependencies.kt | 17 +- .../com/glia/widgets/di/UseCaseFactory.java | 26 +- .../engagement/EngagementRepository.kt | 2 +- .../engagement/EngagementRepositoryImpl.kt | 4 +- .../EngagementCompletionActivityWatcher.kt | 25 +- .../domain/EnqueueForEngagementUseCase.kt | 13 +- .../engagement/domain/ScreenSharingUseCase.kt | 11 +- .../entrywidget/EntryWidgetActivity.kt | 2 +- .../entrywidget/EntryWidgetFragment.kt | 5 + .../glia/widgets/helper/CommonExtensions.kt | 4 - .../glia/widgets/helper/ContextExtensions.kt | 14 +- .../main/java/com/glia/widgets/helper/Data.kt | 7 + .../java/com/glia/widgets/helper/Insets.kt | 1 + .../com/glia/widgets/helper/IntentHelper.kt | 75 +--- .../com/glia/widgets/helper/TimeCounter.kt | 5 +- .../java/com/glia/widgets/helper/Utils.kt | 26 +- .../glia/widgets/launcher/ActivityLauncher.kt | 21 +- .../widgets/launcher/ConfigurationManager.kt | 8 +- .../widgets/launcher/EngagementLauncher.kt | 4 +- .../com/glia/widgets/locale/LocaleProvider.kt | 30 +- .../com/glia/widgets/locale/StringKeyPair.kt | 1 - .../messagecenter/MessageCenterActivity.kt | 36 +- .../messagecenter/MessageCenterContract.kt | 3 - .../messagecenter/MessageCenterController.kt | 18 +- .../messagecenter/MessageCenterView.kt | 7 +- .../glia/widgets/messagecenter/MessageView.kt | 12 +- .../OperatorRequestActivityWatcher.kt | 2 +- .../operator/OperatorRequestController.kt | 4 +- .../glia/widgets/survey/SurveyActivity.java | 92 ----- .../com/glia/widgets/survey/SurveyActivity.kt | 116 ++++++ .../com/glia/widgets/survey/SurveyAdapter.kt | 16 +- .../com/glia/widgets/survey/SurveyView.kt | 34 +- .../com/glia/widgets/view/VisitorCodeView.kt | 7 +- .../view/head/ActivityWatcherForChatHead.kt | 10 +- .../widgets/view/head/ChatHeadContract.kt | 5 - .../glia/widgets/view/head/ChatHeadLayout.kt | 58 +-- .../glia/widgets/view/head/ChatHeadView.kt | 84 ++-- .../controller/ServiceChatHeadController.kt | 23 +- .../textview/BaseConfigurableTextView.java | 4 +- .../entrywidget/MediaTypeItemRemoteConfig.kt | 4 +- .../entrywidget/MediaTypeItemsRemoteConfig.kt | 6 +- .../SecureMessagingRemoteConfig.kt | 8 +- .../glia/widgets/webbrowser/WebBrowserView.kt | 9 +- .../src/test/java/android/TestExtensions.kt | 2 +- .../java/com/glia/widgets/GliaWidgetsTest.kt | 1 + .../com/glia/widgets/chat/ChatManagerTest.kt | 27 +- .../chat/controller/ChatControllerTest.kt | 38 +- .../EngagementCallConfigurationManagerTest.kt | 49 --- .../engagement/EngagementRepositoryTest.kt | 20 +- ...EngagementCompletionActivityWatcherTest.kt | 14 +- .../engagement/domain/EngagementDomainTest.kt | 33 +- .../MessageCenterControllerTest.kt | 26 +- .../OperatorRequestActivityWatcherTest.kt | 6 +- .../operator/OperatorRequestControllerTest.kt | 12 +- .../widgets/call/CallViewVideoSnapshotTest.kt | 3 +- .../com/glia/widgets/call/SnapshotCallView.kt | 27 +- .../OperatorStatusViewHolderSnapshotTest.kt | 6 +- .../widgets/dialog/VisitorCodeDialogTest.kt | 16 +- .../snapshotutils/SnapshotActivityWindow.kt | 4 +- .../widgets/snapshotutils/SnapshotChatView.kt | 12 +- .../widgets/snapshotutils/SnapshotTheme.kt | 1 - .../SnapshotThemeConfiguration.kt | 24 ++ .../view/head/ChatHeadViewSnapshotTest.kt | 22 +- 102 files changed, 864 insertions(+), 1739 deletions(-) delete mode 100644 app/src/main/java/com/glia/exampleapp/ChatFragment.java delete mode 100644 app/src/main/res/layout/chat_fragment.xml delete mode 100644 widgetssdk/src/main/java/com/glia/widgets/call/CallActivityConfigurationHelper.kt delete mode 100644 widgetssdk/src/main/java/com/glia/widgets/call/CallConfiguration.kt delete mode 100644 widgetssdk/src/main/java/com/glia/widgets/core/configuration/EngagementConfiguration.kt delete mode 100644 widgetssdk/src/main/java/com/glia/widgets/core/configuration/GliaSdkConfigurationManager.java delete mode 100644 widgetssdk/src/main/java/com/glia/widgets/survey/SurveyActivity.java create mode 100644 widgetssdk/src/main/java/com/glia/widgets/survey/SurveyActivity.kt delete mode 100644 widgetssdk/src/test/java/com/glia/widgets/core/configuration/EngagementCallConfigurationManagerTest.kt create mode 100644 widgetssdk/src/testSnapshot/java/com/glia/widgets/snapshotutils/SnapshotThemeConfiguration.kt diff --git a/app/src/main/java/com/glia/exampleapp/Application.java b/app/src/main/java/com/glia/exampleapp/Application.java index abf6528e0..1f4cc0ed3 100644 --- a/app/src/main/java/com/glia/exampleapp/Application.java +++ b/app/src/main/java/com/glia/exampleapp/Application.java @@ -1,14 +1,8 @@ package com.glia.exampleapp; -import android.app.Activity; -import android.os.Bundle; import android.text.TextUtils; import android.util.Log; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.glia.androidsdk.Glia; import com.glia.widgets.GliaWidgets; import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; @@ -22,8 +16,6 @@ public void onCreate() { GliaWidgets.onAppCreate(this); GliaWidgets.setCustomCardAdapter(new ExampleCustomCardAdapter()); - - initGliaWidgets(); } private void initFirebase() { @@ -43,35 +35,4 @@ private void initFirebase() { .build(); FirebaseApp.initializeApp(this, options); } - - private void initGliaWidgets() { - registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { - @Override - public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { - if (activity.getClass() != com.glia.exampleapp.Activity.class) { - if (Glia.isInitialized()) return; - - GliaWidgets.init(ExampleAppConfigManager.createDefaultConfig(getApplicationContext())); - } - } - - @Override - public void onActivityStarted(@NonNull Activity activity) {} - - @Override - public void onActivityResumed(@NonNull Activity activity) {} - - @Override - public void onActivityPaused(@NonNull Activity activity) {} - - @Override - public void onActivityStopped(@NonNull Activity activity) {} - - @Override - public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {} - - @Override - public void onActivityDestroyed(@NonNull Activity activity) {} - }); - } } diff --git a/app/src/main/java/com/glia/exampleapp/ChatFragment.java b/app/src/main/java/com/glia/exampleapp/ChatFragment.java deleted file mode 100644 index 66a0e7793..000000000 --- a/app/src/main/java/com/glia/exampleapp/ChatFragment.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.glia.exampleapp; - -import static java.util.Collections.singletonList; - -import android.content.SharedPreferences; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.navigation.NavController; -import androidx.navigation.fragment.NavHostFragment; -import androidx.preference.PreferenceManager; - -import com.glia.widgets.UiTheme; -import com.glia.widgets.chat.ChatView; - -import java.util.Collections; - -public class ChatFragment extends Fragment { - - private NavController navController; - private ChatView chatView; - private ChatView.OnEndListener onEndListener = () -> navController.popBackStack(); - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, - @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.chat_fragment, container, false); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - navController = NavHostFragment.findNavController(this); - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext()); - chatView = view.findViewById(R.id.chat_view); - UiTheme theme = Utils.getRunTimeThemeByPrefs(sharedPreferences, getResources()); - chatView.setUiTheme(theme); - chatView.setOnEndListener(onEndListener); - chatView.startChat( - Utils.getStringFromPrefs(R.string.pref_company_name, getString(R.string.settings_value_default_company_name), sharedPreferences, getResources()), - singletonList(Utils.getStringFromPrefs(R.string.pref_queue_id, getString(R.string.glia_queue_id), sharedPreferences, getResources())), - Utils.getStringFromPrefs(R.string.pref_context_asset_id, null, sharedPreferences, getResources())); - } - - @Override - public void onResume() { - chatView.onResume(); - super.onResume(); - } - - @Override - public void onDestroyView() { - onEndListener = null; - chatView.onDestroyView(); - super.onDestroyView(); - } -} diff --git a/app/src/main/java/com/glia/exampleapp/MainFragment.kt b/app/src/main/java/com/glia/exampleapp/MainFragment.kt index bbf9160c2..1306d6c83 100644 --- a/app/src/main/java/com/glia/exampleapp/MainFragment.kt +++ b/app/src/main/java/com/glia/exampleapp/MainFragment.kt @@ -4,7 +4,6 @@ import android.content.DialogInterface import android.content.Intent import android.content.SharedPreferences import android.os.Bundle -import android.os.Parcelable import android.text.InputType import android.util.TypedValue import android.view.Gravity @@ -27,18 +26,14 @@ import com.glia.androidsdk.Glia import com.glia.androidsdk.GliaException import com.glia.androidsdk.fcm.GliaPushMessage import com.glia.androidsdk.omnibrowse.Omnibrowse -import com.glia.androidsdk.screensharing.ScreenSharing import com.glia.androidsdk.visitor.Authentication import com.glia.exampleapp.ExampleAppConfigManager.createDefaultConfig import com.glia.exampleapp.Utils.getAuthenticationBehaviorFromPrefs import com.glia.widgets.GliaWidgets import com.glia.widgets.UiTheme -import com.glia.widgets.call.CallActivity -import com.glia.widgets.chat.ChatActivity -import com.glia.widgets.chat.ChatType import com.glia.widgets.core.notification.NotificationActionReceiver -import com.glia.widgets.entrywidget.EntryWidgetActivity -import com.glia.widgets.messagecenter.MessageCenterActivity +import com.glia.widgets.entrywidget.EntryWidget +import com.glia.widgets.launcher.EngagementLauncher import com.google.android.material.appbar.MaterialToolbar import kotlin.concurrent.thread import kotlin.properties.Delegates @@ -60,6 +55,19 @@ class MainFragment : Fragment() { return authTokenFromPrefs.ifEmpty { getString(R.string.glia_jwt) } } + private val sharedPreferences: SharedPreferences by lazy { + PreferenceManager.getDefaultSharedPreferences(requireContext()) + } + + private val engagementLauncher: EngagementLauncher by lazy { + ensureInitialized() + GliaWidgets.getEngagementLauncher(getQueueIdsFromPrefs(sharedPreferences)) + } + + private val entryWidget: EntryWidget by lazy { + GliaWidgets.getEntryWidget(getQueueIdsFromPrefs(sharedPreferences)) + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -76,17 +84,15 @@ class MainFragment : Fragment() { view.findViewById(R.id.settings_button) .setOnClickListener { navController.navigate(R.id.settings) } view.findViewById(R.id.entry_widget_button) - .setOnClickListener { - startActivity(Intent(requireContext(), EntryWidgetActivity::class.java)) - } + .setOnClickListener { entryWidget.show(requireActivity()) } view.findViewById(R.id.chat_activity_button) - .setOnClickListener { navigateToChat(ChatType.LIVE_CHAT) } + .setOnClickListener { engagementLauncher.startChat(requireActivity()) } view.findViewById(R.id.audio_call_button) - .setOnClickListener { navigateToCall(GliaWidgets.MEDIA_TYPE_AUDIO) } + .setOnClickListener { engagementLauncher.startAudioCall(requireActivity()) } view.findViewById(R.id.video_call_button) - .setOnClickListener { navigateToCall(GliaWidgets.MEDIA_TYPE_VIDEO) } + .setOnClickListener { engagementLauncher.startVideoCall(requireActivity()) } view.findViewById(R.id.message_center_activity_button) - .setOnClickListener { navigateToMessageCenter() } + .setOnClickListener { engagementLauncher.startSecureMessaging(requireActivity()) } view.findViewById(R.id.end_engagement_button) .setOnClickListener { GliaWidgets.endEngagement() } view.findViewById(R.id.visitor_info_button) @@ -199,9 +205,9 @@ class MainFragment : Fragment() { .handleOnMainActivityCreate(requireActivity().intent.extras) ?: return if (push.type == GliaPushMessage.PushType.QUEUED_MESSAGE) { - authenticate { navigateToChat(ChatType.SECURE_MESSAGING) } + authenticate { engagementLauncher.startSecureMessaging(requireActivity()) } } else { - navigateToChat(ChatType.LIVE_CHAT) + engagementLauncher.startChat(requireActivity()) } } @@ -278,52 +284,6 @@ class MainFragment : Fragment() { } } - private fun navigateToChat(chatType: ChatType) { - val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) - val intent = Intent(requireContext(), ChatActivity::class.java).apply { - putExtra(GliaWidgets.CHAT_TYPE, chatType as Parcelable) - putExtra(GliaWidgets.CONTEXT_ASSET_ID, getContextAssetIdFromPrefs(sharedPreferences)) - putExtra(GliaWidgets.QUEUE_IDS, ArrayList(getQueueIdsFromPrefs(sharedPreferences))) - setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) - } - startActivity(intent) - } - - private fun navigateToMessageCenter() { - val intent = Intent(requireContext(), MessageCenterActivity::class.java) - setNavigationIntentData(intent) - startActivity(intent) - } - - private fun navigateToCall(mediaType: String) { - val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) - val intent = Intent(context, CallActivity::class.java) - .putExtra(GliaWidgets.QUEUE_IDS, ArrayList(getQueueIdsFromPrefs(sharedPreferences))) - .putExtra(GliaWidgets.CONTEXT_ASSET_ID, getContextAssetIdFromPrefs(sharedPreferences)) - .putExtra(GliaWidgets.UI_THEME, getRuntimeThemeFromPrefs(sharedPreferences)) -// .putExtra(GliaWidgets.USE_OVERLAY, true) // Use it to make sure this deprecated approach is still working - .putExtra(GliaWidgets.SCREEN_SHARING_MODE, getScreenSharingModeFromPrefs(sharedPreferences)) - .putExtra(GliaWidgets.MEDIA_TYPE, Utils.toMediaType(mediaType)) - startActivity(intent) - } - - private fun setNavigationIntentData(intent: Intent) { - val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) - intent.putExtra(GliaWidgets.QUEUE_IDS, ArrayList(getQueueIdsFromPrefs(sharedPreferences))) - .putExtra(GliaWidgets.CONTEXT_ASSET_ID, getContextAssetIdFromPrefs(sharedPreferences)) - .putExtra(GliaWidgets.UI_THEME, getRuntimeThemeFromPrefs(sharedPreferences)) -// .putExtra(GliaWidgets.USE_OVERLAY, true) // Use it to make sure this deprecated approach is still working - .putExtra(GliaWidgets.SCREEN_SHARING_MODE, getScreenSharingModeFromPrefs(sharedPreferences)) - } - - private fun getScreenSharingModeFromPrefs(sharedPreferences: SharedPreferences): ScreenSharing.Mode { - return Utils.getScreenSharingModeFromPrefs(sharedPreferences, resources) - } - - private fun getRuntimeThemeFromPrefs(sharedPreferences: SharedPreferences): UiTheme? { - return Utils.getRunTimeThemeByPrefs(sharedPreferences, resources) - } - private fun getQueueIdsFromPrefs(sharedPreferences: SharedPreferences): List { val defaultQueues = sharedPreferences.getBoolean(resources.getString(R.string.pref_default_queues), false) if (defaultQueues) { @@ -350,15 +310,6 @@ class MainFragment : Fragment() { ) } - private fun getCompanyNameFromPrefs(sharedPreferences: SharedPreferences): String { - return Utils.getStringFromPrefs( - R.string.pref_company_name, - "", - sharedPreferences, - resources - ) - } - private fun saveAuthToken(jwt: String) { if (jwt != getString(R.string.glia_jwt)) { val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) @@ -442,8 +393,10 @@ class MainFragment : Fragment() { return container } - private fun prepareJwtInputViewEditText(builder: AlertDialog.Builder, - dialogTitle: Int): EditText { + private fun prepareJwtInputViewEditText( + builder: AlertDialog.Builder, + dialogTitle: Int + ): EditText { val input = EditText(context) input.setHint(R.string.authentication_dialog_jwt_input_hint) input.setSingleLine() @@ -455,8 +408,10 @@ class MainFragment : Fragment() { return input } - private fun prepareExternalTokenInputViewEditText(builder: AlertDialog.Builder, - dialogTitle: Int): EditText { + private fun prepareExternalTokenInputViewEditText( + builder: AlertDialog.Builder, + dialogTitle: Int + ): EditText { val input = EditText(context) input.setHint(R.string.authentication_dialog_external_token_input_hint) input.setSingleLine() @@ -502,7 +457,7 @@ class MainFragment : Fragment() { if (externalToken!!.isEmpty()) externalToken = null authentication?.refresh( jwt, externalToken - ) { response, exception -> + ) { _, exception -> setupAuthButtonsVisibility() if (exception != null || !authentication!!.isAuthenticated) { showToast("Error: $exception") @@ -513,6 +468,12 @@ class MainFragment : Fragment() { saveAuthToken(jwt) } + private fun ensureInitialized() { + if (!Glia.isInitialized()) { + initGliaWidgets() + } + } + private fun initGliaWidgets() { if (Glia.isInitialized()) { setupAuthButtonsVisibility() @@ -523,7 +484,7 @@ class MainFragment : Fragment() { GliaWidgets.init( createDefaultConfig( context = requireActivity().applicationContext, -// uiJsonRemoteConfig = UnifiedUiConfigurationLoader.fetchRemoteConfiguration(), +// uiJsonRemoteConfig = UnifiedUiConfigurationLoader.fetchLocalConfigSample(requireContext()), // runtimeConfig = createSampleRuntimeConfig(), // region = "us" ) @@ -543,8 +504,7 @@ class MainFragment : Fragment() { private fun prepareAuthentication() { val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext()) - authentication = - GliaWidgets.getAuthentication(getAuthenticationBehaviorFromPrefs(sharedPreferences, resources)) + authentication = GliaWidgets.getAuthentication(getAuthenticationBehaviorFromPrefs(sharedPreferences, resources)) } private fun authenticate( diff --git a/app/src/main/java/com/glia/exampleapp/Utils.java b/app/src/main/java/com/glia/exampleapp/Utils.java index 169cbf86f..dc880ebad 100644 --- a/app/src/main/java/com/glia/exampleapp/Utils.java +++ b/app/src/main/java/com/glia/exampleapp/Utils.java @@ -5,15 +5,12 @@ import android.content.res.ColorStateList; import android.content.res.Resources; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.core.content.ContextCompat; -import com.glia.androidsdk.Engagement; import com.glia.androidsdk.screensharing.ScreenSharing; import com.glia.androidsdk.visitor.Authentication; -import com.glia.widgets.GliaWidgets; import com.glia.widgets.UiTheme; import com.glia.widgets.view.configuration.ButtonConfiguration; import com.glia.widgets.view.configuration.ChatHeadConfiguration; @@ -22,8 +19,6 @@ import org.json.JSONException; import org.json.JSONObject; -import java.security.InvalidParameterException; - class Utils { public static String getStringFromPrefs(@StringRes int keyValue, String defaultValue, SharedPreferences sharedPreferences, Resources resources) { @@ -80,7 +75,6 @@ public static UiTheme getRunTimeThemeByPrefs(SharedPreferences sharedPreferences return null; } - String title = Utils.getStringFromPrefs(R.string.pref_header_title, null, sharedPreferences, resources); Integer baseLightColor = getColorValueFromPrefs(R.string.pref_base_light_color, sharedPreferences, resources); Integer baseDarkColor = getColorValueFromPrefs(R.string.pref_base_dark_color, sharedPreferences, resources); Integer baseNormalColor = getColorValueFromPrefs(R.string.pref_base_normal_color, sharedPreferences, resources); @@ -115,7 +109,6 @@ public static UiTheme getRunTimeThemeByPrefs(SharedPreferences sharedPreferences UiTheme.UiThemeBuilder builder = new UiTheme.UiThemeBuilder(); - builder.setAppBarTitle(title); builder.setBaseLightColor(baseLightColor); builder.setBaseDarkColor(baseDarkColor); builder.setBaseNormalColor(baseNormalColor); @@ -321,15 +314,4 @@ public static Authentication.Behavior getAuthenticationBehaviorFromPrefs( return Authentication.Behavior.FORBIDDEN_DURING_ENGAGEMENT; } } - - public static Engagement.MediaType toMediaType(@NonNull String mediaType) { - switch (mediaType) { - case GliaWidgets.MEDIA_TYPE_VIDEO: - return Engagement.MediaType.VIDEO; - case GliaWidgets.MEDIA_TYPE_AUDIO: - return Engagement.MediaType.AUDIO; - default: - throw new InvalidParameterException("Invalid Media Type"); - } - } } diff --git a/app/src/main/res/layout/chat_fragment.xml b/app/src/main/res/layout/chat_fragment.xml deleted file mode 100644 index 915fa734e..000000000 --- a/app/src/main/res/layout/chat_fragment.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index 15407e1d2..ac899432c 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -48,16 +48,8 @@ android:id="@+id/visitor_info" app:destination="@id/visitor_info_fragment" /> - - - - diff --git a/app/src/main/res/raw/sample_unified_config.json b/app/src/main/res/raw/sample_unified_config.json index d2749407e..a9604b0c2 100644 --- a/app/src/main/res/raw/sample_unified_config.json +++ b/app/src/main/res/raw/sample_unified_config.json @@ -36,19 +36,25 @@ "background": { "border": { "type": "fill", - "value": ["#FFFFFF"] + "value": [ + "#FFFFFF" + ] }, "borderWidth": 0, "color": { "type": "fill", - "value": ["#FFFFFF"] + "value": [ + "#FFFFFF" + ] }, "cornerRadius": 8 }, "shadow": { "color": { "type": "fill", - "value": ["#FF0000"] + "value": [ + "#FF0000" + ] }, "offset": 0, "opacity": 1, @@ -58,7 +64,9 @@ "alignment": "center", "background": { "type": "fill", - "value": ["#FF0000"] + "value": [ + "#FF0000" + ] }, "font": { "size": 16, @@ -66,12 +74,16 @@ }, "foreground": { "type": "fill", - "value": ["#04728c"] + "value": [ + "#04728c" + ] } }, "tintColor": { "type": "fill", - "value": ["#ffd100"] + "value": [ + "#ffd100" + ] } }, "negativeButton": { @@ -95,7 +107,7 @@ "color": { "type": "fill", "value": [ - "FF0000" + "#FF0000" ] }, "offset": 0, @@ -107,7 +119,7 @@ "background": { "type": "fill", "value": [ - "FF0000" + "#FF0000" ] }, "font": { @@ -128,6 +140,37 @@ ] } }, + "negativeNeutralButton": { + "background": { + "border": { + "type": "fill", + "value": [ + "#99e5ea" + ] + }, + "borderWidth": 1, + "color": { + "type": "fill", + "value": [ + "#FFFFFF" + ] + }, + "cornerRadius": 8 + }, + "text": { + "alignment": "center", + "font": { + "size": 16, + "style": "regular" + }, + "foreground": { + "type": "fill", + "value": [ + "#d32f2f" + ] + } + } + }, "positiveButton": { "background": { "border": { @@ -149,7 +192,7 @@ "color": { "type": "fill", "value": [ - "FF0000" + "#FF0000" ] }, "offset": 0, @@ -161,7 +204,7 @@ "background": { "type": "fill", "value": [ - "FF0000" + "#FF0000" ] }, "font": { @@ -276,7 +319,7 @@ "border": { "type": "fill", "value": [ - "FF0000" + "#FF0000" ] }, "borderWidth": 2, @@ -1134,10 +1177,9 @@ }, "borderWidth": 2, "color": { - "type": "gradient", + "type": "fill", "value": [ - "#fdd42b", - "#ff0000" + "#000000" ] }, "cornerRadius": 8 @@ -1188,10 +1230,9 @@ }, "borderWidth": 2, "color": { - "type": "gradient", + "type": "fill", "value": [ - "#fdd42b", - "#ff0000" + "#f9d12b" ] }, "cornerRadius": 8 @@ -1397,6 +1438,20 @@ ] } }, + "snackBar": { + "background": { + "type": "fill", + "value": [ + "#FFFFFF" + ] + }, + "text": { + "type": "fill", + "value": [ + "#3B3B40" + ] + } + }, "visitorVideo": { "flipCameraButton": { "background": { @@ -1964,10 +2019,9 @@ }, "borderWidth": 2, "color": { - "type": "gradient", + "type": "fill", "value": [ - "#fdd42b", - "#ff0000" + "#fdd42b" ] }, "cornerRadius": 8 @@ -2649,7 +2703,7 @@ "background": { "type": "fill", "value": [ - "FF0000" + "#FF0000" ] }, "font": { @@ -2703,7 +2757,7 @@ "background": { "type": "fill", "value": [ - "FF0000" + "#FF0000" ] }, "font": { @@ -2757,7 +2811,7 @@ "background": { "type": "fill", "value": [ - "FF0000" + "#FF0000" ] }, "font": { @@ -2784,7 +2838,7 @@ "background": { "type": "fill", "value": [ - "8E8E93" + "#8E8E93" ] }, "font": { @@ -2998,7 +3052,9 @@ "alignment": "center", "background": { "type": "fill", - "value": ["#FFFFFF"] + "value": [ + "#FFFFFF" + ] }, "font": { "size": 16, @@ -3006,7 +3062,9 @@ }, "foreground": { "type": "fill", - "value": ["#FF0000"] + "value": [ + "#FF0000" + ] } }, "text": { @@ -3303,6 +3361,125 @@ "cornerRadius": 24 } } + }, + "secureMessaging": { + "unavailableStatusBackground": { + "color": { + "type": "fill", + "value": [ + "#d32f2f" + ] + } + }, + "unavailableStatusText": { + "alignment": "center", + "foreground": { + "type": "fill", + "value": [ + "#FFFFFF" + ] + } + }, + "bottomBannerBackground": { + "color": { + "type": "fill", + "value": [ + "#99e5ea" + ] + } + }, + "bottomBannerText": { + "alignment": "center", + "font": { + "size": 16, + "style": "regular" + }, + "foreground": { + "type": "fill", + "value": [ + "#8E8E93" + ] + } + }, + "bottomBannerDividerColor": { + "type": "fill", + "value": [ + "#8E8E93" + ] + }, + "topBannerBackground": { + "color": { + "type": "fill", + "value": [ + "#FFFFFF" + ] + } + }, + "topBannerText": { + "alignment": "center", + "font": { + "size": 16, + "style": "regular" + }, + "foreground": { + "type": "fill", + "value": [ + "#04728c" + ] + } + }, + "topBannerDividerColor": { + "type": "fill", + "value": [ + "#8E8E93" + ] + }, + "topBannerDropDownIconColor": { + "type": "fill", + "value": [ + "#04728c" + ] + }, + "mediaTypeItems": { + "mediaTypeItem": { + "background": { + "color": { + "type": "fill", + "value": [ + "#ffffff" + ] + } + }, + "iconColor": { + "type": "fill", + "value": [ + "#ffd100" + ] + }, + "title": { + "foreground": { + "type": "fill", + "value": [ + "#04728c" + ] + } + }, + "message": { + "foreground": { + "type": "fill", + "value": [ + "#444444" + ] + } + } + }, + "dividerColor": { + "type": "fill", + "value": [ + "#04728c" + ] + } + } } }, "surveyScreen": { @@ -3993,10 +4170,9 @@ }, "borderWidth": 2, "color": { - "type": "gradient", + "type": "fill", "value": [ - "#fdd42b", - "#ff0000" + "#fdd42b" ] }, "cornerRadius": 8 @@ -4223,7 +4399,7 @@ "color": { "type": "fill", "value": [ - "FF0000" + "#FF0000" ] }, "offset": 0, @@ -4235,7 +4411,7 @@ "background": { "type": "fill", "value": [ - "FF0000" + "#FF0000" ] }, "font": { @@ -4295,7 +4471,7 @@ "color": { "type": "fill", "value": [ - "FF0000" + "#FF0000" ] }, "offset": 0, @@ -4307,7 +4483,7 @@ "background": { "type": "fill", "value": [ - "FF0000" + "#FF0000" ] }, "font": { @@ -4417,10 +4593,9 @@ }, "borderWidth": 2, "color": { - "type": "gradient", + "type": "fill", "value": [ - "#fdd42b", - "#ff0000" + "#000000" ] }, "cornerRadius": 8 @@ -4471,10 +4646,9 @@ }, "borderWidth": 2, "color": { - "type": "gradient", + "type": "fill", "value": [ - "#fdd42b", - "#ff0000" + "#f9d12b" ] }, "cornerRadius": 8 @@ -4796,10 +4970,9 @@ }, "borderWidth": 2, "color": { - "type": "gradient", + "type": "fill", "value": [ - "#fdd42b", - "#ff0000" + "#000000" ] }, "cornerRadius": 8 @@ -4850,10 +5023,9 @@ }, "borderWidth": 2, "color": { - "type": "gradient", + "type": "fill", "value": [ - "#fdd42b", - "#ff0000" + "#f9d12b" ] }, "cornerRadius": 8 @@ -5209,6 +5381,20 @@ } } }, + "snackBar": { + "background": { + "type": "fill", + "value": [ + "#3B3B40" + ] + }, + "text": { + "type": "fill", + "value": [ + "#FFFFFF" + ] + } + }, "webBrowserScreen": { "header": { "background": { @@ -5220,10 +5406,9 @@ }, "borderWidth": 2, "color": { - "type": "gradient", + "type": "fill", "value": [ - "#fdd42b", - "#ff0000" + "#fdd42b" ] }, "cornerRadius": 8 @@ -5302,5 +5487,88 @@ } } } + }, + "entryWidget": { + "background": { + "color": { + "type": "fill", + "value": [ + "#ffffff" + ] + } + }, + "mediaTypeItems": { + "mediaTypeItem": { + "background": { + "color": { + "type": "fill", + "value": [ + "#ffffff" + ] + } + }, + "iconColor": { + "type": "fill", + "value": [ + "#ffd100" + ] + }, + "title": { + "foreground": { + "type": "fill", + "value": [ + "#04728c" + ] + } + }, + "message": { + "foreground": { + "type": "fill", + "value": [ + "#444444" + ] + } + } + }, + "dividerColor": { + "type": "fill", + "value": [ + "#04728c" + ] + } + }, + "errorTitle": { + "alignment": "center", + "foreground": { + "type": "fill", + "value": [ + "#d32f2f" + ] + } + }, + "errorMessage": { + "alignment": "center", + "foreground": { + "type": "fill", + "value": [ + "#8E8E93" + ] + } + }, + "errorButton": { + "text": { + "alignment": "center", + "font": { + "size": 16, + "style": "regular" + }, + "foreground": { + "type": "fill", + "value": [ + "#04728c" + ] + } + } + } } } diff --git a/widgetssdk/src/androidTest/java/com/glia/widgets/CallActivityTest.kt b/widgetssdk/src/androidTest/java/com/glia/widgets/CallActivityTest.kt index 28574ee56..85c604f06 100644 --- a/widgetssdk/src/androidTest/java/com/glia/widgets/CallActivityTest.kt +++ b/widgetssdk/src/androidTest/java/com/glia/widgets/CallActivityTest.kt @@ -15,12 +15,10 @@ import com.glia.widgets.call.CallActivity import com.glia.widgets.call.CallContract import com.glia.widgets.call.CallStateHelper import com.glia.widgets.call.CallStatus -import com.glia.widgets.core.configuration.GliaSdkConfigurationManager import com.glia.widgets.di.ControllerFactory import com.glia.widgets.di.Dependencies import com.glia.widgets.helper.ResourceProvider import com.glia.widgets.locale.LocaleProvider -import com.glia.widgets.locale.StringKeyPair import com.glia.widgets.view.head.ChatHeadContract import io.mockk.CapturingSlot import io.mockk.every @@ -28,6 +26,7 @@ import io.mockk.mockk import io.mockk.slot import io.mockk.verify import org.hamcrest.Matchers +import org.junit.After import org.junit.Assert import org.junit.Before import org.junit.Rule @@ -41,7 +40,6 @@ class CallActivityTest { private lateinit var callController: CallContract.Controller private lateinit var callView: CallContract.View private lateinit var serviceChatHeadController: ChatHeadContract.Controller - private lateinit var sdkConfigurationManager: GliaSdkConfigurationManager private lateinit var resourceProvider: ResourceProvider private lateinit var callStatus: CallStatus private lateinit var callViewSlot: CapturingSlot @@ -67,11 +65,7 @@ class CallActivityTest { every { controllerFactory.chatHeadController } answers { serviceChatHeadController } Dependencies.controllerFactory = controllerFactory - // set up SdkConfigurationManager - sdkConfigurationManager = mockk(relaxed = true) - every { sdkConfigurationManager.uiTheme } answers { UiTheme() } - every { sdkConfigurationManager.companyName } answers { "Test Company" } - Dependencies.sdkConfigurationManager = sdkConfigurationManager + Dependencies.repositoryFactory = mockk(relaxed = true) // set up ResourceProvider resourceProvider = ResourceProvider(appContext) @@ -87,6 +81,11 @@ class CallActivityTest { launchActivity() } + @After + fun tearDown() { + activityScenario.close() + } + private fun launchActivity() { activityScenario = ActivityScenario.launch(CallActivity::class.java) verify { callController.setView(capture(callViewSlot)) } @@ -279,6 +278,7 @@ class CallActivityTest { callView.emitState(callState.makeCallState()) Thread.sleep(1000) Espresso.onView(ViewMatchers.withContentDescription(R.string.android_app_bar_nav_up_accessibility)).perform(ViewActions.click()) + Thread.sleep(1000) Assert.assertEquals(Lifecycle.State.DESTROYED, activityScenario.state) } diff --git a/widgetssdk/src/androidTest/java/com/glia/widgets/call/CallStateHelper.java b/widgetssdk/src/androidTest/java/com/glia/widgets/call/CallStateHelper.java index b9b1f3a71..416d49595 100644 --- a/widgetssdk/src/androidTest/java/com/glia/widgets/call/CallStateHelper.java +++ b/widgetssdk/src/androidTest/java/com/glia/widgets/call/CallStateHelper.java @@ -113,7 +113,6 @@ public CallStateHelper.Builder copyFrom(CallState callState) { landscapeLayoutControlsVisible = callState.landscapeLayoutControlsVisible; isMuted = callState.isMuted; hasVideo = callState.hasVideo; - companyName = callState.companyName; requestedMediaType = callState.requestedMediaType; isSpeakerOn = callState.isSpeakerOn; return this; @@ -159,7 +158,6 @@ public CallState makeCallState() { .setLandscapeLayoutControlsVisible(landscapeLayoutControlsVisible) .setIsMuted(isMuted) .setHasVideo(hasVideo) - .setCompanyName(companyName) .setRequestedMediaType(requestedMediaType) .setIsSpeakerOn(isSpeakerOn) .createCallState(); diff --git a/widgetssdk/src/main/java/com/glia/widgets/GliaWidgets.java b/widgetssdk/src/main/java/com/glia/widgets/GliaWidgets.java index 5f2a5f8ba..4b526a5e9 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/GliaWidgets.java +++ b/widgetssdk/src/main/java/com/glia/widgets/GliaWidgets.java @@ -38,99 +38,6 @@ */ public class GliaWidgets { - /** - * Use with {@link android.os.Bundle} to pass in a {@link UiTheme} as a navigation argument when - * navigating to {@link com.glia.widgets.chat.ChatActivity} - * - * @deprecated While UiTheme can still be used for UI customization, - * we strongly encourage adopting remote configurations {@link GliaWidgetsConfig.Builder#setUiJsonRemoteConfig(String)}. - * The remote configurations approach is more versatile and better suited for future development. - */ - @Deprecated - public static final String UI_THEME = "ui_theme"; - /** - * Use with {@link android.os.Bundle} to pass in the name of your company as a navigation - * argument when navigating to {@link com.glia.widgets.chat.ChatActivity} - * - * @deprecated Use {@link com.glia.widgets.GliaWidgetsConfig.Builder#companyName} - * or customize the strings from GliaHub - */ - @Deprecated - public static final String COMPANY_NAME = "company_name"; - - /** - * Use with {@link android.os.Bundle} to pass in the ID of the queue you wish to enroll in - * as a navigation argument when navigating to {@link com.glia.widgets.chat.ChatActivity} - * or {@link com.glia.widgets.call.CallActivity} - * - * @deprecated Use {QUEUE_IDS} instead. - */ - @Deprecated - public static final String QUEUE_ID = "queue_id"; - - /** - * Use with {@link android.os.Bundle} to pass in an {@link java.util.ArrayList} of {@link String} of the queues IDs - * you wish to enroll in as a navigation argument when navigating to {@link com.glia.widgets.chat.ChatActivity} - * or {@link com.glia.widgets.call.CallActivity} - */ - public static final String QUEUE_IDS = "queue_ids"; - /** - * Use with {@link android.os.Bundle} to pass in a context url as a navigation - * argument when navigating to {@link com.glia.widgets.chat.ChatActivity} - * - * @deprecated Use {@link com.glia.widgets.GliaWidgets#CONTEXT_ASSET_ID} - */ - @Deprecated - public static final String CONTEXT_URL = "context_url"; - /** - * Use with {@link android.os.Bundle} to pass in a context asset ID as a navigation - * argument when navigating to {@link com.glia.widgets.chat.ChatActivity} - */ - public static final String CONTEXT_ASSET_ID = "context_asset_id"; - /** - * It's recommended to use {@link GliaWidgetsConfig.Builder#setUseOverlay(boolean)} ()} instead of this constant directly. - * Use with {@link android.os.Bundle} to pass in a boolean which represents if you would like to use the chat head bubble - * as an overlay outside your application for navigating to {@link com.glia.widgets.chat.ChatActivity}. - * If set to true then the SDK will ask for overlay permissions and try to always show the navigation bubble outside - * the application. However, it will be shown only if the user has accepted the permissions. - * If false, then overlay permission is not requested and the navigation bubble is shown when the application is active. - * Default value is true. - * - * @deprecated Use {@link com.glia.widgets.GliaWidgetsConfig#isEnableBubbleOutsideApp() and - * {@link GliaWidgetsConfig#isEnableBubbleInsideApp()} - */ - @Deprecated - public static final String USE_OVERLAY = "use_overlay"; - /** - * Use with {@link android.os.Bundle} to pass an input parameter to the call activity to - * tell it which type of engagement you would like to start. Can be one of: - * {@link MEDIA_TYPE_AUDIO} or {@link MEDIA_TYPE_VIDEO}. - * If no parameter is passed then will default to {@link MEDIA_TYPE_AUDIO} - */ - public static final String MEDIA_TYPE = "media_type"; - /** - * Pass this parameter as an input parameter with {@link MEDIA_TYPE} as its key to - * {@link com.glia.widgets.call.CallActivity} to start an audio call media engagement. - */ - public static final String MEDIA_TYPE_AUDIO = "media_type_audio"; - /** - * Pass this parameter as an input parameter with {@link MEDIA_TYPE} as its key to - * {@link com.glia.widgets.call.CallActivity} to start a video call media engagement. - */ - public static final String MEDIA_TYPE_VIDEO = "media_type_video"; - /** - * Pass this parameter to call activity to tell it that upgrade to audio/video call is ongoing - * If no parameter is passed then will default to false - */ - public static final String IS_UPGRADE_TO_CALL = "upgrade_to_call"; - public static final String SURVEY = "survey"; - /** - * Use with {@link android.os.Bundle} to pass in - * {@link com.glia.androidsdk.screensharing.ScreenSharing.Mode} as a navigation - * argument when navigating to {@link com.glia.widgets.chat.ChatActivity} - */ - public static final String SCREEN_SHARING_MODE = "screens_haring_mode"; - public static final String CHAT_TYPE = "chat_type"; private final static String TAG = "GliaWidgets"; @Nullable private static CustomCardAdapter customCardAdapter = new WebViewCardAdapter(); @@ -207,7 +114,9 @@ private static void setupQueueIds(@Nullable List queueIds) { * Your activity in turn must call this method to pass the results of the request to Glia SDK.

* *

This method is no-op for other non-Glia triggered results.

+ * @deprecated This method is no longer required, as all the required permissions are now managed internally. */ + @Deprecated(forRemoval = true) public static void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { Logger.d(TAG, "onRequestPermissionsResult"); Dependencies.glia().onRequestPermissionsResult(requestCode, permissions, grantResults); @@ -225,7 +134,9 @@ public static void onRequestPermissionsResult(int requestCode, String[] permissi * Your activity in turn must call this method to pass the results of the request to Glia SDK.

* *

This method is no-op for other non-Glia triggered results.

+ * @deprecated This method is no longer required, as required activity results are now managed internally. */ + @Deprecated(forRemoval = true) public static void onActivityResult(int requestCode, int resultCode, Intent data) { Logger.d(TAG, "onActivityResult"); Dependencies.getRepositoryFactory().getEngagementRepository().onActivityResult(requestCode, resultCode, data); diff --git a/widgetssdk/src/main/java/com/glia/widgets/UiTheme.kt b/widgetssdk/src/main/java/com/glia/widgets/UiTheme.kt index a7d8525b0..9ea4df6f5 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/UiTheme.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/UiTheme.kt @@ -30,10 +30,6 @@ import kotlinx.parcelize.Parcelize "The remote configurations approach is more versatile and better suited for future development." ) data class UiTheme( - /** - * Text to be shown on the top of the app bar in the chat - */ - val appBarTitle: String? = null, /** * Primary color for your brand. Used for example to set the color of the appbar @@ -372,7 +368,6 @@ data class UiTheme( ) : Parcelable, Mergeable { private constructor(builder: UiThemeBuilder) : this( - appBarTitle = builder.appBarTitle, brandPrimaryColor = builder.brandPrimaryColor, baseLightColor = builder.baseLightColor, baseDarkColor = builder.baseDarkColor, @@ -439,7 +434,6 @@ data class UiTheme( ) override fun merge(other: UiTheme): UiTheme = UiTheme( - appBarTitle = appBarTitle merge other.appBarTitle, brandPrimaryColor = brandPrimaryColor merge other.brandPrimaryColor, baseLightColor = baseLightColor merge other.baseLightColor, baseDarkColor = baseDarkColor merge other.baseDarkColor, @@ -544,11 +538,6 @@ data class UiTheme( "The remote configurations approach is more versatile and better suited for future development." ) class UiThemeBuilder { - /** - * Text to be shown on the top of the app bar in the chat - */ - var appBarTitle: String? = null - private set /** * Primary color for your brand. Used for example to set the color of the appbar @@ -932,10 +921,6 @@ data class UiTheme( var gvaQuickReplyTextColor: Int? = null private set - fun setAppBarTitle(appBarTitle: String?) { - this.appBarTitle = appBarTitle - } - fun setFontRes(@FontRes fontRes: Int?) { this.fontRes = fontRes?.takeIf { it != 0 } } @@ -1185,7 +1170,6 @@ data class UiTheme( } fun setTheme(theme: UiTheme) { - appBarTitle = theme.appBarTitle brandPrimaryColor = theme.brandPrimaryColor baseLightColor = theme.baseLightColor baseDarkColor = theme.baseDarkColor diff --git a/widgetssdk/src/main/java/com/glia/widgets/call/CallActivity.kt b/widgetssdk/src/main/java/com/glia/widgets/call/CallActivity.kt index 534585dbd..8a52e799f 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/call/CallActivity.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/call/CallActivity.kt @@ -1,14 +1,16 @@ package com.glia.widgets.call import android.os.Bundle -import com.glia.widgets.GliaWidgets +import com.glia.androidsdk.Engagement.MediaType import com.glia.widgets.R import com.glia.widgets.base.FadeTransitionActivity import com.glia.widgets.call.CallView.OnNavigateToChatListener import com.glia.widgets.call.CallView.OnNavigateToWebBrowserListener import com.glia.widgets.di.Dependencies +import com.glia.widgets.helper.ExtraKeys import com.glia.widgets.helper.Logger import com.glia.widgets.helper.TAG +import com.glia.widgets.helper.getEnumExtra import com.glia.widgets.launcher.ActivityLauncher import com.glia.widgets.locale.LocaleString import kotlin.properties.Delegates @@ -25,24 +27,9 @@ import kotlin.properties.Delegates * * * Before this activity is launched, make sure that Glia Widgets SDK is set up correctly. - * - * - * Data that can be passed together with the Activity intent: - * - [GliaWidgets.QUEUE_IDS]: IDs list of the queues you would like to use for your engagements. - * For a full list of optional parameters, see the constants defined in [GliaWidgets]. - * - * - * Code example: - *
- * Intent intent = new Intent(requireContext(), CallActivity.class);
- * intent.putExtra(GliaWidgets.QUEUE_IDS, new ArrayList<>(List.of("AUDIO_QUEUE_ID")));
- * intent.putExtra(GliaWidgets.MEDIA_TYPE, Engagement.MediaType.VIDEO);
- * startActivity(intent);
-
* */ -class CallActivity : FadeTransitionActivity() { +internal class CallActivity : FadeTransitionActivity() { private val activityLauncher: ActivityLauncher by lazy { Dependencies.activityLauncher } - private var callConfiguration: CallConfiguration by Delegates.notNull() private var callView: CallView by Delegates.notNull() private var onBackClickedListener: CallView.OnBackClickedListener? = CallView.OnBackClickedListener { this.finish() } @@ -58,25 +45,14 @@ class CallActivity : FadeTransitionActivity() { setContentView(R.layout.call_activity) callView = findViewById(R.id.call_view) - // Legacy company name support - Dependencies.sdkConfigurationManager.setLegacyCompanyName(intent.getStringExtra(GliaWidgets.COMPANY_NAME)) + val isUpgradeToCall = intent.getBooleanExtra(ExtraKeys.IS_UPGRADE_TO_CALL, false) - callConfiguration = CallActivityConfigurationHelper.readConfiguration(this) - if (this.intent.hasExtra(GliaWidgets.USE_OVERLAY)) { - // Integrator has passed a deprecated GliaWidgets.USE_OVERLAY parameter with Intent - // Override bubble configuration with USE_OVERLAY value - val useOverlay = this.intent.getBooleanExtra(GliaWidgets.USE_OVERLAY, true) - Dependencies.sdkConfigurationManager.setLegacyUseOverlay(useOverlay) - } - - if (!callView.shouldShowMediaEngagementView(callConfiguration.isUpgradeToCall)) { + if (!callView.shouldShowMediaEngagementView(isUpgradeToCall)) { finishAndRemoveTask() return } callView.setOnTitleUpdatedListener(this::setTitle) - callView.setEngagementConfiguration(callConfiguration.engagementConfiguration) - callView.setUiTheme(callConfiguration.engagementConfiguration?.runTimeTheme) onBackClickedListener?.also(callView::setOnBackClickedListener) // In case the engagement ends, Activity is removed from the device's Recent menu @@ -89,7 +65,8 @@ class CallActivity : FadeTransitionActivity() { callView.setOnNavigateToWebBrowserListener(onNavigateToWebBrowserListener) if (savedInstanceState == null) { - startCall() + + startCall(intent.getEnumExtra(ExtraKeys.MEDIA_TYPE), isUpgradeToCall) } } @@ -116,21 +93,13 @@ class CallActivity : FadeTransitionActivity() { callView.onUserInteraction() } - private fun startCall() { - val engagementConfiguration = callConfiguration.engagementConfiguration!! - callView.startCall( - engagementConfiguration.companyName!!, - engagementConfiguration.queueIds, - engagementConfiguration.contextAssetId, - engagementConfiguration.screenSharingMode!!, - callConfiguration.isUpgradeToCall, - callConfiguration.mediaType - ) + private fun startCall(mediaType: MediaType?, isUpgradeToCall: Boolean) { + callView.startCall(isUpgradeToCall, mediaType) } private fun navigateToChat() { Logger.d(TAG, "navigateToChat") - activityLauncher.launchChat(this, callConfiguration.engagementConfiguration ?: return) + activityLauncher.launchChat(this) } private fun navigateToWebBrowser(title: LocaleString, url: String) = activityLauncher.launchWebBrowser(this, title, url) diff --git a/widgetssdk/src/main/java/com/glia/widgets/call/CallActivityConfigurationHelper.kt b/widgetssdk/src/main/java/com/glia/widgets/call/CallActivityConfigurationHelper.kt deleted file mode 100644 index 4e25aecc9..000000000 --- a/widgetssdk/src/main/java/com/glia/widgets/call/CallActivityConfigurationHelper.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.glia.widgets.call - -import androidx.appcompat.app.AppCompatActivity -import com.glia.androidsdk.Engagement -import com.glia.widgets.GliaWidgets -import com.glia.widgets.core.configuration.EngagementConfiguration -import com.glia.widgets.helper.getSerializableExtraCompat - -internal object CallActivityConfigurationHelper { - - fun readConfiguration(activity: AppCompatActivity): CallConfiguration { - val intent = activity.intent - val engagementConfiguration = EngagementConfiguration(intent) - val mediaType = intent.getSerializableExtraCompat(GliaWidgets.MEDIA_TYPE) - val isUpgradeToCall = intent.getBooleanExtra(GliaWidgets.IS_UPGRADE_TO_CALL, false) - return CallConfiguration(engagementConfiguration = engagementConfiguration, mediaType = mediaType, isUpgradeToCall = isUpgradeToCall) - } -} diff --git a/widgetssdk/src/main/java/com/glia/widgets/call/CallConfiguration.kt b/widgetssdk/src/main/java/com/glia/widgets/call/CallConfiguration.kt deleted file mode 100644 index 176ae6672..000000000 --- a/widgetssdk/src/main/java/com/glia/widgets/call/CallConfiguration.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.glia.widgets.call - -import com.glia.androidsdk.Engagement -import com.glia.widgets.core.configuration.EngagementConfiguration - -internal data class CallConfiguration @JvmOverloads constructor( - @JvmField - val engagementConfiguration: EngagementConfiguration?, - @JvmField - val mediaType: Engagement.MediaType? = null, - @JvmField - val isUpgradeToCall: Boolean = false -) diff --git a/widgetssdk/src/main/java/com/glia/widgets/call/CallContract.kt b/widgetssdk/src/main/java/com/glia/widgets/call/CallContract.kt index c75420bee..fcfa070a5 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/call/CallContract.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/call/CallContract.kt @@ -1,12 +1,11 @@ package com.glia.widgets.call import com.glia.androidsdk.Engagement -import com.glia.androidsdk.screensharing.ScreenSharing -import com.glia.widgets.locale.LocaleString import com.glia.widgets.base.BaseController import com.glia.widgets.base.BaseView import com.glia.widgets.core.dialog.model.ConfirmationDialogLinks import com.glia.widgets.core.dialog.model.Link +import com.glia.widgets.locale.LocaleString internal interface CallContract { interface Controller : BaseController { @@ -21,14 +20,7 @@ internal interface CallContract { fun muteButtonClicked() fun videoButtonClicked() fun flipVideoButtonClicked() - fun startCall( - companyName: String, - queueIds: List?, - visitorContextAssetId: String?, - mediaType: Engagement.MediaType?, - screenSharingMode: ScreenSharing.Mode, - upgradeToCall: Boolean - ) + fun startCall(mediaType: Engagement.MediaType?, upgradeToCall: Boolean) fun onResume() fun onPause() diff --git a/widgetssdk/src/main/java/com/glia/widgets/call/CallController.kt b/widgetssdk/src/main/java/com/glia/widgets/call/CallController.kt index 90aa92b59..53dfc7c80 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/call/CallController.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/call/CallController.kt @@ -8,7 +8,6 @@ import com.glia.androidsdk.comms.MediaDirection import com.glia.androidsdk.comms.MediaState import com.glia.androidsdk.comms.MediaUpgradeOffer import com.glia.androidsdk.comms.Video -import com.glia.androidsdk.screensharing.ScreenSharing import com.glia.widgets.Constants import com.glia.widgets.call.CallStatus.EngagementOngoingAudioCallStarted import com.glia.widgets.call.CallStatus.EngagementOngoingVideoCallStarted @@ -16,7 +15,6 @@ import com.glia.widgets.call.domain.HandleCallPermissionsUseCase import com.glia.widgets.chat.domain.DecideOnQueueingUseCase import com.glia.widgets.chat.domain.UpdateFromCallScreenUseCase import com.glia.widgets.core.audio.domain.TurnSpeakerphoneUseCase -import com.glia.widgets.core.configuration.GliaSdkConfigurationManager import com.glia.widgets.core.dialog.DialogContract import com.glia.widgets.core.dialog.domain.ConfirmationDialogLinksUseCase import com.glia.widgets.core.dialog.domain.IsShowOverlayPermissionRequestDialogUseCase @@ -64,10 +62,8 @@ import java.util.concurrent.TimeUnit private const val MAX_IDLE_TIME = 3200 private const val INACTIVITY_TIMER_TICKER_VALUE = 400 private const val INACTIVITY_TIMER_DELAY_VALUE = 0 -private const val TAG = "CallController" internal class CallController( - private val sdkConfigurationManager: GliaSdkConfigurationManager, private val callTimer: TimeCounter, private val inactivityTimeCounter: TimeCounter, private val connectingTimerCounter: TimeCounter, @@ -184,45 +180,21 @@ internal class CallController( emitViewState(callState.engagementStarted()) } - override fun startCall( - companyName: String, - queueIds: List?, - visitorContextAssetId: String?, - mediaType: Engagement.MediaType?, - screenSharingMode: ScreenSharing.Mode, - upgradeToCall: Boolean - ) { + override fun startCall(mediaType: Engagement.MediaType?, upgradeToCall: Boolean) { if (upgradeToCall || mediaType == null) { - initCall( - companyName, - queueIds, - visitorContextAssetId, - mediaType, - screenSharingMode) + initCall(mediaType) return } handleCallPermissionsUseCase.invoke(mediaType) { isPermissionsGranted: Boolean -> if (isPermissionsGranted) { - initCall( - companyName, - queueIds, - visitorContextAssetId, - mediaType, - screenSharingMode) + initCall(mediaType) } else { view?.showMissingPermissionsDialog() } } } - private fun initCall( - companyName: String, - queueIds: List?, - visitorContextAssetId: String?, - mediaType: Engagement.MediaType?, - screenSharingMode: ScreenSharing.Mode - ) { - sdkConfigurationManager.screenSharingMode = screenSharingMode + private fun initCall(mediaType: Engagement.MediaType?) { if (isShowOverlayPermissionRequestDialogUseCase()) { dialogController.showOverlayPermissionsDialog() } else { @@ -232,7 +204,7 @@ internal class CallController( if (callState.integratorCallStarted || dialogController.isShowingUnexpectedErrorDialog) { return } - emitViewState(callState.initCall(companyName, queueIds, visitorContextAssetId, mediaType)) + emitViewState(callState.initCall(mediaType)) createNewTimerStatusCallback() initMessagesNotSeenCallback() tryToQueueForEngagement() @@ -288,7 +260,7 @@ internal class CallController( } private fun enqueueForEngagement() { - enqueueForEngagementUseCase(callState.queueIds, callState.requestedMediaType, callState.visitorContextAssetId) + enqueueForEngagementUseCase(callState.requestedMediaType ?: return) } override fun onDestroy(retained: Boolean) { diff --git a/widgetssdk/src/main/java/com/glia/widgets/call/CallState.java b/widgetssdk/src/main/java/com/glia/widgets/call/CallState.java index e52d4143e..cf74450bd 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/call/CallState.java +++ b/widgetssdk/src/main/java/com/glia/widgets/call/CallState.java @@ -10,7 +10,6 @@ import com.glia.widgets.helper.Logger; import com.glia.widgets.view.floatingvisitorvideoview.FloatingVisitorVideoContract.FlipButtonState; -import java.util.List; import java.util.Objects; class CallState { @@ -23,7 +22,6 @@ class CallState { public final boolean landscapeLayoutControlsVisible; public final boolean isMuted; public final boolean hasVideo; - public final String companyName; @Nullable public final Engagement.MediaType requestedMediaType; public final boolean isSpeakerOn; @@ -31,8 +29,6 @@ class CallState { // Need this to not update all views when only time is changed. public final boolean isOnlyTimeChanged; public final boolean isCallVisualizer; - public final List queueIds; - public final String visitorContextAssetId; public final boolean isSharingScreen; public final FlipButtonState flipButtonState; @@ -45,14 +41,11 @@ private CallState(Builder builder) { this.landscapeLayoutControlsVisible = builder.landscapeLayoutControlsVisible; this.isMuted = builder.isMuted; this.hasVideo = builder.hasVideo; - this.companyName = builder.companyName; this.requestedMediaType = builder.requestedMediaType; this.isSpeakerOn = builder.isSpeakerOn; this.isOnHold = builder.isOnHold; this.isOnlyTimeChanged = builder.isOnlyTimeChanged; this.isCallVisualizer = builder.isCallVisualizer; - this.queueIds = builder.queueIds; - this.visitorContextAssetId = builder.visitorContextAssetId; this.isSharingScreen = builder.isSharingScreen; this.flipButtonState = builder.flipButtonState; } @@ -83,7 +76,6 @@ public boolean equals(Object o) { isMuted == callState.isMuted && hasVideo == callState.hasVideo && Objects.equals(callStatus, callState.callStatus) && - Objects.equals(companyName, callState.companyName) && Objects.equals(requestedMediaType, callState.requestedMediaType) && isSpeakerOn == callState.isSpeakerOn && isOnHold == callState.isOnHold && @@ -97,7 +89,7 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(integratorCallStarted, isVisible, messagesNotSeen, callStatus, landscapeLayoutControlsVisible, isMuted, hasVideo, - companyName, requestedMediaType, isSpeakerOn, isOnHold, isOnlyTimeChanged, + requestedMediaType, isSpeakerOn, isOnHold, isOnlyTimeChanged, isCallVisualizer, isSharingScreen, flipButtonState); } @@ -163,7 +155,6 @@ public String toString() { ", landscapeLayoutControlsVisible=" + landscapeLayoutControlsVisible + ", isMuted=" + isMuted + ", hasVideo=" + hasVideo + - ", companyName: " + companyName + ", requestedMediaType: " + requestedMediaType + ", isSpeakerOn: " + isSpeakerOn + ", isOnHold: " + isOnHold + @@ -481,15 +472,12 @@ private boolean isMuted(MediaState visitorMediaState) { visitorMediaState.getAudio().getStatus() != Media.Status.PLAYING; } - public CallState initCall(String companyName, List queueIds, String visitorContextAssetId, @Nullable Engagement.MediaType requestedMediaType) { + public CallState initCall(@Nullable Engagement.MediaType requestedMediaType) { return new Builder() .copyFrom(this) .setIntegratorCallStarted(true) .setVisible(true) .setIsOnHold(false) - .setCompanyName(companyName) - .setQueueIds(queueIds) - .setVisitorContextAssetId(visitorContextAssetId) .setRequestedMediaType(requestedMediaType) .createCallState(); } @@ -506,15 +494,12 @@ public static class Builder { private boolean landscapeLayoutControlsVisible; private boolean isMuted; private boolean hasVideo; - private String companyName; private Engagement.MediaType requestedMediaType; private boolean isSpeakerOn; private boolean isOnHold; //Maybe helpful when converting to Kotlin, as an android studio makes fields nullable. private boolean isOnlyTimeChanged = false; private boolean isCallVisualizer; - private List queueIds; - private String visitorContextAssetId; private boolean isSharingScreen; private FlipButtonState flipButtonState = FlipButtonState.HIDE; @@ -553,11 +538,6 @@ public Builder setHasVideo(boolean hasVideo) { return this; } - public Builder setCompanyName(String companyName) { - this.companyName = companyName; - return this; - } - public Builder setRequestedMediaType(Engagement.MediaType requestedMediaType) { this.requestedMediaType = requestedMediaType; return this; @@ -583,16 +563,6 @@ public Builder setIsCallVisualizer(boolean isCallVisualizer) { return this; } - public Builder setQueueIds(List queueIds) { - this.queueIds = queueIds; - return this; - } - - public Builder setVisitorContextAssetId(String visitorContextAssetId) { - this.visitorContextAssetId = visitorContextAssetId; - return this; - } - public Builder setIsSharingScreen(Boolean isSharingScreen) { this.isSharingScreen = isSharingScreen; return this; @@ -611,15 +581,12 @@ Builder copyFrom(CallState callState) { landscapeLayoutControlsVisible = callState.landscapeLayoutControlsVisible; isMuted = callState.isMuted; hasVideo = callState.hasVideo; - companyName = callState.companyName; requestedMediaType = callState.requestedMediaType; isSpeakerOn = callState.isSpeakerOn; isOnHold = callState.isOnHold; //as we are updating this field only when only time is changed, so needs to make it false every time. isOnlyTimeChanged = false; isCallVisualizer = callState.isCallVisualizer; - queueIds = callState.queueIds; - visitorContextAssetId = callState.visitorContextAssetId; isSharingScreen = callState.isSharingScreen; flipButtonState = callState.flipButtonState; return this; diff --git a/widgetssdk/src/main/java/com/glia/widgets/call/CallView.kt b/widgetssdk/src/main/java/com/glia/widgets/call/CallView.kt index 0fc2d61c4..10b4f1adc 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/call/CallView.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/call/CallView.kt @@ -22,13 +22,11 @@ import androidx.transition.TransitionSet import com.glia.androidsdk.Engagement import com.glia.androidsdk.comms.MediaState import com.glia.androidsdk.comms.VideoView -import com.glia.androidsdk.screensharing.ScreenSharing import com.glia.widgets.Constants import com.glia.widgets.R import com.glia.widgets.UiTheme import com.glia.widgets.UiTheme.UiThemeBuilder import com.glia.widgets.call.CallState.ViewState -import com.glia.widgets.core.configuration.EngagementConfiguration import com.glia.widgets.core.dialog.DialogContract import com.glia.widgets.core.dialog.model.DialogState import com.glia.widgets.databinding.CallButtonsLayoutBinding @@ -41,7 +39,6 @@ import com.glia.widgets.helper.Utils import com.glia.widgets.helper.getColorCompat import com.glia.widgets.helper.getColorStateListCompat import com.glia.widgets.helper.getFontCompat -import com.glia.widgets.helper.getFullHybridTheme import com.glia.widgets.helper.hideKeyboard import com.glia.widgets.helper.insetsController import com.glia.widgets.helper.requireActivity @@ -176,22 +173,8 @@ internal class CallView( } } - fun startCall( - companyName: String, - queueIds: List?, - visitorContextAssetId: String?, - screenSharingMode: ScreenSharing.Mode, - isUpgradeToCall: Boolean, - mediaType: Engagement.MediaType? - ) { - callController?.startCall( - companyName, - queueIds, - visitorContextAssetId, - mediaType, - screenSharingMode, - isUpgradeToCall - ) + fun startCall(isUpgradeToCall: Boolean, mediaType: Engagement.MediaType?) { + callController?.startCall(mediaType, isUpgradeToCall) } fun onDestroy() { @@ -514,13 +497,7 @@ internal class CallView( } private fun setDefaultTheme(typedArray: TypedArray) { - theme = Utils.getThemeFromTypedArray(typedArray, this.context) - .getFullHybridTheme(Dependencies.sdkConfigurationManager.uiTheme) - } - - fun setUiTheme(uiTheme: UiTheme?) { - theme = theme.getFullHybridTheme(uiTheme ?: return) - setupViewAppearance() + theme = Utils.getFullHybridTheme(typedArray, this.context) } fun setOnBackClickedListener(onBackClicked: OnBackClickedListener) { @@ -664,11 +641,6 @@ internal class CallView( callController?.onUserInteraction() } - fun setEngagementConfiguration(engagementConfiguration: EngagementConfiguration?) { - serviceChatHeadController?.setBuildTimeTheme(theme) - serviceChatHeadController?.setEngagementConfiguration(engagementConfiguration) - } - override fun showToast(message: String) { post { context.showToast(message, Toast.LENGTH_SHORT) } } diff --git a/widgetssdk/src/main/java/com/glia/widgets/callvisualizer/EndScreenSharingView.kt b/widgetssdk/src/main/java/com/glia/widgets/callvisualizer/EndScreenSharingView.kt index 46b423730..d5fbd8ea6 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/callvisualizer/EndScreenSharingView.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/callvisualizer/EndScreenSharingView.kt @@ -9,15 +9,12 @@ import com.glia.widgets.R import com.glia.widgets.UiTheme import com.glia.widgets.databinding.EndScreenSharingViewBinding import com.glia.widgets.di.Dependencies -import com.glia.widgets.helper.Logger import com.glia.widgets.helper.SimpleWindowInsetsAndAnimationHandler -import com.glia.widgets.helper.TAG import com.glia.widgets.helper.Utils import com.glia.widgets.helper.applyButtonTheme import com.glia.widgets.helper.applyTextTheme import com.glia.widgets.helper.getColorCompat import com.glia.widgets.helper.getFontCompat -import com.glia.widgets.helper.getFullHybridTheme import com.glia.widgets.helper.layoutInflater import com.glia.widgets.helper.setLocaleText import com.glia.widgets.locale.LocaleString @@ -70,12 +67,7 @@ internal class EndScreenSharingView( private fun applyDefaultTheme(attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) { context.withStyledAttributes(attrs, R.styleable.GliaView, defStyleAttr, defStyleRes) { - var theme = Utils.getThemeFromTypedArray(this, context) - theme.iconEndScreenShare?.let { - binding.endSharingButton.icon = ResourcesCompat.getDrawable(context.resources, it, null) - } - theme = theme.getFullHybridTheme(Dependencies.sdkConfigurationManager.uiTheme) - applyRuntimeTheme(theme) + applyRuntimeTheme(Utils.getFullHybridTheme(this, context)) } } @@ -109,10 +101,9 @@ internal class EndScreenSharingView( binding.root.applyLayerTheme(theme.background) } - private fun applyRuntimeTheme(theme: UiTheme?) { - if (theme == null) { - Logger.d(TAG, "UiTheme is null!") - return + private fun applyRuntimeTheme(theme: UiTheme) { + theme.iconEndScreenShare?.let { + binding.endSharingButton.icon = ResourcesCompat.getDrawable(context.resources, it, null) } val systemNegativeColor = theme.systemNegativeColor?.let(::getColorCompat) diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/ChatActivity.kt b/widgetssdk/src/main/java/com/glia/widgets/chat/ChatActivity.kt index 2580b97a6..9f80d750e 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/ChatActivity.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/ChatActivity.kt @@ -1,20 +1,15 @@ package com.glia.widgets.chat -import android.content.Intent import android.os.Bundle import androidx.activity.OnBackPressedCallback import androidx.activity.enableEdgeToEdge -import com.glia.widgets.GliaWidgets import com.glia.widgets.R -import com.glia.widgets.UiTheme import com.glia.widgets.base.FadeTransitionActivity -import com.glia.widgets.call.CallConfiguration -import com.glia.widgets.core.configuration.EngagementConfiguration import com.glia.widgets.di.Dependencies -import com.glia.widgets.di.Dependencies.sdkConfigurationManager +import com.glia.widgets.helper.ExtraKeys import com.glia.widgets.helper.Logger import com.glia.widgets.helper.TAG -import com.glia.widgets.helper.Utils +import com.glia.widgets.helper.getEnumExtra import com.glia.widgets.launcher.ActivityLauncher import kotlin.properties.Delegates @@ -31,28 +26,11 @@ import kotlin.properties.Delegates * * * Before this activity is launched, make sure that Glia Widgets SDK is set up correctly. - * - * - * Data that can be passed together with the Activity intent: - * - [GliaWidgets.QUEUE_IDS]: IDs list of the queues you would like to use for your engagements. - * For a full list of optional parameters, see the constants defined in [GliaWidgets]. - * - * - * Code example: - *
- * Intent intent = new Intent(requireContext(), ChatActivity.class);
- * intent.putExtra(GliaWidgets.QUEUE_IDS, new ArrayList<>(List.of("CHAT_QUEUE_ID")));
- * startActivity(intent);
- * 

-
*/ -class ChatActivity : FadeTransitionActivity() { + */ +internal class ChatActivity : FadeTransitionActivity() { private val activityLauncher: ActivityLauncher by lazy { Dependencies.activityLauncher } private var chatView: ChatView by Delegates.notNull() - private var engagementConfiguration: EngagementConfiguration by Delegates.notNull() - - private val defaultCallConfiguration: CallConfiguration - get() = CallConfiguration(engagementConfiguration) override fun onCreate(savedInstanceState: Bundle?) { this.enableEdgeToEdge() @@ -67,25 +45,13 @@ class ChatActivity : FadeTransitionActivity() { } }) - // Legacy company name support - sdkConfigurationManager.setLegacyCompanyName(intent.getStringExtra(GliaWidgets.COMPANY_NAME)) - chatView.setOnTitleUpdatedListener(this::setTitle) - engagementConfiguration = createEngagementConfiguration(intent) - if (intent.hasExtra(GliaWidgets.USE_OVERLAY)) { - // Integrator has passed a deprecated GliaWidgets.USE_OVERLAY parameter with Intent - // Override bubble configuration with USE_OVERLAY value - val useOverlay = intent.getBooleanExtra(GliaWidgets.USE_OVERLAY, true) - sdkConfigurationManager.setLegacyUseOverlay(useOverlay) - } if (!chatView.shouldShow()) { finishAndRemoveTask() return } - chatView.setConfiguration(engagementConfiguration) - chatView.setUiTheme(engagementConfiguration.runTimeTheme) chatView.setOnBackClickedListener(::finish) chatView.setOnBackToCallListener(::backToCallScreen) @@ -95,14 +61,10 @@ class ChatActivity : FadeTransitionActivity() { chatView.setOnEndListener(::finishAndRemoveTask) chatView.setOnMinimizeListener(::finish) - chatView.setOnNavigateToCallListener(this::startCallScreen) - chatView.startChat( - engagementConfiguration.companyName, - engagementConfiguration.queueIds, - engagementConfiguration.contextAssetId, - engagementConfiguration.screenSharingMode, - engagementConfiguration.chatType ?: ChatType.LIVE_CHAT - ) + + val chatType = intent.getEnumExtra(ExtraKeys.CHAT_TYPE) ?: ChatType.LIVE_CHAT + + chatView.startChat(chatType) } override fun onResume() { @@ -121,16 +83,8 @@ class ChatActivity : FadeTransitionActivity() { super.onDestroy() } - private fun createEngagementConfiguration(intent: Intent): EngagementConfiguration = EngagementConfiguration(intent) - - //TODO: Check why theme attribute is not anymore used - private fun startCallScreen(theme: UiTheme, mediaType: String) { - activityLauncher.launchCall(this, defaultCallConfiguration.copy(mediaType = Utils.toMediaType(mediaType), isUpgradeToCall = true)) - finish() - } - private fun backToCallScreen() { - activityLauncher.launchCall(this, defaultCallConfiguration) + activityLauncher.launchCall(this, null, false) finish() } } diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/ChatContract.kt b/widgetssdk/src/main/java/com/glia/widgets/chat/ChatContract.kt index 192f2a2ed..9f421ee43 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/ChatContract.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/ChatContract.kt @@ -4,7 +4,6 @@ import android.net.Uri import android.widget.Toast import com.glia.androidsdk.chat.AttachmentFile import com.glia.androidsdk.chat.SingleChoiceOption -import com.glia.widgets.locale.LocaleString import com.glia.widgets.base.BaseController import com.glia.widgets.base.BaseView import com.glia.widgets.chat.model.ChatItem @@ -15,6 +14,7 @@ import com.glia.widgets.chat.model.OperatorMessageItem import com.glia.widgets.core.dialog.model.ConfirmationDialogLinks import com.glia.widgets.core.dialog.model.Link import com.glia.widgets.core.fileupload.model.FileAttachment +import com.glia.widgets.locale.LocaleString internal interface ChatContract { interface Controller : BaseController { @@ -49,7 +49,7 @@ internal interface ChatContract { fun onLinkClicked(link: Link) fun getConfirmationDialogLinks(): ConfirmationDialogLinks fun onEngagementConfirmationDialogRequested() - fun initChat(companyName: String?, queueIds: List?, visitorContextAssetId: String?, chatType: ChatType) + fun initChat(chatType: ChatType) fun show() fun onPause() fun onResume() @@ -63,7 +63,6 @@ internal interface ChatContract { fun emitUploadAttachments(attachments: List) fun emitState(chatState: ChatState) fun emitItems(items: List) - fun navigateToCall(mediaType: String) fun backToCall() fun minimizeView() fun smoothScrollToBottom() diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/ChatManager.kt b/widgetssdk/src/main/java/com/glia/widgets/chat/ChatManager.kt index ad1c3d849..cb0fc8e94 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/ChatManager.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/ChatManager.kt @@ -191,7 +191,7 @@ internal class ChatManager( @VisibleForTesting fun mapAction(action: Action, state: State): State { return when (action) { - is Action.QueuingStarted -> mapInQueue(action.companyName, state) + Action.QueuingStarted -> mapInQueue(state) is Action.OperatorConnected -> mapOperatorConnected(action, state) Action.Transferring -> mapTransferring(state) is Action.OperatorJoined -> mapOperatorJoined(action, state) @@ -264,7 +264,7 @@ internal class ChatManager( fun mapOperatorJoined(action: Action.OperatorJoined, state: State): State = state.apply { chatItems -= OperatorStatusItem.Transferring chatItems += action.run { - OperatorStatusItem.Joined(companyName, operatorFormattedName, operatorImageUrl) + OperatorStatusItem.Joined(operatorFormattedName, operatorImageUrl) } } @@ -337,7 +337,7 @@ internal class ChatManager( @VisibleForTesting fun mapOperatorConnected(action: Action.OperatorConnected, state: State): State { - val operatorStatusItem = action.run { OperatorStatusItem.Connected(companyName, operatorFormattedName, operatorImageUrl) } + val operatorStatusItem = action.run { OperatorStatusItem.Connected(operatorFormattedName, operatorImageUrl) } val oldOperatorStatusItem: OperatorStatusItem? = state.operatorStatusItem state.operatorStatusItem = operatorStatusItem @@ -367,8 +367,8 @@ internal class ChatManager( } @VisibleForTesting - fun mapInQueue(companyName: String, state: State): State = state.apply { - OperatorStatusItem.InQueue(companyName).also { + fun mapInQueue(state: State): State = state.apply { + OperatorStatusItem.InQueue.also { operatorStatusItem = it chatItems += it } @@ -422,10 +422,10 @@ internal class ChatManager( } internal sealed interface Action { - data class QueuingStarted(val companyName: String) : Action - data class OperatorConnected(val companyName: String, val operatorFormattedName: String, val operatorImageUrl: String?) : Action + object QueuingStarted : Action + data class OperatorConnected(val operatorFormattedName: String, val operatorImageUrl: String?) : Action object Transferring : Action - data class OperatorJoined(val companyName: String, val operatorFormattedName: String, val operatorImageUrl: String?) : Action + data class OperatorJoined(val operatorFormattedName: String, val operatorImageUrl: String?) : Action data class UnsentMessageReceived(val message: Unsent) : Action data class ResponseCardClicked(val responseCard: OperatorMessageItem.ResponseCard) : Action data class OnMediaUpgradeStarted(val isVideo: Boolean) : Action diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/ChatType.kt b/widgetssdk/src/main/java/com/glia/widgets/chat/ChatType.kt index 720ed8841..2278e43ee 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/ChatType.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/ChatType.kt @@ -1,21 +1,9 @@ package com.glia.widgets.chat -import android.os.Parcelable -import kotlinx.parcelize.Parcelize - /** * Determines which type of chat engagement to launch. - * - * Code example: - * ``` - * Intent intent = new Intent(requireContext(), ChatActivity.class); - * intent.putExtra(GliaWidgets.QUEUE_ID, "MESSAGING_QUEUE_ID"); - * intent.putExtra(GliaWidgets.CHAT_TYPE, (Parcelable) ChatType.SECURE_MESSAGING); - * startActivity(intent); - * ``` */ -@Parcelize -enum class ChatType : Parcelable { +internal enum class ChatType { /** * Regular engagements with live chat. */ diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/ChatView.kt b/widgetssdk/src/main/java/com/glia/widgets/chat/ChatView.kt index 396873a3c..21f141e2f 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/ChatView.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/ChatView.kt @@ -23,7 +23,6 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver import com.glia.androidsdk.chat.AttachmentFile -import com.glia.androidsdk.screensharing.ScreenSharing import com.glia.widgets.Constants import com.glia.widgets.GliaWidgets import com.glia.widgets.R @@ -39,7 +38,6 @@ import com.glia.widgets.chat.model.ChatInputMode import com.glia.widgets.chat.model.ChatItem import com.glia.widgets.chat.model.ChatState import com.glia.widgets.chat.model.CustomCardChatItem -import com.glia.widgets.core.configuration.EngagementConfiguration import com.glia.widgets.core.dialog.DialogContract import com.glia.widgets.core.dialog.model.DialogState import com.glia.widgets.core.fileupload.model.FileAttachment @@ -57,7 +55,6 @@ import com.glia.widgets.helper.getColorCompat import com.glia.widgets.helper.getColorStateListCompat import com.glia.widgets.helper.getContentUriCompat import com.glia.widgets.helper.getFontCompat -import com.glia.widgets.helper.getFullHybridTheme import com.glia.widgets.helper.hideKeyboard import com.glia.widgets.helper.insetsController import com.glia.widgets.helper.layoutInflater @@ -105,7 +102,6 @@ internal class ChatView(context: Context, attrs: AttributeSet?, defStyleAttr: In private var onTitleUpdatedListener: OnTitleUpdatedListener? = null private var onEndListener: OnEndListener? = null private var onMinimizeListener: OnMinimizeListener? = null - private var onNavigateToCallListener: OnNavigateToCallListener? = null private var onBackToCallListener: OnBackToCallListener? = null private val onMessageClickListener = ChatAdapter.OnMessageClickListener { messageId: String -> controller?.onMessageClicked(messageId) @@ -192,36 +188,10 @@ internal class ChatView(context: Context, attrs: AttributeSet?, defStyleAttr: In context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = R.attr.gliaChatStyle ) : this(context, attrs, defStyleAttr, R.style.Application_Glia_Chat) - /** - * @param uiTheme sets this view's appearance using the parameters provided in the - * [com.glia.widgets.UiTheme] - */ - fun setUiTheme(uiTheme: UiTheme?) { - if (uiTheme == null) return - theme = theme.getFullHybridTheme(uiTheme) - setupViewAppearance() - } - /** - * Used to start the chat functionality. - * - * @param companyName Text shown in the chat while waiting in a queue. - * @param queueIds The queue ids to which you would like to queue to and speak to operators from. - * @param visitorContextAssetId Provide some context asset ID as to from where are you initiating the chat from. - * @see [com.glia.widgets.GliaWidgets].USE_OVERLAY to see its full usage description. - * Important! This parameter is ignored if the view is not used in the sdk's [ChatActivity] - */ - @JvmOverloads - fun startChat( - companyName: String?, - queueIds: List?, - visitorContextAssetId: String?, - screenSharingMode: ScreenSharing.Mode? = null, - chatType: ChatType = ChatType.LIVE_CHAT - ) { - Dependencies.sdkConfigurationManager.screenSharingMode = screenSharingMode + fun startChat(chatType: ChatType = ChatType.LIVE_CHAT) { dialogCallback?.also { dialogController?.addCallback(it) } - controller?.initChat(companyName, queueIds, visitorContextAssetId, chatType) + controller?.initChat(chatType) } /** @@ -266,19 +236,6 @@ internal class ChatView(context: Context, attrs: AttributeSet?, defStyleAttr: In this.onMinimizeListener = onMinimizeListener } - /** - * Add a listener here for when the user has accepted an audio or video call and should navigate - * to a call. - * Important! Should be used together with [.navigateToCallSuccess] to notify the view - * of a completed navigation. - * - * @param onNavigateToCallListener The callback which is fired when the user accepts a media - * upgrade offer. - */ - fun setOnNavigateToCallListener(onNavigateToCallListener: OnNavigateToCallListener?) { - this.onNavigateToCallListener = onNavigateToCallListener - } - fun setOnBackToCallListener(onBackToCallListener: OnBackToCallListener?) { this.onBackToCallListener = onBackToCallListener } @@ -305,7 +262,6 @@ internal class ChatView(context: Context, attrs: AttributeSet?, defStyleAttr: In resetDialogStateAndDismiss() onEndListener = null - onNavigateToCallListener = null destroyController() adapter.unregisterAdapterDataObserver(dataObserver) binding.chatRecyclerView.adapter = null @@ -364,10 +320,6 @@ internal class ChatView(context: Context, attrs: AttributeSet?, defStyleAttr: In post { adapter.submitList(updatedItems) } } - override fun navigateToCall(mediaType: String) { - onNavigateToCallListener?.call(theme, mediaType) - } - override fun backToCall() { onBackToCallListener?.onBackToCall() } @@ -580,8 +532,7 @@ internal class ChatView(context: Context, attrs: AttributeSet?, defStyleAttr: In } private fun setDefaultTheme(typedArray: TypedArray) { - theme = Utils.getThemeFromTypedArray(typedArray, this.context) - theme = theme.getFullHybridTheme(Dependencies.sdkConfigurationManager.uiTheme) + theme = Utils.getFullHybridTheme(typedArray, this.context) } private fun initConfigurations() { @@ -803,11 +754,6 @@ internal class ChatView(context: Context, attrs: AttributeSet?, defStyleAttr: In controller?.onImageItemClick(item, view) } - fun setConfiguration(configuration: EngagementConfiguration?) { - serviceChatHeadController?.setBuildTimeTheme(theme) - serviceChatHeadController?.setEngagementConfiguration(configuration) - } - override fun showToast(message: String, duration: Int) { Toast.makeText(context, message, duration).show() } @@ -887,17 +833,6 @@ internal class ChatView(context: Context, attrs: AttributeSet?, defStyleAttr: In fun onMinimize() } - fun interface OnNavigateToCallListener { - /** - * Callback which is fired when the user has accepted a media upgrade offer and should be - * navigated to a view where they can visually see data about their media upgrade. - * - * @param theme Used to pass the finalized [UiTheme] - * to the activity which is being navigated to. - */ - fun call(theme: UiTheme, mediaType: String) - } - fun interface OnBackToCallListener { fun onBackToCall() } diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/adapter/holder/OperatorStatusViewHolder.kt b/widgetssdk/src/main/java/com/glia/widgets/chat/adapter/holder/OperatorStatusViewHolder.kt index 4376560f6..8f9862a5f 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/adapter/holder/OperatorStatusViewHolder.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/adapter/holder/OperatorStatusViewHolder.kt @@ -85,7 +85,7 @@ internal class OperatorStatusViewHolder( chatStartingHeadingView.setLocaleText(R.string.general_company_name) when (item) { is OperatorStatusItem.Connected -> applyConnectedState(item.operatorName, item.profileImgUrl) - is OperatorStatusItem.InQueue -> applyInQueueState(item.companyName) + is OperatorStatusItem.InQueue -> applyInQueueState() is OperatorStatusItem.Joined -> applyConnectedState(item.operatorName, item.profileImgUrl) is OperatorStatusItem.Transferring -> applyTransferringState() } @@ -93,13 +93,13 @@ internal class OperatorStatusViewHolder( statusPictureView.setShowRippleAnimation(isShowStatusViewRippleAnimation(item)) } - private fun applyInQueueState(companyName: String?) { + private fun applyInQueueState() { statusPictureView.showPlaceholder() applyChatStartingViewsVisibility() applyChatStartedViewsVisibility(false) itemView.setLocaleContentDescription( R.string.android_chat_queue_message_accessibility_label, - StringKeyPair(StringKey.COMPANY_NAME, companyName ?: "") + StringKeyPair(StringKey.COMPANY_NAME, "") ) engagementStatesTheme?.queue.also(::applyEngagementState) @@ -124,24 +124,6 @@ internal class OperatorStatusViewHolder( engagementStatesTheme?.connected.also(::applyEngagementState) } - private fun applyJoinedState(operatorName: String, profileImgUrl: String?) { - profileImgUrl?.let { statusPictureView.showProfileImage(it) } - ?: statusPictureView.showPlaceholder() - chatStartedNameView.text = operatorName - chatStartedCaptionView.setLocaleText( - R.string.chat_operator_joined_system_message, StringKeyPair(StringKey.OPERATOR_NAME, operatorName) - ) - itemView.setLocaleContentDescription( - R.string.chat_operator_joined_system_message, - StringKeyPair(StringKey.OPERATOR_NAME, operatorName) - ) - - applyChatStartingViewsVisibility(false) - applyChatStartedViewsVisibility() - - engagementStatesTheme?.connecting.also(::applyEngagementState) - } - private fun applyTransferringState() { statusPictureView.showPlaceholder() chatStartingCaptionView.isVisible = true diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/controller/ChatController.kt b/widgetssdk/src/main/java/com/glia/widgets/chat/controller/ChatController.kt index 24fa4f113..8b1411fa6 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/controller/ChatController.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/controller/ChatController.kt @@ -211,8 +211,8 @@ internal class ChatController( screenSharingUseCase.end() } - override fun initChat(companyName: String?, queueIds: List?, visitorContextAssetId: String?, chatType: ChatType) { - engagementConfigUseCase(chatType, queueIds ?: emptyList()) + override fun initChat(chatType: ChatType) { + engagementConfigUseCase(chatType) updateOperatorDefaultImageUrlUseCase() ensureSecureMessagingAvailable() @@ -225,7 +225,7 @@ internal class ChatController( return } - emitViewState { chatState.initChat(companyName, queueIds, visitorContextAssetId) } + emitViewState { chatState.initChat() } initChatManager() } @@ -242,7 +242,6 @@ internal class ChatController( getAvailableQueueIdsForSecureMessagingUseCase().subscribe({ if (it.result != null) { Logger.d(TAG, "Messaging is available") - engagementConfigUseCase(ChatType.SECURE_MESSAGING, it.result) } else { Logger.d(TAG, "Messaging is unavailable") dialogController.showMessageCenterUnavailableDialog() @@ -293,9 +292,7 @@ internal class ChatController( } private fun enqueueForEngagement() { - requestNotificationPermissionIfPushNotificationsSetUpUseCase { - enqueueForEngagementUseCase(queueIds = chatState.queueIds, visitorContextAssetId = chatState.visitorContextAssetId) - } + requestNotificationPermissionIfPushNotificationsSetUpUseCase(enqueueForEngagementUseCase::invoke) } @Synchronized @@ -585,7 +582,7 @@ internal class ChatController( if (isQueueingOrOngoingEngagement) return Logger.d(TAG, "viewInitPreQueueing") - chatManager.onChatAction(ChatManager.Action.QueuingStarted(chatState.companyName.orEmpty())) + chatManager.onChatAction(ChatManager.Action.QueuingStarted) confirmationDialogUseCase { shouldShow -> if (shouldShow) { dialogController.showEngagementConfirmationDialog() @@ -606,18 +603,14 @@ internal class ChatController( private fun operatorConnected(formattedOperatorName: String, profileImgUrl: String?) { chatManager.onChatAction( - ChatManager.Action.OperatorConnected( - chatState.companyName.orEmpty(), formattedOperatorName, profileImgUrl - ) + ChatManager.Action.OperatorConnected(formattedOperatorName, profileImgUrl) ) emitViewState { chatState.operatorConnected(formattedOperatorName, profileImgUrl).setLiveChatState() } } private fun operatorChanged(formattedOperatorName: String, profileImgUrl: String?) { chatManager.onChatAction( - ChatManager.Action.OperatorJoined( - chatState.companyName.orEmpty(), formattedOperatorName, profileImgUrl - ) + ChatManager.Action.OperatorJoined(formattedOperatorName, profileImgUrl) ) emitViewState { chatState.operatorConnected(formattedOperatorName, profileImgUrl) } } diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/model/ChatItems.kt b/widgetssdk/src/main/java/com/glia/widgets/chat/model/ChatItems.kt index 9017fd34b..49f885880 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/model/ChatItems.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/model/ChatItems.kt @@ -34,9 +34,11 @@ internal abstract class OperatorChatItem(@ChatAdapter.Type viewType: Int) : Serv internal sealed class Attachment(val id: String) { val remoteAttachment: AttachmentFile? get() = (this as? Remote)?.attachmentFile val localAttachment: FileAttachment? get() = (this as? Local)?.fileAttachment + data class Remote(val attachmentFile: AttachmentFile) : Attachment(attachmentFile.id) data class Local(val fileAttachment: FileAttachment) : Attachment(UUID.randomUUID().toString()) } + internal interface AttachmentItem { val attachment: Attachment val isFileExists: Boolean @@ -173,25 +175,19 @@ internal sealed class OperatorStatusItem : ChatItem(ChatAdapter.OPERATOR_STATUS_ override val id: String = "operator_status_item" override val timestamp: Long = -1 - abstract val companyName: String? - - data class InQueue(override val companyName: String?) : OperatorStatusItem() + object InQueue : OperatorStatusItem() data class Connected( - override val companyName: String?, val operatorName: String, val profileImgUrl: String? ) : OperatorStatusItem() data class Joined( - override val companyName: String?, val operatorName: String, val profileImgUrl: String? ) : OperatorStatusItem() - object Transferring : OperatorStatusItem() { - override val companyName: String? = null - } + object Transferring : OperatorStatusItem() } // Visitor diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/model/ChatState.kt b/widgetssdk/src/main/java/com/glia/widgets/chat/model/ChatState.kt index 3ee59b76f..763d286a9 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/model/ChatState.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/model/ChatState.kt @@ -7,9 +7,6 @@ internal data class ChatState( val messagesNotSeen: Int = 0, val formattedOperatorName: String? = null, val operatorProfileImgUrl: String? = null, - val companyName: String? = null, - val queueIds: List? = null, - val visitorContextAssetId: String? = null, val isMediaUpgradeVide: Boolean? = null, val chatInputMode: ChatInputMode = ChatInputMode.ENABLED_NO_ENGAGEMENT, val lastTypedText: String = "", @@ -35,11 +32,8 @@ internal data class ChatState( val isAttachmentButtonVisible: Boolean get() = isAttachmentButtonNeeded && isAttachmentAllowed - fun initChat(companyName: String?, queueIds: List?, visitorContextAssetId: String?): ChatState = copy( + fun initChat(): ChatState = copy( integratorChatStarted = true, - companyName = companyName, - queueIds = queueIds, - visitorContextAssetId = visitorContextAssetId, isVisible = true, showSendButton = false, isAttachmentButtonEnabled = true, diff --git a/widgetssdk/src/main/java/com/glia/widgets/core/chathead/domain/IsDisplayBubbleInsideAppUseCase.kt b/widgetssdk/src/main/java/com/glia/widgets/core/chathead/domain/IsDisplayBubbleInsideAppUseCase.kt index 9fbc2ed3d..0bc93064c 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/core/chathead/domain/IsDisplayBubbleInsideAppUseCase.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/core/chathead/domain/IsDisplayBubbleInsideAppUseCase.kt @@ -1,18 +1,18 @@ package com.glia.widgets.core.chathead.domain -import com.glia.widgets.core.configuration.GliaSdkConfigurationManager import com.glia.widgets.core.permissions.PermissionManager import com.glia.widgets.engagement.domain.EngagementTypeUseCase import com.glia.widgets.engagement.domain.IsCurrentEngagementCallVisualizerUseCase import com.glia.widgets.engagement.domain.IsQueueingOrEngagementUseCase import com.glia.widgets.engagement.domain.ScreenSharingUseCase +import com.glia.widgets.launcher.ConfigurationManager internal class IsDisplayBubbleInsideAppUseCase( isQueueingOrEngagementUseCase: IsQueueingOrEngagementUseCase, isCurrentEngagementCallVisualizerUseCase: IsCurrentEngagementCallVisualizerUseCase, screenSharingUseCase: ScreenSharingUseCase, permissionManager: PermissionManager, - configurationManager: GliaSdkConfigurationManager, + configurationManager: ConfigurationManager, engagementTypeUseCase: EngagementTypeUseCase ) : IsDisplayBubbleUseCase( isQueueingOrEngagementUseCase, @@ -23,12 +23,12 @@ internal class IsDisplayBubbleInsideAppUseCase( engagementTypeUseCase ) { override fun isBubbleEnabled(): Boolean { - return configurationManager.isEnableBubbleInsideApp + return configurationManager.enableBubbleInsideApp } override fun isShowBasedOnForegroundBackground(viewName: String?): Boolean { return viewName != null && // App is in foreground // Use only ChatHeadService instead of ChatHeadService + app bubble if bubble is enabled outside and inside - (!configurationManager.isEnableBubbleOutsideApp || !configurationManager.isEnableBubbleInsideApp || !permissionManager.hasOverlayPermission()) + (!configurationManager.enableBubbleOutsideApp || !configurationManager.enableBubbleInsideApp || !permissionManager.hasOverlayPermission()) } } diff --git a/widgetssdk/src/main/java/com/glia/widgets/core/chathead/domain/IsDisplayBubbleOutsideAppUseCase.kt b/widgetssdk/src/main/java/com/glia/widgets/core/chathead/domain/IsDisplayBubbleOutsideAppUseCase.kt index 08ef94ec8..14fe24056 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/core/chathead/domain/IsDisplayBubbleOutsideAppUseCase.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/core/chathead/domain/IsDisplayBubbleOutsideAppUseCase.kt @@ -1,7 +1,6 @@ package com.glia.widgets.core.chathead.domain import com.glia.widgets.core.chathead.ChatHeadManager -import com.glia.widgets.core.configuration.GliaSdkConfigurationManager import com.glia.widgets.core.permissions.PermissionManager import com.glia.widgets.engagement.domain.EngagementTypeUseCase import com.glia.widgets.engagement.domain.IsCurrentEngagementCallVisualizerUseCase @@ -9,6 +8,7 @@ import com.glia.widgets.engagement.domain.IsQueueingOrEngagementUseCase import com.glia.widgets.engagement.domain.ScreenSharingUseCase import com.glia.widgets.helper.Logger import com.glia.widgets.helper.TAG +import com.glia.widgets.launcher.ConfigurationManager /** * This use case: @@ -21,7 +21,7 @@ internal class IsDisplayBubbleOutsideAppUseCase( screenSharingUseCase: ScreenSharingUseCase, private val chatHeadManager: ChatHeadManager, permissionManager: PermissionManager, - configurationManager: GliaSdkConfigurationManager, + configurationManager: ConfigurationManager, engagementTypeUseCase: EngagementTypeUseCase ) : IsDisplayBubbleUseCase( isQueueingOrEngagementUseCase, @@ -50,13 +50,13 @@ internal class IsDisplayBubbleOutsideAppUseCase( // global device bubble is NOT turned off by integrator (turned ON by default) // AND // global device bubble is allowed by visitor (overlay permission). - return configurationManager.isEnableBubbleOutsideApp && permissionManager.hasOverlayPermission() + return configurationManager.enableBubbleOutsideApp && permissionManager.hasOverlayPermission() } override fun isShowBasedOnForegroundBackground(viewName: String?): Boolean { return viewName == null || // true when app is in background // Use only ChatHeadService instead of ChatHeadService + app bubble if bubble is enabled outside and inside - (configurationManager.isEnableBubbleOutsideApp && configurationManager.isEnableBubbleInsideApp && permissionManager.hasOverlayPermission()) + (configurationManager.enableBubbleOutsideApp && configurationManager.enableBubbleInsideApp && permissionManager.hasOverlayPermission()) } fun onDestroy() { diff --git a/widgetssdk/src/main/java/com/glia/widgets/core/chathead/domain/IsDisplayBubbleUseCase.kt b/widgetssdk/src/main/java/com/glia/widgets/core/chathead/domain/IsDisplayBubbleUseCase.kt index 9094ddc1f..f876a9ffa 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/core/chathead/domain/IsDisplayBubbleUseCase.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/core/chathead/domain/IsDisplayBubbleUseCase.kt @@ -3,7 +3,6 @@ package com.glia.widgets.core.chathead.domain import com.glia.widgets.call.CallView import com.glia.widgets.callvisualizer.EndScreenSharingView import com.glia.widgets.chat.ChatView -import com.glia.widgets.core.configuration.GliaSdkConfigurationManager import com.glia.widgets.core.permissions.PermissionManager import com.glia.widgets.engagement.domain.EngagementTypeUseCase import com.glia.widgets.engagement.domain.IsCurrentEngagementCallVisualizerUseCase @@ -11,6 +10,7 @@ import com.glia.widgets.engagement.domain.IsQueueingOrEngagementUseCase import com.glia.widgets.engagement.domain.ScreenSharingUseCase import com.glia.widgets.filepreview.ui.ImagePreviewView import com.glia.widgets.helper.DialogHolderView +import com.glia.widgets.launcher.ConfigurationManager import com.glia.widgets.messagecenter.MessageCenterView internal abstract class IsDisplayBubbleUseCase( @@ -18,7 +18,7 @@ internal abstract class IsDisplayBubbleUseCase( private val isCurrentEngagementCallVisualizerUseCase: IsCurrentEngagementCallVisualizerUseCase, private val screenSharingUseCase: ScreenSharingUseCase, val permissionManager: PermissionManager, - internal val configurationManager: GliaSdkConfigurationManager, + internal val configurationManager: ConfigurationManager, private val engagementTypeUseCase: EngagementTypeUseCase ) { open operator fun invoke(viewName: String?): Boolean { diff --git a/widgetssdk/src/main/java/com/glia/widgets/core/configuration/EngagementConfiguration.kt b/widgetssdk/src/main/java/com/glia/widgets/core/configuration/EngagementConfiguration.kt deleted file mode 100644 index 63d08031c..000000000 --- a/widgetssdk/src/main/java/com/glia/widgets/core/configuration/EngagementConfiguration.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.glia.widgets.core.configuration - -import android.content.Intent -import com.glia.androidsdk.screensharing.ScreenSharing -import com.glia.widgets.GliaWidgets -import com.glia.widgets.UiTheme -import com.glia.widgets.chat.ChatType -import com.glia.widgets.di.Dependencies -import com.glia.widgets.helper.getParcelableExtraCompat -import com.glia.widgets.helper.getSerializableExtraCompat - -internal data class EngagementConfiguration( - val companyName: String? = null, - val queueIds: List? = null, - val contextAssetId: String? = null, - val chatType: ChatType? = null, - private val _runTimeTheme: UiTheme? = null, - private val _screenSharingMode: ScreenSharing.Mode? = null -) { - constructor(intent: Intent) : this( - companyName = Dependencies.sdkConfigurationManager.companyName, - queueIds = intent.getStringArrayListExtra(GliaWidgets.QUEUE_IDS) ?: intent.getStringExtra(GliaWidgets.QUEUE_ID)?.let(::listOf), - contextAssetId = intent.getStringExtra(GliaWidgets.CONTEXT_ASSET_ID), - chatType = intent.getParcelableExtraCompat(GliaWidgets.CHAT_TYPE), - _runTimeTheme = intent.getParcelableExtraCompat(GliaWidgets.UI_THEME) ?: Dependencies.sdkConfigurationManager.uiTheme, - _screenSharingMode = intent.getSerializableExtraCompat(GliaWidgets.SCREEN_SHARING_MODE) - ?: Dependencies.sdkConfigurationManager.screenSharingMode - ) - - val runTimeTheme: UiTheme? - get() = _runTimeTheme ?: Dependencies.sdkConfigurationManager.uiTheme - - val screenSharingMode: ScreenSharing.Mode? - get() = _screenSharingMode ?: Dependencies.sdkConfigurationManager.screenSharingMode -} diff --git a/widgetssdk/src/main/java/com/glia/widgets/core/configuration/GliaSdkConfigurationManager.java b/widgetssdk/src/main/java/com/glia/widgets/core/configuration/GliaSdkConfigurationManager.java deleted file mode 100644 index 288ec7394..000000000 --- a/widgetssdk/src/main/java/com/glia/widgets/core/configuration/GliaSdkConfigurationManager.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.glia.widgets.core.configuration; - -import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; - -import com.glia.androidsdk.screensharing.ScreenSharing; -import com.glia.widgets.GliaWidgetsConfig; -import com.glia.widgets.UiTheme; -import com.glia.widgets.di.Dependencies; -import com.glia.widgets.helper.Logger; -import com.glia.widgets.helper.ResourceProvider; - -/** - * @hide - */ -public class GliaSdkConfigurationManager { - - private static final String TAG = GliaSdkConfigurationManager.class.getSimpleName(); - - private ScreenSharing.Mode screenSharingMode = null; - private String companyName = null; - private String legacyCompanyName = null; - private boolean enableBubbleOutsideApp = true; // default values - private boolean enableBubbleInsideApp = true; // default values - - private UiTheme uiTheme = null; - - public void fromConfiguration(@NonNull GliaWidgetsConfig configuration) { - this.screenSharingMode = configuration.screenSharingMode; - this.companyName = configuration.companyName; - this.uiTheme = configuration.uiTheme; - - Boolean enableBubbleOutsideApp = configuration.enableBubbleOutsideApp; - if (enableBubbleOutsideApp != null) { - this.enableBubbleOutsideApp = enableBubbleOutsideApp; - } - - Boolean enableBubbleInsideApp = configuration.enableBubbleInsideApp; - if (enableBubbleInsideApp != null) { - this.enableBubbleInsideApp = enableBubbleInsideApp; - } - } - - public boolean isEnableBubbleOutsideApp() { - return this.enableBubbleOutsideApp; - } - - public boolean isEnableBubbleInsideApp() { - return this.enableBubbleInsideApp; - } - - /** - * @deprecated Should be removed together with GliaWidgetsConfig.USE_OVERLAY - */ - @Deprecated - public void setLegacyUseOverlay(boolean useOverlay) { - Logger.logDeprecatedMethodUse(TAG, "setLegacyUseOverlay()"); - this.enableBubbleOutsideApp = useOverlay; - this.enableBubbleInsideApp = useOverlay; - } - - public void setLegacyCompanyName(String companyName) { - this.legacyCompanyName = companyName; - } - - public String getCompanyName() { - if (companyName == null && legacyCompanyName != null) { - // Legacy company name configuration method used before local default - companyName = legacyCompanyName; - } - return companyName; - } - - @VisibleForTesting - public ResourceProvider getResourceProvider() { - return Dependencies.getResourceProvider(); - } - - public void setCompanyName(String companyName) { - this.companyName = companyName; - } - - public UiTheme getUiTheme() { - return uiTheme; - } - - public void setUiTheme(UiTheme uiTheme) { - this.uiTheme = uiTheme; - } - - public ScreenSharing.Mode getScreenSharingMode() { - return screenSharingMode; - } - - public void setScreenSharingMode(ScreenSharing.Mode screenSharingMode) { - this.screenSharingMode = screenSharingMode; - } - - @NonNull - public EngagementConfiguration buildEngagementConfiguration() { - return new EngagementConfiguration( - companyName, - null, - null, - null, - uiTheme, - screenSharingMode - ); - } -} diff --git a/widgetssdk/src/main/java/com/glia/widgets/core/dialog/domain/IsShowOverlayPermissionRequestDialogUseCase.kt b/widgetssdk/src/main/java/com/glia/widgets/core/dialog/domain/IsShowOverlayPermissionRequestDialogUseCase.kt index 04125e4d7..4533bf9ee 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/core/dialog/domain/IsShowOverlayPermissionRequestDialogUseCase.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/core/dialog/domain/IsShowOverlayPermissionRequestDialogUseCase.kt @@ -1,8 +1,8 @@ package com.glia.widgets.core.dialog.domain -import com.glia.widgets.core.configuration.GliaSdkConfigurationManager import com.glia.widgets.core.dialog.PermissionDialogManager import com.glia.widgets.core.permissions.PermissionManager +import com.glia.widgets.launcher.ConfigurationManager internal interface IsShowOverlayPermissionRequestDialogUseCase { operator fun invoke(): Boolean @@ -11,11 +11,11 @@ internal interface IsShowOverlayPermissionRequestDialogUseCase { internal class IsShowOverlayPermissionRequestDialogUseCaseImpl( private val permissionManager: PermissionManager, private val permissionDialogManager: PermissionDialogManager, - private val gliaSdkConfigurationManager: GliaSdkConfigurationManager + private val gliaSdkConfigurationManager: ConfigurationManager ) : IsShowOverlayPermissionRequestDialogUseCase { private val hasNoOverlayPermissions: Boolean get() = !permissionManager.hasOverlayPermission() private val hasNotShownOverlayPermissionRequest: Boolean get() = !permissionDialogManager.hasOverlayPermissionDialogShown() - private val isUseOverlay: Boolean get() = gliaSdkConfigurationManager.isEnableBubbleOutsideApp + private val isUseOverlay: Boolean get() = gliaSdkConfigurationManager.enableBubbleOutsideApp override fun invoke(): Boolean = hasNoOverlayPermissions && hasNotShownOverlayPermissionRequest && isUseOverlay } diff --git a/widgetssdk/src/main/java/com/glia/widgets/core/engagement/GliaEngagementConfigRepository.kt b/widgetssdk/src/main/java/com/glia/widgets/core/engagement/GliaEngagementConfigRepository.kt index 6b274b40d..e69587ec6 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/core/engagement/GliaEngagementConfigRepository.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/core/engagement/GliaEngagementConfigRepository.kt @@ -3,11 +3,11 @@ package com.glia.widgets.core.engagement import com.glia.widgets.chat.ChatType internal class GliaEngagementConfigRepository { - var queueIds = emptyList() + @Volatile + var queueIds = emptyList() //TODO this line must be removed after we have layer for up to date queue list monitoring var chatType = ChatType.LIVE_CHAT fun reset() { - queueIds = emptyList() chatType = ChatType.LIVE_CHAT } } diff --git a/widgetssdk/src/main/java/com/glia/widgets/core/engagement/domain/SetEngagementConfigUseCase.kt b/widgetssdk/src/main/java/com/glia/widgets/core/engagement/domain/SetEngagementConfigUseCase.kt index d320a6a03..5c8fca567 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/core/engagement/domain/SetEngagementConfigUseCase.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/core/engagement/domain/SetEngagementConfigUseCase.kt @@ -4,8 +4,7 @@ import com.glia.widgets.chat.ChatType import com.glia.widgets.core.engagement.GliaEngagementConfigRepository internal class SetEngagementConfigUseCase(private val engagementConfigRepository: GliaEngagementConfigRepository) { - operator fun invoke(chatType: ChatType, queueIds: List) { + operator fun invoke(chatType: ChatType) { engagementConfigRepository.chatType = chatType - engagementConfigRepository.queueIds = queueIds } } diff --git a/widgetssdk/src/main/java/com/glia/widgets/core/queue/GliaQueueRepository.kt b/widgetssdk/src/main/java/com/glia/widgets/core/queue/GliaQueueRepository.kt index 7cc48080d..8784b63c5 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/core/queue/GliaQueueRepository.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/core/queue/GliaQueueRepository.kt @@ -14,7 +14,7 @@ internal class GliaQueueRepository(private val gliaCore: GliaCore) { when { exception != null -> emitter.onError(exception) queues != null -> emitter.onSuccess(queues) - else -> emitter.onError(RuntimeException("Fetching file failed")) + else -> emitter.onError(RuntimeException("Fetching queues failed")) } } } diff --git a/widgetssdk/src/main/java/com/glia/widgets/core/secureconversations/domain/GetAvailableQueueIdsForSecureMessagingUseCase.kt b/widgetssdk/src/main/java/com/glia/widgets/core/secureconversations/domain/GetAvailableQueueIdsForSecureMessagingUseCase.kt index 77c663ff6..b2e2edccb 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/core/secureconversations/domain/GetAvailableQueueIdsForSecureMessagingUseCase.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/core/secureconversations/domain/GetAvailableQueueIdsForSecureMessagingUseCase.kt @@ -12,6 +12,7 @@ import com.glia.widgets.helper.rx.Schedulers import io.reactivex.rxjava3.disposables.CompositeDisposable import java.util.UUID +//TODO this Class must be removed after we have layer for up to date queue list monitoring internal class GetAvailableQueueIdsForSecureMessagingUseCase( private val engagementConfigRepository: GliaEngagementConfigRepository, private val queueRepository: GliaQueueRepository, diff --git a/widgetssdk/src/main/java/com/glia/widgets/di/ControllerFactory.java b/widgetssdk/src/main/java/com/glia/widgets/di/ControllerFactory.java index a7002e093..6837f6a13 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/di/ControllerFactory.java +++ b/widgetssdk/src/main/java/com/glia/widgets/di/ControllerFactory.java @@ -12,7 +12,6 @@ import com.glia.widgets.callvisualizer.controller.VisitorCodeController; import com.glia.widgets.chat.ChatContract; import com.glia.widgets.chat.controller.ChatController; -import com.glia.widgets.core.configuration.GliaSdkConfigurationManager; import com.glia.widgets.core.dialog.DialogContract; import com.glia.widgets.core.dialog.DialogController; import com.glia.widgets.engagement.completion.EngagementCompletionContract; @@ -23,6 +22,7 @@ import com.glia.widgets.filepreview.ui.ImagePreviewController; import com.glia.widgets.helper.Logger; import com.glia.widgets.helper.TimeCounter; +import com.glia.widgets.launcher.ConfigurationManager; import com.glia.widgets.messagecenter.MessageCenterContract; import com.glia.widgets.messagecenter.MessageCenterController; import com.glia.widgets.operator.OperatorRequestContract; @@ -57,7 +57,7 @@ public class ControllerFactory { private final DialogContract.Controller dialogController; private final MessagesNotSeenHandler messagesNotSeenHandler; private final UseCaseFactory useCaseFactory; - private final GliaSdkConfigurationManager sdkConfigurationManager; + private final ConfigurationManager configurationManager; private final ImagePreviewContract.Controller filePreviewController; private final ManagerFactory managerFactory; private EngagementCompletionContract.Controller engagementCompletionController; @@ -71,7 +71,7 @@ public class ControllerFactory { public ControllerFactory( RepositoryFactory repositoryFactory, UseCaseFactory useCaseFactory, - GliaSdkConfigurationManager sdkConfigurationManager, + ConfigurationManager configurationManager, ManagerFactory managerFactory ) { this.repositoryFactory = repositoryFactory; @@ -86,7 +86,7 @@ public ControllerFactory( useCaseFactory.createGetImageFileFromCacheUseCase(), useCaseFactory.createPutImageFileToDownloadsUseCase() ); - this.sdkConfigurationManager = sdkConfigurationManager; + this.configurationManager = configurationManager; this.managerFactory = managerFactory; } @@ -150,7 +150,6 @@ public CallContract.Controller getCallController() { if (retainedCallController == null) { Logger.d(TAG, "new call controller"); retainedCallController = new CallController( - sdkConfigurationManager, sharedTimer, new TimeCounter(), new TimeCounter(), @@ -292,7 +291,6 @@ public CallVisualizerContract.Controller getCallVisualizerController() { public MessageCenterContract.Controller getMessageCenterController() { return new MessageCenterController( - serviceChatHeadController, useCaseFactory.createSetEngagementConfigUseCase(), useCaseFactory.createSendSecureMessageUseCase(), useCaseFactory.createSecureMessagingAvailableQueueIdsUseCase(), @@ -381,7 +379,6 @@ public OperatorRequestContract.Controller getOperatorRequestController() { useCaseFactory.getIsCurrentEngagementCallVisualizer(), useCaseFactory.createSetOverlayPermissionRequestDialogShownUseCase(), dialogController, - sdkConfigurationManager, useCaseFactory.getWithNotificationPermissionUseCase(), useCaseFactory.getPrepareToScreenSharingUseCase(), useCaseFactory.getReleaseScreenSharingResourcesUseCase() diff --git a/widgetssdk/src/main/java/com/glia/widgets/di/Dependencies.kt b/widgetssdk/src/main/java/com/glia/widgets/di/Dependencies.kt index add8504de..4eb46f834 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/di/Dependencies.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/di/Dependencies.kt @@ -15,7 +15,6 @@ import com.glia.widgets.core.audio.domain.OnAudioStartedUseCase import com.glia.widgets.core.authentication.AuthenticationManager import com.glia.widgets.core.callvisualizer.CallVisualizerManager import com.glia.widgets.core.chathead.ChatHeadManager -import com.glia.widgets.core.configuration.GliaSdkConfigurationManager import com.glia.widgets.core.dialog.PermissionDialogManager import com.glia.widgets.core.notification.device.INotificationManager import com.glia.widgets.core.notification.device.NotificationManager @@ -75,13 +74,9 @@ internal object Dependencies { @VisibleForTesting set @JvmStatic - var sdkConfigurationManager: GliaSdkConfigurationManager = GliaSdkConfigurationManager() - @VisibleForTesting set - - @JvmStatic - val configurationManager: ConfigurationManager = ConfigurationManagerImpl() + val configurationManager: ConfigurationManager by lazy { ConfigurationManagerImpl(repositoryFactory.engagementConfigRepository) } - val activityLauncher: ActivityLauncher by lazy { ActivityLauncherImpl(IntentHelperImpl(sdkConfigurationManager)) } + val activityLauncher: ActivityLauncher by lazy { ActivityLauncherImpl(IntentHelperImpl()) } @JvmStatic val engagementLauncher: EngagementLauncher by lazy { EngagementLauncherImpl(activityLauncher) } @@ -113,7 +108,7 @@ internal object Dependencies { permissionManager, PermissionDialogManager(application), notificationManager, - sdkConfigurationManager, + configurationManager, ChatHeadManager(application), audioControlManager, authenticationManagerProvider, @@ -129,7 +124,7 @@ internal object Dependencies { controllerFactory = ControllerFactory( repositoryFactory, useCaseFactory, - sdkConfigurationManager, + configurationManager, managerFactory ) initApplicationLifecycleObserver( @@ -172,7 +167,8 @@ internal object Dependencies { val engagementCompletionActivityWatcher = EngagementCompletionActivityWatcher( controllerFactory.endEngagementController, - GliaActivityManagerImpl() + GliaActivityManagerImpl(), + activityLauncher ) application.registerActivityLifecycleCallbacks(engagementCompletionActivityWatcher) @@ -190,7 +186,6 @@ internal object Dependencies { gliaCore.init(gliaConfig) controllerFactory.init() repositoryFactory.engagementRepository.initialize() - sdkConfigurationManager.fromConfiguration(gliaWidgetsConfig) configurationManager.applyConfiguration(gliaWidgetsConfig) localeProvider.setCompanyName(gliaWidgetsConfig.companyName) } diff --git a/widgetssdk/src/main/java/com/glia/widgets/di/UseCaseFactory.java b/widgetssdk/src/main/java/com/glia/widgets/di/UseCaseFactory.java index 1d91c3c77..68e61a738 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/di/UseCaseFactory.java +++ b/widgetssdk/src/main/java/com/glia/widgets/di/UseCaseFactory.java @@ -66,9 +66,8 @@ import com.glia.widgets.core.callvisualizer.domain.VisitorCodeViewBuilderUseCase; import com.glia.widgets.core.chathead.ChatHeadManager; import com.glia.widgets.core.chathead.domain.IsDisplayBubbleInsideAppUseCase; -import com.glia.widgets.core.chathead.domain.ResolveChatHeadNavigationUseCase; import com.glia.widgets.core.chathead.domain.IsDisplayBubbleOutsideAppUseCase; -import com.glia.widgets.core.configuration.GliaSdkConfigurationManager; +import com.glia.widgets.core.chathead.domain.ResolveChatHeadNavigationUseCase; import com.glia.widgets.core.dialog.DialogContract; import com.glia.widgets.core.dialog.PermissionDialogManager; import com.glia.widgets.core.dialog.domain.ConfirmationDialogLinksUseCase; @@ -105,6 +104,7 @@ import com.glia.widgets.core.permissions.domain.WithReadWritePermissionsUseCaseImpl; import com.glia.widgets.core.secureconversations.domain.AddSecureFileAttachmentsObserverUseCase; import com.glia.widgets.core.secureconversations.domain.AddSecureFileToAttachmentAndUploadUseCase; +import com.glia.widgets.core.secureconversations.domain.GetAvailableQueueIdsForSecureMessagingUseCase; import com.glia.widgets.core.secureconversations.domain.GetSecureFileAttachmentsUseCase; import com.glia.widgets.core.secureconversations.domain.GetUnreadMessagesCountWithTimeoutUseCase; import com.glia.widgets.core.secureconversations.domain.IsMessagingAvailableUseCase; @@ -113,7 +113,6 @@ import com.glia.widgets.core.secureconversations.domain.OnNextMessageUseCase; import com.glia.widgets.core.secureconversations.domain.RemoveSecureFileAttachmentUseCase; import com.glia.widgets.core.secureconversations.domain.ResetMessageCenterUseCase; -import com.glia.widgets.core.secureconversations.domain.GetAvailableQueueIdsForSecureMessagingUseCase; import com.glia.widgets.core.secureconversations.domain.SendMessageButtonStateUseCase; import com.glia.widgets.core.secureconversations.domain.SendSecureMessageUseCase; import com.glia.widgets.core.secureconversations.domain.ShowMessageLimitErrorUseCase; @@ -150,14 +149,14 @@ import com.glia.widgets.engagement.domain.IsOperatorPresentUseCaseImpl; import com.glia.widgets.engagement.domain.IsQueueingOrEngagementUseCase; import com.glia.widgets.engagement.domain.IsQueueingOrEngagementUseCaseImpl; +import com.glia.widgets.engagement.domain.OnIncomingEngagementRequestTimeoutUseCase; +import com.glia.widgets.engagement.domain.OnIncomingEngagementRequestTimeoutUseCaseImpl; import com.glia.widgets.engagement.domain.OperatorMediaUpgradeOfferUseCase; import com.glia.widgets.engagement.domain.OperatorMediaUpgradeOfferUseCaseImpl; import com.glia.widgets.engagement.domain.OperatorMediaUseCase; import com.glia.widgets.engagement.domain.OperatorMediaUseCaseImpl; import com.glia.widgets.engagement.domain.OperatorTypingUseCase; import com.glia.widgets.engagement.domain.OperatorTypingUseCaseImpl; -import com.glia.widgets.engagement.domain.OnIncomingEngagementRequestTimeoutUseCase; -import com.glia.widgets.engagement.domain.OnIncomingEngagementRequestTimeoutUseCaseImpl; import com.glia.widgets.engagement.domain.PrepareToScreenSharingUseCase; import com.glia.widgets.engagement.domain.PrepareToScreenSharingUseCaseImpl; import com.glia.widgets.engagement.domain.ReleaseResourcesUseCase; @@ -185,6 +184,7 @@ import com.glia.widgets.filepreview.domain.usecase.IsFileReadyForPreviewUseCase; import com.glia.widgets.filepreview.domain.usecase.PutImageFileToDownloadsUseCase; import com.glia.widgets.helper.rx.Schedulers; +import com.glia.widgets.launcher.ConfigurationManager; import com.glia.widgets.locale.LocaleProvider; import com.glia.widgets.push.notifications.IsPushNotificationsSetUpUseCase; import com.glia.widgets.push.notifications.IsPushNotificationsSetUpUseCaseImpl; @@ -208,7 +208,7 @@ public class UseCaseFactory { private final RepositoryFactory repositoryFactory; private final PermissionManager permissionManager; private final PermissionDialogManager permissionDialogManager; - private final GliaSdkConfigurationManager gliaSdkConfigurationManager; + private final ConfigurationManager configurationManager; private final INotificationManager notificationManager; private final ChatHeadManager chatHeadManager; private final AudioControlManager audioControlManager; @@ -223,7 +223,7 @@ public class UseCaseFactory { PermissionManager permissionManager, PermissionDialogManager permissionDialogManager, INotificationManager notificationManager, - GliaSdkConfigurationManager gliaSdkConfigurationManager, + ConfigurationManager configurationManager, ChatHeadManager chatHeadManager, AudioControlManager audioControlManager, Dependencies.AuthenticationManagerProvider authenticationManagerProvider, @@ -235,7 +235,7 @@ public class UseCaseFactory { this.permissionManager = permissionManager; this.permissionDialogManager = permissionDialogManager; this.notificationManager = notificationManager; - this.gliaSdkConfigurationManager = gliaSdkConfigurationManager; + this.configurationManager = configurationManager; this.chatHeadManager = chatHeadManager; this.audioControlManager = audioControlManager; this.schedulers = schedulers; @@ -278,7 +278,7 @@ public IsDisplayBubbleOutsideAppUseCase getToggleChatHeadServiceUseCase() { getScreenSharingUseCase(), chatHeadManager, permissionManager, - gliaSdkConfigurationManager, + configurationManager, getEngagementTypeUseCase() ); } @@ -293,7 +293,7 @@ public IsDisplayBubbleInsideAppUseCase getIsDisplayApplicationChatHeadUseCase() getIsCurrentEngagementCallVisualizer(), getScreenSharingUseCase(), permissionManager, - gliaSdkConfigurationManager, + configurationManager, getEngagementTypeUseCase() ); } @@ -435,7 +435,7 @@ public IsShowSendButtonUseCase createIsShowSendButtonUseCase() { @NonNull public IsShowOverlayPermissionRequestDialogUseCase createIsShowOverlayPermissionRequestDialogUseCase() { - return new IsShowOverlayPermissionRequestDialogUseCaseImpl(permissionManager, permissionDialogManager, gliaSdkConfigurationManager); + return new IsShowOverlayPermissionRequestDialogUseCaseImpl(permissionManager, permissionDialogManager, configurationManager); } @NonNull @@ -970,12 +970,12 @@ public ToggleVisitorVideoMediaStateUseCase getToggleVisitorVideoMediaStateUseCas @NonNull public EnqueueForEngagementUseCase getQueueForEngagementUseCase() { - return new EnqueueForEngagementUseCaseImpl(repositoryFactory.getEngagementRepository()); + return new EnqueueForEngagementUseCaseImpl(repositoryFactory.getEngagementRepository(), configurationManager); } @NonNull public ScreenSharingUseCase getScreenSharingUseCase() { - return new ScreenSharingUseCaseImpl(repositoryFactory.getEngagementRepository(), getReleaseScreenSharingResourcesUseCase()); + return new ScreenSharingUseCaseImpl(repositoryFactory.getEngagementRepository(), getReleaseScreenSharingResourcesUseCase(), configurationManager); } @NonNull diff --git a/widgetssdk/src/main/java/com/glia/widgets/engagement/EngagementRepository.kt b/widgetssdk/src/main/java/com/glia/widgets/engagement/EngagementRepository.kt index cc59fbbe9..4243fd6ac 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/engagement/EngagementRepository.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/engagement/EngagementRepository.kt @@ -45,7 +45,7 @@ internal interface EngagementRepository { fun reset() fun resetQueueing() fun endEngagement(silently: Boolean) - fun queueForEngagement(queueIds: List, mediaType: MediaType, visitorContextAssetId: String?) + fun queueForEngagement(queueIds: List, mediaType: MediaType) fun cancelQueuing() fun acceptCurrentEngagementRequest(visitorContextAssetId: String) fun declineCurrentEngagementRequest() diff --git a/widgetssdk/src/main/java/com/glia/widgets/engagement/EngagementRepositoryImpl.kt b/widgetssdk/src/main/java/com/glia/widgets/engagement/EngagementRepositoryImpl.kt index 43dac4332..401d7fefe 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/engagement/EngagementRepositoryImpl.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/engagement/EngagementRepositoryImpl.kt @@ -196,11 +196,11 @@ internal class EngagementRepositoryImpl(private val core: GliaCore, private val } } - override fun queueForEngagement(queueIds: List, mediaType: MediaType, visitorContextAssetId: String?) { + override fun queueForEngagement(queueIds: List, mediaType: MediaType) { if (isQueueingOrEngagement) return Logger.i(TAG, "Start queueing for media engagement") - core.queueForEngagement(queueIds.toTypedArray(), mediaType, visitorContextAssetId, null, MEDIA_PERMISSION_REQUEST_CODE) { + core.queueForEngagement(queueIds.toTypedArray(), mediaType, null, null, MEDIA_PERMISSION_REQUEST_CODE) { handleQueueingResponse(it, queueIds, mediaType) } } diff --git a/widgetssdk/src/main/java/com/glia/widgets/engagement/completion/EngagementCompletionActivityWatcher.kt b/widgetssdk/src/main/java/com/glia/widgets/engagement/completion/EngagementCompletionActivityWatcher.kt index 2fa0a0666..6edb4591e 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/engagement/completion/EngagementCompletionActivityWatcher.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/engagement/completion/EngagementCompletionActivityWatcher.kt @@ -1,24 +1,22 @@ package com.glia.widgets.engagement.completion import android.app.Activity -import android.content.Intent -import android.os.Parcelable import com.glia.androidsdk.engagement.Survey -import com.glia.widgets.GliaWidgets -import com.glia.widgets.R import com.glia.widgets.base.BaseSingleActivityWatcher import com.glia.widgets.helper.GliaActivityManager import com.glia.widgets.helper.Logger import com.glia.widgets.helper.OneTimeEvent import com.glia.widgets.helper.TAG -import com.glia.widgets.helper.withRuntimeTheme -import com.glia.widgets.survey.SurveyActivity +import com.glia.widgets.launcher.ActivityLauncher import com.glia.widgets.view.Dialogs import io.reactivex.rxjava3.core.Flowable import java.lang.ref.WeakReference -internal class EngagementCompletionActivityWatcher(controller: EngagementCompletionContract.Controller, gliaActivityManager: GliaActivityManager) : - BaseSingleActivityWatcher(gliaActivityManager) { +internal class EngagementCompletionActivityWatcher( + controller: EngagementCompletionContract.Controller, + gliaActivityManager: GliaActivityManager, + private val activityLauncher: ActivityLauncher +) : BaseSingleActivityWatcher(gliaActivityManager) { init { Flowable.combineLatest(resumedActivity, controller.state, ::handleState).subscribe() @@ -44,16 +42,7 @@ internal class EngagementCompletionActivityWatcher(controller: EngagementComplet } } - private fun showSurvey(activity: Activity, survey: Survey) { - activity.withRuntimeTheme { _, uiTheme -> - val newIntent: Intent = Intent(activity, SurveyActivity::class.java) - .putExtra(GliaWidgets.UI_THEME, uiTheme) - .putExtra(GliaWidgets.SURVEY, survey as Parcelable) - - activity.overridePendingTransition(R.anim.slide_up, 0) - activity.startActivity(newIntent) - } - } + private fun showSurvey(activity: Activity, survey: Survey) = activityLauncher.launchSurvey(activity, survey) private fun showOperatorEndedEngagementDialog(activity: Activity, consumeCallback: () -> Unit) { showAlertDialogWithStyledContext(activity) { context, theme -> diff --git a/widgetssdk/src/main/java/com/glia/widgets/engagement/domain/EnqueueForEngagementUseCase.kt b/widgetssdk/src/main/java/com/glia/widgets/engagement/domain/EnqueueForEngagementUseCase.kt index 9779fa67d..10d489388 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/engagement/domain/EnqueueForEngagementUseCase.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/engagement/domain/EnqueueForEngagementUseCase.kt @@ -2,14 +2,15 @@ package com.glia.widgets.engagement.domain import com.glia.androidsdk.Engagement import com.glia.widgets.engagement.EngagementRepository +import com.glia.widgets.launcher.ConfigurationManager internal interface EnqueueForEngagementUseCase { - operator fun invoke(queueIds: List?, mediaType: Engagement.MediaType? = null, visitorContextAssetId: String? = null) + operator fun invoke(mediaType: Engagement.MediaType = Engagement.MediaType.TEXT) } -internal class EnqueueForEngagementUseCaseImpl(private val engagementRepository: EngagementRepository) : EnqueueForEngagementUseCase { - override fun invoke(queueIds: List?, mediaType: Engagement.MediaType?, visitorContextAssetId: String?) { - val type = mediaType ?: Engagement.MediaType.TEXT - engagementRepository.queueForEngagement(queueIds ?: emptyList(), type, visitorContextAssetId) - } +internal class EnqueueForEngagementUseCaseImpl( + private val engagementRepository: EngagementRepository, + private val configurationManager: ConfigurationManager +) : EnqueueForEngagementUseCase { + override fun invoke(mediaType: Engagement.MediaType) = engagementRepository.queueForEngagement(configurationManager.queueIds.orEmpty(), mediaType) } diff --git a/widgetssdk/src/main/java/com/glia/widgets/engagement/domain/ScreenSharingUseCase.kt b/widgetssdk/src/main/java/com/glia/widgets/engagement/domain/ScreenSharingUseCase.kt index b07ae147d..bc32a6270 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/engagement/domain/ScreenSharingUseCase.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/engagement/domain/ScreenSharingUseCase.kt @@ -2,9 +2,9 @@ package com.glia.widgets.engagement.domain import android.app.Activity import android.content.Intent -import com.glia.androidsdk.screensharing.ScreenSharing import com.glia.widgets.engagement.EngagementRepository import com.glia.widgets.engagement.ScreenSharingState +import com.glia.widgets.launcher.ConfigurationManager import io.reactivex.rxjava3.core.Flowable internal interface ScreenSharingUseCase { @@ -12,13 +12,14 @@ internal interface ScreenSharingUseCase { operator fun invoke(): Flowable fun end() fun declineRequest() - fun acceptRequestWithAskedPermission(activity: Activity, mode: ScreenSharing.Mode) + fun acceptRequestWithAskedPermission(activity: Activity) fun onActivityResultSkipPermissionRequest(resultCode: Int, intent: Intent?) } internal class ScreenSharingUseCaseImpl( private val engagementRepository: EngagementRepository, - private val releaseScreenSharingResourcesUseCase: ReleaseScreenSharingResourcesUseCase + private val releaseScreenSharingResourcesUseCase: ReleaseScreenSharingResourcesUseCase, + private val configurationManager: ConfigurationManager ) : ScreenSharingUseCase { override val isSharing: Boolean get() = engagementRepository.isSharingScreen override fun invoke(): Flowable = engagementRepository.screenSharingState @@ -28,8 +29,8 @@ internal class ScreenSharingUseCaseImpl( } override fun declineRequest() = engagementRepository.declineScreenSharingRequest() - override fun acceptRequestWithAskedPermission(activity: Activity, mode: ScreenSharing.Mode) = - engagementRepository.acceptScreenSharingWithAskedPermission(activity, mode) + override fun acceptRequestWithAskedPermission(activity: Activity) = + engagementRepository.acceptScreenSharingWithAskedPermission(activity, configurationManager.screenSharingMode) override fun onActivityResultSkipPermissionRequest(resultCode: Int, intent: Intent?) = engagementRepository.onActivityResultSkipScreenSharingPermissionRequest(resultCode, intent) diff --git a/widgetssdk/src/main/java/com/glia/widgets/entrywidget/EntryWidgetActivity.kt b/widgetssdk/src/main/java/com/glia/widgets/entrywidget/EntryWidgetActivity.kt index 66bec588e..d0fe6b41d 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/entrywidget/EntryWidgetActivity.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/entrywidget/EntryWidgetActivity.kt @@ -6,7 +6,7 @@ import com.glia.widgets.base.FadeTransitionActivity /** * EntryWidgetActivity provides a way to display the EntryWidget bottom sheet. */ -class EntryWidgetActivity : FadeTransitionActivity(), EntryWidgetFragment.OnDismissListener { +internal class EntryWidgetActivity : FadeTransitionActivity(), EntryWidgetFragment.OnDismissListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/widgetssdk/src/main/java/com/glia/widgets/entrywidget/EntryWidgetFragment.kt b/widgetssdk/src/main/java/com/glia/widgets/entrywidget/EntryWidgetFragment.kt index 80644206c..f87ec82ff 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/entrywidget/EntryWidgetFragment.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/entrywidget/EntryWidgetFragment.kt @@ -13,6 +13,7 @@ import com.glia.widgets.R import com.glia.widgets.databinding.EntryWidgetFragmentBinding import com.glia.widgets.di.Dependencies import com.glia.widgets.entrywidget.adapter.EntryWidgetAdapter +import com.glia.widgets.view.unifiedui.applyLayerTheme import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment @@ -48,6 +49,10 @@ internal class EntryWidgetFragment : BottomSheetDialogFragment() { } } + entryWidgetsTheme?.background?.let { + binding.root.applyLayerTheme(it) + } + return binding.root } diff --git a/widgetssdk/src/main/java/com/glia/widgets/helper/CommonExtensions.kt b/widgetssdk/src/main/java/com/glia/widgets/helper/CommonExtensions.kt index 67353feac..69c26ee27 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/helper/CommonExtensions.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/helper/CommonExtensions.kt @@ -20,7 +20,6 @@ import com.glia.androidsdk.comms.MediaState import com.glia.androidsdk.comms.MediaUpgradeOffer import com.glia.androidsdk.queuing.Queue import com.glia.widgets.UiTheme -import com.glia.widgets.di.Dependencies import com.glia.widgets.view.unifiedui.merge import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Completable @@ -56,9 +55,6 @@ internal fun UiTheme?.isAlertDialogButtonUseVerticalAlignment(): Boolean = this? internal fun UiTheme?.getFullHybridTheme(newTheme: UiTheme?): UiTheme = merge(newTheme) ?: UiTheme.UiThemeBuilder().build() -internal val UiTheme?.withConfigurationTheme: UiTheme - get() = getFullHybridTheme(Dependencies.sdkConfigurationManager.uiTheme) - /** * Returns styled text from the provided HTML string. Replaces \n to
regardless of the operating system where the string was created. */ diff --git a/widgetssdk/src/main/java/com/glia/widgets/helper/ContextExtensions.kt b/widgetssdk/src/main/java/com/glia/widgets/helper/ContextExtensions.kt index 23d63f6d1..4370f5b7f 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/helper/ContextExtensions.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/helper/ContextExtensions.kt @@ -1,3 +1,4 @@ +@file:JvmName("ContextExtensions") package com.glia.widgets.helper import android.app.Activity @@ -18,7 +19,6 @@ import androidx.appcompat.app.AlertDialog import androidx.core.content.withStyledAttributes import androidx.core.util.TypedValueCompat import com.glia.widgets.BuildConfig -import com.glia.widgets.GliaWidgets import com.glia.widgets.R import com.glia.widgets.UiTheme import com.google.android.material.theme.overlay.MaterialThemeOverlay @@ -61,11 +61,8 @@ internal val Activity.rootView: View internal fun Activity.withRuntimeTheme(callback: (themedContext: Context, uiTheme: UiTheme) -> Unit) { val themedContext = wrapWithMaterialThemeOverlay() - - intent.getParcelableExtraCompat(GliaWidgets.UI_THEME)?.also { - callback(themedContext, it.withConfigurationTheme) - } ?: themedContext.withStyledAttributes(R.style.Application_Glia_Chat, R.styleable.GliaView) { - callback(themedContext, Utils.getThemeFromTypedArray(this, themedContext).withConfigurationTheme) + themedContext.withStyledAttributes(R.style.Application_Glia_Chat, R.styleable.GliaView) { + callback(themedContext, Utils.getFullHybridTheme(this, themedContext)) } } @@ -103,3 +100,8 @@ internal inline fun Intent.getParcelableExtraCompat(key @Suppress("DEPRECATION") getParcelableExtra(key) as? T } + +internal inline fun > Intent.putEnumExtra(key: String, value: T?): Intent = putExtra(key, value?.ordinal) + +internal inline fun > Intent.getEnumExtra(key: String): T? = getIntExtra(key, -1).takeIf { it != -1 } + ?.let { T::class.java.enumConstants?.getOrNull(it) } diff --git a/widgetssdk/src/main/java/com/glia/widgets/helper/Data.kt b/widgetssdk/src/main/java/com/glia/widgets/helper/Data.kt index 914a01bd9..91f556875 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/helper/Data.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/helper/Data.kt @@ -6,4 +6,11 @@ internal sealed class Data { data class Value(val result: T) : Data() object Empty : Data() + + companion object +} + +internal fun Data.Companion.from(value: T?): Data = when (value) { + null -> Data.Empty + else -> Data.Value(value) } diff --git a/widgetssdk/src/main/java/com/glia/widgets/helper/Insets.kt b/widgetssdk/src/main/java/com/glia/widgets/helper/Insets.kt index 00eab7bf1..33972ca91 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/helper/Insets.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/helper/Insets.kt @@ -24,6 +24,7 @@ internal val View.insetsController: WindowInsetsControllerCompat? get() = context.asActivity()?.let { WindowCompat.getInsetsController(it.window, this) } + internal val View.rootWindowInsetsCompat: WindowInsetsCompat? get() = ViewCompat.getRootWindowInsets(this) diff --git a/widgetssdk/src/main/java/com/glia/widgets/helper/IntentHelper.kt b/widgetssdk/src/main/java/com/glia/widgets/helper/IntentHelper.kt index f7fcb02eb..b12fb4823 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/helper/IntentHelper.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/helper/IntentHelper.kt @@ -1,5 +1,3 @@ -@file:Suppress("DEPRECATION") - package com.glia.widgets.helper import android.app.Activity @@ -15,15 +13,10 @@ import androidx.core.net.toUri import com.glia.androidsdk.Engagement.MediaType import com.glia.androidsdk.chat.AttachmentFile import com.glia.androidsdk.engagement.Survey -import com.glia.widgets.GliaWidgets -import com.glia.widgets.UiTheme import com.glia.widgets.call.CallActivity -import com.glia.widgets.call.CallConfiguration import com.glia.widgets.callvisualizer.EndScreenSharingActivity import com.glia.widgets.chat.ChatActivity import com.glia.widgets.chat.ChatType -import com.glia.widgets.core.configuration.EngagementConfiguration -import com.glia.widgets.core.configuration.GliaSdkConfigurationManager import com.glia.widgets.entrywidget.EntryWidgetActivity import com.glia.widgets.filepreview.ui.ImagePreviewActivity import com.glia.widgets.locale.LocaleString @@ -38,26 +31,27 @@ internal object ExtraKeys { const val IMAGE_PREVIEW_IMAGE_ID = "image_preview_image_id" const val IMAGE_PREVIEW_IMAGE_NAME = "image_preview_image_name" + + const val CHAT_TYPE = "chat_screen_chat_type" + const val MEDIA_TYPE = "media_type" + const val SURVEY = "survey" + const val IS_UPGRADE_TO_CALL = "call_screen_is_upgrade_to_call" } internal interface IntentHelper { - fun chatIntent(context: Context, queueIds: List, chatType: ChatType? = null, contextId: String? = null): Intent - - fun chatIntent(context: Context, engagementConfiguration: EngagementConfiguration): Intent + fun chatIntent(context: Context): Intent fun secureMessagingChatIntent(activity: Activity): Intent fun secureMessagingWelcomeScreenIntent(activity: Activity): Intent - fun callIntent(context: Context, mediaType: MediaType, upgradeToCall: Boolean = true): Intent - - fun callIntent(context: Context, callConfiguration: CallConfiguration): Intent + fun callIntent(context: Context, mediaType: MediaType?, upgradeToCall: Boolean): Intent fun imagePreviewIntent(context: Context, attachment: AttachmentFile): Intent fun shareImageIntent(context: Context, fileName: String): Intent - fun surveyIntent(context: Context, survey: Survey, uiTheme: UiTheme): Intent + fun surveyIntent(context: Context, survey: Survey): Intent fun endScreenSharingIntent(context: Context): Intent @@ -75,58 +69,26 @@ internal interface IntentHelper { fun entryWidgetIntent(activity: Activity): Intent } -internal class IntentHelperImpl(private val configurationManager: GliaSdkConfigurationManager) : IntentHelper { - private val defaultEngagementConfiguration: EngagementConfiguration - get() = configurationManager.buildEngagementConfiguration() +internal class IntentHelperImpl : IntentHelper { - - override fun chatIntent(context: Context, queueIds: List, chatType: ChatType?, contextId: String?): Intent = + override fun chatIntent(context: Context): Intent = Intent(context, ChatActivity::class.java).apply { - (chatType as? Parcelable)?.also { putExtra(GliaWidgets.CHAT_TYPE, it) } - contextId?.also { putExtra(GliaWidgets.CONTEXT_ASSET_ID, it) } - putExtra(GliaWidgets.QUEUE_IDS, ArrayList(queueIds)) setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) setSafeFlags(context) } - override fun chatIntent(context: Context, engagementConfiguration: EngagementConfiguration): Intent = Intent(context, ChatActivity::class.java) - .putExtra(GliaWidgets.QUEUE_IDS, engagementConfiguration.queueIds?.let { ArrayList(it) }) - .putExtra(GliaWidgets.CONTEXT_ASSET_ID, engagementConfiguration.contextAssetId) - .putExtra(GliaWidgets.UI_THEME, engagementConfiguration.runTimeTheme) - .putExtra(GliaWidgets.SCREEN_SHARING_MODE, engagementConfiguration.screenSharingMode) - .setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) - .setSafeFlags(context) - override fun secureMessagingChatIntent(activity: Activity): Intent = Intent(activity, ChatActivity::class.java) - .putExtra(GliaWidgets.CHAT_TYPE, ChatType.SECURE_MESSAGING as Parcelable) + .putEnumExtra(ExtraKeys.CHAT_TYPE, ChatType.SECURE_MESSAGING) .setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) override fun secureMessagingWelcomeScreenIntent(activity: Activity): Intent = Intent(activity, MessageCenterActivity::class.java) .setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) - override fun callIntent(context: Context, mediaType: MediaType, upgradeToCall: Boolean): Intent = callIntent( - context, - CallConfiguration( - engagementConfiguration = defaultEngagementConfiguration, - mediaType = mediaType, - isUpgradeToCall = upgradeToCall - ) - ) - - override fun callIntent(context: Context, callConfiguration: CallConfiguration): Intent { - val engagementConfiguration = - callConfiguration.engagementConfiguration ?: throw NullPointerException("WidgetsSdk Configuration can't be null") - - return Intent(context, CallActivity::class.java) - .putExtra(GliaWidgets.QUEUE_IDS, engagementConfiguration.queueIds?.let(::ArrayList)) - .putExtra(GliaWidgets.CONTEXT_ASSET_ID, engagementConfiguration.contextAssetId) - .putExtra(GliaWidgets.UI_THEME, engagementConfiguration.runTimeTheme) - .putExtra(GliaWidgets.SCREEN_SHARING_MODE, engagementConfiguration.screenSharingMode) - .putExtra(GliaWidgets.MEDIA_TYPE, callConfiguration.mediaType) - .putExtra(GliaWidgets.IS_UPGRADE_TO_CALL, callConfiguration.isUpgradeToCall) - .setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) - .setSafeFlags(context) - } + override fun callIntent(context: Context, mediaType: MediaType?, upgradeToCall: Boolean): Intent = Intent(context, CallActivity::class.java) + .putEnumExtra(ExtraKeys.MEDIA_TYPE, mediaType) + .putExtra(ExtraKeys.IS_UPGRADE_TO_CALL, upgradeToCall) + .setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) + .setSafeFlags(context) override fun imagePreviewIntent(context: Context, attachment: AttachmentFile): Intent { return Intent(context, ImagePreviewActivity::class.java) @@ -147,9 +109,8 @@ internal class IntentHelperImpl(private val configurationManager: GliaSdkConfigu .setType("image/jpeg") } - override fun surveyIntent(context: Context, survey: Survey, uiTheme: UiTheme): Intent = Intent(context, SurveyActivity::class.java) - .putExtra(GliaWidgets.UI_THEME, uiTheme) - .putExtra(GliaWidgets.SURVEY, survey as Parcelable) + override fun surveyIntent(context: Context, survey: Survey): Intent = Intent(context, SurveyActivity::class.java) + .putExtra(ExtraKeys.SURVEY, survey as Parcelable) .setSafeFlags(context) override fun endScreenSharingIntent(context: Context): Intent = Intent(context, EndScreenSharingActivity::class.java) diff --git a/widgetssdk/src/main/java/com/glia/widgets/helper/TimeCounter.kt b/widgetssdk/src/main/java/com/glia/widgets/helper/TimeCounter.kt index 30b097852..4df607449 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/helper/TimeCounter.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/helper/TimeCounter.kt @@ -18,10 +18,11 @@ internal class TimeCounter { fun stop() { Logger.d(TAG, "stop") - timerTask?.cancel() - timerTask = null timer?.cancel() timer = null + + timerTask?.cancel() + timerTask = null } fun clear() { diff --git a/widgetssdk/src/main/java/com/glia/widgets/helper/Utils.kt b/widgetssdk/src/main/java/com/glia/widgets/helper/Utils.kt index a9cc027d8..40567a72a 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/helper/Utils.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/helper/Utils.kt @@ -7,26 +7,18 @@ import android.util.TypedValue import androidx.annotation.AttrRes import androidx.annotation.StyleableRes import androidx.core.content.res.ResourcesCompat -import com.glia.androidsdk.Engagement -import com.glia.widgets.GliaWidgets import com.glia.widgets.R import com.glia.widgets.UiTheme import com.glia.widgets.UiTheme.UiThemeBuilder -import java.security.InvalidParameterException +import com.glia.widgets.di.Dependencies internal object Utils { - @JvmStatic - fun toMediaType(mediaType: String): Engagement.MediaType { - return when (mediaType) { - GliaWidgets.MEDIA_TYPE_VIDEO -> Engagement.MediaType.VIDEO - GliaWidgets.MEDIA_TYPE_AUDIO -> Engagement.MediaType.AUDIO - else -> throw InvalidParameterException("Invalid Media Type") - } - } - fun getThemeFromTypedArray(typedArray: TypedArray, context: Context): UiTheme { + fun getFullHybridTheme(typedArray: TypedArray, context: Context): UiTheme = getThemeFromTypedArray(typedArray, context) + .getFullHybridTheme(Dependencies.configurationManager.uiTheme) + + private fun getThemeFromTypedArray(typedArray: TypedArray, context: Context): UiTheme { val defaultThemeBuilder = UiThemeBuilder().apply { - setAppBarTitle(getAppBarTitleValue(typedArray)) setBrandPrimaryColor( getTypedArrayIntegerValue( typedArray, @@ -424,14 +416,6 @@ internal object Utils { return typedArray.hasValue(index) && typedArray.getBoolean(index, false) } - private fun getAppBarTitleValue(typedArray: TypedArray): String? { - return if (typedArray.hasValue(R.styleable.GliaView_appBarTitle)) { - typedArray.getString(R.styleable.GliaView_appBarTitle) - } else { - null - } - } - fun getTypedArrayStringValue( typedArray: TypedArray, @StyleableRes index: Int diff --git a/widgetssdk/src/main/java/com/glia/widgets/launcher/ActivityLauncher.kt b/widgetssdk/src/main/java/com/glia/widgets/launcher/ActivityLauncher.kt index a3afcb0df..3841b38d8 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/launcher/ActivityLauncher.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/launcher/ActivityLauncher.kt @@ -6,8 +6,7 @@ import android.net.Uri import android.os.Bundle import com.glia.androidsdk.Engagement.MediaType import com.glia.androidsdk.chat.AttachmentFile -import com.glia.widgets.call.CallConfiguration -import com.glia.widgets.core.configuration.EngagementConfiguration +import com.glia.androidsdk.engagement.Survey import com.glia.widgets.helper.IntentHelper import com.glia.widgets.helper.safeStartActivity import com.glia.widgets.locale.LocaleString @@ -15,9 +14,8 @@ import com.glia.widgets.locale.LocaleString internal interface ActivityLauncher { fun launchChat(activity: Activity) - fun launchChat(context: Context, engagementConfiguration: EngagementConfiguration) - fun launchCall(context: Context, callConfiguration: CallConfiguration) - fun launchCall(activity: Activity, mediaType: MediaType) + fun launchChat(context: Context) + fun launchCall(context: Context, mediaType: MediaType?, upgradeToCall: Boolean) fun launchSecureMessagingChat(activity: Activity) fun launchSecureMessagingWelcomeScreen(activity: Activity) fun launchEndScreenSharing(context: Context) @@ -30,19 +28,17 @@ internal interface ActivityLauncher { fun launchFileReader(context: Context, contentUri: Uri, fileContentType: String, onFailure: () -> Unit) fun launchShareImage(activity: Activity, fileName: String) fun launchEntryWidget(activity: Activity) + fun launchSurvey(activity: Activity, survey: Survey) } internal class ActivityLauncherImpl(private val intentHelper: IntentHelper) : ActivityLauncher { - override fun launchChat(activity: Activity) = activity.startActivity(intentHelper.chatIntent(activity, emptyList())) + override fun launchChat(activity: Activity) = activity.startActivity(intentHelper.chatIntent(activity)) - override fun launchChat(context: Context, engagementConfiguration: EngagementConfiguration) = - context.startActivity(intentHelper.chatIntent(context, engagementConfiguration)) + override fun launchChat(context: Context) = context.startActivity(intentHelper.chatIntent(context)) - override fun launchCall(context: Context, callConfiguration: CallConfiguration) = - context.startActivity(intentHelper.callIntent(context, callConfiguration)) - - override fun launchCall(activity: Activity, mediaType: MediaType) = activity.startActivity(intentHelper.callIntent(activity, mediaType)) + override fun launchCall(context: Context, mediaType: MediaType?, upgradeToCall: Boolean) = + context.startActivity(intentHelper.callIntent(context, mediaType, upgradeToCall)) override fun launchSecureMessagingChat(activity: Activity) = activity.startActivity(intentHelper.secureMessagingChatIntent(activity)) @@ -75,4 +71,5 @@ internal class ActivityLauncherImpl(private val intentHelper: IntentHelper) : Ac override fun launchEntryWidget(activity: Activity) = activity.startActivity(intentHelper.entryWidgetIntent(activity)) + override fun launchSurvey(activity: Activity, survey: Survey) = activity.startActivity(intentHelper.surveyIntent(activity, survey)) } diff --git a/widgetssdk/src/main/java/com/glia/widgets/launcher/ConfigurationManager.kt b/widgetssdk/src/main/java/com/glia/widgets/launcher/ConfigurationManager.kt index 93c3eee7e..3c9d1f504 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/launcher/ConfigurationManager.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/launcher/ConfigurationManager.kt @@ -4,7 +4,9 @@ import com.glia.androidsdk.screensharing.ScreenSharing import com.glia.widgets.GliaWidgets import com.glia.widgets.GliaWidgetsConfig import com.glia.widgets.UiTheme +import com.glia.widgets.core.engagement.GliaEngagementConfigRepository import com.glia.widgets.helper.Data +import com.glia.widgets.helper.from import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.processors.BehaviorProcessor @@ -31,7 +33,7 @@ internal interface ConfigurationManager { fun setQueueIds(queueIds: List?) } -internal class ConfigurationManagerImpl : ConfigurationManager { +internal class ConfigurationManagerImpl(private val engagementConfigRepository: GliaEngagementConfigRepository) : ConfigurationManager { private var _screenSharingMode: ScreenSharing.Mode = ScreenSharing.Mode.APP_BOUNDED override val screenSharingMode: ScreenSharing.Mode get() = _screenSharingMode @@ -62,7 +64,7 @@ internal class ConfigurationManagerImpl : ConfigurationManager { } override fun setQueueIds(queueIds: List?) { - val data = queueIds?.let { Data.Value(it) } ?: Data.Empty - _queueIdsObservable.onNext(data) + engagementConfigRepository.queueIds = queueIds ?: emptyList() + _queueIdsObservable.onNext(Data.from(queueIds)) } } diff --git a/widgetssdk/src/main/java/com/glia/widgets/launcher/EngagementLauncher.kt b/widgetssdk/src/main/java/com/glia/widgets/launcher/EngagementLauncher.kt index 08d450552..7541e7948 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/launcher/EngagementLauncher.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/launcher/EngagementLauncher.kt @@ -44,11 +44,11 @@ internal class EngagementLauncherImpl(private val activityLauncher: ActivityLaun } override fun startAudioCall(activity: Activity) { - activityLauncher.launchCall(activity, Engagement.MediaType.AUDIO) + activityLauncher.launchCall(activity, Engagement.MediaType.AUDIO, false) } override fun startVideoCall(activity: Activity) { - activityLauncher.launchCall(activity, Engagement.MediaType.VIDEO) + activityLauncher.launchCall(activity, Engagement.MediaType.VIDEO, false) } override fun startSecureMessaging(activity: Activity) { diff --git a/widgetssdk/src/main/java/com/glia/widgets/locale/LocaleProvider.kt b/widgetssdk/src/main/java/com/glia/widgets/locale/LocaleProvider.kt index 8448a897c..8b8d1391a 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/locale/LocaleProvider.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/locale/LocaleProvider.kt @@ -17,7 +17,6 @@ import io.reactivex.rxjava3.core.Observer import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.subjects.PublishSubject import kotlinx.parcelize.Parcelize -import java.lang.Exception /** * @hide @@ -26,7 +25,7 @@ import java.lang.Exception data class LocaleString( @StringRes val stringKey: Int, val values: List = emptyList() -): Parcelable { +) : Parcelable { constructor(@StringRes stringKey: Int, vararg values: StringKeyPair) : this(stringKey, values.toList()) @@ -86,10 +85,10 @@ internal open class LocaleProvider @JvmOverloads constructor( } fun getString(stringKey: Int, values: List): String { - if (stringKey == R.string.general_company_name) { - return getCompanyName() + return if (stringKey == R.string.general_company_name) { + getCompanyName() } else { - return getStringInternal(stringKey, values) + getStringInternal(stringKey, values) } } @@ -103,10 +102,10 @@ internal open class LocaleProvider @JvmOverloads constructor( return try { getLocaleManager().getRemoteString(key)?.let { values.fold(it, ::replaceInsertedValues).run(::cleanupRemainingReferences) - } ?: resourceProvider.getString(stringKey, *values.map { pair -> pair.value }.toTypedArray()) + } ?: resourceProvider.getString(stringKey, *values.map { pair -> valueOrCompanyName(pair) }.toTypedArray()) } catch (e: GliaException) { Logger.d(TAG, "Remote locale string failed to load : ${e.message}") - resourceProvider.getString(stringKey, *values.map { pair -> pair.value }.toTypedArray()) + resourceProvider.getString(stringKey, *values.map { pair -> valueOrCompanyName(pair) }.toTypedArray()) } } @@ -118,18 +117,21 @@ internal open class LocaleProvider @JvmOverloads constructor( hardcodedCompanyName = companyName } - // Priority for remote company name but not found or no locales it will fall back to hardcoded one or "" if no hardcoded one - fun getCompanyName(): String { - var companyName = getStringInternal(R.string.general_company_name) - if (companyName.isBlank()) { - companyName = hardcodedCompanyName ?: "" + fun valueOrCompanyName(stringKeyPair: StringKeyPair): String { + return if (stringKeyPair.key == StringKey.COMPANY_NAME) { + getCompanyName() + } else { + stringKeyPair.value } - return companyName } + // Priority for remote company name but not found or no locales it will fall back to hardcoded one or "" if no hardcoded one + private fun getCompanyName(): String = getStringInternal(R.string.general_company_name) + .takeIf { it.isNotBlank() } ?: hardcodedCompanyName.orEmpty() + private fun replaceInsertedValues(string: String, pair: StringKeyPair): String { return if (string.contains(pair.key.value, false)) { - string.replace("{${pair.key.value}}", pair.value) + string.replace("{${pair.key.value}}", valueOrCompanyName(pair)) } else { string } diff --git a/widgetssdk/src/main/java/com/glia/widgets/locale/StringKeyPair.kt b/widgetssdk/src/main/java/com/glia/widgets/locale/StringKeyPair.kt index 556b80e92..da5a3b6cd 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/locale/StringKeyPair.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/locale/StringKeyPair.kt @@ -13,7 +13,6 @@ data class StringKeyPair(val key: StringKey, val value: String): Parcelable { deprecatedStringKeyPair.value ) } - /** * @hide */ diff --git a/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterActivity.kt b/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterActivity.kt index 240c25787..86314251b 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterActivity.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterActivity.kt @@ -1,20 +1,13 @@ package com.glia.widgets.messagecenter import android.Manifest -import android.content.Intent import android.net.Uri import android.os.Bundle -import android.os.Parcelable import androidx.activity.OnBackPressedCallback import androidx.activity.result.contract.ActivityResultContracts.GetContent import androidx.activity.result.contract.ActivityResultContracts.RequestPermission import androidx.activity.result.contract.ActivityResultContracts.TakePicture -import com.glia.widgets.GliaWidgets -import com.glia.widgets.GliaWidgets.CHAT_TYPE import com.glia.widgets.base.FadeTransitionActivity -import com.glia.widgets.chat.ChatActivity -import com.glia.widgets.chat.ChatType -import com.glia.widgets.core.configuration.EngagementConfiguration import com.glia.widgets.databinding.MessageCenterActivityBinding import com.glia.widgets.di.Dependencies import com.glia.widgets.helper.Logger @@ -29,26 +22,14 @@ import com.glia.widgets.helper.TAG * - Offers the option to access chat history. * * Before this activity is launched, make sure that Glia Widgets SDK is set up correctly. - * - * Required data that should be passed together with the Activity intent: - * - {@link GliaWidgets#QUEUE_IDS}: IDs of the queues you would like to use for your engagements. - * For a full list of optional parameters, see the constants defined in {@link GliaWidgets}. - * - * Code example: - * ``` - * Intent intent = new Intent(requireContext(), MessageCenterActivity.class); - * intent.putExtra(GliaWidgets.QUEUE_IDS, new ArrayList<>(List.of("MESSAGING_QUEUE_ID"))); - * startActivity(intent); - * ``` */ -class MessageCenterActivity : FadeTransitionActivity(), +internal class MessageCenterActivity : FadeTransitionActivity(), MessageCenterView.OnFinishListener, MessageCenterView.OnNavigateToMessagingListener, MessageCenterView.OnAttachFileListener { private lateinit var binding: MessageCenterActivityBinding private val messageCenterView get() = binding.messageCenterView - private var engagementConfiguration: EngagementConfiguration? = null private val controller: MessageCenterContract.Controller by lazy { Dependencies.controllerFactory.messageCenterController @@ -75,20 +56,11 @@ class MessageCenterActivity : FadeTransitionActivity(), binding = MessageCenterActivityBinding.inflate(layoutInflater) setContentView(binding.root) - engagementConfiguration = createConfiguration(intent) - if (intent.hasExtra(GliaWidgets.USE_OVERLAY)) { - // Integrator has passed a deprecated GliaWidgets.USE_OVERLAY parameter with Intent - // Override bubble configuration with USE_OVERLAY value - val useOverlay = intent.getBooleanExtra(GliaWidgets.USE_OVERLAY, true) - Dependencies.sdkConfigurationManager.setLegacyUseOverlay(useOverlay) - } - messageCenterView.onFinishListener = this messageCenterView.onNavigateToMessagingListener = this messageCenterView.onAttachFileListener = this messageCenterView.setController(controller) - messageCenterView.setConfiguration(engagementConfiguration) onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { messageCenterView.onSystemBack() @@ -129,12 +101,8 @@ class MessageCenterActivity : FadeTransitionActivity(), } override fun navigateToMessaging() { - val intent = Intent(this, ChatActivity::class.java) - intent.putExtras(getIntent()) - intent.putExtra(CHAT_TYPE, ChatType.SECURE_MESSAGING as Parcelable) - startActivity(intent) + Dependencies.activityLauncher.launchSecureMessagingChat(this) finish() } - private fun createConfiguration(intent: Intent): EngagementConfiguration = EngagementConfiguration(intent) } diff --git a/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterContract.kt b/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterContract.kt index 81a119c3b..d7935bc4c 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterContract.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterContract.kt @@ -1,16 +1,13 @@ package com.glia.widgets.messagecenter import android.net.Uri -import com.glia.widgets.UiTheme import com.glia.widgets.base.BaseController import com.glia.widgets.base.BaseView -import com.glia.widgets.core.configuration.EngagementConfiguration import com.glia.widgets.core.dialog.DialogContract import com.glia.widgets.core.fileupload.model.FileAttachment internal interface MessageCenterContract { interface Controller : BaseController { - fun setConfiguration(uiTheme: UiTheme?, configuration: EngagementConfiguration?) fun setView(view: View) fun initialize() fun onCheckMessagesClicked() diff --git a/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterController.kt b/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterController.kt index e1fab5cdd..b00a38e54 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterController.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterController.kt @@ -8,13 +8,11 @@ import com.glia.androidsdk.chat.VisitorMessage import com.glia.androidsdk.engagement.EngagementFile import com.glia.androidsdk.site.SiteInfo import com.glia.widgets.Constants -import com.glia.widgets.UiTheme import com.glia.widgets.chat.ChatType import com.glia.widgets.chat.domain.IsAuthenticatedUseCase import com.glia.widgets.chat.domain.SiteInfoUseCase import com.glia.widgets.chat.domain.TakePictureUseCase import com.glia.widgets.chat.domain.UriToFileAttachmentUseCase -import com.glia.widgets.core.configuration.EngagementConfiguration import com.glia.widgets.core.dialog.DialogContract import com.glia.widgets.core.engagement.domain.SetEngagementConfigUseCase import com.glia.widgets.core.fileupload.domain.AddFileToAttachmentAndUploadUseCase @@ -22,21 +20,19 @@ import com.glia.widgets.core.fileupload.model.FileAttachment import com.glia.widgets.core.permissions.domain.RequestNotificationPermissionIfPushNotificationsSetUpUseCase import com.glia.widgets.core.secureconversations.domain.AddSecureFileAttachmentsObserverUseCase import com.glia.widgets.core.secureconversations.domain.AddSecureFileToAttachmentAndUploadUseCase +import com.glia.widgets.core.secureconversations.domain.GetAvailableQueueIdsForSecureMessagingUseCase import com.glia.widgets.core.secureconversations.domain.GetSecureFileAttachmentsUseCase import com.glia.widgets.core.secureconversations.domain.OnNextMessageUseCase import com.glia.widgets.core.secureconversations.domain.RemoveSecureFileAttachmentUseCase import com.glia.widgets.core.secureconversations.domain.ResetMessageCenterUseCase -import com.glia.widgets.core.secureconversations.domain.GetAvailableQueueIdsForSecureMessagingUseCase import com.glia.widgets.core.secureconversations.domain.SendMessageButtonStateUseCase import com.glia.widgets.core.secureconversations.domain.SendSecureMessageUseCase import com.glia.widgets.core.secureconversations.domain.ShowMessageLimitErrorUseCase import com.glia.widgets.helper.Logger import com.glia.widgets.helper.TAG -import com.glia.widgets.view.head.ChatHeadContract import io.reactivex.rxjava3.disposables.CompositeDisposable internal class MessageCenterController( - private var serviceChatHeadController: ChatHeadContract.Controller, private val engagementConfigUseCase: SetEngagementConfigUseCase, private val sendSecureMessageUseCase: SendSecureMessageUseCase, private val getAvailableQueueIdsForSecureMessagingUseCase: GetAvailableQueueIdsForSecureMessagingUseCase, @@ -61,15 +57,8 @@ internal class MessageCenterController( @Volatile private var state = MessageCenterState() - override fun setConfiguration(uiTheme: UiTheme?, configuration: EngagementConfiguration?) { - setQueueIds(configuration?.queueIds) - - serviceChatHeadController.setBuildTimeTheme(uiTheme) - serviceChatHeadController.setEngagementConfiguration(configuration) - } - - private fun setQueueIds(queueIds: List?) { - engagementConfigUseCase(ChatType.SECURE_MESSAGING, queueIds ?: emptyList()) + init { + engagementConfigUseCase(ChatType.SECURE_MESSAGING) } override fun setView(view: MessageCenterContract.View) { @@ -203,7 +192,6 @@ internal class MessageCenterController( override fun ensureMessageCenterAvailability() { getAvailableQueueIdsForSecureMessagingUseCase( RequestCallback { queueIds, exception -> - setQueueIds(queueIds) val showSendMessageGroup = when { exception != null -> { diff --git a/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterView.kt b/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterView.kt index 4799c242f..356c4ae98 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterView.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageCenterView.kt @@ -17,7 +17,6 @@ import androidx.core.view.isVisible import com.glia.widgets.Constants import com.glia.widgets.R import com.glia.widgets.UiTheme -import com.glia.widgets.core.configuration.EngagementConfiguration import com.glia.widgets.core.dialog.DialogContract import com.glia.widgets.core.dialog.model.DialogState import com.glia.widgets.core.fileupload.model.FileAttachment @@ -125,7 +124,7 @@ internal class MessageCenterView( } private fun setDefaultTheme(typedArray: TypedArray) { - theme = Utils.getThemeFromTypedArray(typedArray, this.context) + theme = Utils.getFullHybridTheme(typedArray, this.context) } private fun initCallbacks() { @@ -157,10 +156,6 @@ internal class MessageCenterView( } } - fun setConfiguration(configuration: EngagementConfiguration?) { - controller?.setConfiguration(theme, configuration) - } - private fun showUnAuthenticatedDialog() { showDialog { Dialogs.showUnAuthenticatedDialog(context, theme) { diff --git a/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageView.kt b/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageView.kt index 96eefe063..3cf765c53 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageView.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/messagecenter/MessageView.kt @@ -74,8 +74,6 @@ internal class MessageView( Dependencies.gliaThemeManager.theme?.secureMessagingWelcomeScreenTheme } - private var theme: UiTheme by Delegates.notNull() - private val attachmentPopup by lazy { AttachmentPopup(addAttachmentButton, unifiedTheme?.pickMediaTheme) } @@ -116,12 +114,12 @@ internal class MessageView( } private fun setDefaultTheme(typedArray: TypedArray) { - theme = Utils.getThemeFromTypedArray(typedArray, this.context) - setupAttachmentIconTheme() - setupMessageErrorTextTheme() + val theme = Utils.getFullHybridTheme(typedArray, this.context) + setupAttachmentIconTheme(theme) + setupMessageErrorTextTheme(theme) } - private fun setupMessageErrorTextTheme() { + private fun setupMessageErrorTextTheme(theme: UiTheme) { val systemNegativeColorId = theme.systemNegativeColor ?: return TextViewCompat.setCompoundDrawableTintList( @@ -185,7 +183,7 @@ internal class MessageView( attachmentRecyclerView.adapter = uploadAttachmentAdapter } - private fun setupAttachmentIconTheme() { + private fun setupAttachmentIconTheme(theme: UiTheme) { val normalColor = unifiedTheme?.filePickerButtonTheme?.primaryColor ?: theme.baseNormalColor?.let { getColorCompat(it) } val disabledColor = unifiedTheme?.filePickerButtonDisabledTheme?.primaryColor diff --git a/widgetssdk/src/main/java/com/glia/widgets/operator/OperatorRequestActivityWatcher.kt b/widgetssdk/src/main/java/com/glia/widgets/operator/OperatorRequestActivityWatcher.kt index 0c5f53eaa..767b779b7 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/operator/OperatorRequestActivityWatcher.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/operator/OperatorRequestActivityWatcher.kt @@ -136,7 +136,7 @@ internal class OperatorRequestActivityWatcher( activity.isGlia -> finishActivities() } - activityLauncher.launchCall(activity, mediaType) + activityLauncher.launchCall(activity, mediaType, true) } private fun showUpgradeDialog(state: ControllerState.RequestMediaUpgrade, activity: Activity, consumeCallback: () -> Unit) { diff --git a/widgetssdk/src/main/java/com/glia/widgets/operator/OperatorRequestController.kt b/widgetssdk/src/main/java/com/glia/widgets/operator/OperatorRequestController.kt index 801736a20..ca224b3eb 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/operator/OperatorRequestController.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/operator/OperatorRequestController.kt @@ -7,7 +7,6 @@ import androidx.activity.ComponentActivity import androidx.activity.result.ActivityResult import com.glia.androidsdk.Engagement import com.glia.androidsdk.comms.MediaUpgradeOffer -import com.glia.widgets.core.configuration.GliaSdkConfigurationManager import com.glia.widgets.core.dialog.DialogContract import com.glia.widgets.core.dialog.domain.IsShowOverlayPermissionRequestDialogUseCase import com.glia.widgets.core.dialog.domain.SetOverlayPermissionRequestDialogShownUseCase @@ -48,7 +47,6 @@ internal class OperatorRequestController( private val isCurrentEngagementCallVisualizerUseCase: IsCurrentEngagementCallVisualizerUseCase, private val setOverlayPermissionRequestDialogShownUseCase: SetOverlayPermissionRequestDialogShownUseCase, private val dialogController: DialogContract.Controller, - private val gliaSdkConfigurationManager: GliaSdkConfigurationManager, private val withNotificationPermissionUseCase: WithNotificationPermissionUseCase, private val prepareToScreenSharingUseCase: PrepareToScreenSharingUseCase, private val releaseScreenSharingResourcesUseCase: ReleaseScreenSharingResourcesUseCase @@ -160,7 +158,7 @@ internal class OperatorRequestController( withNotificationPermissionUseCase { _state.onNext(State.AcquireMediaProjectionToken) - screenSharingUseCase.acceptRequestWithAskedPermission(activity, gliaSdkConfigurationManager.screenSharingMode) + screenSharingUseCase.acceptRequestWithAskedPermission(activity) } } diff --git a/widgetssdk/src/main/java/com/glia/widgets/survey/SurveyActivity.java b/widgetssdk/src/main/java/com/glia/widgets/survey/SurveyActivity.java deleted file mode 100644 index 174220e78..000000000 --- a/widgetssdk/src/main/java/com/glia/widgets/survey/SurveyActivity.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.glia.widgets.survey; - -import android.os.Bundle; - -import androidx.activity.EdgeToEdge; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.view.WindowCompat; -import androidx.core.view.WindowInsetsControllerCompat; - -import com.glia.androidsdk.engagement.Survey; -import com.glia.widgets.GliaWidgets; -import com.glia.widgets.R; -import com.glia.widgets.UiTheme; -import com.glia.widgets.di.Dependencies; -import com.glia.widgets.helper.Insets; -import com.glia.widgets.helper.Logger; - -/** - * Glia internal class. - *

- * It will be automatically added to the integrator's manifest file by the manifest merger during compilation. - *

- * This activity is used to display post-engagement surveys. - */ -public class SurveyActivity extends AppCompatActivity implements SurveyView.OnFinishListener { - private static final String TAG = SurveyActivity.class.getSimpleName(); - - private SurveyView surveyView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - EdgeToEdge.enable(this); - Insets.insetsControllerCompat(getWindow()).setAppearanceLightStatusBars(false); - super.onCreate(savedInstanceState); - Logger.i(TAG, "Create Survey screen"); - setContentView(R.layout.survey_activity); - prepareSurveyView(); - } - - @Override - protected void onDestroy() { - Logger.i(TAG, "Destroy Survey screen"); - hideSoftKeyboard(); - if (surveyView != null) { - surveyView.onDestroyView(); - } - super.onDestroy(); - } - - @Override - public void onBackPressed() { - super.onBackPressed(); - - // Back press behaves the same way as Callback.onFinish(). See the comment below. - finishAndRemoveTask(); - } - - @Override - public void onFinish() { - - // In case the engagement ends, Activity is removed from the device's Recents menu - // to avoid app users to accidentally start queueing for another call when they resume - // the app from the Recents menu and the app's backstack was empty. - finishAndRemoveTask(); - } - - @Override - public void finishAndRemoveTask() { - overridePendingTransition(0, R.anim.slide_down); - super.finishAndRemoveTask(); - } - - private void hideSoftKeyboard() { - WindowInsetsControllerCompat insetsController = WindowCompat.getInsetsController(getWindow(), findViewById(R.id.survey_view)); - Insets.hideKeyboard(insetsController); - } - - private void prepareSurveyView() { - surveyView = findViewById(R.id.survey_view); - surveyView.setOnTitleUpdatedListener(this::setTitle); - surveyView.setOnFinishListener(this); - SurveyContract.Controller surveyController = Dependencies.getControllerFactory().getSurveyController(); - surveyView.setController(surveyController); - Bundle extras = getIntent().getExtras(); - if (extras != null) { - UiTheme uiTheme = extras.getParcelable(GliaWidgets.UI_THEME); - surveyView.setTheme(uiTheme); - Survey survey = extras.getParcelable(GliaWidgets.SURVEY); - surveyController.init(survey); - } - } -} diff --git a/widgetssdk/src/main/java/com/glia/widgets/survey/SurveyActivity.kt b/widgetssdk/src/main/java/com/glia/widgets/survey/SurveyActivity.kt new file mode 100644 index 000000000..79073062b --- /dev/null +++ b/widgetssdk/src/main/java/com/glia/widgets/survey/SurveyActivity.kt @@ -0,0 +1,116 @@ +package com.glia.widgets.survey + +import android.os.Build +import android.os.Bundle +import androidx.activity.OnBackPressedCallback +import androidx.activity.enableEdgeToEdge +import androidx.annotation.RequiresApi +import androidx.appcompat.app.AppCompatActivity +import com.glia.androidsdk.engagement.Survey +import com.glia.widgets.R +import com.glia.widgets.di.Dependencies.controllerFactory +import com.glia.widgets.helper.ExtraKeys +import com.glia.widgets.helper.Logger.i +import com.glia.widgets.helper.TAG +import com.glia.widgets.helper.getParcelableExtraCompat +import com.glia.widgets.helper.hideKeyboard +import com.glia.widgets.helper.insetsController +import com.glia.widgets.helper.insetsControllerCompat + +/** + * Glia internal class. + * + * + * It will be automatically added to the integrator's manifest file by the manifest merger during compilation. + * + * + * This activity is used to display post-engagement surveys. + */ +internal class SurveyActivity : AppCompatActivity(), SurveyView.OnFinishListener { + private val surveyView: SurveyView by lazy { findViewById(R.id.survey_view) } + + override fun onCreate(savedInstanceState: Bundle?) { + this.enableEdgeToEdge() + window.insetsControllerCompat.isAppearanceLightStatusBars = false + + overrideEnterAnimation() + super.onCreate(savedInstanceState) + + i(TAG, "Create Survey screen") + setContentView(R.layout.survey_activity) + + onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + finishAndRemoveTask() + } + }) + + prepareSurveyView() + } + + override fun onDestroy() { + i(TAG, "Destroy Survey screen") + hideSoftKeyboard() + surveyView.onDestroyView() + super.onDestroy() + } + + override fun onFinish() { + // In case the engagement ends, Activity is removed from the device's Recents menu + // to avoid app users to accidentally start queueing for another call when they resume + // the app from the Recents menu and the app's backstack was empty. + + finishAndRemoveTask() + } + + override fun finishAndRemoveTask() { + overrideExitAnimation() + super.finishAndRemoveTask() + } + + private fun hideSoftKeyboard() { + surveyView.insetsController?.hideKeyboard() + } + + private fun prepareSurveyView() { + surveyView.setOnTitleUpdatedListener(object : SurveyView.OnTitleUpdatedListener { + override fun onTitleUpdated(title: String?) { + updateTitle(title) + } + }) + + surveyView.setOnFinishListener(this) + val surveyController = controllerFactory.surveyController + surveyView.setController(surveyController) + + intent.getParcelableExtraCompat(ExtraKeys.SURVEY)?.let { + surveyController.init(it) + } + } + + private fun updateTitle(title: String?) { + this.title = title + } + + @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) + private fun overrideAnimations() { + overrideActivityTransition(OVERRIDE_TRANSITION_OPEN, R.anim.slide_up, 0) + overrideActivityTransition(OVERRIDE_TRANSITION_CLOSE, 0, R.anim.slide_down) + } + + private fun overrideEnterAnimation() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + overrideAnimations() + return + } + + overridePendingTransition(R.anim.slide_up, 0) + } + + @Suppress("DEPRECATION") + private fun overrideExitAnimation() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + overridePendingTransition(0, R.anim.slide_down) + } + } +} diff --git a/widgetssdk/src/main/java/com/glia/widgets/survey/SurveyAdapter.kt b/widgetssdk/src/main/java/com/glia/widgets/survey/SurveyAdapter.kt index 585d2db15..4f2004836 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/survey/SurveyAdapter.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/survey/SurveyAdapter.kt @@ -16,20 +16,16 @@ import com.glia.widgets.survey.viewholder.SingleQuestionViewHolder import com.glia.widgets.survey.viewholder.SurveyViewHolder import com.glia.widgets.view.configuration.survey.SurveyStyle -internal class SurveyAdapter(private val listener: SurveyAdapterListener) : - RecyclerView.Adapter() { +internal class SurveyAdapter( + private val listener: SurveyAdapterListener, + private val style: SurveyStyle +) : RecyclerView.Adapter() { interface SurveyAdapterListener { fun onAnswer(answer: Survey.Answer) } - private var style: SurveyStyle private val questionItems: MutableList = ArrayList() - init { - // initialize style with default empty SurveyStyle, to make sure that style usage is safe even if new style is not set. - style = SurveyStyle.Builder().build() - } - fun submitList(items: List?) { questionItems.clear() if (items == null) { @@ -40,10 +36,6 @@ internal class SurveyAdapter(private val listener: SurveyAdapterListener) : private fun getItem(position: Int): QuestionItem = questionItems[position] - fun setStyle(style: SurveyStyle) { - this.style = style - } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SurveyViewHolder { val inflater = LayoutInflater.from(parent.context) return when (viewType) { diff --git a/widgetssdk/src/main/java/com/glia/widgets/survey/SurveyView.kt b/widgetssdk/src/main/java/com/glia/widgets/survey/SurveyView.kt index f7b4bb03e..8712455c8 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/survey/SurveyView.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/survey/SurveyView.kt @@ -14,12 +14,10 @@ import androidx.cardview.widget.CardView import androidx.recyclerview.widget.RecyclerView import com.glia.androidsdk.engagement.Survey import com.glia.widgets.R -import com.glia.widgets.UiTheme import com.glia.widgets.databinding.SurveyViewBinding import com.glia.widgets.di.Dependencies import com.glia.widgets.helper.SimpleWindowInsetsAndAnimationHandler import com.glia.widgets.helper.Utils -import com.glia.widgets.helper.getFullHybridTheme import com.glia.widgets.helper.hideKeyboard import com.glia.widgets.helper.insetsController import com.glia.widgets.helper.layoutInflater @@ -37,7 +35,6 @@ import com.google.android.material.button.MaterialButton import com.google.android.material.shape.CornerFamily import com.google.android.material.shape.MaterialShapeDrawable import com.google.android.material.shape.ShapeAppearanceModel -import kotlin.properties.Delegates internal class SurveyView(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : FrameLayout( @@ -52,8 +49,6 @@ internal class SurveyView(context: Context, attrs: AttributeSet?, defStyleAttr: private var onFinishListener: OnFinishListener? = null private var controller: SurveyContract.Controller? = null - private var uiTheme: UiTheme by Delegates.notNull() - private val surveyTheme: SurveyTheme? by lazy { Dependencies.gliaThemeManager.theme?.surveyTheme } @@ -80,16 +75,10 @@ internal class SurveyView(context: Context, attrs: AttributeSet?, defStyleAttr: ) : this(context, attrs, defStyleAttr, R.style.Application_Glia_Chat) init { + SimpleWindowInsetsAndAnimationHandler(this) readTypedArray(attrs, defStyleAttr, defStyleRes) setupViewAppearance() initCallbacks() - initAdapter() - SimpleWindowInsetsAndAnimationHandler(this) - } - - override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { - super.onLayout(changed, left, top, right, bottom) - applyStyle(uiTheme.surveyStyle) } private fun setupViewAppearance() { @@ -206,24 +195,15 @@ internal class SurveyView(context: Context, attrs: AttributeSet?, defStyleAttr: private fun setDefaultTheme(attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) { @SuppressLint("CustomViewStyleable") - val typedArray = this.context.obtainStyledAttributes( - attrs, - R.styleable.GliaView, - defStyleAttr, - defStyleRes - ) - uiTheme = Utils.getThemeFromTypedArray(typedArray, this.context) + val typedArray = context.obtainStyledAttributes(attrs, R.styleable.GliaView, defStyleAttr, defStyleRes) + val surveyStyle = Utils.getFullHybridTheme(typedArray, this.context).surveyStyle + initAdapter(surveyStyle) + applyStyle(surveyStyle) typedArray.recycle() } - fun setTheme(uiTheme: UiTheme?) { - if (uiTheme == null) return - this.uiTheme = this.uiTheme.getFullHybridTheme(uiTheme) - this.uiTheme.surveyStyle?.also { surveyAdapter?.setStyle(it) } - } - - private fun initAdapter() { - surveyAdapter = SurveyAdapter(this) + private fun initAdapter(surveyStyle: SurveyStyle?) { + surveyAdapter = SurveyAdapter(this, surveyStyle ?: SurveyStyle.Builder().build()) recyclerView.adapter = surveyAdapter recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { diff --git a/widgetssdk/src/main/java/com/glia/widgets/view/VisitorCodeView.kt b/widgetssdk/src/main/java/com/glia/widgets/view/VisitorCodeView.kt index 9c7d2c68e..f7587efef 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/view/VisitorCodeView.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/view/VisitorCodeView.kt @@ -28,7 +28,6 @@ import com.glia.widgets.helper.applyTextTheme import com.glia.widgets.helper.combineStringWith import com.glia.widgets.helper.getColorCompat import com.glia.widgets.helper.getFontCompat -import com.glia.widgets.helper.getFullHybridTheme import com.glia.widgets.helper.layoutInflater import com.glia.widgets.helper.separateStringWithSymbol import com.glia.widgets.helper.setLocaleContentDescription @@ -56,7 +55,6 @@ internal class VisitorCodeView internal constructor( private val uiThreadExecutor: Executor? = null ) : FrameLayout(context.wrapWithMaterialThemeOverlay(), null, 0), VisitorCodeContract.View { private lateinit var controller: VisitorCodeContract.Controller - private var theme: UiTheme? = null private var timer: CountDownTimer? = null @@ -139,10 +137,7 @@ internal class VisitorCodeView internal constructor( } private fun setDefaultTheme(typedArray: TypedArray) { - val typedArrayTheme = Utils.getThemeFromTypedArray(typedArray, this.context) - val runtimeGlobalTheme = Dependencies.sdkConfigurationManager.uiTheme - theme = typedArrayTheme.getFullHybridTheme(runtimeGlobalTheme) - applyRuntimeThemeConfig(theme) + applyRuntimeThemeConfig(Utils.getFullHybridTheme(typedArray, this.context)) } override fun startLoading() { diff --git a/widgetssdk/src/main/java/com/glia/widgets/view/head/ActivityWatcherForChatHead.kt b/widgetssdk/src/main/java/com/glia/widgets/view/head/ActivityWatcherForChatHead.kt index cdead95b0..457a28d8c 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/view/head/ActivityWatcherForChatHead.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/view/head/ActivityWatcherForChatHead.kt @@ -10,10 +10,8 @@ import androidx.core.util.Pair import androidx.core.view.contains import com.glia.widgets.R import com.glia.widgets.base.BaseActivityStackWatcher -import com.glia.widgets.call.CallConfiguration import com.glia.widgets.callvisualizer.EndScreenSharingView import com.glia.widgets.chat.ChatView -import com.glia.widgets.di.Dependencies import com.glia.widgets.filepreview.ui.ImagePreviewView import com.glia.widgets.helper.DialogHolderView import com.glia.widgets.helper.Logger @@ -133,7 +131,7 @@ internal class ActivityWatcherForChatHead( } private fun saveBubblePosition() { - chatHeadLayout?.getPosition()?.let { + chatHeadLayout?.position?.let { if (it.first == null || it.second == null) return chatHeadViewPosition = Pair(it.first, it.second) } @@ -171,10 +169,6 @@ internal class ActivityWatcherForChatHead( } } - private fun getDefaultCallConfiguration(): CallConfiguration = Dependencies.sdkConfigurationManager - .buildEngagementConfiguration() - .let(::CallConfiguration) - private fun navigateToChat(activity: Activity?) { activity?.also(activityLauncher::launchChat) } @@ -184,6 +178,6 @@ internal class ActivityWatcherForChatHead( } private fun navigateToCall(activity: Activity?) { - activity?.also { activityLauncher.launchCall(it, getDefaultCallConfiguration().copy(isUpgradeToCall = true)) } + activity?.also { activityLauncher.launchCall(it, null, false) } } } diff --git a/widgetssdk/src/main/java/com/glia/widgets/view/head/ChatHeadContract.kt b/widgetssdk/src/main/java/com/glia/widgets/view/head/ChatHeadContract.kt index de55d3cdb..3c2a0611f 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/view/head/ChatHeadContract.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/view/head/ChatHeadContract.kt @@ -1,9 +1,7 @@ package com.glia.widgets.view.head -import com.glia.widgets.UiTheme import com.glia.widgets.base.BaseController import com.glia.widgets.base.BaseView -import com.glia.widgets.core.configuration.EngagementConfiguration internal interface ChatHeadContract { interface Controller : BaseController { @@ -12,8 +10,6 @@ internal interface ChatHeadContract { fun onResume(view: android.view.View?) fun onApplicationStop() fun onChatHeadPositionChanged(x: Int, y: Int) - fun setBuildTimeTheme(uiTheme: UiTheme?) - fun setEngagementConfiguration(configuration: EngagementConfiguration?) fun onPause(gliaOrRootView: android.view.View?) fun updateChatHeadView() fun onSetChatHeadView(view: View) @@ -30,6 +26,5 @@ internal interface ChatHeadContract { fun navigateToChat() fun navigateToCall() fun navigateToEndScreenSharing() - fun updateConfiguration(buildTimeTheme: UiTheme, engagementConfiguration: EngagementConfiguration?) } } diff --git a/widgetssdk/src/main/java/com/glia/widgets/view/head/ChatHeadLayout.kt b/widgetssdk/src/main/java/com/glia/widgets/view/head/ChatHeadLayout.kt index 963f5e6de..2963997fe 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/view/head/ChatHeadLayout.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/view/head/ChatHeadLayout.kt @@ -8,11 +8,8 @@ import androidx.core.util.Pair import androidx.core.view.ViewCompat import com.glia.widgets.Constants import com.glia.widgets.R -import com.glia.widgets.UiTheme -import com.glia.widgets.core.configuration.EngagementConfiguration import com.glia.widgets.databinding.ChatHeadLayoutBinding import com.glia.widgets.di.Dependencies -import com.glia.widgets.helper.Utils import com.glia.widgets.helper.layoutInflater import com.glia.widgets.helper.wrapWithMaterialThemeOverlay import com.glia.widgets.view.ViewHelpers @@ -33,12 +30,12 @@ internal class ChatHeadLayout @JvmOverloads constructor( private var chatHeadController: ChatHeadLayoutContract.Controller by Delegates.notNull() private var navigationCallback: NavigationCallback? = null - private var chatHeadClickedListener: OnChatHeadClickedListener? = null - private var uiTheme: UiTheme by Delegates.notNull() - private val chatHeadViewPosition: Pair + private val _chatHeadViewPosition: Pair get() = Pair(chatHeadView.x.roundToInt(), chatHeadView.y.roundToInt()) + val position: Pair get() = _chatHeadViewPosition + private val chatHeadSize: Float by lazy { resources.getDimension(R.dimen.glia_chat_head_size) } private val chatHeadMargin: Float by lazy { resources.getDimension(R.dimen.glia_chat_head_content_padding) } @@ -49,7 +46,7 @@ internal class ChatHeadLayout @JvmOverloads constructor( private val chatHeadView: ChatHeadView by lazy { binding.chatHeadView } init { - init(attrs, defStyleAttr, defStyleRes) + initialize() } override fun showOperatorImage(operatorImgUrl: String) { @@ -133,16 +130,6 @@ internal class ChatHeadLayout @JvmOverloads constructor( super.onDetachedFromWindow() } - /** - * Method for the integrator to override if they want to do custom logic when the chat head is - * clicked. - * - * @param listener - */ - fun setOnChatHeadClickedListener(listener: OnChatHeadClickedListener) { - chatHeadClickedListener = listener - } - /** * Method that allows integrator to override navigation on click with using own paths * @@ -155,11 +142,10 @@ internal class ChatHeadLayout @JvmOverloads constructor( navigationCallback = callback } - private fun init(attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) { + private fun initialize() { visibility = GONE initConfigurations() setupViewActions() - readTypedArray(attrs, defStyleAttr, defStyleRes) setController(Dependencies.controllerFactory.chatHeadLayoutController) chatHeadController.setView(this) } @@ -174,45 +160,19 @@ internal class ChatHeadLayout @JvmOverloads constructor( private fun setupViewActions() { chatHeadView.setOnTouchListener( ViewHelpers.OnTouchListener( - { chatHeadViewPosition }, + { _chatHeadViewPosition }, ::onChatHeadDragged ) { onChatHeadClicked() } ) } - private fun readTypedArray(attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) { - @SuppressLint("CustomViewStyleable") - val typedArray = - context.obtainStyledAttributes(attrs, R.styleable.GliaView, defStyleAttr, defStyleRes) - setBuildTimeTheme(Utils.getThemeFromTypedArray(typedArray, context)) - typedArray.recycle() - } - - private fun setBuildTimeTheme(theme: UiTheme) { - uiTheme = theme - updateChatHeadConfiguration(uiTheme) - } - - private fun updateChatHeadConfiguration( - buildTimeTheme: UiTheme, - engagementConfiguration: EngagementConfiguration? = null - ) { - chatHeadView.updateConfiguration(buildTimeTheme, engagementConfiguration) - } - private fun onChatHeadDragged(x: Float, y: Float) { chatHeadView.x = x chatHeadView.y = y chatHeadView.invalidate() } - private fun onChatHeadClicked() { - chatHeadClickedListener?.onClicked(null) ?: chatHeadController.onChatHeadClicked() - } - - fun getPosition(): Pair { - return chatHeadViewPosition - } + private fun onChatHeadClicked() = chatHeadController.onChatHeadClicked() fun setPosition(x: Float, y: Float) { chatHeadView.x = x @@ -220,10 +180,6 @@ internal class ChatHeadLayout @JvmOverloads constructor( chatHeadView.invalidate() } - fun interface OnChatHeadClickedListener { - fun onClicked(engagementConfiguration: EngagementConfiguration?) - } - interface NavigationCallback { fun onNavigateToChat() fun onNavigateToCall() diff --git a/widgetssdk/src/main/java/com/glia/widgets/view/head/ChatHeadView.kt b/widgetssdk/src/main/java/com/glia/widgets/view/head/ChatHeadView.kt index 04f3cc664..868bfb402 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/view/head/ChatHeadView.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/view/head/ChatHeadView.kt @@ -15,9 +15,7 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat import androidx.core.view.isVisible import com.glia.widgets.R import com.glia.widgets.UiTheme -import com.glia.widgets.call.CallConfiguration import com.glia.widgets.core.callvisualizer.domain.IsCallVisualizerScreenSharingUseCase -import com.glia.widgets.core.configuration.EngagementConfiguration import com.glia.widgets.databinding.ChatHeadViewBinding import com.glia.widgets.di.Dependencies import com.glia.widgets.engagement.domain.IsCurrentEngagementCallVisualizerUseCase @@ -51,21 +49,17 @@ internal class ChatHeadView @JvmOverloads constructor( ), ChatHeadContract.View { private val activityLauncher: ActivityLauncher by lazy { Dependencies.activityLauncher } private val binding by lazy { ChatHeadViewBinding.inflate(layoutInflater, this) } - private var engagementConfiguration: EngagementConfiguration? = null private var configuration: ChatHeadConfiguration by Delegates.notNull() private val isService by lazy { context is Service } private val bubbleTheme: BubbleTheme? - get() = Dependencies.gliaThemeManager.theme?.run { - if (isService) bubbleTheme else chatTheme?.bubble - } + get() = Dependencies.gliaThemeManager.theme?.run { if (isService) bubbleTheme else chatTheme?.bubble } @Suppress("JoinDeclarationAndAssignment") private var serviceChatHeadController: ChatHeadContract.Controller private var isCallVisualizerScreenSharingUseCase: IsCallVisualizerScreenSharingUseCase private var isCallVisualizerUseCase: IsCurrentEngagementCallVisualizerUseCase - private var theme: UiTheme? = null init { serviceChatHeadController = Dependencies.controllerFactory.chatHeadController @@ -76,17 +70,15 @@ internal class ChatHeadView @JvmOverloads constructor( } private fun readTypedArray() { - context.withStyledAttributes( - set = null, - attrs = R.styleable.GliaView, - defStyleAttr = 0 - ) { + context.withStyledAttributes(set = null, attrs = R.styleable.GliaView, defStyleAttr = 0) { setDefaultTheme(this) } } + private fun setDefaultTheme(typedArray: TypedArray) { - theme = Utils.getThemeFromTypedArray(typedArray, this.context) - serviceChatHeadController.setBuildTimeTheme(theme) + configuration = createConfiguration(Utils.getFullHybridTheme(typedArray, this.context)) + post { updateView() } + updateView() } override fun showUnreadMessageCount(count: Int) { @@ -159,16 +151,6 @@ internal class ChatHeadView @JvmOverloads constructor( post { binding.onHoldIcon.visibility = GONE } } - override fun updateConfiguration( - buildTimeTheme: UiTheme, - engagementConfiguration: EngagementConfiguration? - ) { - this.engagementConfiguration = engagementConfiguration - serviceChatHeadController.setBuildTimeTheme(buildTimeTheme) - createHybridConfiguration(buildTimeTheme, engagementConfiguration) - post { updateView() } - } - private fun applyBubbleTheme() { bubbleTheme?.badge?.also(binding.chatBubbleBadge::applyBadgeTheme) bubbleTheme?.onHoldOverlay?.also { @@ -186,54 +168,31 @@ internal class ChatHeadView @JvmOverloads constructor( } override fun navigateToChat() { - engagementConfiguration?.let { - activityLauncher.launchChat(context, it) - } + activityLauncher.launchChat(context) } override fun navigateToCall() { - activityLauncher.launchCall(context, CallConfiguration(engagementConfiguration)) + activityLauncher.launchCall(context, null, false) } override fun navigateToEndScreenSharing() { activityLauncher.launchEndScreenSharing(context) } - private fun createBuildTimeConfiguration(buildTimeTheme: UiTheme): ChatHeadConfiguration { - return ChatHeadConfiguration.builder() - .operatorPlaceholderBackgroundColor(buildTimeTheme.brandPrimaryColor) - .operatorPlaceholderIcon(buildTimeTheme.iconPlaceholder) - .operatorPlaceholderIconTintList(buildTimeTheme.baseLightColor) - .badgeTextColor(buildTimeTheme.baseLightColor) - .badgeBackgroundTintList(buildTimeTheme.brandPrimaryColor) - .backgroundColorRes(buildTimeTheme.brandPrimaryColor) - .iconOnHold(buildTimeTheme.iconOnHold) - .iconOnHoldTintList(buildTimeTheme.baseLightColor) - .iconScreenSharingDialog(buildTimeTheme.iconScreenSharingDialog) - .build() - } - - private fun createHybridConfiguration( - buildTimeTheme: UiTheme, - engagementConfiguration: EngagementConfiguration? - ) { - configuration = createBuildTimeConfiguration(buildTimeTheme) - val runTimeTheme = engagementConfiguration?.runTimeTheme ?: return - - val builder = ChatHeadConfiguration.builder(configuration) - - runTimeTheme.chatHeadConfiguration?.apply { - operatorPlaceholderBackgroundColor?.also(builder::operatorPlaceholderBackgroundColor) - operatorPlaceholderIcon?.also(builder::operatorPlaceholderIcon) - operatorPlaceholderIconTintList?.also(builder::operatorPlaceholderIconTintList) - badgeBackgroundTintList?.also(builder::badgeBackgroundTintList) - badgeTextColor?.also(builder::badgeTextColor) - backgroundColorRes?.also(builder::backgroundColorRes) - iconOnHold?.also(builder::iconOnHold) - iconOnHoldTintList?.also(builder::iconOnHoldTintList) - iconScreenSharingDialog?.also(builder::iconScreenSharingDialog) + private fun createConfiguration(buildTimeTheme: UiTheme): ChatHeadConfiguration { + return buildTimeTheme.chatHeadConfiguration.let { + ChatHeadConfiguration.builder() + .operatorPlaceholderBackgroundColor(it?.operatorPlaceholderBackgroundColor ?: buildTimeTheme.brandPrimaryColor) + .operatorPlaceholderIcon(it?.operatorPlaceholderIcon ?: buildTimeTheme.iconPlaceholder) + .operatorPlaceholderIconTintList(it?.operatorPlaceholderIconTintList ?: buildTimeTheme.baseLightColor) + .badgeTextColor(it?.badgeTextColor ?: buildTimeTheme.baseLightColor) + .badgeBackgroundTintList(it?.badgeBackgroundTintList ?: buildTimeTheme.brandPrimaryColor) + .backgroundColorRes(it?.backgroundColorRes ?: buildTimeTheme.brandPrimaryColor) + .iconOnHold(it?.iconOnHold ?: buildTimeTheme.iconOnHold) + .iconOnHoldTintList(it?.iconOnHoldTintList ?: buildTimeTheme.baseLightColor) + .iconScreenSharingDialog(it?.iconScreenSharingDialog ?: buildTimeTheme.iconScreenSharingDialog) + .build() } - configuration = builder.build() } private fun setAccessibilityLabels() { @@ -300,6 +259,7 @@ internal class ChatHeadView @JvmOverloads constructor( updateQueueingAnimationView() applyBubbleTheme() + invalidate() } private fun isDisplayUnreadMessageBadge(unreadMessageCount: Int): Boolean = diff --git a/widgetssdk/src/main/java/com/glia/widgets/view/head/controller/ServiceChatHeadController.kt b/widgetssdk/src/main/java/com/glia/widgets/view/head/controller/ServiceChatHeadController.kt index 118ec23ae..3c8ffdbcc 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/view/head/controller/ServiceChatHeadController.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/view/head/controller/ServiceChatHeadController.kt @@ -2,13 +2,10 @@ package com.glia.widgets.view.head.controller import android.view.View import com.glia.androidsdk.Operator -import com.glia.widgets.UiTheme import com.glia.widgets.core.callvisualizer.domain.IsCallVisualizerScreenSharingUseCase +import com.glia.widgets.core.chathead.domain.IsDisplayBubbleOutsideAppUseCase import com.glia.widgets.core.chathead.domain.ResolveChatHeadNavigationUseCase import com.glia.widgets.core.chathead.domain.ResolveChatHeadNavigationUseCase.Destinations -import com.glia.widgets.core.chathead.domain.IsDisplayBubbleOutsideAppUseCase -import com.glia.widgets.core.configuration.EngagementConfiguration -import com.glia.widgets.di.Dependencies import com.glia.widgets.engagement.domain.CurrentOperatorUseCase import com.glia.widgets.engagement.domain.EngagementStateUseCase import com.glia.widgets.engagement.domain.ScreenSharingUseCase @@ -38,8 +35,6 @@ internal class ServiceChatHeadController( private var operatorProfileImgUrl: String? = null private var unreadMessagesCount = 0 private var isOnHold = false - private var engagementConfiguration: EngagementConfiguration? = null - private var buildTimeTheme: UiTheme? = null /* * We need to keep track of the currently active (topmost) view. This can be either ChatView @@ -101,9 +96,6 @@ internal class ServiceChatHeadController( updateChatHeadView() } - override fun setEngagementConfiguration(engagementConfiguration: EngagementConfiguration?) { - this.engagementConfiguration = engagementConfiguration - } private fun handleEngagementState(state: com.glia.widgets.engagement.State) { when (state) { @@ -138,18 +130,13 @@ internal class ServiceChatHeadController( } override fun updateChatHeadView() { - if (chatHeadView != null && buildTimeTheme != null) { + if (chatHeadView != null) { updateChatHeadViewState() updateOnHold() chatHeadView!!.showUnreadMessageCount(unreadMessagesCount) - chatHeadView!!.updateConfiguration(buildTimeTheme!!, engagementConfiguration) } } - override fun setBuildTimeTheme(uiTheme: UiTheme?) { - buildTimeTheme = uiTheme - } - private fun engagementEnded() { isDisplayBubbleOutsideAppUseCase.onDestroy() isOnHold = false @@ -164,18 +151,12 @@ internal class ServiceChatHeadController( isOnHold = false state = State.ENGAGEMENT isDisplayBubbleOutsideAppUseCase(resumedViewName) - if (engagementConfiguration == null) setEngagementConfiguration( - Dependencies.sdkConfigurationManager.buildEngagementConfiguration() - ) updateChatHeadView() } private fun queueingStarted() { state = State.QUEUEING isDisplayBubbleOutsideAppUseCase(resumedViewName) - if (engagementConfiguration == null) setEngagementConfiguration( - Dependencies.sdkConfigurationManager.buildEngagementConfiguration() - ) updateChatHeadView() } diff --git a/widgetssdk/src/main/java/com/glia/widgets/view/textview/BaseConfigurableTextView.java b/widgetssdk/src/main/java/com/glia/widgets/view/textview/BaseConfigurableTextView.java index efdd7eb7d..8680dda7c 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/view/textview/BaseConfigurableTextView.java +++ b/widgetssdk/src/main/java/com/glia/widgets/view/textview/BaseConfigurableTextView.java @@ -1,7 +1,6 @@ package com.glia.widgets.view.textview; -import static com.glia.widgets.helper.ContextExtensionsKt.pxToSp; import android.content.Context; import android.util.AttributeSet; @@ -13,6 +12,7 @@ import com.glia.widgets.R; import com.glia.widgets.UiTheme; +import com.glia.widgets.helper.ContextExtensions; import com.glia.widgets.view.configuration.TextConfiguration; import com.google.android.material.textview.MaterialTextView; @@ -48,7 +48,7 @@ private void createBuildTimeConfiguration() { .textColor(getTextColors()) .textColorHighlight(getHighlightColor()) .hintColor(getHintTextColors()) - .textSize(pxToSp(getContext(), getTextSize())) + .textSize(ContextExtensions.pxToSp(getContext(), getTextSize())) .build(); } diff --git a/widgetssdk/src/main/java/com/glia/widgets/view/unifiedui/config/entrywidget/MediaTypeItemRemoteConfig.kt b/widgetssdk/src/main/java/com/glia/widgets/view/unifiedui/config/entrywidget/MediaTypeItemRemoteConfig.kt index 78e967b62..314b7e8cc 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/view/unifiedui/config/entrywidget/MediaTypeItemRemoteConfig.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/view/unifiedui/config/entrywidget/MediaTypeItemRemoteConfig.kt @@ -1,6 +1,6 @@ package com.glia.widgets.view.unifiedui.config.entrywidget -import com.glia.widgets.view.unifiedui.config.base.ColorRemoteConfig +import com.glia.widgets.view.unifiedui.config.base.ColorLayerRemoteConfig import com.glia.widgets.view.unifiedui.config.base.LayerRemoteConfig import com.glia.widgets.view.unifiedui.config.base.TextRemoteConfig import com.glia.widgets.view.unifiedui.theme.entrywidget.MediaTypeItemTheme @@ -10,7 +10,7 @@ internal data class MediaTypeItemRemoteConfig( @SerializedName("background") val background: LayerRemoteConfig?, @SerializedName("iconColor") - val iconColor: ColorRemoteConfig?, + val iconColor: ColorLayerRemoteConfig?, @SerializedName("title") val title: TextRemoteConfig?, @SerializedName("message") diff --git a/widgetssdk/src/main/java/com/glia/widgets/view/unifiedui/config/entrywidget/MediaTypeItemsRemoteConfig.kt b/widgetssdk/src/main/java/com/glia/widgets/view/unifiedui/config/entrywidget/MediaTypeItemsRemoteConfig.kt index f9a48c44d..cbb1d69df 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/view/unifiedui/config/entrywidget/MediaTypeItemsRemoteConfig.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/view/unifiedui/config/entrywidget/MediaTypeItemsRemoteConfig.kt @@ -1,14 +1,14 @@ package com.glia.widgets.view.unifiedui.config.entrywidget -import com.glia.widgets.view.unifiedui.config.base.ColorRemoteConfig -import com.google.gson.annotations.SerializedName +import com.glia.widgets.view.unifiedui.config.base.ColorLayerRemoteConfig import com.glia.widgets.view.unifiedui.theme.entrywidget.MediaTypeItemsTheme +import com.google.gson.annotations.SerializedName internal data class MediaTypeItemsRemoteConfig( @SerializedName("mediaTypeItem") val mediaTypeItem: MediaTypeItemRemoteConfig?, @SerializedName("dividerColor") - val dividerColor: ColorRemoteConfig? + val dividerColor: ColorLayerRemoteConfig? ) { fun toMediaTypeItemsTheme(): MediaTypeItemsTheme = MediaTypeItemsTheme( mediaTypeItem = mediaTypeItem?.toMediaTypeItemTheme(), diff --git a/widgetssdk/src/main/java/com/glia/widgets/view/unifiedui/config/securemessaging/SecureMessagingRemoteConfig.kt b/widgetssdk/src/main/java/com/glia/widgets/view/unifiedui/config/securemessaging/SecureMessagingRemoteConfig.kt index fc64b4bee..c610e6287 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/view/unifiedui/config/securemessaging/SecureMessagingRemoteConfig.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/view/unifiedui/config/securemessaging/SecureMessagingRemoteConfig.kt @@ -1,6 +1,6 @@ package com.glia.widgets.view.unifiedui.config.securemessaging -import com.glia.widgets.view.unifiedui.config.base.ColorRemoteConfig +import com.glia.widgets.view.unifiedui.config.base.ColorLayerRemoteConfig import com.glia.widgets.view.unifiedui.config.base.LayerRemoteConfig import com.glia.widgets.view.unifiedui.config.base.TextRemoteConfig import com.glia.widgets.view.unifiedui.config.entrywidget.MediaTypeItemsRemoteConfig @@ -17,15 +17,15 @@ internal data class SecureMessagingRemoteConfig( @SerializedName("bottomBannerText") val bottomBannerText: TextRemoteConfig?, @SerializedName("bottomBannerDividerColor") - val bottomBannerDividerColor: ColorRemoteConfig?, + val bottomBannerDividerColor: ColorLayerRemoteConfig?, @SerializedName("topBannerBackground") val topBannerBackground: LayerRemoteConfig?, @SerializedName("topBannerText") val topBannerText: TextRemoteConfig?, @SerializedName("topBannerDividerColor") - val topBannerDividerColor: ColorRemoteConfig?, + val topBannerDividerColor: ColorLayerRemoteConfig?, @SerializedName("topBannerDropDownIconColor") - val topBannerDropDownIconColor: ColorRemoteConfig?, + val topBannerDropDownIconColor: ColorLayerRemoteConfig?, @SerializedName("mediaTypeItems") val mediaTypeItems: MediaTypeItemsRemoteConfig? ) { diff --git a/widgetssdk/src/main/java/com/glia/widgets/webbrowser/WebBrowserView.kt b/widgetssdk/src/main/java/com/glia/widgets/webbrowser/WebBrowserView.kt index 600f12b24..9e5ce517a 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/webbrowser/WebBrowserView.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/webbrowser/WebBrowserView.kt @@ -4,7 +4,6 @@ import android.content.Context import android.content.res.TypedArray import android.net.Uri import android.util.AttributeSet -import android.view.Window import android.webkit.WebResourceRequest import android.webkit.WebView import android.webkit.WebViewClient @@ -13,19 +12,16 @@ import androidx.core.content.withStyledAttributes import androidx.core.view.ViewCompat import com.glia.widgets.Constants import com.glia.widgets.R -import com.glia.widgets.UiTheme import com.glia.widgets.databinding.WebBrowserViewBinding import com.glia.widgets.di.Dependencies import com.glia.widgets.helper.SimpleWindowInsetsAndAnimationHandler import com.glia.widgets.helper.Utils -import com.glia.widgets.helper.asActivity import com.glia.widgets.helper.layoutInflater import com.glia.widgets.locale.LocaleString import com.glia.widgets.view.header.AppBarView import com.glia.widgets.view.unifiedui.theme.UnifiedTheme import com.glia.widgets.view.unifiedui.theme.base.HeaderTheme import com.google.android.material.theme.overlay.MaterialThemeOverlay -import kotlin.properties.Delegates internal class WebBrowserView( context: Context, @@ -39,7 +35,6 @@ internal class WebBrowserView( defStyleRes ) { - private var theme: UiTheme by Delegates.notNull() private val unifiedTheme: UnifiedTheme? by lazy { Dependencies.gliaThemeManager.theme } var onFinishListener: OnFinishListener? = null @@ -50,8 +45,6 @@ internal class WebBrowserView( private val appBar: AppBarView? get() = binding?.appBarView private val webView: WebView? get() = binding?.webView - private val window: Window? by lazy { context.asActivity()?.window } - init { isSaveEnabled = true orientation = VERTICAL @@ -107,7 +100,7 @@ internal class WebBrowserView( } private fun setDefaultTheme(typedArray: TypedArray) { - theme = Utils.getThemeFromTypedArray(typedArray, this.context) + binding?.appBarView?.setTheme(Utils.getFullHybridTheme(typedArray, this.context)) } private fun initCallbacks() { diff --git a/widgetssdk/src/test/java/android/TestExtensions.kt b/widgetssdk/src/test/java/android/TestExtensions.kt index 2daadd2df..919538080 100644 --- a/widgetssdk/src/test/java/android/TestExtensions.kt +++ b/widgetssdk/src/test/java/android/TestExtensions.kt @@ -4,7 +4,7 @@ import android.content.Intent import java.nio.charset.StandardCharsets internal const val COMMON_EXTENSIONS_CLASS_PATH = "com.glia.widgets.helper.CommonExtensionsKt" -internal const val CONTEXT_EXTENSIONS_CLASS_PATH = "com.glia.widgets.helper.ContextExtensionsKt" +internal const val CONTEXT_EXTENSIONS_CLASS_PATH = "com.glia.widgets.helper.ContextExtensions" internal const val LOGGER_PATH = "com.glia.widgets.helper.Logger" fun Class.readRawResource(resName: String): String = classLoader?.getResourceAsStream(resName)?.run { diff --git a/widgetssdk/src/test/java/com/glia/widgets/GliaWidgetsTest.kt b/widgetssdk/src/test/java/com/glia/widgets/GliaWidgetsTest.kt index 5b3ad4cfd..26ccad6d7 100644 --- a/widgetssdk/src/test/java/com/glia/widgets/GliaWidgetsTest.kt +++ b/widgetssdk/src/test/java/com/glia/widgets/GliaWidgetsTest.kt @@ -70,6 +70,7 @@ class GliaWidgetsTest { val callVisualizerController = mock() whenever(controllerFactory.callVisualizerController).thenReturn(callVisualizerController) whenever(repositoryFactory.engagementRepository) doReturn mock() + whenever(repositoryFactory.engagementConfigRepository) doReturn mock() GliaWidgets.init(widgetsConfig) val captor = argumentCaptor() verify(gliaCore).init(captor.capture()) diff --git a/widgetssdk/src/test/java/com/glia/widgets/chat/ChatManagerTest.kt b/widgetssdk/src/test/java/com/glia/widgets/chat/ChatManagerTest.kt index c0007015d..4a7cf2472 100644 --- a/widgetssdk/src/test/java/com/glia/widgets/chat/ChatManagerTest.kt +++ b/widgetssdk/src/test/java/com/glia/widgets/chat/ChatManagerTest.kt @@ -146,17 +146,14 @@ class ChatManagerTest { @Test fun `mapInQueue adds OperatorStatusItem_InQueue to chatItems and updates operatorStatusItem`() { - val companyName = "company Name" - val newState = subjectUnderTest.mapInQueue(companyName, state) + val newState = subjectUnderTest.mapInQueue(state) val lastItem = newState.chatItems.last() as OperatorStatusItem.InQueue - assertEquals(companyName, lastItem.companyName) - assertEquals(companyName, newState.operatorStatusItem!!.companyName) assertEquals(lastItem, newState.operatorStatusItem) } @Test fun `mapTransferring removes old OperatorStatusItem when it exists and adds new one`() { - subjectUnderTest.mapTransferring(subjectUnderTest.mapInQueue("name", state)).apply { + subjectUnderTest.mapTransferring(subjectUnderTest.mapInQueue(state)).apply { assertTrue(chatItems.count() == 1) assertTrue(chatItems.contains(OperatorStatusItem.Transferring)) } @@ -164,7 +161,7 @@ class ChatManagerTest { @Test fun `mapOperatorConnected adds OperatorStatusItem_Connected when the old is null`() { - val action = ChatManager.Action.OperatorConnected("c_name", "o_name", "o_image") + val action = ChatManager.Action.OperatorConnected("o_name", "o_image") val stateSpy = spy(state) val subjectUnderTestSpy = spy(subjectUnderTest) subjectUnderTestSpy.mapOperatorConnected(action, stateSpy) @@ -172,13 +169,12 @@ class ChatManagerTest { verify(stateSpy).resetOperator() val newItem = stateSpy.chatItems.last() as OperatorStatusItem.Connected assertEquals(newItem.operatorName, action.operatorFormattedName) - assertEquals(newItem.companyName, action.companyName) assertEquals(newItem.profileImgUrl, action.operatorImageUrl) } @Test fun `mapOperatorConnected replaces old OperatorStatusItem when the old is exists`() { - val action = ChatManager.Action.OperatorConnected("c_name", "o_name", "o_image") + val action = ChatManager.Action.OperatorConnected("o_name", "o_image") state.apply { operatorStatusItem = OperatorStatusItem.Transferring chatItems.add(mock()) @@ -190,7 +186,6 @@ class ChatManagerTest { verify(subjectUnderTestSpy).checkUnsentMessages(any()) val newItem = newState.chatItems.last() as OperatorStatusItem.Connected assertEquals(newItem.operatorName, action.operatorFormattedName) - assertEquals(newItem.companyName, action.companyName) assertEquals(newItem.profileImgUrl, action.operatorImageUrl) assertFalse(newState.chatItems.contains(OperatorStatusItem.Transferring)) } @@ -198,7 +193,7 @@ class ChatManagerTest { @Test fun `addUnsentMessage adds Unsent message before OperatorStatusItem when chatItems contain OperatorStatusItem_InQueue`() { val message = Unsent(SendMessagePayload(content = "message")) - val inQueue = OperatorStatusItem.InQueue("company_name") + val inQueue = OperatorStatusItem.InQueue assertTrue(state.unsentItems.isEmpty()) assertTrue(state.chatItems.isEmpty()) val newState = subjectUnderTest.addUnsentMessage(message, state) @@ -229,7 +224,7 @@ class ChatManagerTest { @Test fun `mapOperatorJoined adds OperatorStatusItem_Joined to chatItems when called`() { - val action: ChatManager.Action.OperatorJoined = ChatManager.Action.OperatorJoined("", "", "") + val action: ChatManager.Action.OperatorJoined = ChatManager.Action.OperatorJoined("", "") subjectUnderTest.mapTransferring(state).apply { assertTrue(chatItems.contains(OperatorStatusItem.Transferring)) } @@ -326,19 +321,14 @@ class ChatManagerTest { @Test fun `mapAction calls mapInQueue when Action_QueuingStarted passed`() { - val action: ChatManager.Action.QueuingStarted = mock { - on { companyName } doReturn "" - } - val subjectUnderTestSpy = spy(subjectUnderTest) - subjectUnderTestSpy.mapAction(action, state) - verify(subjectUnderTestSpy).mapInQueue(any(), any()) + subjectUnderTestSpy.mapAction(ChatManager.Action.QueuingStarted, state) + verify(subjectUnderTestSpy).mapInQueue(any()) } @Test fun `mapAction calls mapOperatorConnected when Action_OperatorConnected passed`() { val action: ChatManager.Action.OperatorConnected = mock { - on { companyName } doReturn "" on { operatorFormattedName } doReturn "" } @@ -359,7 +349,6 @@ class ChatManagerTest { @Test fun `mapAction calls mapOperatorJoined when Action_OperatorJoined passed`() { val action: ChatManager.Action.OperatorJoined = mock { - on { companyName } doReturn "" on { operatorFormattedName } doReturn "" } diff --git a/widgetssdk/src/test/java/com/glia/widgets/chat/controller/ChatControllerTest.kt b/widgetssdk/src/test/java/com/glia/widgets/chat/controller/ChatControllerTest.kt index a04368db3..e90c96298 100644 --- a/widgetssdk/src/test/java/com/glia/widgets/chat/controller/ChatControllerTest.kt +++ b/widgetssdk/src/test/java/com/glia/widgets/chat/controller/ChatControllerTest.kt @@ -34,8 +34,8 @@ import com.glia.widgets.core.notification.domain.CallNotificationUseCase import com.glia.widgets.core.permissions.domain.RequestNotificationPermissionIfPushNotificationsSetUpUseCase import com.glia.widgets.core.permissions.domain.WithCameraPermissionUseCase import com.glia.widgets.core.permissions.domain.WithReadWritePermissionsUseCase -import com.glia.widgets.core.secureconversations.domain.IsSecureEngagementUseCase import com.glia.widgets.core.secureconversations.domain.GetAvailableQueueIdsForSecureMessagingUseCase +import com.glia.widgets.core.secureconversations.domain.IsSecureEngagementUseCase import com.glia.widgets.engagement.domain.AcceptMediaUpgradeOfferUseCase import com.glia.widgets.engagement.domain.DeclineMediaUpgradeOfferUseCase import com.glia.widgets.engagement.domain.EndEngagementUseCase @@ -238,35 +238,23 @@ class ChatControllerTest { @Test fun initChat_setsConfiguration_withInitialParams() { - val queueIds = listOf("QueueId1", "QueueId2") whenever(chatManager.initialize(any(), any(), any())) doReturn Flowable.never() - chatController.initChat( - "CompanyName", - queueIds, - "VisitorId", - ChatType.SECURE_MESSAGING - ) + chatController.initChat(ChatType.SECURE_MESSAGING) - verify(engagementConfigUseCase).invoke(ChatType.SECURE_MESSAGING, queueIds) + verify(engagementConfigUseCase).invoke(ChatType.SECURE_MESSAGING) } @Test fun initChat_setsConfiguration_withAvailableQueues() { val queueIds = listOf("QueueId1", "QueueId2") whenever(isSecureEngagementUseCase.invoke()) doReturn true - whenever(getAvailableQueueIdsForSecureMessagingUseCase.invoke()) doReturn Single.just(Data.Value(queueIds)) + whenever(getAvailableQueueIdsForSecureMessagingUseCase()) doReturn Single.just(Data.Value(queueIds)) whenever(chatManager.initialize(any(), any(), any())) doReturn Flowable.never() - chatController.initChat( - "CompanyName", - emptyList(), - "VisitorId", - ChatType.SECURE_MESSAGING - ) + chatController.initChat(ChatType.SECURE_MESSAGING) - verify(engagementConfigUseCase).invoke(ChatType.SECURE_MESSAGING, emptyList()) - verify(engagementConfigUseCase).invoke(ChatType.SECURE_MESSAGING, queueIds) + verify(engagementConfigUseCase).invoke(ChatType.SECURE_MESSAGING) } @Test @@ -275,12 +263,7 @@ class ChatControllerTest { whenever(getAvailableQueueIdsForSecureMessagingUseCase.invoke()) doReturn Single.just(Data.Value(null)) whenever(chatManager.initialize(any(), any(), any())) doReturn Flowable.never() - chatController.initChat( - "CompanyName", - emptyList(), - "VisitorId", - ChatType.SECURE_MESSAGING - ) + chatController.initChat(ChatType.SECURE_MESSAGING) verify(dialogController).showMessageCenterUnavailableDialog() } @@ -291,12 +274,7 @@ class ChatControllerTest { whenever(getAvailableQueueIdsForSecureMessagingUseCase.invoke()) doReturn Single.error(Exception()) whenever(chatManager.initialize(any(), any(), any())) doReturn Flowable.never() - chatController.initChat( - "CompanyName", - emptyList(), - "VisitorId", - ChatType.SECURE_MESSAGING - ) + chatController.initChat(ChatType.SECURE_MESSAGING) verify(dialogController).showUnexpectedErrorDialog() } diff --git a/widgetssdk/src/test/java/com/glia/widgets/core/configuration/EngagementCallConfigurationManagerTest.kt b/widgetssdk/src/test/java/com/glia/widgets/core/configuration/EngagementCallConfigurationManagerTest.kt deleted file mode 100644 index 45cf455c0..000000000 --- a/widgetssdk/src/test/java/com/glia/widgets/core/configuration/EngagementCallConfigurationManagerTest.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.glia.widgets.core.configuration - -import com.glia.androidsdk.Glia -import com.glia.widgets.R -import com.glia.widgets.di.Dependencies -import com.glia.widgets.helper.ResourceProvider -import com.glia.widgets.locale.LocaleProvider -import io.mockk.every -import io.mockk.justRun -import io.mockk.mockk -import io.mockk.mockkStatic -import org.junit.Assert.assertEquals -import org.junit.Before -import org.junit.Test - -private const val DEFAULT_LOCAL_COMPANY_NAME = "Local Company Name" - -class EngagementCallConfigurationManagerTest { - - private val configurationManager: GliaSdkConfigurationManager = GliaSdkConfigurationManager() - private val resourceProvider: ResourceProvider = mockk() - private val localeProvider: LocaleProvider = mockk() - - @Before - fun setup() { - mockkStatic(Glia::class) - Dependencies.resourceProvider = resourceProvider - Dependencies.localeProvider = localeProvider - every { resourceProvider.getResourceKey(R.string.general_company_name)} returns "key" - every { resourceProvider.getString(any()) } returns DEFAULT_LOCAL_COMPANY_NAME - justRun { localeProvider.reportImproperInitialisation(any())} - } - - @Test - fun `getCompanyName returns legacy value when non-legacy is null`() { - configurationManager.setLegacyCompanyName("Legacy name") - configurationManager.companyName = null - assertEquals("Legacy name", configurationManager.companyName) - } - - @Test - fun `getCompanyName should not be replaced when remote value is empty but local custom value is set using GliaWidgetsConfig setCompanyName`() { - configurationManager.setLegacyCompanyName("Legacy name") - configurationManager.companyName = "Init company name" - every { Glia.getRemoteString(any()) } returns "" - every { resourceProvider.getString(R.string.general_company_name) } returns DEFAULT_LOCAL_COMPANY_NAME - assertEquals("Init company name", configurationManager.companyName) - } -} diff --git a/widgetssdk/src/test/java/com/glia/widgets/engagement/EngagementRepositoryTest.kt b/widgetssdk/src/test/java/com/glia/widgets/engagement/EngagementRepositoryTest.kt index 6fc06bf3a..9cc3e50e1 100644 --- a/widgetssdk/src/test/java/com/glia/widgets/engagement/EngagementRepositoryTest.kt +++ b/widgetssdk/src/test/java/com/glia/widgets/engagement/EngagementRepositoryTest.kt @@ -789,7 +789,7 @@ class EngagementRepositoryTest { fun `queueForEngagement with TEXT type produces PreQueueing when queueing success`() { val queueId = "queue_id" val queueForEngagementCallbackSlot = slot>() - repository.queueForEngagement(listOf(queueId), MediaType.TEXT,null) + repository.queueForEngagement(listOf(queueId), MediaType.TEXT) verify(exactly = 1) { core.queueForEngagement(arrayOf(queueId), MediaType.TEXT, null, any(), any(), capture(queueForEngagementCallbackSlot)) } queueForEngagementCallbackSlot.captured.accept(null) @@ -799,7 +799,7 @@ class EngagementRepositoryTest { repository.engagementState.test().assertNotComplete().assertValue(State.PreQueuing(listOf(queueId), MediaType.TEXT)) - repository.queueForEngagement(listOf(queueId), MediaType.TEXT, "url") + repository.queueForEngagement(listOf(queueId), MediaType.TEXT) verify(exactly = 0) { core.queueForEngagement(arrayOf(queueId), MediaType.TEXT, "url", any(), any(), capture(queueForEngagementCallbackSlot)) } } @@ -809,7 +809,7 @@ class EngagementRepositoryTest { val queueId = "queue_id" val mediaType = MediaType.AUDIO val queueForEngagementCallbackSlot = slot>() - repository.queueForEngagement(listOf(queueId), mediaType, null) + repository.queueForEngagement(listOf(queueId), mediaType) verify { core.queueForEngagement(arrayOf(queueId), mediaType, null, any(), any(), capture(queueForEngagementCallbackSlot)) } queueForEngagementCallbackSlot.captured.accept(null) @@ -822,7 +822,7 @@ class EngagementRepositoryTest { val queueId = "queue_id" val mediaType = MediaType.AUDIO val queueForEngagementCallbackSlot = slot>() - repository.queueForEngagement(listOf(queueId), mediaType, null) + repository.queueForEngagement(listOf(queueId), mediaType) verify(exactly = 1) { core.queueForEngagement(arrayOf(queueId), mediaType, null, any(), any(), capture(queueForEngagementCallbackSlot)) } queueForEngagementCallbackSlot.captured.accept(GliaException("message", GliaException.Cause.ALREADY_QUEUED)) @@ -832,7 +832,7 @@ class EngagementRepositoryTest { repository.engagementState.test().assertNotComplete().assertValue(State.PreQueuing(listOf(queueId), mediaType)) - repository.queueForEngagement(listOf(queueId), MediaType.VIDEO, null) + repository.queueForEngagement(listOf(queueId), MediaType.VIDEO) verify(exactly = 0) { core.queueForEngagement(arrayOf(queueId), MediaType.VIDEO, null, any(), any(), capture(queueForEngagementCallbackSlot)) } } @@ -843,7 +843,7 @@ class EngagementRepositoryTest { val mediaType = MediaType.AUDIO val queueForEngagementCallbackSlot = slot>() val testSubscriber = repository.engagementState.test() - repository.queueForEngagement(listOf(queueId), mediaType, null) + repository.queueForEngagement(listOf(queueId), mediaType) verify { core.queueForEngagement(arrayOf(queueId), mediaType, null, any(), any(), capture(queueForEngagementCallbackSlot)) } queueForEngagementCallbackSlot.captured.accept(GliaException("message", GliaException.Cause.QUEUE_CLOSED)) @@ -861,7 +861,7 @@ class EngagementRepositoryTest { val mediaType = MediaType.AUDIO val queueForEngagementCallbackSlot = slot>() val testSubscriber = repository.engagementState.test() - repository.queueForEngagement(listOf(queueId), mediaType, null) + repository.queueForEngagement(listOf(queueId), mediaType) verify { core.queueForEngagement(arrayOf(queueId), mediaType, null, any(), any(), capture(queueForEngagementCallbackSlot)) } queueForEngagementCallbackSlot.captured.accept(GliaException("message", GliaException.Cause.NETWORK_TIMEOUT)) @@ -883,7 +883,7 @@ class EngagementRepositoryTest { val queueTicket: QueueTicket = mockk(relaxed = true) { every { id } returns ticketId } - repository.queueForEngagement(listOf(queueId), mediaType, null) + repository.queueForEngagement(listOf(queueId), mediaType) verify(exactly = 1) { core.queueForEngagement(arrayOf(queueId), mediaType, null, any(), any(), capture(queueForEngagementCallbackSlot)) } queueForEngagementCallbackSlot.captured.accept(null) @@ -922,7 +922,7 @@ class EngagementRepositoryTest { val queueTicket: QueueTicket = mockk(relaxed = true) { every { id } returns ticketId } - repository.queueForEngagement(listOf(queueId), mediaType, null) + repository.queueForEngagement(listOf(queueId), mediaType) verify(exactly = 1) { core.queueForEngagement(arrayOf(queueId), mediaType, null, any(), any(), capture(queueForEngagementCallbackSlot)) } queueForEngagementCallbackSlot.captured.accept(null) @@ -960,7 +960,7 @@ class EngagementRepositoryTest { val queueTicket: QueueTicket = mockk(relaxed = true) { every { id } returns ticketId } - repository.queueForEngagement(listOf(queueId), mediaType, null) + repository.queueForEngagement(listOf(queueId), mediaType) verify(exactly = 1) { core.queueForEngagement(arrayOf(queueId), mediaType, null, any(), any(), capture(queueForEngagementCallbackSlot)) } queueForEngagementCallbackSlot.captured.accept(null) diff --git a/widgetssdk/src/test/java/com/glia/widgets/engagement/completion/EngagementCompletionActivityWatcherTest.kt b/widgetssdk/src/test/java/com/glia/widgets/engagement/completion/EngagementCompletionActivityWatcherTest.kt index 648c96723..a804b5ffa 100644 --- a/widgetssdk/src/test/java/com/glia/widgets/engagement/completion/EngagementCompletionActivityWatcherTest.kt +++ b/widgetssdk/src/test/java/com/glia/widgets/engagement/completion/EngagementCompletionActivityWatcherTest.kt @@ -7,12 +7,14 @@ import android.content.Context import android.os.Parcelable import android.view.View import androidx.appcompat.app.AlertDialog +import com.glia.androidsdk.engagement.Survey import com.glia.widgets.UiTheme import com.glia.widgets.chat.ChatActivity import com.glia.widgets.helper.GliaActivityManager import com.glia.widgets.helper.Logger import com.glia.widgets.helper.OneTimeEvent import com.glia.widgets.helper.withRuntimeTheme +import com.glia.widgets.launcher.ActivityLauncher import com.glia.widgets.view.Dialogs import io.mockk.Runs import io.mockk.confirmVerified @@ -40,6 +42,7 @@ class EngagementCompletionActivityWatcherTest { private lateinit var controller: EngagementCompletionContract.Controller private lateinit var watcher: EngagementCompletionActivityWatcher + private lateinit var activityLauncher: ActivityLauncher @Before fun setUp() { @@ -59,7 +62,9 @@ class EngagementCompletionActivityWatcherTest { every { state } returns stateProcessor } - watcher = EngagementCompletionActivityWatcher(controller, gliaActivityManager) + activityLauncher = mockk(relaxUnitFun = true) + + watcher = EngagementCompletionActivityWatcher(controller, gliaActivityManager, activityLauncher) verify { controller.state } } @@ -275,7 +280,8 @@ class EngagementCompletionActivityWatcherTest { @Test fun `handleState will start Survey when event is SurveyLoaded`() { - val event = createMockEvent(EngagementCompletionState.SurveyLoaded(mockk(moreInterfaces = arrayOf(Parcelable::class)))) + val survey = mockk(moreInterfaces = arrayOf(Parcelable::class)) + val event = createMockEvent(EngagementCompletionState.SurveyLoaded(survey)) val activity = mockkActivity() @@ -292,9 +298,7 @@ class EngagementCompletionActivityWatcherTest { verify { event.consume(any()) } - verify { activity.overridePendingTransition(any(), any()) } - verify { activity.startActivity(any()) } - verify { activity.packageName } + verify { activityLauncher.launchSurvey(eq(activity), eq(survey)) } verify(exactly = 0) { dialog.dismiss() } verify(exactly = 0) { gliaActivityManager.finishActivities() } diff --git a/widgetssdk/src/test/java/com/glia/widgets/engagement/domain/EngagementDomainTest.kt b/widgetssdk/src/test/java/com/glia/widgets/engagement/domain/EngagementDomainTest.kt index e75729c03..a1a9a9d89 100644 --- a/widgetssdk/src/test/java/com/glia/widgets/engagement/domain/EngagementDomainTest.kt +++ b/widgetssdk/src/test/java/com/glia/widgets/engagement/domain/EngagementDomainTest.kt @@ -24,6 +24,7 @@ import com.glia.widgets.engagement.EngagementRepository import com.glia.widgets.engagement.ScreenSharingState import com.glia.widgets.helper.Data import com.glia.widgets.helper.formattedName +import com.glia.widgets.launcher.ConfigurationManager import com.glia.widgets.permissions.Permissions import com.glia.widgets.permissions.PermissionsGrantedCallback import io.mockk.Runs @@ -308,30 +309,18 @@ class EngagementDomainTest { assertTrue(useCase.isMediaEngagement) } - @Test - fun `EnqueueForEngagementUseCase invoke enqueues for chat engagement when media type is absent`() { - val repository: EngagementRepository = mockk(relaxUnitFun = true) - val queueIds = listOf("queueId1", "queueId2") - val mediaType: Engagement.MediaType? = null - val visitorContextAssetId = null - - val useCase: EnqueueForEngagementUseCase = EnqueueForEngagementUseCaseImpl(engagementRepository = repository) - useCase(queueIds, mediaType, visitorContextAssetId) - - verify { repository.queueForEngagement(queueIds, Engagement.MediaType.TEXT, visitorContextAssetId) } - } - @Test fun `EnqueueForEngagementUseCase invoke enqueues with selected type engagement when media type is present`() { val repository: EngagementRepository = mockk(relaxUnitFun = true) val queueIds = listOf("queueId1", "queueId2") val mediaType: Engagement.MediaType = mockk(relaxUnitFun = true) - val visitorContextAssetId = null - val useCase: EnqueueForEngagementUseCase = EnqueueForEngagementUseCaseImpl(engagementRepository = repository) - useCase(queueIds, mediaType, visitorContextAssetId) + val configurationManager = mockk() + every { configurationManager.queueIds } returns queueIds + val useCase: EnqueueForEngagementUseCase = EnqueueForEngagementUseCaseImpl(engagementRepository = repository, configurationManager) + useCase(mediaType) - verify { repository.queueForEngagement(queueIds, mediaType, visitorContextAssetId) } + verify { repository.queueForEngagement(queueIds, mediaType) } } @Test @@ -523,12 +512,17 @@ class EngagementDomainTest { @Test fun `ScreenSharingUseCase test`() { + val mode = ScreenSharing.Mode.UNBOUNDED val engagementRepository: EngagementRepository = mockk(relaxUnitFun = true) val releaseScreenSharingResourcesUseCase: ReleaseScreenSharingResourcesUseCase = mockk(relaxUnitFun = true) + val configurationManager = mockk { + every { screenSharingMode } returns mode + } val useCase: ScreenSharingUseCase = ScreenSharingUseCaseImpl( engagementRepository = engagementRepository, - releaseScreenSharingResourcesUseCase = releaseScreenSharingResourcesUseCase + releaseScreenSharingResourcesUseCase = releaseScreenSharingResourcesUseCase, + configurationManager ) every { engagementRepository.isSharingScreen } returns true @@ -548,8 +542,7 @@ class EngagementDomainTest { verify { engagementRepository.declineScreenSharingRequest() } val activity: Activity = mockk(relaxUnitFun = true) - val mode: ScreenSharing.Mode = mockk(relaxUnitFun = true) - useCase.acceptRequestWithAskedPermission(activity, mode) + useCase.acceptRequestWithAskedPermission(activity) verify { engagementRepository.acceptScreenSharingWithAskedPermission(activity, mode) } val resultCode = 1 diff --git a/widgetssdk/src/test/java/com/glia/widgets/messagecenter/MessageCenterControllerTest.kt b/widgetssdk/src/test/java/com/glia/widgets/messagecenter/MessageCenterControllerTest.kt index c67141707..dce704eea 100644 --- a/widgetssdk/src/test/java/com/glia/widgets/messagecenter/MessageCenterControllerTest.kt +++ b/widgetssdk/src/test/java/com/glia/widgets/messagecenter/MessageCenterControllerTest.kt @@ -2,28 +2,25 @@ package com.glia.widgets.messagecenter import com.glia.androidsdk.GliaException import com.glia.androidsdk.RequestCallback -import com.glia.widgets.UiTheme import com.glia.widgets.chat.ChatType import com.glia.widgets.chat.domain.IsAuthenticatedUseCase import com.glia.widgets.chat.domain.SiteInfoUseCase import com.glia.widgets.chat.domain.TakePictureUseCase import com.glia.widgets.chat.domain.UriToFileAttachmentUseCase -import com.glia.widgets.core.configuration.EngagementConfiguration import com.glia.widgets.core.dialog.DialogContract import com.glia.widgets.core.engagement.domain.SetEngagementConfigUseCase import com.glia.widgets.core.fileupload.model.FileAttachment import com.glia.widgets.core.permissions.domain.RequestNotificationPermissionIfPushNotificationsSetUpUseCase import com.glia.widgets.core.secureconversations.domain.AddSecureFileAttachmentsObserverUseCase import com.glia.widgets.core.secureconversations.domain.AddSecureFileToAttachmentAndUploadUseCase +import com.glia.widgets.core.secureconversations.domain.GetAvailableQueueIdsForSecureMessagingUseCase import com.glia.widgets.core.secureconversations.domain.GetSecureFileAttachmentsUseCase import com.glia.widgets.core.secureconversations.domain.OnNextMessageUseCase import com.glia.widgets.core.secureconversations.domain.RemoveSecureFileAttachmentUseCase import com.glia.widgets.core.secureconversations.domain.ResetMessageCenterUseCase -import com.glia.widgets.core.secureconversations.domain.GetAvailableQueueIdsForSecureMessagingUseCase import com.glia.widgets.core.secureconversations.domain.SendMessageButtonStateUseCase import com.glia.widgets.core.secureconversations.domain.SendSecureMessageUseCase import com.glia.widgets.core.secureconversations.domain.ShowMessageLimitErrorUseCase -import com.glia.widgets.view.head.controller.ServiceChatHeadController import io.reactivex.rxjava3.core.Observable import org.junit.Before import org.junit.Test @@ -37,7 +34,6 @@ import org.mockito.kotlin.mock import org.mockito.kotlin.whenever internal class MessageCenterControllerTest { - private lateinit var serviceChatHeadController: ServiceChatHeadController private lateinit var messageCenterController: MessageCenterController private lateinit var engagementConfigUseCase: SetEngagementConfigUseCase private lateinit var sendSecureMessageUseCase: SendSecureMessageUseCase @@ -60,7 +56,6 @@ internal class MessageCenterControllerTest { @Before fun setUp() { - serviceChatHeadController = mock() engagementConfigUseCase = mock() sendSecureMessageUseCase = mock() getAvailableQueueIdsForSecureMessagingUseCase = mock() @@ -80,7 +75,6 @@ internal class MessageCenterControllerTest { uriToFileAttachmentUseCase = mock() requestNotificationPermissionIfPushNotificationsSetUpUseCase = mock() messageCenterController = MessageCenterController( - serviceChatHeadController = serviceChatHeadController, engagementConfigUseCase = engagementConfigUseCase, sendSecureMessageUseCase = sendSecureMessageUseCase, getAvailableQueueIdsForSecureMessagingUseCase = getAvailableQueueIdsForSecureMessagingUseCase, @@ -101,22 +95,6 @@ internal class MessageCenterControllerTest { ) } - @Test - fun setConfiguration_setBuildTimeTheme_onTrigger() { - val uiTheme = mock() - messageCenterController.setConfiguration(uiTheme, mock()) - - verify(serviceChatHeadController, times(1)).setBuildTimeTheme(uiTheme) - } - - @Test - fun setConfiguration_setEngagementConfiguration_onTrigger() { - val configuration = mock() - messageCenterController.setConfiguration(mock(), configuration) - - verify(serviceChatHeadController, times(1)).setEngagementConfiguration(configuration) - } - @Test fun initialize_ExecutesAddSecureFileAttachmentsObserverUseCase_onTrigger() { whenever(isAuthenticatedUseCase()) doReturn true @@ -275,7 +253,7 @@ internal class MessageCenterControllerTest { argumentCaptor.firstValue.onResult(availableQueueIds, null) - verify(engagementConfigUseCase, times(1)).invoke(ChatType.SECURE_MESSAGING, availableQueueIds) + verify(engagementConfigUseCase, times(1)).invoke(ChatType.SECURE_MESSAGING) } @Test diff --git a/widgetssdk/src/test/java/com/glia/widgets/operator/OperatorRequestActivityWatcherTest.kt b/widgetssdk/src/test/java/com/glia/widgets/operator/OperatorRequestActivityWatcherTest.kt index 350d995de..dacb425a6 100644 --- a/widgetssdk/src/test/java/com/glia/widgets/operator/OperatorRequestActivityWatcherTest.kt +++ b/widgetssdk/src/test/java/com/glia/widgets/operator/OperatorRequestActivityWatcherTest.kt @@ -133,7 +133,7 @@ class OperatorRequestActivityWatcherTest { ) { event, activity -> verify { event.consume(any()) } verify { gliaActivityManager.finishActivities() } - verify { activityLauncher.launchCall(any(), any()) } + verify { activityLauncher.launchCall(any(), any(), eq(true)) } confirmVerified(activity, event) } @@ -146,7 +146,7 @@ class OperatorRequestActivityWatcherTest { ) { event, activity -> verify { event.consume(any()) } verify(exactly = 0) { gliaActivityManager.finishActivities() } - verify { activityLauncher.launchCall(any(), any()) } + verify { activityLauncher.launchCall(any(), any(), eq(true)) } confirmVerified(activity, event) } @@ -159,7 +159,7 @@ class OperatorRequestActivityWatcherTest { ) { event, activity -> verify { event.consume(any()) } verify(exactly = 0) { gliaActivityManager.finishActivities() } - verify(exactly = 0) { activityLauncher.launchCall(any(), any()) } + verify(exactly = 0) { activityLauncher.launchCall(any(), any(), eq(true)) } confirmVerified(activity, event) } diff --git a/widgetssdk/src/test/java/com/glia/widgets/operator/OperatorRequestControllerTest.kt b/widgetssdk/src/test/java/com/glia/widgets/operator/OperatorRequestControllerTest.kt index a57f039c4..2d5047904 100644 --- a/widgetssdk/src/test/java/com/glia/widgets/operator/OperatorRequestControllerTest.kt +++ b/widgetssdk/src/test/java/com/glia/widgets/operator/OperatorRequestControllerTest.kt @@ -8,7 +8,6 @@ import androidx.activity.result.ActivityResult import com.glia.androidsdk.Engagement import com.glia.androidsdk.comms.MediaUpgradeOffer import com.glia.widgets.chat.ChatActivity -import com.glia.widgets.core.configuration.GliaSdkConfigurationManager import com.glia.widgets.core.dialog.DialogContract import com.glia.widgets.core.dialog.domain.IsShowOverlayPermissionRequestDialogUseCase import com.glia.widgets.core.dialog.domain.SetOverlayPermissionRequestDialogShownUseCase @@ -62,7 +61,6 @@ class OperatorRequestControllerTest { private lateinit var setOverlayPermissionRequestDialogShownUseCase: SetOverlayPermissionRequestDialogShownUseCase private lateinit var dialogController: DialogContract.Controller private lateinit var dialogCallbackSlot: CapturingSlot - private lateinit var gliaSdkConfigurationManager: GliaSdkConfigurationManager private lateinit var withNotificationPermissionUseCase: WithNotificationPermissionUseCase private lateinit var prepareToScreenSharingUseCase: PrepareToScreenSharingUseCase private lateinit var releaseScreenSharingResourcesUseCase: ReleaseScreenSharingResourcesUseCase @@ -93,8 +91,6 @@ class OperatorRequestControllerTest { dialogCallbackSlot = slot() - gliaSdkConfigurationManager = mockk(relaxed = true) - controller = OperatorRequestController( operatorMediaUpgradeOfferUseCase, acceptMediaUpgradeOfferUseCase, @@ -106,7 +102,6 @@ class OperatorRequestControllerTest { isCurrentEngagementCallVisualizerUseCase, setOverlayPermissionRequestDialogShownUseCase, dialogController, - gliaSdkConfigurationManager, withNotificationPermissionUseCase, prepareToScreenSharingUseCase, releaseScreenSharingResourcesUseCase @@ -308,20 +303,17 @@ class OperatorRequestControllerTest { verify { withNotificationPermissionUseCase(capture(callbackSlot)) } - verify(exactly = 0) { gliaSdkConfigurationManager.screenSharingMode } - verify(exactly = 0) { screenSharingUseCase.acceptRequestWithAskedPermission(eq(activity), any()) } + verify(exactly = 0) { screenSharingUseCase.acceptRequestWithAskedPermission(eq(activity)) } state.assertNotComplete().assertNoValues() callbackSlot.captured.invoke() - verify { gliaSdkConfigurationManager.screenSharingMode } - verify { screenSharingUseCase.acceptRequestWithAskedPermission(eq(activity), any()) } + verify { screenSharingUseCase.acceptRequestWithAskedPermission(eq(activity)) } state.assertNotComplete().assertValue { it.value == OperatorRequestContract.State.AcquireMediaProjectionToken } confirmVerified( releaseScreenSharingResourcesUseCase, prepareToScreenSharingUseCase, screenSharingUseCase, - gliaSdkConfigurationManager, withNotificationPermissionUseCase ) } diff --git a/widgetssdk/src/testSnapshot/java/com/glia/widgets/call/CallViewVideoSnapshotTest.kt b/widgetssdk/src/testSnapshot/java/com/glia/widgets/call/CallViewVideoSnapshotTest.kt index b8ccd0a55..aa7190b9e 100644 --- a/widgetssdk/src/testSnapshot/java/com/glia/widgets/call/CallViewVideoSnapshotTest.kt +++ b/widgetssdk/src/testSnapshot/java/com/glia/widgets/call/CallViewVideoSnapshotTest.kt @@ -12,8 +12,7 @@ internal class CallViewVideoSnapshotTest : SnapshotTest( // MARK: Init call - private fun initCallState() = callState() - .initCall(requestedMediaType = Engagement.MediaType.VIDEO) + private fun initCallState() = callState().initCall(requestedMediaType = Engagement.MediaType.VIDEO) @Test fun initCall() { diff --git a/widgetssdk/src/testSnapshot/java/com/glia/widgets/call/SnapshotCallView.kt b/widgetssdk/src/testSnapshot/java/com/glia/widgets/call/SnapshotCallView.kt index 6ba95af98..94702678c 100644 --- a/widgetssdk/src/testSnapshot/java/com/glia/widgets/call/SnapshotCallView.kt +++ b/widgetssdk/src/testSnapshot/java/com/glia/widgets/call/SnapshotCallView.kt @@ -22,6 +22,7 @@ import com.glia.widgets.snapshotutils.SnapshotLottie import com.glia.widgets.snapshotutils.SnapshotProviders import com.glia.widgets.snapshotutils.SnapshotSchedulers import com.glia.widgets.snapshotutils.SnapshotTheme +import com.glia.widgets.snapshotutils.SnapshotThemeConfiguration import com.glia.widgets.view.floatingvisitorvideoview.FloatingVisitorVideoContract.FlipButtonState import com.glia.widgets.view.unifiedui.theme.UnifiedTheme import com.google.gson.JsonObject @@ -36,7 +37,7 @@ import java.util.concurrent.Executor // TODO: move to com.glia.widgets.snapshotutils after CallState refactored @Suppress("EXTENSION_SHADOWED_BY_MEMBER") internal interface SnapshotCallView : SnapshotContent, SnapshotTheme, SnapshotActivityWindow, - SnapshotProviders, SnapshotSchedulers, SnapshotLottie { + SnapshotProviders, SnapshotSchedulers, SnapshotLottie, SnapshotThemeConfiguration { data class Mock( val activityMock: SnapshotActivityWindow.Mock, @@ -58,10 +59,6 @@ internal interface SnapshotCallView : SnapshotContent, SnapshotTheme, SnapshotAc whenever(controllerFactoryMock.callController).thenReturn(callControllerMock) Dependencies.controllerFactory = controllerFactoryMock -// setOnEndListener { -// Dependencies.controllerFactory = null -// } - return Mock(activityMock, schedulersMock, controllerFactoryMock, callControllerMock) } @@ -73,17 +70,14 @@ internal interface SnapshotCallView : SnapshotContent, SnapshotTheme, SnapshotAc fun setupView( callState: CallState? = null, - companyName: String? = "SnapshotCall Tests", executor: Executor? = Executor(Runnable::run), unifiedTheme: UnifiedTheme? = null, uiTheme: UiTheme? = null, callViewCallback: ((CallContract.View, callState: CallState?) -> Unit)? = null ): ViewData { + setGlobalThemes(uiTheme, unifiedTheme) val mock = callViewMock() - unifiedTheme?.let { Dependencies.gliaThemeManager.theme = it } - Dependencies.sdkConfigurationManager.companyName = companyName - val callViewCaptor: KArgumentCaptor = argumentCaptor() val callActivityBinding = CallActivityBinding.inflate(layoutInflater) @@ -91,19 +85,11 @@ internal interface SnapshotCallView : SnapshotContent, SnapshotTheme, SnapshotAc val callView = callActivityBinding.callView verify(mock.callControllerMock).setView(callViewCaptor.capture()) - callView.setUiTheme(uiTheme) - callView.executor = executor val callViewContract = callViewCaptor.lastValue callState?.let { callViewContract.emitState(it) } callViewCallback?.invoke(callViewContract, callState) - - setOnEndListener { - Dependencies.gliaThemeManager.theme = null - Dependencies.sdkConfigurationManager.companyName = null - } - return ViewData(root, callView, mock) } @@ -160,6 +146,7 @@ internal interface SnapshotCallView : SnapshotContent, SnapshotTheme, SnapshotAc ) = mock