diff --git a/CHANGELOG.md b/CHANGELOG.md index d664cc37..b446e3a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,16 @@ # Changelog +### v3.14.0 (Mar 19, 2024) with Chat SDK `v4.15.6` +* A feedback feature has been added to give opinions on the message. + * Added `setEmptyIcon(int)`, `setEmptyIcon(int, ColorStateList)`, `setEmptyText(int)`, and `setErrorText(int)` in `ChatNotificationChannelFragment`. + * Added `setEmptyIcon(int)`, `setEmptyIcon(int, ColorStateList)`, `setEmptyText(int)`, and `setErrorText(int)` in `FeedNotificationChannelFragment`. +* Simple example for creating `FeedNotificationChannelFragment` with empty icon and text. +```kotlin +val feedChannelFragment = FeedNotificationChannelFragment.Builder(channelUrl) + .withArguments(args) + .setEmptyIcon(R.drawable.icon_empty) + .setEmptyText(R.string.text_empty_notification) + .build() +``` ### v3.13.0 (Feb 1, 2024) with Chat SDK `v4.14.2` * A feedback feature has been added to give opinions on the message. * Added `enableFeedback` in `ChannelConfig`. diff --git a/gradle.properties b/gradle.properties index 5e6ef987..c8ede4fc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,5 +16,5 @@ org.gradle.jvmargs=-Xmx1536m # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true -UIKIT_VERSION = 3.13.0 +UIKIT_VERSION = 3.14.0 UIKIT_VERSION_CODE = 1 diff --git a/uikit-samples/src/main/java/com/sendbird/uikit/samples/notification/NotificationHomeActivity.kt b/uikit-samples/src/main/java/com/sendbird/uikit/samples/notification/NotificationHomeActivity.kt index 79dd1b85..fbced08a 100644 --- a/uikit-samples/src/main/java/com/sendbird/uikit/samples/notification/NotificationHomeActivity.kt +++ b/uikit-samples/src/main/java/com/sendbird/uikit/samples/notification/NotificationHomeActivity.kt @@ -3,8 +3,6 @@ package com.sendbird.uikit.samples.notification import android.content.Intent import android.os.Bundle import android.view.View -import androidx.appcompat.app.AppCompatActivity -import androidx.viewbinding.ViewBinding import com.sendbird.uikit.activities.FeedNotificationChannelActivity import com.sendbird.uikit.samples.R import com.sendbird.uikit.samples.common.ThemeHomeActivity diff --git a/uikit/build.gradle b/uikit/build.gradle index 7e212fa6..745f51e2 100644 --- a/uikit/build.gradle +++ b/uikit/build.gradle @@ -64,7 +64,7 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) // Sendbird - api 'com.sendbird.sdk:sendbird-chat:4.14.2' + api 'com.sendbird.sdk:sendbird-chat:4.15.6' implementation 'com.github.bumptech.glide:glide:4.13.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.13.0' diff --git a/uikit/internal.gradle b/uikit/internal.gradle index 5cb5970e..0ae6bd5b 100644 --- a/uikit/internal.gradle +++ b/uikit/internal.gradle @@ -42,6 +42,7 @@ dependencies { testImplementation "io.mockk:mockk:1.13.4" testImplementation 'androidx.arch.core:core-testing:2.2.0' testImplementation "org.jetbrains.kotlin:kotlin-reflect:1.8.20" + testImplementation("pl.pragmatists:JUnitParams:1.1.0") } tasks.register("ktlintCheck", JavaExec) { diff --git a/uikit/src/main/java/com/sendbird/uikit/SendbirdUIKit.java b/uikit/src/main/java/com/sendbird/uikit/SendbirdUIKit.java index b0297bb3..ca52e2d9 100644 --- a/uikit/src/main/java/com/sendbird/uikit/SendbirdUIKit.java +++ b/uikit/src/main/java/com/sendbird/uikit/SendbirdUIKit.java @@ -47,10 +47,10 @@ import com.sendbird.uikit.internal.singleton.NotificationChannelManager; import com.sendbird.uikit.internal.singleton.UIKitConfigRepository; import com.sendbird.uikit.internal.tasks.JobResultTask; -import com.sendbird.uikit.internal.wrappers.SendbirdChatImpl; -import com.sendbird.uikit.internal.wrappers.SendbirdChatWrapper; -import com.sendbird.uikit.internal.wrappers.TaskQueueImpl; -import com.sendbird.uikit.internal.wrappers.TaskQueueWrapper; +import com.sendbird.uikit.internal.contracts.SendbirdChatImpl; +import com.sendbird.uikit.internal.contracts.SendbirdChatContract; +import com.sendbird.uikit.internal.contracts.TaskQueueImpl; +import com.sendbird.uikit.internal.contracts.TaskQueueContract; import com.sendbird.uikit.log.Logger; import com.sendbird.uikit.model.EmojiManager; import com.sendbird.uikit.model.UserMentionConfig; @@ -269,7 +269,7 @@ public synchronized static void initFromForeground(@NonNull SendbirdUIKitAdapter @VisibleForTesting synchronized static void init( - @NonNull SendbirdChatWrapper sendbirdChatWrapper, + @NonNull SendbirdChatContract sendbirdChatContract, @NonNull SendbirdUIKitAdapter adapter, @NonNull UIKitConfigRepository uikitConfigRepo, @NonNull Context context, @@ -296,7 +296,7 @@ public void onInitFailed(@NonNull SendbirdException e) { public void onInitSucceed() { Logger.d(">> onInitSucceed()"); try { - sendbirdChatWrapper.addExtension(StringSet.sb_uikit, BuildConfig.VERSION_NAME); + sendbirdChatContract.addExtension(StringSet.sb_uikit, BuildConfig.VERSION_NAME); } catch (Throwable ignored) { } try { @@ -305,7 +305,7 @@ public void onInitSucceed() { SendbirdPlatform.ANDROID, BuildConfig.VERSION_NAME ); - sendbirdChatWrapper.addSendbirdExtensions(Collections.singletonList(o), null); + sendbirdChatContract.addSendbirdExtensions(Collections.singletonList(o), null); } catch (Throwable ignored) { } @@ -316,7 +316,7 @@ public void onInitSucceed() { final com.sendbird.android.LogLevel logLevel = BuildConfig.DEBUG ? com.sendbird.android.LogLevel.VERBOSE : com.sendbird.android.LogLevel.WARN; // useCaching=true is required for UIKit final InitParams initParams = new InitParams(adapter.getAppId(), context, true, logLevel, isForeground); - sendbirdChatWrapper.init(initParams, initResultHandler); + sendbirdChatContract.init(initParams, initResultHandler); FileUtils.removeDeletableDir(context.getApplicationContext()); UIKitPrefs.init(context.getApplicationContext()); NotificationChannelManager.init(context.getApplicationContext()); @@ -564,18 +564,18 @@ private enum ConnectType { } @VisibleForTesting - static void connectInternal(@NonNull SendbirdChatWrapper sendbirdChat, - @NonNull TaskQueueWrapper taskQueueWrapper, + static void connectInternal(@NonNull SendbirdChatContract sendbirdChat, + @NonNull TaskQueueContract taskQueueContract, @Nullable ConnectHandler handler) { - connectInternal(ConnectType.CONNECT, sendbirdChat, taskQueueWrapper, handler); + connectInternal(ConnectType.CONNECT, sendbirdChat, taskQueueContract, handler); } private static void connectInternal( @NonNull ConnectType connectType, - @NonNull SendbirdChatWrapper sendbirdChat, - @NonNull TaskQueueWrapper taskQueueWrapper, + @NonNull SendbirdChatContract sendbirdChat, + @NonNull TaskQueueContract taskQueueContract, @Nullable ConnectHandler handler) { - taskQueueWrapper.addTask(new JobResultTask>() { + taskQueueContract.addTask(new JobResultTask>() { @Override public Pair call() throws Exception { final Pair data; @@ -654,7 +654,7 @@ public void onResultForUiThread(@Nullable Pair data, @N } @NonNull - private static Pair connectBlocking(@NonNull SendbirdChatWrapper sendbirdChat) throws InterruptedException { + private static Pair connectBlocking(@NonNull SendbirdChatContract sendbirdChat) throws InterruptedException { AtomicReference result = new AtomicReference<>(); AtomicReference error = new AtomicReference<>(); CountDownLatch latch = new CountDownLatch(1); @@ -675,7 +675,7 @@ private static Pair connectBlocking(@NonNull SendbirdCh } @NonNull - private static Pair authenticateFeedBlocking(@NonNull SendbirdChatWrapper sendbirdChat) throws InterruptedException { + private static Pair authenticateFeedBlocking(@NonNull SendbirdChatContract sendbirdChat) throws InterruptedException { AtomicReference result = new AtomicReference<>(); AtomicReference error = new AtomicReference<>(); CountDownLatch latch = new CountDownLatch(1); @@ -719,10 +719,10 @@ public static void updateUserInfo(@NonNull UserUpdateParams params, @Nullable Co SendbirdChat.updateCurrentUserInfo(params, handler); } - private static void updateUserInfoBlocking(@NonNull SendbirdChatWrapper sendbirdChatWrapper, @NonNull UserUpdateParams params) throws SendbirdException, InterruptedException { + private static void updateUserInfoBlocking(@NonNull SendbirdChatContract sendbirdChatContract, @NonNull UserUpdateParams params) throws SendbirdException, InterruptedException { CountDownLatch latch = new CountDownLatch(1); AtomicReference error = new AtomicReference<>(); - sendbirdChatWrapper.updateCurrentUserInfo(params, e -> { + sendbirdChatContract.updateCurrentUserInfo(params, e -> { if (e != null) error.set(e); latch.countDown(); }); diff --git a/uikit/src/main/java/com/sendbird/uikit/activities/adapter/BaseMessageListAdapter.java b/uikit/src/main/java/com/sendbird/uikit/activities/adapter/BaseMessageListAdapter.java index f0913d02..e5fffab3 100644 --- a/uikit/src/main/java/com/sendbird/uikit/activities/adapter/BaseMessageListAdapter.java +++ b/uikit/src/main/java/com/sendbird/uikit/activities/adapter/BaseMessageListAdapter.java @@ -35,8 +35,8 @@ import com.sendbird.uikit.internal.singleton.MessageDisplayDataManager; import com.sendbird.uikit.internal.ui.viewholders.MyUserMessageViewHolder; import com.sendbird.uikit.internal.ui.viewholders.OtherUserMessageViewHolder; -import com.sendbird.uikit.internal.wrappers.SendbirdUIKitImpl; -import com.sendbird.uikit.internal.wrappers.SendbirdUIKitWrapper; +import com.sendbird.uikit.internal.contracts.SendbirdUIKitImpl; +import com.sendbird.uikit.internal.contracts.SendbirdUIKitContract; import com.sendbird.uikit.log.Logger; import com.sendbird.uikit.model.MessageListUIParams; import com.sendbird.uikit.model.MessageUIConfig; @@ -86,7 +86,7 @@ abstract public class BaseMessageListAdapter extends BaseMessageAdapter> FeedNotificationChannelFragment::onBindFeedNotificationListComponent()"); listComponent.setOnMessageTemplateActionHandler(actionHandler != null ? actionHandler : this::handleAction); listComponent.setOnTooltipClickListener(v -> listComponent.scrollToFirst()); - listComponent.setOnImpressionDetectedListener(viewModel::sendLogImpression); + listComponent.setOnNotificationViewedDetectedListener(viewModel::sendLogImpression); listComponent.setOnNotificationCategorySelectListener(category -> { Logger.d("++ selected category = %s", category); listComponent.clearData(); @@ -416,6 +419,59 @@ public Builder setNotificationListParams(@NonNull MessageListParams params) { return this; } + /** + * Sets the icon when the data is not exists. + * + * @param resId the resource identifier of the drawable. + * @return This Builder object to allow for chaining of calls to set methods. + * since 3.14.0 + */ + @NonNull + public Builder setEmptyIcon(@DrawableRes int resId) { + return setEmptyIcon(resId, null); + } + + /** + * Sets the icon when the data is not exists. + * + * @param resId the resource identifier of the drawable. + * @param tint Color state list to use for tinting this resource, or null to clear the tint. + * @return This Builder object to allow for chaining of calls to set methods. + * since 3.14.0 + */ + @NonNull + public Builder setEmptyIcon(@DrawableRes int resId, @Nullable ColorStateList tint) { + bundle.putInt(StringSet.KEY_EMPTY_ICON_RES_ID, resId); + bundle.putParcelable(StringSet.KEY_EMPTY_ICON_TINT, tint); + return this; + } + + /** + * Sets the text when the data is not exists + * + * @param resId the resource identifier of text to be displayed. + * @return This Builder object to allow for chaining of calls to set methods. + * since 3.14.0 + */ + @NonNull + public Builder setEmptyText(@StringRes int resId) { + bundle.putInt(StringSet.KEY_EMPTY_TEXT_RES_ID, resId); + return this; + } + + /** + * Sets the text when error occurs + * + * @param resId the resource identifier of text to be displayed. + * @return This Builder object to allow for chaining of calls to set methods. + * since 3.14.0 + */ + @NonNull + public Builder setErrorText(@StringRes int resId) { + bundle.putInt(StringSet.KEY_ERROR_TEXT_RES_ID, resId); + return this; + } + /** * Creates an {@link FeedNotificationChannelFragment} with the arguments supplied to this * builder. diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/GroupChannelCollectionWrapper.kt b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/GroupChannelCollectionContract.kt similarity index 80% rename from uikit/src/main/java/com/sendbird/uikit/internal/wrappers/GroupChannelCollectionWrapper.kt rename to uikit/src/main/java/com/sendbird/uikit/internal/contracts/GroupChannelCollectionContract.kt index 1ebc1ba5..e5f9a24a 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/GroupChannelCollectionWrapper.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/GroupChannelCollectionContract.kt @@ -1,10 +1,10 @@ -package com.sendbird.uikit.internal.wrappers +package com.sendbird.uikit.internal.contracts import com.sendbird.android.channel.GroupChannel import com.sendbird.android.handler.GroupChannelCollectionHandler import com.sendbird.android.handler.GroupChannelsCallbackHandler -internal interface GroupChannelCollectionWrapper { +internal interface GroupChannelCollectionContract { fun setGroupChannelCollectionHandler(handler: GroupChannelCollectionHandler?) fun loadMore(handler: GroupChannelsCallbackHandler) fun getChannelList(): List diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/GroupChannelCollectionImpl.kt b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/GroupChannelCollectionImpl.kt similarity index 92% rename from uikit/src/main/java/com/sendbird/uikit/internal/wrappers/GroupChannelCollectionImpl.kt rename to uikit/src/main/java/com/sendbird/uikit/internal/contracts/GroupChannelCollectionImpl.kt index d6f8c76b..3f1c4e4d 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/GroupChannelCollectionImpl.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/GroupChannelCollectionImpl.kt @@ -1,4 +1,4 @@ -package com.sendbird.uikit.internal.wrappers +package com.sendbird.uikit.internal.contracts import com.sendbird.android.SendbirdChat.createGroupChannelCollection import com.sendbird.android.channel.GroupChannel @@ -8,7 +8,7 @@ import com.sendbird.android.handler.GroupChannelCollectionHandler import com.sendbird.android.handler.GroupChannelsCallbackHandler import com.sendbird.android.params.GroupChannelCollectionCreateParams -internal class GroupChannelCollectionImpl(query: GroupChannelListQuery) : GroupChannelCollectionWrapper { +internal class GroupChannelCollectionImpl(query: GroupChannelListQuery) : GroupChannelCollectionContract { private val collection: GroupChannelCollection init { diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/MessageCollectionWrapper.kt b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/MessageCollectionContract.kt similarity index 91% rename from uikit/src/main/java/com/sendbird/uikit/internal/wrappers/MessageCollectionWrapper.kt rename to uikit/src/main/java/com/sendbird/uikit/internal/contracts/MessageCollectionContract.kt index fde369cf..cbc88fc6 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/MessageCollectionWrapper.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/MessageCollectionContract.kt @@ -1,4 +1,4 @@ -package com.sendbird.uikit.internal.wrappers +package com.sendbird.uikit.internal.contracts import com.sendbird.android.collection.MessageCollectionInitPolicy import com.sendbird.android.handler.BaseMessagesHandler @@ -7,7 +7,7 @@ import com.sendbird.android.handler.MessageCollectionInitHandler import com.sendbird.android.handler.RemoveFailedMessagesHandler import com.sendbird.android.message.BaseMessage -internal interface MessageCollectionWrapper { +internal interface MessageCollectionContract { fun initialize(initPolicy: MessageCollectionInitPolicy, handler: MessageCollectionInitHandler?) fun loadPrevious(handler: BaseMessagesHandler?) fun loadNext(handler: BaseMessagesHandler?) diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/MessageCollectionImpl.kt b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/MessageCollectionImpl.kt similarity index 94% rename from uikit/src/main/java/com/sendbird/uikit/internal/wrappers/MessageCollectionImpl.kt rename to uikit/src/main/java/com/sendbird/uikit/internal/contracts/MessageCollectionImpl.kt index 19666443..adeebca5 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/MessageCollectionImpl.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/MessageCollectionImpl.kt @@ -1,4 +1,4 @@ -package com.sendbird.uikit.internal.wrappers +package com.sendbird.uikit.internal.contracts import com.sendbird.android.collection.MessageCollection import com.sendbird.android.collection.MessageCollectionInitPolicy @@ -8,7 +8,7 @@ import com.sendbird.android.handler.MessageCollectionInitHandler import com.sendbird.android.handler.RemoveFailedMessagesHandler import com.sendbird.android.message.BaseMessage -internal class MessageCollectionImpl(private val collection: MessageCollection) : MessageCollectionWrapper { +internal class MessageCollectionImpl(private val collection: MessageCollection) : MessageCollectionContract { override fun initialize(initPolicy: MessageCollectionInitPolicy, handler: MessageCollectionInitHandler?) { collection.initialize(initPolicy, handler) } diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/SendbirdChatWrapper.kt b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/SendbirdChatContract.kt similarity index 94% rename from uikit/src/main/java/com/sendbird/uikit/internal/wrappers/SendbirdChatWrapper.kt rename to uikit/src/main/java/com/sendbird/uikit/internal/contracts/SendbirdChatContract.kt index 3e8cb90d..b6c1c879 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/SendbirdChatWrapper.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/SendbirdChatContract.kt @@ -1,4 +1,4 @@ -package com.sendbird.uikit.internal.wrappers +package com.sendbird.uikit.internal.contracts import com.sendbird.android.AppInfo import com.sendbird.android.ConnectionState @@ -13,7 +13,7 @@ import com.sendbird.android.internal.sb.SendbirdSdkInfo import com.sendbird.android.params.InitParams import com.sendbird.android.params.UserUpdateParams -internal interface SendbirdChatWrapper { +internal interface SendbirdChatContract { fun addChannelHandler(identifier: String, handler: BaseChannelHandler) fun addConnectionHandler(identifier: String, handler: ConnectionHandler) fun removeChannelHandler(identifier: String): BaseChannelHandler? diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/SendbirdChatImpl.kt b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/SendbirdChatImpl.kt similarity index 96% rename from uikit/src/main/java/com/sendbird/uikit/internal/wrappers/SendbirdChatImpl.kt rename to uikit/src/main/java/com/sendbird/uikit/internal/contracts/SendbirdChatImpl.kt index 651a71e1..abc3d41e 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/SendbirdChatImpl.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/SendbirdChatImpl.kt @@ -1,4 +1,4 @@ -package com.sendbird.uikit.internal.wrappers +package com.sendbird.uikit.internal.contracts import com.sendbird.android.AppInfo import com.sendbird.android.ConnectionState @@ -14,7 +14,7 @@ import com.sendbird.android.internal.sb.SendbirdSdkInfo import com.sendbird.android.params.InitParams import com.sendbird.android.params.UserUpdateParams -internal class SendbirdChatImpl : SendbirdChatWrapper { +internal class SendbirdChatImpl : SendbirdChatContract { override fun addChannelHandler(identifier: String, handler: BaseChannelHandler) { SendbirdChat.addChannelHandler(identifier, handler) } diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/SendbirdUIKitWrapper.kt b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/SendbirdUIKitContract.kt similarity index 60% rename from uikit/src/main/java/com/sendbird/uikit/internal/wrappers/SendbirdUIKitWrapper.kt rename to uikit/src/main/java/com/sendbird/uikit/internal/contracts/SendbirdUIKitContract.kt index 4c8512dc..29b3f3a8 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/SendbirdUIKitWrapper.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/SendbirdUIKitContract.kt @@ -1,8 +1,8 @@ -package com.sendbird.uikit.internal.wrappers +package com.sendbird.uikit.internal.contracts import com.sendbird.android.handler.ConnectHandler -internal interface SendbirdUIKitWrapper { +internal interface SendbirdUIKitContract { fun connect(handler: ConnectHandler?) fun runOnUIThread(runnable: Runnable) } diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/SendbirdUIKitImpl.kt b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/SendbirdUIKitImpl.kt similarity index 74% rename from uikit/src/main/java/com/sendbird/uikit/internal/wrappers/SendbirdUIKitImpl.kt rename to uikit/src/main/java/com/sendbird/uikit/internal/contracts/SendbirdUIKitImpl.kt index 7564e7be..ee62bfdb 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/SendbirdUIKitImpl.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/SendbirdUIKitImpl.kt @@ -1,9 +1,9 @@ -package com.sendbird.uikit.internal.wrappers +package com.sendbird.uikit.internal.contracts import com.sendbird.android.handler.ConnectHandler import com.sendbird.uikit.SendbirdUIKit -internal class SendbirdUIKitImpl : SendbirdUIKitWrapper { +internal class SendbirdUIKitImpl : SendbirdUIKitContract { override fun connect(handler: ConnectHandler?) { SendbirdUIKit.connect(handler) } diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/TaskQueueWrapper.kt b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/TaskQueueContract.kt similarity index 74% rename from uikit/src/main/java/com/sendbird/uikit/internal/wrappers/TaskQueueWrapper.kt rename to uikit/src/main/java/com/sendbird/uikit/internal/contracts/TaskQueueContract.kt index fb419e82..faf3c7ca 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/TaskQueueWrapper.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/TaskQueueContract.kt @@ -1,10 +1,10 @@ -package com.sendbird.uikit.internal.wrappers +package com.sendbird.uikit.internal.contracts import com.sendbird.uikit.internal.tasks.JobResultTask import com.sendbird.uikit.internal.tasks.JobTask import java.util.concurrent.Future -internal interface TaskQueueWrapper { +internal interface TaskQueueContract { fun addTask(task: JobTask): Future fun addTask(task: JobResultTask): Future } diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/TaskQueueImpl.kt b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/TaskQueueImpl.kt similarity index 80% rename from uikit/src/main/java/com/sendbird/uikit/internal/wrappers/TaskQueueImpl.kt rename to uikit/src/main/java/com/sendbird/uikit/internal/contracts/TaskQueueImpl.kt index acb1d419..6bfcc6e2 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/wrappers/TaskQueueImpl.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/contracts/TaskQueueImpl.kt @@ -1,11 +1,11 @@ -package com.sendbird.uikit.internal.wrappers +package com.sendbird.uikit.internal.contracts import com.sendbird.uikit.internal.tasks.JobResultTask import com.sendbird.uikit.internal.tasks.JobTask import com.sendbird.uikit.internal.tasks.TaskQueue import java.util.concurrent.Future -internal class TaskQueueImpl : TaskQueueWrapper { +internal class TaskQueueImpl : TaskQueueContract { override fun addTask(task: JobTask): Future { return TaskQueue.addTask(task) } diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/extensions/ChannelExtensions.kt b/uikit/src/main/java/com/sendbird/uikit/internal/extensions/ChannelExtensions.kt new file mode 100644 index 00000000..2c02101b --- /dev/null +++ b/uikit/src/main/java/com/sendbird/uikit/internal/extensions/ChannelExtensions.kt @@ -0,0 +1,9 @@ +package com.sendbird.uikit.internal.extensions + +import com.sendbird.android.channel.GroupChannel +import com.sendbird.uikit.consts.StringSet +import com.sendbird.uikit.model.configurations.ChannelConfig + +internal fun GroupChannel.shouldDisableInput(channelConfig: ChannelConfig): Boolean { + return channelConfig.enableSuggestedReplies && this.lastMessage?.extendedMessagePayload?.get(StringSet.disable_chat_input) == true.toString() +} diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/interfaces/OnImpressionDetectedListener.kt b/uikit/src/main/java/com/sendbird/uikit/internal/interfaces/OnImpressionDetectedListener.kt deleted file mode 100644 index e0f1891c..00000000 --- a/uikit/src/main/java/com/sendbird/uikit/internal/interfaces/OnImpressionDetectedListener.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.sendbird.uikit.internal.interfaces - -/** - * On visible item detect listener - */ -@JvmSuppressWildcards -internal fun interface OnImpressionDetectedListener { - fun onImpressionDetected(items: List) -} diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/interfaces/OnNotificationViewedDetectedListener.kt b/uikit/src/main/java/com/sendbird/uikit/internal/interfaces/OnNotificationViewedDetectedListener.kt new file mode 100644 index 00000000..56b1f80b --- /dev/null +++ b/uikit/src/main/java/com/sendbird/uikit/internal/interfaces/OnNotificationViewedDetectedListener.kt @@ -0,0 +1,9 @@ +package com.sendbird.uikit.internal.interfaces + +/** + * On visible item detect listener + */ +@JvmSuppressWildcards +internal fun interface OnNotificationViewedDetectedListener { + fun onNotificationViewedDetected(items: List) +} diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/model/notifications/NotificationConfig.kt b/uikit/src/main/java/com/sendbird/uikit/internal/model/notifications/NotificationConfig.kt index 1d948aec..3fbe7c14 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/model/notifications/NotificationConfig.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/model/notifications/NotificationConfig.kt @@ -1,13 +1,9 @@ package com.sendbird.uikit.internal.model.notifications -import com.sendbird.uikit.interfaces.OnNotificationTemplateActionHandler - internal class NotificationConfig( val themeMode: NotificationThemeMode, val theme: NotificationChannelTheme ) { - var onMessageTemplateActionHandler: OnNotificationTemplateActionHandler? = null - companion object { @JvmStatic fun from(notificationChannelSettings: NotificationChannelSettings?): NotificationConfig? { diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/model/template_messages/KeySet.kt b/uikit/src/main/java/com/sendbird/uikit/internal/model/template_messages/KeySet.kt index 0e21b8a6..43c63c67 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/model/template_messages/KeySet.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/model/template_messages/KeySet.kt @@ -120,4 +120,5 @@ internal object KeySet { const val clicked = "clicked" const val channel_url = "channel_url" const val message_ts = "message_ts" + const val notification_event_deadline = "notification_event_deadline" } diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/singleton/UIKitConfigRepository.kt b/uikit/src/main/java/com/sendbird/uikit/internal/singleton/UIKitConfigRepository.kt index c3b467c9..e43646ed 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/singleton/UIKitConfigRepository.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/singleton/UIKitConfigRepository.kt @@ -4,7 +4,7 @@ import android.content.Context import androidx.annotation.VisibleForTesting import com.sendbird.android.config.UIKitConfigInfo import com.sendbird.android.exception.SendbirdException -import com.sendbird.uikit.internal.wrappers.SendbirdChatWrapper +import com.sendbird.uikit.internal.contracts.SendbirdChatContract import com.sendbird.uikit.model.configurations.Configurations import com.sendbird.uikit.model.configurations.UIKitConfig import com.sendbird.uikit.model.configurations.UIKitConfigurations @@ -52,7 +52,7 @@ internal class UIKitConfigRepository constructor( @Synchronized @Throws(SendbirdException::class) fun requestConfigurationsBlocking( - sendbirdChatWrapper: SendbirdChatWrapper, + sendbirdChatContract: SendbirdChatContract, uikitConfigInfo: UIKitConfigInfo ): UIKitConfigurations { val shouldInitUIKitConfig = isFirstRequestConfig.getAndSet(false) @@ -60,7 +60,7 @@ internal class UIKitConfigRepository constructor( val lock = CountDownLatch(1) val config = AtomicReference() val error = AtomicReference() - sendbirdChatWrapper.getUIKitConfiguration { uikitConfiguration, e -> + sendbirdChatContract.getUIKitConfiguration { uikitConfiguration, e -> try { if (e != null) { error.set(e) diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/testmodel/ChannelListViewModelDataContract.kt b/uikit/src/main/java/com/sendbird/uikit/internal/testmodel/ChannelListViewModelDataContract.kt new file mode 100644 index 00000000..da0ef0f7 --- /dev/null +++ b/uikit/src/main/java/com/sendbird/uikit/internal/testmodel/ChannelListViewModelDataContract.kt @@ -0,0 +1,20 @@ +package com.sendbird.uikit.internal.testmodel + +import androidx.lifecycle.MutableLiveData +import com.sendbird.android.channel.GroupChannel +import com.sendbird.android.channel.query.GroupChannelListQuery +import com.sendbird.android.handler.GroupChannelCollectionHandler +import com.sendbird.uikit.internal.contracts.GroupChannelCollectionContract +import com.sendbird.uikit.internal.contracts.SendbirdUIKitContract +import com.sendbird.uikit.internal.contracts.TaskQueueContract + +internal interface ViewModelDataContract + +internal interface ChannelListViewModelDataContract : ViewModelDataContract { + val sendbirdUIKit: SendbirdUIKitContract + var collection: GroupChannelCollectionContract? + val query: GroupChannelListQuery + val channelList: MutableLiveData> + val collectionHandler: GroupChannelCollectionHandler + val taskQueue: TaskQueueContract +} diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/ui/messages/BaseNotificationView.kt b/uikit/src/main/java/com/sendbird/uikit/internal/ui/messages/BaseNotificationView.kt index 6f9862cf..3c01d976 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/ui/messages/BaseNotificationView.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/ui/messages/BaseNotificationView.kt @@ -40,48 +40,29 @@ internal abstract class BaseNotificationView @JvmOverloads internal constructor( val handler = object : GetTemplateResultHandler { override fun onResult(templateKey: String, jsonTemplate: String?, e: SendbirdException?) { Logger.d("++ get template has been succeed, matched=${parentView.tag == message.messageId}") - if (parentView.tag == message.messageId) { - val layout = try { - e?.let { throw e } - jsonTemplate?.let { - val viewParams: Params = MessageTemplateParser.parse(jsonTemplate) - TemplateViewGenerator.inflateViews(context, viewParams) { view, params -> - params.action?.register( - view, - { v, action, message -> - try { - // if `tags` key doesn't exist, empty value has to delivery.(spec) - val tags: List = message.notificationData?.tags ?: listOf() - val result = SendbirdStatistics.appendStat( - KeySet.noti_stats, - mapOf( - KeySet.action to KeySet.clicked, - KeySet.template_key to templateKey, - KeySet.channel_url to message.channelUrl, - KeySet.tags to tags, - KeySet.message_id to message.messageId, - KeySet.source to KeySet.notification, - KeySet.message_ts to message.createdAt, - ) - ) - Logger.d("++ appendStat end, result=%s, tags=%s", result, tags) - } catch (e: Throwable) { - Logger.w(e) - } - onNotificationTemplateActionHandler?.onHandleAction( - v, action, message - ) - }, message - ) - } + if (parentView.tag != message.messageId) return + val layout = try { + e?.let { throw e } + jsonTemplate?.let { + val viewParams: Params = MessageTemplateParser.parse(jsonTemplate) + TemplateViewGenerator.inflateViews(context, viewParams) { view, params -> + params.action?.register( + view, + { v, action, message -> + sendNotificationStats(templateKey, message) + onNotificationTemplateActionHandler?.onHandleAction( + v, action, message + ) + }, message + ) } - } catch (e: Throwable) { - Logger.w("${e.printStackTrace()}") - createFallbackNotification(message, themeMode, onNotificationTemplateActionHandler) } - parentView.removeAllViews() - parentView.addView(layout) + } catch (e: Throwable) { + Logger.w("${e.printStackTrace()}") + createFallbackNotification(message, themeMode, onNotificationTemplateActionHandler) } + parentView.removeAllViews() + parentView.addView(layout) } } @@ -125,6 +106,28 @@ internal abstract class BaseNotificationView @JvmOverloads internal constructor( } } + private fun sendNotificationStats(templateKey: String, message: BaseMessage) { + try { + // if `tags` key doesn't exist, empty value has to delivery.(spec) + val tags: List = message.notificationData?.tags ?: listOf() + val result = SendbirdStatistics.appendStat( + KeySet.noti_stats, + mapOf( + KeySet.action to KeySet.clicked, + KeySet.template_key to templateKey, + KeySet.channel_url to message.channelUrl, + KeySet.tags to tags, + KeySet.message_id to message.messageId, + KeySet.source to KeySet.notification, + KeySet.message_ts to message.createdAt, + ) + ) + Logger.d("++ appendStat end, result=%s, tags=%s", result, tags) + } catch (e: Throwable) { + Logger.w(e) + } + } + private fun createLoadingView( isChatNotification: Boolean, themeMode: NotificationThemeMode, diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/ui/notifications/ChatNotificationListAdapter.kt b/uikit/src/main/java/com/sendbird/uikit/internal/ui/notifications/ChatNotificationListAdapter.kt index be99bdcc..e203afe7 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/ui/notifications/ChatNotificationListAdapter.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/ui/notifications/ChatNotificationListAdapter.kt @@ -36,10 +36,6 @@ internal class ChatNotificationListAdapter( // the worker must be a single thread. private val differWorker by lazy { Executors.newSingleThreadExecutor() } var onMessageTemplateActionHandler: OnNotificationTemplateActionHandler? = null - set(value) { - field = value - notificationConfig?.onMessageTemplateActionHandler = onMessageTemplateActionHandler - } /** * Called when RecyclerView needs a new [NotificationViewHolder] of the given type to represent @@ -61,7 +57,9 @@ internal class ChatNotificationListAdapter( if (MessageType.from(viewType) == MessageType.VIEW_TYPE_TIME_LINE) { return NotificationTimelineViewHolder(SbViewTimeLineMessageBinding.inflate(inflater, parent, false)) } - return ChatNotificationViewHolder(SbViewChatNotificationBinding.inflate(inflater, parent, false)) + return ChatNotificationViewHolder(SbViewChatNotificationBinding.inflate(inflater, parent, false)).apply { + binding.chatNotification.onNotificationTemplateActionHandler = onMessageTemplateActionHandler + } } /** diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/ui/notifications/FeedNotificationListAdapter.kt b/uikit/src/main/java/com/sendbird/uikit/internal/ui/notifications/FeedNotificationListAdapter.kt index e00c9b0e..d57fbed2 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/ui/notifications/FeedNotificationListAdapter.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/ui/notifications/FeedNotificationListAdapter.kt @@ -34,10 +34,6 @@ internal class FeedNotificationListAdapter( // the worker must be a single thread. private val dataWorker by lazy { Executors.newSingleThreadExecutor() } var onMessageTemplateActionHandler: OnNotificationTemplateActionHandler? = null - set(value) { - field = value - notificationConfig?.onMessageTemplateActionHandler = onMessageTemplateActionHandler - } init { this.currentLastSeenAt = channel.myLastRead @@ -60,7 +56,9 @@ internal class FeedNotificationListAdapter( parent.context.theme.resolveAttribute(R.attr.sb_component_list, values, true) val contextWrapper: Context = ContextThemeWrapper(parent.context, values.resourceId) val inflater = LayoutInflater.from(contextWrapper) - return FeedNotificationViewHolder(SbViewFeedNotificationBinding.inflate(inflater, parent, false)) + return FeedNotificationViewHolder(SbViewFeedNotificationBinding.inflate(inflater, parent, false)).apply { + binding.feedNotification.onNotificationTemplateActionHandler = onMessageTemplateActionHandler + } } /** diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/ui/notifications/FeedNotificationListComponent.kt b/uikit/src/main/java/com/sendbird/uikit/internal/ui/notifications/FeedNotificationListComponent.kt index 649d741b..64e09adc 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/ui/notifications/FeedNotificationListComponent.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/ui/notifications/FeedNotificationListComponent.kt @@ -14,7 +14,7 @@ import com.sendbird.uikit.interfaces.OnNotificationCategorySelectListener import com.sendbird.uikit.interfaces.OnNotificationTemplateActionHandler import com.sendbird.uikit.internal.extensions.intToDp import com.sendbird.uikit.internal.extensions.setTypeface -import com.sendbird.uikit.internal.interfaces.OnImpressionDetectedListener +import com.sendbird.uikit.internal.interfaces.OnNotificationViewedDetectedListener import com.sendbird.uikit.internal.model.notifications.NotificationConfig import com.sendbird.uikit.internal.ui.widgets.InnerLinearLayoutManager import com.sendbird.uikit.log.Logger @@ -33,7 +33,7 @@ internal open class FeedNotificationListComponent @JvmOverloads constructor( uiConfig: NotificationConfig? = null ) : NotificationListComponent(params, uiConfig) { - var onImpressionDetectedListener: OnImpressionDetectedListener? = null + var onNotificationViewedDetectedListener: OnNotificationViewedDetectedListener? = null /** * Returns the feed notification list adapter. @@ -77,7 +77,7 @@ internal open class FeedNotificationListComponent @JvmOverloads constructor( val layout = super.onCreateView(context, inflater, parent, args) notificationListView?.let { it.recyclerView.layoutManager = InnerLinearLayoutManager(context).apply { reverseLayout = false } - it.onImpressionDetectedListener = { firstVisibleItemPosition, lastVisibleItemPosition -> + it.onNotificationViewedDetectedListener = { firstVisibleItemPosition, lastVisibleItemPosition -> onVisibleItemDetected(firstVisibleItemPosition, lastVisibleItemPosition) } } @@ -89,10 +89,10 @@ internal open class FeedNotificationListComponent @JvmOverloads constructor( if (adapter == null) return if (firstVisibleItem < 0 || lastVisibleItem < 0) return - onImpressionDetectedListener?.let { + onNotificationViewedDetectedListener?.let { val range = if (firstVisibleItem <= lastVisibleItem) firstVisibleItem..lastVisibleItem else lastVisibleItem..firstVisibleItem val items = range.mapNotNull { i -> adapter?.getItem(i) } - it.onImpressionDetected(items) + it.onNotificationViewedDetected(items) } } diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/ChatNotificationViewHolder.kt b/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/ChatNotificationViewHolder.kt index 92b39bbd..08b87446 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/ChatNotificationViewHolder.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/ChatNotificationViewHolder.kt @@ -10,7 +10,6 @@ internal class ChatNotificationViewHolder internal constructor( ) : NotificationViewHolder(binding.root) { override fun bind(channel: BaseChannel, message: BaseMessage, config: NotificationConfig?) { - binding.chatNotification.onNotificationTemplateActionHandler = config?.onMessageTemplateActionHandler binding.chatNotification.drawMessage(channel, message, config) } } diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/FeedNotificationViewHolder.kt b/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/FeedNotificationViewHolder.kt index 1ee1f3d1..f2b3a201 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/FeedNotificationViewHolder.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/FeedNotificationViewHolder.kt @@ -16,8 +16,6 @@ internal class FeedNotificationViewHolder internal constructor( lastSeenAt: Long, config: NotificationConfig? ) { - binding.feedNotification.onNotificationTemplateActionHandler = - config?.onMessageTemplateActionHandler binding.feedNotification.drawMessage(message, channel, lastSeenAt, config) } } diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/ui/widgets/NotificationRecyclerView.kt b/uikit/src/main/java/com/sendbird/uikit/internal/ui/widgets/NotificationRecyclerView.kt index 992de6a6..6037ff13 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/ui/widgets/NotificationRecyclerView.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/ui/widgets/NotificationRecyclerView.kt @@ -21,7 +21,7 @@ import com.sendbird.uikit.internal.extensions.addRipple import com.sendbird.uikit.internal.extensions.intToDp import com.sendbird.uikit.internal.extensions.setAppearance import com.sendbird.uikit.internal.extensions.setTypeface -import com.sendbird.uikit.internal.utils.NotificationImpressionTracker +import com.sendbird.uikit.internal.utils.NotificationViewedTracker import com.sendbird.uikit.utils.SoftInputUtils internal class NotificationRecyclerView @JvmOverloads constructor( @@ -33,18 +33,18 @@ internal class NotificationRecyclerView @JvmOverloads constructor( private var categoryMenuTextAppearance: Int private var categoryMenuBackground: Int private val binding: SbViewChatNotificationRecyclerViewBinding - private val notificationScrollImpressionTracker by lazy { - NotificationImpressionTracker(recyclerView).apply { - onImpressionDetected = { + private val notificationScrollViewedTracker by lazy { + NotificationViewedTracker(recyclerView).apply { + onNotificationViewedDetected = { recyclerView.layoutManager?.let { val firstVisibleItemPosition = it.findFirstVisibleItemPosition() val lastVisibleItemPosition = it.findLastVisibleItemPosition() - onImpressionDetectedListener?.invoke(firstVisibleItemPosition, lastVisibleItemPosition) + onNotificationViewedDetectedListener?.invoke(firstVisibleItemPosition, lastVisibleItemPosition) } } } } - var onImpressionDetectedListener: ((firstVisibleItemPosition: Int, lastVisibleItemPosition: Int) -> Unit)? = null + var onNotificationViewedDetectedListener: ((firstVisibleItemPosition: Int, lastVisibleItemPosition: Int) -> Unit)? = null val recyclerView: PagerRecyclerView get() = binding.rvMessageList val isReverseLayout @@ -109,7 +109,7 @@ internal class NotificationRecyclerView @JvmOverloads constructor( layoutParams = RadioGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, - resources.getDimensionPixelSize(com.sendbird.uikit.R.dimen.sb_size_30) + resources.getDimensionPixelSize(R.dimen.sb_size_30) ).apply { marginEnd = resources.intToDp(8) } @@ -143,12 +143,12 @@ internal class NotificationRecyclerView @JvmOverloads constructor( override fun onAttachedToWindow() { super.onAttachedToWindow() - notificationScrollImpressionTracker.start() + notificationScrollViewedTracker.start() } override fun onDetachedFromWindow() { super.onDetachedFromWindow() - notificationScrollImpressionTracker.stop() + notificationScrollViewedTracker.stop() } init { diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/utils/NotificationImpressionTracker.kt b/uikit/src/main/java/com/sendbird/uikit/internal/utils/NotificationViewedTracker.kt similarity index 81% rename from uikit/src/main/java/com/sendbird/uikit/internal/utils/NotificationImpressionTracker.kt rename to uikit/src/main/java/com/sendbird/uikit/internal/utils/NotificationViewedTracker.kt index 664860b6..70e3e3b5 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/utils/NotificationImpressionTracker.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/utils/NotificationViewedTracker.kt @@ -9,20 +9,20 @@ import com.sendbird.uikit.utils.ClearableScheduledExecutorService import java.util.concurrent.TimeUnit /** - * Notification Impression Tracker fires events in two cases + * Notification Viewed Tracker fires events in two cases * 1. when an item is initially added to the recycler view.(Track only once for the first time.) * 2. when scrolling stops. * * The first time an item is added, the event is fired immediately with no delay, and if the scroll stops, the event is fired after the time value of [debounce]. */ -internal class NotificationImpressionTracker( +internal class NotificationViewedTracker( private val recyclerView: RecyclerView, private val debounce: Long = 500L ) : RecyclerView.OnScrollListener(), OnGlobalLayoutListener { private val scheduler by lazy { ClearableScheduledExecutorService() } private var initialDataLoaded = false private var isRunning = false - var onImpressionDetected: (() -> Unit)? = null + var onNotificationViewedDetected: (() -> Unit)? = null override fun onScrollStateChanged(view: RecyclerView, scrollState: Int) { if (view.childCount <= 0) return @@ -59,14 +59,14 @@ internal class NotificationImpressionTracker( @Synchronized fun start() { - Logger.d(">> NotificationScrollImpressionTracker::start()") + Logger.d(">> NotificationViewedTracker::start()") if (isRunning) return recyclerView.addOnScrollListener(this) /** * If it is organized in tabs, the View's Visibility is View.Visible, but it may not actually be visible on the screen. * In this case, we need to watch for events that change the layout, - * because we want the Impression to act the moment it is actually visible. + * because we want the notifications viewed to act the moment it is actually visible. */ recyclerView.viewTreeObserver.addOnGlobalLayoutListener(this) isRunning = true @@ -74,7 +74,7 @@ internal class NotificationImpressionTracker( @Synchronized fun stop() { - Logger.d(">> NotificationScrollImpressionTracker stop()") + Logger.d(">> NotificationViewedTracker stop()") isRunning = false recyclerView.removeOnScrollListener(this) recyclerView.viewTreeObserver.removeOnGlobalLayoutListener(this) @@ -83,28 +83,28 @@ internal class NotificationImpressionTracker( @Synchronized private fun startSchedule(initialDelay: Long = 300L) { - Logger.d(">> NotificationScrollImpressionTracker::startSchedule(), initialDelay: $initialDelay") + Logger.d(">> NotificationViewedTracker::startSchedule(), initialDelay: $initialDelay") if (initialDelay > 0L) { scheduler.schedule({ - notifyImpressions() + notifyNotificationViewed() }, debounce, TimeUnit.MILLISECONDS) return } else { - notifyImpressions() + notifyNotificationViewed() } } @Synchronized private fun cancelSchedule() { - Logger.d(">> NotificationScrollImpressionTracker cancelSchedule()") + Logger.d(">> NotificationViewedTracker cancelSchedule()") scheduler.cancelAllJobs(true) } - private fun notifyImpressions() { + private fun notifyNotificationViewed() { runOnUiThread { - Logger.i(">> impression detected") - onImpressionDetected?.invoke() + Logger.i(">> notifications viewed detected") + onNotificationViewedDetected?.invoke() } } } diff --git a/uikit/src/main/java/com/sendbird/uikit/modules/components/MessageInputComponent.java b/uikit/src/main/java/com/sendbird/uikit/modules/components/MessageInputComponent.java index 03086b0b..b15c7245 100644 --- a/uikit/src/main/java/com/sendbird/uikit/modules/components/MessageInputComponent.java +++ b/uikit/src/main/java/com/sendbird/uikit/modules/components/MessageInputComponent.java @@ -27,6 +27,7 @@ import com.sendbird.uikit.interfaces.OnInputModeChangedListener; import com.sendbird.uikit.interfaces.OnInputTextChangedListener; import com.sendbird.uikit.interfaces.OnMentionEventListener; +import com.sendbird.uikit.internal.extensions.ChannelExtensionsKt; import com.sendbird.uikit.internal.ui.widgets.MessageInputDialogWrapper; import com.sendbird.uikit.log.Logger; import com.sendbird.uikit.model.MessageUIConfig; @@ -526,7 +527,8 @@ void setHintMessageTextInternal(@NonNull MessageInputView inputView, @NonNull Gr boolean isOperator = channel.getMyRole() == Role.OPERATOR; boolean isMuted = channel.getMyMutedState() == MutedState.MUTED; boolean isFrozen = channel.isFrozen() && !isOperator; - inputView.setEnabled(!isMuted && !isFrozen); + boolean shouldDisableInput = ChannelExtensionsKt.shouldDisableInput(channel, params.channelConfig); + inputView.setEnabled(!isMuted && !isFrozen && !shouldDisableInput); final MessageInputView.Mode mode = inputView.getInputMode(); // set hint diff --git a/uikit/src/main/java/com/sendbird/uikit/modules/components/MessageThreadInputComponent.java b/uikit/src/main/java/com/sendbird/uikit/modules/components/MessageThreadInputComponent.java index 60b23e08..8e7e97b2 100644 --- a/uikit/src/main/java/com/sendbird/uikit/modules/components/MessageThreadInputComponent.java +++ b/uikit/src/main/java/com/sendbird/uikit/modules/components/MessageThreadInputComponent.java @@ -9,6 +9,7 @@ import com.sendbird.android.message.BaseMessage; import com.sendbird.android.user.MutedState; import com.sendbird.uikit.R; +import com.sendbird.uikit.internal.extensions.ChannelExtensionsKt; import com.sendbird.uikit.log.Logger; import com.sendbird.uikit.widgets.MessageInputView; import com.sendbird.uikit.widgets.StatusFrameView; @@ -82,7 +83,8 @@ void setHintMessageTextInternal(@NonNull MessageInputView inputView, @NonNull Gr boolean isOperator = channel.getMyRole() == Role.OPERATOR; boolean isMuted = channel.getMyMutedState() == MutedState.MUTED; boolean isFrozen = channel.isFrozen() && !isOperator; - inputView.setEnabled(!isMuted && !isFrozen && + boolean shouldDisableInput = ChannelExtensionsKt.shouldDisableInput(channel, getParams().getChannelConfig()); + inputView.setEnabled(!isMuted && !isFrozen && !shouldDisableInput && status != StatusFrameView.Status.ERROR && status != StatusFrameView.Status.CONNECTION_ERROR); diff --git a/uikit/src/main/java/com/sendbird/uikit/modules/components/StatusComponent.java b/uikit/src/main/java/com/sendbird/uikit/modules/components/StatusComponent.java index 1cf82032..ab24dff7 100644 --- a/uikit/src/main/java/com/sendbird/uikit/modules/components/StatusComponent.java +++ b/uikit/src/main/java/com/sendbird/uikit/modules/components/StatusComponent.java @@ -84,6 +84,7 @@ public View onCreateView(@NonNull Context context, @NonNull LayoutInflater infla if (params.emptyIcon != null) { statusView.setEmptyIcon(params.emptyIcon); } + if (params.emptyIconTint != null) { statusView.setEmptyIconTint(params.emptyIconTint); statusView.setActionIconTint(params.emptyIconTint); @@ -255,7 +256,8 @@ public String getErrorText() { @NonNull protected Params apply(@NonNull Context context, @NonNull Bundle args) { if (args.containsKey(StringSet.KEY_EMPTY_ICON_RES_ID)) { - setEmptyIcon(ContextCompat.getDrawable(context, args.getInt(StringSet.KEY_EMPTY_ICON_RES_ID))); + final int iconResId = args.getInt(StringSet.KEY_EMPTY_ICON_RES_ID); + setEmptyIcon(ContextCompat.getDrawable(context, iconResId > 0 ? iconResId : android.R.color.transparent)); } if (args.containsKey(StringSet.KEY_EMPTY_ICON_TINT)) { setEmptyIconTint(args.getParcelable(StringSet.KEY_EMPTY_ICON_TINT)); diff --git a/uikit/src/main/java/com/sendbird/uikit/utils/ChannelUtils.java b/uikit/src/main/java/com/sendbird/uikit/utils/ChannelUtils.java index 029df1f0..ad7d89eb 100644 --- a/uikit/src/main/java/com/sendbird/uikit/utils/ChannelUtils.java +++ b/uikit/src/main/java/com/sendbird/uikit/utils/ChannelUtils.java @@ -144,10 +144,10 @@ private static boolean isDefaultChannelCover(@NonNull BaseChannel channel) { public static String makeTypingText(@NonNull Context context, @NonNull List typingUsers) { if (typingUsers.size() == 1) { return String.format(context.getString(R.string.sb_text_channel_typing_indicator_single), - typingUsers.get(0).getNickname()); + UserUtils.getDisplayName(context, typingUsers.get(0), false)); } else if (typingUsers.size() == 2) { return String.format(context.getString(R.string.sb_text_channel_typing_indicator_double), - typingUsers.get(0).getNickname(), typingUsers.get(1).getNickname()); + UserUtils.getDisplayName(context, typingUsers.get(0), false), UserUtils.getDisplayName(context, typingUsers.get(1), false)); } else { return context.getString(R.string.sb_text_channel_typing_indicator_multiple); } diff --git a/uikit/src/main/java/com/sendbird/uikit/vm/BaseMessageListViewModel.java b/uikit/src/main/java/com/sendbird/uikit/vm/BaseMessageListViewModel.java index 80bbf048..b776918f 100644 --- a/uikit/src/main/java/com/sendbird/uikit/vm/BaseMessageListViewModel.java +++ b/uikit/src/main/java/com/sendbird/uikit/vm/BaseMessageListViewModel.java @@ -28,9 +28,8 @@ import com.sendbird.uikit.interfaces.AuthenticateHandler; import com.sendbird.uikit.interfaces.OnCompleteHandler; import com.sendbird.uikit.interfaces.OnPagedDataLoader; -import com.sendbird.uikit.internal.extensions.MessageExtensionsKt; -import com.sendbird.uikit.internal.wrappers.SendbirdUIKitImpl; -import com.sendbird.uikit.internal.wrappers.SendbirdUIKitWrapper; +import com.sendbird.uikit.internal.contracts.SendbirdUIKitImpl; +import com.sendbird.uikit.internal.contracts.SendbirdUIKitContract; import com.sendbird.uikit.log.Logger; import com.sendbird.uikit.model.FileInfo; import com.sendbird.uikit.model.LiveDataEx; @@ -61,8 +60,8 @@ public BaseMessageListViewModel(@NonNull String channelUrl) { } @VisibleForTesting - BaseMessageListViewModel(@NonNull String channelUrl, @NonNull SendbirdUIKitWrapper sendbirdUIKitWrapper) { - super(sendbirdUIKitWrapper); + BaseMessageListViewModel(@NonNull String channelUrl, @NonNull SendbirdUIKitContract sendbirdUIKitContract) { + super(sendbirdUIKitContract); this.channel = null; this.channelUrl = channelUrl; } diff --git a/uikit/src/main/java/com/sendbird/uikit/vm/BaseViewModel.java b/uikit/src/main/java/com/sendbird/uikit/vm/BaseViewModel.java index 7c1b6058..8507bc04 100644 --- a/uikit/src/main/java/com/sendbird/uikit/vm/BaseViewModel.java +++ b/uikit/src/main/java/com/sendbird/uikit/vm/BaseViewModel.java @@ -6,8 +6,8 @@ import com.sendbird.android.handler.ConnectHandler; import com.sendbird.uikit.interfaces.AuthenticateHandler; -import com.sendbird.uikit.internal.wrappers.SendbirdUIKitImpl; -import com.sendbird.uikit.internal.wrappers.SendbirdUIKitWrapper; +import com.sendbird.uikit.internal.contracts.SendbirdUIKitImpl; +import com.sendbird.uikit.internal.contracts.SendbirdUIKitContract; import com.sendbird.uikit.log.Logger; /** @@ -17,14 +17,14 @@ */ public abstract class BaseViewModel extends ViewModel { @NonNull - protected final SendbirdUIKitWrapper sendbirdUIKit; + protected final SendbirdUIKitContract sendbirdUIKit; protected BaseViewModel() { this(new SendbirdUIKitImpl()); } @VisibleForTesting - BaseViewModel(@NonNull SendbirdUIKitWrapper sendbirdUIKit) { + BaseViewModel(@NonNull SendbirdUIKitContract sendbirdUIKit) { this.sendbirdUIKit = sendbirdUIKit; } diff --git a/uikit/src/main/java/com/sendbird/uikit/vm/ChannelListViewModel.java b/uikit/src/main/java/com/sendbird/uikit/vm/ChannelListViewModel.java index 59ff0f1b..9377ac43 100644 --- a/uikit/src/main/java/com/sendbird/uikit/vm/ChannelListViewModel.java +++ b/uikit/src/main/java/com/sendbird/uikit/vm/ChannelListViewModel.java @@ -16,12 +16,13 @@ import com.sendbird.uikit.interfaces.OnCompleteHandler; import com.sendbird.uikit.interfaces.OnPagedDataLoader; import com.sendbird.uikit.internal.tasks.JobTask; -import com.sendbird.uikit.internal.wrappers.GroupChannelCollectionImpl; -import com.sendbird.uikit.internal.wrappers.GroupChannelCollectionWrapper; -import com.sendbird.uikit.internal.wrappers.SendbirdUIKitImpl; -import com.sendbird.uikit.internal.wrappers.SendbirdUIKitWrapper; -import com.sendbird.uikit.internal.wrappers.TaskQueueImpl; -import com.sendbird.uikit.internal.wrappers.TaskQueueWrapper; +import com.sendbird.uikit.internal.testmodel.ChannelListViewModelDataContract; +import com.sendbird.uikit.internal.contracts.GroupChannelCollectionImpl; +import com.sendbird.uikit.internal.contracts.GroupChannelCollectionContract; +import com.sendbird.uikit.internal.contracts.SendbirdUIKitImpl; +import com.sendbird.uikit.internal.contracts.SendbirdUIKitContract; +import com.sendbird.uikit.internal.contracts.TaskQueueImpl; +import com.sendbird.uikit.internal.contracts.TaskQueueContract; import com.sendbird.uikit.log.Logger; import com.sendbird.uikit.utils.Available; @@ -40,32 +41,21 @@ public class ChannelListViewModel extends BaseViewModel implements OnPagedDataLoader> { @Nullable - private GroupChannelCollectionWrapper collection; + private GroupChannelCollectionContract collection; @NonNull private final GroupChannelListQuery query; @NonNull - private final MutableLiveData> channelList = new MutableLiveData<>(); + private final MutableLiveData> channelList; @NonNull - private final GroupChannelCollectionHandler collectionHandler = new GroupChannelCollectionHandler() { - @Override - public void onChannelsAdded(@NonNull GroupChannelContext context, @NonNull List channels) { - notifyChannelChanged(); - } - - @Override - public void onChannelsUpdated(@NonNull GroupChannelContext context, @NonNull List channels) { - notifyChannelChanged(); - } - - @Override - public void onChannelsDeleted(@NonNull GroupChannelContext context, @NonNull List deletedChannelUrls) { - notifyChannelChanged(); - } - }; + private final GroupChannelCollectionHandler collectionHandler; @NonNull - private final TaskQueueWrapper taskQueue; + private final TaskQueueContract taskQueue; + + @Nullable + @VisibleForTesting + ChannelListViewModelDataContract contract; /** * Constructor @@ -77,10 +67,49 @@ public ChannelListViewModel(@Nullable GroupChannelListQuery query) { } @VisibleForTesting - ChannelListViewModel(@Nullable GroupChannelListQuery query, @NonNull SendbirdUIKitWrapper sendbirdUIKit, @NonNull TaskQueueWrapper taskQueue) { + ChannelListViewModel(@Nullable GroupChannelListQuery query, @NonNull SendbirdUIKitContract sendbirdUIKit, @NonNull TaskQueueContract taskQueue) { super(sendbirdUIKit); this.query = query == null ? createGroupChannelListQuery() : query; + this.channelList = new MutableLiveData<>(); this.taskQueue = taskQueue; + this.collectionHandler = new GroupChannelCollectionHandler() { + @Override + public void onChannelsAdded(@NonNull GroupChannelContext context, @NonNull List channels) { + notifyChannelChanged(); + } + + @Override + public void onChannelsUpdated(@NonNull GroupChannelContext context, @NonNull List channels) { + notifyChannelChanged(); + } + + @Override + public void onChannelsDeleted(@NonNull GroupChannelContext context, @NonNull List deletedChannelUrls) { + notifyChannelChanged(); + } + }; + } + + @TestOnly + ChannelListViewModel(@NonNull ChannelListViewModelDataContract contract) { + super(contract.getSendbirdUIKit()); + this.collection = contract.getCollection(); + this.query = contract.getQuery(); + this.channelList = contract.getChannelList(); + this.collectionHandler = contract.getCollectionHandler(); + this.taskQueue = contract.getTaskQueue(); + this.contract = contract; + } + + @TestOnly + boolean isSameProperties(@NonNull ChannelListViewModelDataContract contract) { + // It's enough to check the instance's reference. + return contract.getSendbirdUIKit() == this.sendbirdUIKit + && contract.getCollection() == this.collection + && contract.getQuery() == query + && contract.getChannelList() == channelList + && contract.getCollectionHandler() == collectionHandler + && contract.getTaskQueue() == taskQueue; } /** @@ -94,7 +123,8 @@ public LiveData> getChannelList() { return channelList; } - private synchronized void initChannelCollection() { + @VisibleForTesting + synchronized void initChannelCollection() { Logger.d(">> ChannelListViewModel::initChannelCollection()"); if (this.collection != null) { disposeChannelCollection(); @@ -269,15 +299,8 @@ protected GroupChannelListQuery createGroupChannelListQuery() { return GroupChannel.createMyGroupChannelListQuery(params); } - @VisibleForTesting @NonNull - GroupChannelCollectionWrapper createGroupChannelCollection() { + private GroupChannelCollectionContract createGroupChannelCollection() { return new GroupChannelCollectionImpl(query); } - - @TestOnly - @NonNull - GroupChannelListQuery getGroupChannelListQuery() { - return query; - } } diff --git a/uikit/src/main/java/com/sendbird/uikit/vm/ChannelViewModel.java b/uikit/src/main/java/com/sendbird/uikit/vm/ChannelViewModel.java index 3119a29a..f2252e17 100644 --- a/uikit/src/main/java/com/sendbird/uikit/vm/ChannelViewModel.java +++ b/uikit/src/main/java/com/sendbird/uikit/vm/ChannelViewModel.java @@ -36,12 +36,12 @@ import com.sendbird.uikit.consts.StringSet; import com.sendbird.uikit.consts.TypingIndicatorType; import com.sendbird.uikit.interfaces.OnCompleteHandler; -import com.sendbird.uikit.internal.wrappers.MessageCollectionImpl; -import com.sendbird.uikit.internal.wrappers.MessageCollectionWrapper; -import com.sendbird.uikit.internal.wrappers.SendbirdChatImpl; -import com.sendbird.uikit.internal.wrappers.SendbirdChatWrapper; -import com.sendbird.uikit.internal.wrappers.SendbirdUIKitImpl; -import com.sendbird.uikit.internal.wrappers.SendbirdUIKitWrapper; +import com.sendbird.uikit.internal.contracts.MessageCollectionImpl; +import com.sendbird.uikit.internal.contracts.MessageCollectionContract; +import com.sendbird.uikit.internal.contracts.SendbirdChatImpl; +import com.sendbird.uikit.internal.contracts.SendbirdChatContract; +import com.sendbird.uikit.internal.contracts.SendbirdUIKitImpl; +import com.sendbird.uikit.internal.contracts.SendbirdUIKitContract; import com.sendbird.uikit.log.Logger; import com.sendbird.uikit.model.SuggestedRepliesMessage; import com.sendbird.uikit.model.TypingIndicatorMessage; @@ -93,12 +93,12 @@ public class ChannelViewModel extends BaseMessageListViewModel { @Nullable private MessageListParams messageListParams; @Nullable - private MessageCollectionWrapper collection; + private MessageCollectionContract collection; @Nullable private MessageCollectionHandler handler; private boolean needToLoadMessageCache = true; @NonNull - private final SendbirdChatWrapper sendbirdChatWrapper; + private final SendbirdChatContract sendbirdChatContract; @NonNull private final ChannelConfig channelConfig; @@ -155,13 +155,13 @@ public ChannelViewModel(@NonNull String channelUrl, @Nullable MessageListParams } @VisibleForTesting - ChannelViewModel(@NonNull String channelUrl, @Nullable MessageListParams messageListParams, @NonNull SendbirdUIKitWrapper sendbirdUIKitWrapper, @NonNull SendbirdChatWrapper sendbirdChatWrapper, @NonNull ChannelConfig channelConfig) { - super(channelUrl, sendbirdUIKitWrapper); + ChannelViewModel(@NonNull String channelUrl, @Nullable MessageListParams messageListParams, @NonNull SendbirdUIKitContract sendbirdUIKitContract, @NonNull SendbirdChatContract sendbirdChatContract, @NonNull ChannelConfig channelConfig) { + super(channelUrl, sendbirdUIKitContract); this.messageListParams = messageListParams; - this.sendbirdChatWrapper = sendbirdChatWrapper; + this.sendbirdChatContract = sendbirdChatContract; this.channelConfig = channelConfig; - this.sendbirdChatWrapper.addChannelHandler(ID_CHANNEL_EVENT_HANDLER, new GroupChannelHandler() { + this.sendbirdChatContract.addChannelHandler(ID_CHANNEL_EVENT_HANDLER, new GroupChannelHandler() { @Override public void onMessageReceived(@NonNull BaseChannel channel, @NonNull BaseMessage message) { if (ChannelViewModel.this.getChannel() != null && channel.getUrl().equals(channelUrl) && hasNext()) { @@ -171,7 +171,7 @@ public void onMessageReceived(@NonNull BaseChannel channel, @NonNull BaseMessage } }); - this.sendbirdChatWrapper.addConnectionHandler(CONNECTION_HANDLER_ID, new ConnectionHandler() { + this.sendbirdChatContract.addConnectionHandler(CONNECTION_HANDLER_ID, new ConnectionHandler() { @Override public void onDisconnected(@NonNull String s) { } @@ -350,7 +350,7 @@ private void loadLatestMessagesForCache() { return; final GroupChannel channel = getChannel(); if (channel == null) return; - final MessageCollectionWrapper syncCollection = createSyncMessageCollection(channel); + final MessageCollectionContract syncCollection = createSyncMessageCollection(channel); syncCollection.initialize(MessageCollectionInitPolicy.CACHE_AND_REPLACE_BY_API, new MessageCollectionInitHandler() { @Override public void onCacheResult(@Nullable List list, @Nullable SendbirdException e) {} @@ -581,7 +581,7 @@ boolean shouldIgnoreEvent(@NonNull String traceName) { @NonNull @Override public List buildMessageList() { - MessageCollectionWrapper collection = this.collection; + MessageCollectionContract collection = this.collection; if (collection == null) return Collections.emptyList(); final List pendingMessages = new ArrayList<>(collection.getPendingMessages()); @@ -680,8 +680,8 @@ private synchronized void notifyHugeGapDetected() { protected void onCleared() { super.onCleared(); Logger.dev("-- onCleared ChannelViewModel"); - this.sendbirdChatWrapper.removeChannelHandler(ID_CHANNEL_EVENT_HANDLER); - this.sendbirdChatWrapper.removeConnectionHandler(CONNECTION_HANDLER_ID); + this.sendbirdChatContract.removeChannelHandler(ID_CHANNEL_EVENT_HANDLER); + this.sendbirdChatContract.removeConnectionHandler(CONNECTION_HANDLER_ID); disposeMessageCollection(); } @@ -896,13 +896,13 @@ public void removeFeedback(@NonNull BaseMessage message) { @VisibleForTesting @NonNull - MessageCollectionWrapper createMessageCollection(long startingPoint, @NonNull MessageListParams params, @NonNull GroupChannel channel, @NonNull MessageCollectionHandler handler) { + MessageCollectionContract createMessageCollection(long startingPoint, @NonNull MessageListParams params, @NonNull GroupChannel channel, @NonNull MessageCollectionHandler handler) { return new MessageCollectionImpl(SendbirdChat.createMessageCollection(new MessageCollectionCreateParams(channel, params, startingPoint, handler))); } @VisibleForTesting @NonNull - MessageCollectionWrapper createSyncMessageCollection(GroupChannel channel) { + MessageCollectionContract createSyncMessageCollection(GroupChannel channel) { return new MessageCollectionImpl(SendbirdChat.createMessageCollection(new MessageCollectionCreateParams(channel, new MessageListParams()))); } @@ -925,7 +925,7 @@ boolean isNeedToLoadMessageCache() { @TestOnly @Nullable - MessageCollectionWrapper getCollection() { + MessageCollectionContract getCollection() { return collection; } } diff --git a/uikit/src/main/java/com/sendbird/uikit/vm/FeedNotificationChannelViewModel.java b/uikit/src/main/java/com/sendbird/uikit/vm/FeedNotificationChannelViewModel.java index 79294315..525ba864 100644 --- a/uikit/src/main/java/com/sendbird/uikit/vm/FeedNotificationChannelViewModel.java +++ b/uikit/src/main/java/com/sendbird/uikit/vm/FeedNotificationChannelViewModel.java @@ -38,7 +38,6 @@ /** * ViewModel preparing and managing data related with the notification channel. - * * since 3.5.0 */ public class FeedNotificationChannelViewModel extends BaseViewModel implements OnPagedDataLoader>, LifecycleEventObserver { @@ -445,11 +444,12 @@ public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Ev * * @param messages The list of messages to be sent * since 3.12.0 + * */ public void sendLogImpression(@NonNull List messages) { Logger.d(">> FeedNotificationChannelViewModel::sendLogImpression(), size=%s, isVisible", messages.size(), isVisible); if (channel == null || !isVisible) return; final boolean result = channel.logImpression(messages); - Logger.d("++ logImpression result=%s", result); + Logger.d("++ sendlogView result=%s", result); } }