From 7785f2a62ceff33449efe68c0d9639ea6e6221bd Mon Sep 17 00:00:00 2001 From: "sha.sdk_deployment" Date: Thu, 28 Mar 2024 05:03:51 +0000 Subject: [PATCH] Added v3.15.0 --- CHANGELOG.md | 5 ++ gradle.properties | 2 +- .../uikit/samples/common/consts/StringSet.kt | 2 + .../common/extensions/UIKitExtensions.kt | 11 ++++ .../common/fcm/MyFirebaseMessagingService.kt | 21 +++++-- .../notification/NotificationHomeActivity.kt | 56 +++++++++++++++++++ .../notification/NotificationMainActivity.kt | 18 +++++- uikit/build.gradle | 2 +- .../fragments/BaseMessageListFragment.java | 17 +++--- .../FeedNotificationChannelFragment.java | 2 +- .../model/template_messages/KeySet.kt | 1 + .../ui/messages/BaseNotificationView.kt | 8 ++- .../ui/messages/ChatNotificationView.kt | 5 +- .../FeedNotificationListAdapter.kt | 1 + .../FeedNotificationListComponent.kt | 11 +++- .../viewholders/ChatNotificationViewHolder.kt | 4 +- .../NotificationTimelineViewHolder.kt | 6 +- .../ui/viewholders/NotificationViewHolder.kt | 4 +- .../model/configurations/ChannelConfig.kt | 42 +++++++++++++- .../vm/FeedNotificationChannelViewModel.java | 18 +++++- .../uikit/vm/MessageChangeLogsPager.java | 2 +- 21 files changed, 200 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25c1e15b..a8ce0850 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ # Changelog +### v3.15.0 (Mar 28, 2024) with Chat SDK `v4.16.0` +* Added `sendLogViewed(List)` in `FeedNotificationChannelViewModel`. +* Deprecated `sendLogImpression(List)` in `FeedNotificationChannelViewModel`. +* Supported reactions in super group channel. + Added `enableReactionsSupergroup` in `ChannelConfig`. ### v3.14.1 (Mar 20, 2024) with Chat SDK `v4.15.6` * Fixed issue where the position of the empty icon was displayed incorrectly. ### v3.14.0 (Mar 19, 2024) with Chat SDK `v4.15.6` diff --git a/gradle.properties b/gradle.properties index dcafcc80..55f3e3a4 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.14.1 +UIKIT_VERSION = 3.15.0 UIKIT_VERSION_CODE = 1 diff --git a/uikit-samples/src/main/java/com/sendbird/uikit/samples/common/consts/StringSet.kt b/uikit-samples/src/main/java/com/sendbird/uikit/samples/common/consts/StringSet.kt index 6aa10cd6..4ac554d9 100644 --- a/uikit-samples/src/main/java/com/sendbird/uikit/samples/common/consts/StringSet.kt +++ b/uikit-samples/src/main/java/com/sendbird/uikit/samples/common/consts/StringSet.kt @@ -7,6 +7,7 @@ object StringSet { const val PUSH_REDIRECT_CHANNEL = "PUSH_REDIRECT_CHANNEL" const val PUSH_REDIRECT_MESSAGE_ID = "PUSH_REDIRECT_MESSAGE_ID" const val PUSH_REDIRECT_CHANNEL_TYPE = "PUSH_REDIRECT_CHANNEL_TYPE" + const val PUSH_NOTIFICATION_DATA = "PUSH_NOTIFICATION_DATA" const val SETTINGS_USE_HEADER = "SETTINGS_USE_HEADER" const val SETTINGS_USE_DO_NOT_DISTURB = "SETTINGS_USE_DO_NOT_DISTURB" const val SB_LIVE_TYPE = "SB_LIVE_TYPE" @@ -32,4 +33,5 @@ object StringSet { const val notification_chat = "notification_chat" const val push_title = "push_title" const val channel_type = "channel_type" + const val notification_channel_key = "notification_channel_key" } diff --git a/uikit-samples/src/main/java/com/sendbird/uikit/samples/common/extensions/UIKitExtensions.kt b/uikit-samples/src/main/java/com/sendbird/uikit/samples/common/extensions/UIKitExtensions.kt index 11bf3d78..49083c6c 100644 --- a/uikit-samples/src/main/java/com/sendbird/uikit/samples/common/extensions/UIKitExtensions.kt +++ b/uikit-samples/src/main/java/com/sendbird/uikit/samples/common/extensions/UIKitExtensions.kt @@ -5,6 +5,7 @@ import android.app.NotificationManager import android.content.Context import android.content.Intent import android.graphics.drawable.Drawable +import android.os.Build import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import com.sendbird.android.SendbirdChat @@ -33,6 +34,7 @@ import com.sendbird.uikit.samples.customization.CustomizationHomeActivity import com.sendbird.uikit.samples.notification.NotificationHomeActivity import com.sendbird.uikit.samples.notification.NotificationLoginActivity import com.sendbird.uikit.samples.notification.NotificationMainActivity +import java.io.Serializable internal fun SampleType?.getLogoDrawable(context: Context): Drawable? { return when (this) { @@ -170,3 +172,12 @@ internal fun getFeedChannelUrl(): String { feedChannels?.get(StringSet.feed) } ?: "" } + +internal fun Intent.getSerializable(key: String, clazz: Class): T? { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + this.getSerializableExtra(key, clazz) + } else { + @Suppress("UNCHECKED_CAST") + this.getSerializableExtra(key) as? T + } +} diff --git a/uikit-samples/src/main/java/com/sendbird/uikit/samples/common/fcm/MyFirebaseMessagingService.kt b/uikit-samples/src/main/java/com/sendbird/uikit/samples/common/fcm/MyFirebaseMessagingService.kt index cab3795f..0d20b762 100644 --- a/uikit-samples/src/main/java/com/sendbird/uikit/samples/common/fcm/MyFirebaseMessagingService.kt +++ b/uikit-samples/src/main/java/com/sendbird/uikit/samples/common/fcm/MyFirebaseMessagingService.kt @@ -53,9 +53,13 @@ class MyFirebaseMessagingService : SendbirdPushHandler() { try { if (remoteMessage.data.containsKey(StringSet.sendbird)) { val jsonStr = remoteMessage.data[StringSet.sendbird] - markAsDelivered(remoteMessage.data) + try { + markAsDelivered(remoteMessage.data) + } catch (e: Exception) { + Logger.e(e) + } if (jsonStr == null) return - sendNotification(context, JSONObject(jsonStr)) + sendNotification(context, JSONObject(jsonStr), remoteMessage.data) } } catch (e: JSONException) { Logger.e(e) @@ -72,12 +76,13 @@ class MyFirebaseMessagingService : SendbirdPushHandler() { * @param sendBird JSONObject payload from FCM */ @Throws(JSONException::class) - fun sendNotification(context: Context, sendBird: JSONObject) { + fun sendNotification(context: Context, sendBird: JSONObject, data: Map) { val message = sendBird.getString(StringSet.message) val channel = sendBird.getJSONObject(StringSet.channel) val channelUrl = channel.getString(StringSet.channel_url) val messageId = sendBird.getLong(StringSet.message_id) val channelType = sendBird.optString(StringSet.channel_type, "") + val channelKey = sendBird.optString(StringSet.notification_channel_key, "") var pushTitle = context.getString(R.string.app_name) if (sendBird.has(StringSet.sender)) { val sender = sendBird.getJSONObject(StringSet.sender) @@ -95,7 +100,8 @@ class MyFirebaseMessagingService : SendbirdPushHandler() { } } - val intent = newRedirectToChannelIntent(context, channelUrl, messageId, channelType) + val hashedData = if (channelKey.isNotEmpty()) HashMap(data) else null + val intent = newRedirectToChannelIntent(context, channelUrl, messageId, channelType, hashedData) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) @SuppressLint("UnspecifiedImmutableFlag") @@ -128,14 +134,17 @@ class MyFirebaseMessagingService : SendbirdPushHandler() { context: Context, channelUrl: String, messageId: Long, - channelType: String + channelType: String, + data: HashMap?, ): Intent { return PreferenceUtils.selectedSampleType.newRedirectToChannelIntent( context, channelUrl, messageId, channelType - ) + ).apply { + data?.let { putExtra(StringSet.PUSH_NOTIFICATION_DATA, it) } + } } } } 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 fbced08a..a6247fe5 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 @@ -1,8 +1,18 @@ package com.sendbird.uikit.samples.notification +import android.Manifest +import android.content.DialogInterface import android.content.Intent +import android.net.Uri +import android.os.Build import android.os.Bundle +import android.provider.Settings import android.view.View +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AlertDialog +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat +import androidx.core.content.PermissionChecker import com.sendbird.uikit.activities.FeedNotificationChannelActivity import com.sendbird.uikit.samples.R import com.sendbird.uikit.samples.common.ThemeHomeActivity @@ -11,9 +21,15 @@ import com.sendbird.uikit.samples.common.extensions.logout import com.sendbird.uikit.samples.common.extensions.setTextColorResource import com.sendbird.uikit.samples.common.preferences.PreferenceUtils import com.sendbird.uikit.samples.databinding.ActivityNotificationHomeBinding +import com.sendbird.uikit.utils.ContextUtils +import java.util.Locale class NotificationHomeActivity : ThemeHomeActivity() { override val binding: ActivityNotificationHomeBinding by lazy { ActivityNotificationHomeBinding.inflate(layoutInflater) } + private val requestPermissionLauncher = + registerForActivityResult(ActivityResultContracts.RequestPermission()) { } + private val appSettingLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding.apply { @@ -31,6 +47,21 @@ class NotificationHomeActivity : ThemeHomeActivity() { } btSignOut.setOnClickListener { logout() } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + val permission = Manifest.permission.POST_NOTIFICATIONS + if (ContextCompat.checkSelfPermission( + this@NotificationHomeActivity, + permission + ) == PermissionChecker.PERMISSION_GRANTED + ) { + return@apply + } + if (ActivityCompat.shouldShowRequestPermissionRationale(this@NotificationHomeActivity, permission)) { + showPermissionRationalePopup() + return@apply + } + requestPermissionLauncher.launch(permission) + } } } @@ -42,4 +73,29 @@ class NotificationHomeActivity : ThemeHomeActivity() { else R.drawable.selector_home_signout_button ) } + + private fun showPermissionRationalePopup() { + val builder = AlertDialog.Builder(this) + builder.setTitle(getString(com.sendbird.uikit.R.string.sb_text_dialog_permission_title)) + builder.setMessage( + String.format( + Locale.US, + getString(R.string.sb_text_need_to_allow_permission_notification), + ContextUtils.getApplicationName(this) + ) + ) + builder.setPositiveButton(com.sendbird.uikit.R.string.sb_text_go_to_settings) { _: DialogInterface?, _: Int -> + val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) + intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS + intent.addCategory(Intent.CATEGORY_DEFAULT) + intent.data = Uri.parse("package:$packageName") + intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY) + intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) + appSettingLauncher.launch(intent) + } + val dialog = builder.create() + dialog.show() + dialog.getButton(AlertDialog.BUTTON_POSITIVE) + .setTextColor(ContextCompat.getColor(this, com.sendbird.uikit.R.color.secondary_300)) + } } diff --git a/uikit-samples/src/main/java/com/sendbird/uikit/samples/notification/NotificationMainActivity.kt b/uikit-samples/src/main/java/com/sendbird/uikit/samples/notification/NotificationMainActivity.kt index 514ab2ea..142180d9 100644 --- a/uikit-samples/src/main/java/com/sendbird/uikit/samples/notification/NotificationMainActivity.kt +++ b/uikit-samples/src/main/java/com/sendbird/uikit/samples/notification/NotificationMainActivity.kt @@ -16,6 +16,7 @@ import com.sendbird.android.SendbirdChat.removeUserEventHandler import com.sendbird.android.exception.SendbirdException import com.sendbird.android.handler.UnreadMessageCountHandler import com.sendbird.android.handler.UserEventHandler +import com.sendbird.android.push.SendbirdPushHelper import com.sendbird.android.user.UnreadMessageCount import com.sendbird.android.user.User import com.sendbird.uikit.SendbirdUIKit @@ -30,6 +31,7 @@ import com.sendbird.uikit.samples.common.SampleSettingsFragment import com.sendbird.uikit.samples.common.consts.InitState import com.sendbird.uikit.samples.common.consts.StringSet import com.sendbird.uikit.samples.common.extensions.getFeedChannelUrl +import com.sendbird.uikit.samples.common.extensions.getSerializable import com.sendbird.uikit.samples.common.extensions.isUsingDarkTheme import com.sendbird.uikit.samples.common.preferences.PreferenceUtils import com.sendbird.uikit.samples.common.widgets.CustomTabView @@ -152,7 +154,19 @@ class NotificationMainActivity : AppCompatActivity() { private fun redirectChannelIfNeeded(intent: Intent?) { if (intent == null) return - Logger.i("++ intent: %s", intent) + Logger.i("++ intent: %s, %s", intent, intent.extras) + if (intent.hasExtra(StringSet.PUSH_NOTIFICATION_DATA)) { + intent.getSerializable(StringSet.PUSH_NOTIFICATION_DATA, HashMap::class.java)?.let { + val resultMap = HashMap() + for ((key, value) in it) { + if (key is String && value is String) { + resultMap[key] = value + } + } + SendbirdPushHelper.markPushNotificationAsClicked(resultMap) + } + intent.removeExtra(StringSet.PUSH_NOTIFICATION_DATA) + } if (intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY == Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) { intent.removeExtra(StringSet.PUSH_REDIRECT_CHANNEL) intent.removeExtra(StringSet.PUSH_REDIRECT_MESSAGE_ID) @@ -160,7 +174,7 @@ class NotificationMainActivity : AppCompatActivity() { if (intent.hasExtra(StringSet.PUSH_REDIRECT_CHANNEL)) { val channelUrl = intent.getStringExtra(StringSet.PUSH_REDIRECT_CHANNEL) intent.removeExtra(StringSet.PUSH_REDIRECT_CHANNEL) - if (channelUrl == null) return + if (channelUrl.isNullOrEmpty()) return val channelType = intent.getStringExtra(StringSet.PUSH_REDIRECT_CHANNEL_TYPE) if (channelType.isNullOrEmpty()) return diff --git a/uikit/build.gradle b/uikit/build.gradle index 745f51e2..cf89a04e 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.15.6' + api 'com.sendbird.sdk:sendbird-chat:4.16.0' implementation 'com.github.bumptech.glide:glide:4.13.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.13.0' diff --git a/uikit/src/main/java/com/sendbird/uikit/fragments/BaseMessageListFragment.java b/uikit/src/main/java/com/sendbird/uikit/fragments/BaseMessageListFragment.java index a4551595..53a5bc6f 100644 --- a/uikit/src/main/java/com/sendbird/uikit/fragments/BaseMessageListFragment.java +++ b/uikit/src/main/java/com/sendbird/uikit/fragments/BaseMessageListFragment.java @@ -515,16 +515,15 @@ void showEmojiReactionDialog(@NonNull BaseMessage message, int position) { return; } + final GroupChannel channel = getViewModel().getChannel(); + if (channel == null || channel.isSuper()) return; final Context contextThemeWrapper = ContextUtils.extractModuleThemeContext(getContext(), getModule().getParams().getTheme(), R.attr.sb_component_list); final EmojiReactionUserListView emojiReactionUserListView = new EmojiReactionUserListView(contextThemeWrapper); emojiReactionUserListView.setOnProfileClickListener(this::onEmojiReactionUserListProfileClicked); - final GroupChannel channel = getViewModel().getChannel(); - if (channel != null) { - emojiReactionUserListView.setEmojiReactionUserData(this, - position, - message.getReactions(), - getReactionUserInfo(channel, message.getReactions())); - } + emojiReactionUserListView.setEmojiReactionUserData(this, + position, + message.getReactions(), + getReactionUserInfo(channel, message.getReactions())); hideKeyboard(); DialogUtils.showContentDialog(requireContext(), emojiReactionUserListView); } @@ -863,9 +862,9 @@ private boolean isUploadFileSizeLimitExceeded(@NonNull List fileSizes) private static int getMultipleFilesMessageFileCountLimit() { return Math.min( MULTIPLE_FILES_COUNT_LIMIT, - SendbirdChat.getAppInfo() == null ? - MULTIPLE_FILES_COUNT_LIMIT : + SendbirdChat.isInitialized() && SendbirdChat.getAppInfo() != null ? SendbirdChat.getAppInfo().getMultipleFilesMessageFileCountLimit() + : MULTIPLE_FILES_COUNT_LIMIT ); } diff --git a/uikit/src/main/java/com/sendbird/uikit/fragments/FeedNotificationChannelFragment.java b/uikit/src/main/java/com/sendbird/uikit/fragments/FeedNotificationChannelFragment.java index 3c480ce2..68698db0 100644 --- a/uikit/src/main/java/com/sendbird/uikit/fragments/FeedNotificationChannelFragment.java +++ b/uikit/src/main/java/com/sendbird/uikit/fragments/FeedNotificationChannelFragment.java @@ -126,7 +126,7 @@ protected void onBindNotificationListComponent(@NonNull FeedNotificationListComp Logger.d(">> FeedNotificationChannelFragment::onBindFeedNotificationListComponent()"); listComponent.setOnMessageTemplateActionHandler(actionHandler != null ? actionHandler : this::handleAction); listComponent.setOnTooltipClickListener(v -> listComponent.scrollToFirst()); - listComponent.setOnNotificationViewedDetectedListener(viewModel::sendLogImpression); + listComponent.setOnNotificationViewedDetectedListener(viewModel::sendLogViewed); listComponent.setOnNotificationCategorySelectListener(category -> { Logger.d("++ selected category = %s", category); listComponent.clearData(); 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 43c63c67..94d0d779 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 @@ -90,6 +90,7 @@ internal object KeySet { const val enable_typing_indicator = "enable_typing_indicator" const val typing_indicator_types = "typing_indicator_types" const val enable_reactions = "enable_reactions" + const val enable_reactions_supergroup = "enable_reactions_supergroup" const val enable_voice_message = "enable_voice_message" const val enable_multiple_files_message = "enable_multiple_files_message" const val enable_suggested_replies = "enable_suggested_replies" 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 3c01d976..2c89198f 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 @@ -112,7 +112,7 @@ internal abstract class BaseNotificationView @JvmOverloads internal constructor( val tags: List = message.notificationData?.tags ?: listOf() val result = SendbirdStatistics.appendStat( KeySet.noti_stats, - mapOf( + mutableMapOf( KeySet.action to KeySet.clicked, KeySet.template_key to templateKey, KeySet.channel_url to message.channelUrl, @@ -120,7 +120,11 @@ internal abstract class BaseNotificationView @JvmOverloads internal constructor( KeySet.message_id to message.messageId, KeySet.source to KeySet.notification, KeySet.message_ts to message.createdAt, - ) + ).apply { + message.notificationEventDeadline?.let { + put(KeySet.notification_event_deadline, it) + } + }.toMap() ) Logger.d("++ appendStat end, result=%s, tags=%s", result, tags) } catch (e: Throwable) { diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/ui/messages/ChatNotificationView.kt b/uikit/src/main/java/com/sendbird/uikit/internal/ui/messages/ChatNotificationView.kt index a9dc9f5f..5446a5b0 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/ui/messages/ChatNotificationView.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/ui/messages/ChatNotificationView.kt @@ -5,7 +5,7 @@ import android.util.AttributeSet import android.util.TypedValue import android.view.LayoutInflater import android.view.View -import com.sendbird.android.channel.BaseChannel +import com.sendbird.android.channel.GroupChannel import com.sendbird.android.message.BaseMessage import com.sendbird.uikit.R import com.sendbird.uikit.databinding.SbViewChatNotificationComponentBinding @@ -65,8 +65,9 @@ internal class ChatNotificationView @JvmOverloads internal constructor( } } - fun drawMessage(channel: BaseChannel, message: BaseMessage, config: NotificationConfig? = null) { + fun drawMessage(channel: GroupChannel, message: BaseMessage, config: NotificationConfig? = null) { binding.tvLabel.text = MessageUtils.getNotificationLabel(message) + binding.tvLabel.visibility = if (channel.isTemplateLabelEnabled) View.VISIBLE else View.INVISIBLE binding.tvSentAt.text = DateUtils.formatDateTime(context, message.createdAt) binding.ivProfileView.loadCircle(channel.coverUrl) 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 d57fbed2..ebf34ee7 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 @@ -36,6 +36,7 @@ internal class FeedNotificationListAdapter( var onMessageTemplateActionHandler: OnNotificationTemplateActionHandler? = null init { + this.prevLastSeenAt = channel.myLastRead this.currentLastSeenAt = channel.myLastRead } 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 64e09adc..3925af87 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 @@ -20,6 +20,7 @@ import com.sendbird.uikit.internal.ui.widgets.InnerLinearLayoutManager import com.sendbird.uikit.log.Logger import com.sendbird.uikit.model.Action import com.sendbird.uikit.utils.DrawableUtils +import java.lang.Exception import java.util.concurrent.atomic.AtomicBoolean /** @@ -91,8 +92,14 @@ internal open class FeedNotificationListComponent @JvmOverloads constructor( onNotificationViewedDetectedListener?.let { val range = if (firstVisibleItem <= lastVisibleItem) firstVisibleItem..lastVisibleItem else lastVisibleItem..firstVisibleItem - val items = range.mapNotNull { i -> adapter?.getItem(i) } - it.onNotificationViewedDetected(items) + val copiedList = adapter?.getItems()?.toList() + if (copiedList != null) { + try { + val items = range.mapNotNull { i -> copiedList[i] } + it.onNotificationViewedDetected(items) + } catch (ignore: Exception) { + } + } } } 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 08b87446..052dbe69 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 @@ -1,6 +1,6 @@ package com.sendbird.uikit.internal.ui.viewholders -import com.sendbird.android.channel.BaseChannel +import com.sendbird.android.channel.GroupChannel import com.sendbird.android.message.BaseMessage import com.sendbird.uikit.databinding.SbViewChatNotificationBinding import com.sendbird.uikit.internal.model.notifications.NotificationConfig @@ -9,7 +9,7 @@ internal class ChatNotificationViewHolder internal constructor( val binding: SbViewChatNotificationBinding ) : NotificationViewHolder(binding.root) { - override fun bind(channel: BaseChannel, message: BaseMessage, config: NotificationConfig?) { + override fun bind(channel: GroupChannel, message: BaseMessage, config: NotificationConfig?) { binding.chatNotification.drawMessage(channel, message, config) } } diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/NotificationTimelineViewHolder.kt b/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/NotificationTimelineViewHolder.kt index 9379b10f..da5f7e59 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/NotificationTimelineViewHolder.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/NotificationTimelineViewHolder.kt @@ -1,6 +1,6 @@ package com.sendbird.uikit.internal.ui.viewholders -import com.sendbird.android.channel.BaseChannel +import com.sendbird.android.channel.GroupChannel import com.sendbird.android.message.BaseMessage import com.sendbird.uikit.databinding.SbViewTimeLineMessageBinding import com.sendbird.uikit.internal.model.notifications.NotificationConfig @@ -9,7 +9,7 @@ internal class NotificationTimelineViewHolder internal constructor( val binding: SbViewTimeLineMessageBinding, ) : NotificationViewHolder(binding.root) { - override fun bind(channel: BaseChannel, message: BaseMessage, uiConfig: NotificationConfig?) { - binding.timelineMessageView.drawTimeline(message, uiConfig) + override fun bind(channel: GroupChannel, message: BaseMessage, config: NotificationConfig?) { + binding.timelineMessageView.drawTimeline(message, config) } } diff --git a/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/NotificationViewHolder.kt b/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/NotificationViewHolder.kt index 166115ac..81de1e76 100644 --- a/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/NotificationViewHolder.kt +++ b/uikit/src/main/java/com/sendbird/uikit/internal/ui/viewholders/NotificationViewHolder.kt @@ -2,7 +2,7 @@ package com.sendbird.uikit.internal.ui.viewholders import android.view.View import androidx.recyclerview.widget.RecyclerView -import com.sendbird.android.channel.BaseChannel +import com.sendbird.android.channel.GroupChannel import com.sendbird.android.message.BaseMessage import com.sendbird.uikit.internal.model.notifications.NotificationConfig @@ -10,5 +10,5 @@ internal abstract class NotificationViewHolder internal constructor( view: View ) : RecyclerView.ViewHolder(view) { - abstract fun bind(channel: BaseChannel, message: BaseMessage, config: NotificationConfig?) + abstract fun bind(channel: GroupChannel, message: BaseMessage, config: NotificationConfig?) } diff --git a/uikit/src/main/java/com/sendbird/uikit/model/configurations/ChannelConfig.kt b/uikit/src/main/java/com/sendbird/uikit/model/configurations/ChannelConfig.kt index 452ea518..0e7126d0 100644 --- a/uikit/src/main/java/com/sendbird/uikit/model/configurations/ChannelConfig.kt +++ b/uikit/src/main/java/com/sendbird/uikit/model/configurations/ChannelConfig.kt @@ -35,6 +35,8 @@ data class ChannelConfig internal constructor( private var _typingIndicatorTypes: Set = setOf(TypingIndicatorType.TEXT), @SerialName(KeySet.enable_reactions) private var _enableReactions: Boolean = true, + @SerialName(KeySet.enable_reactions_supergroup) + private var _enableReactionsSupergroup: Boolean = false, @SerialName(KeySet.enable_voice_message) private var _enableVoiceMessage: Boolean = false, @SerialName(KeySet.enable_multiple_files_message) @@ -70,6 +72,8 @@ data class ChannelConfig internal constructor( @Transient private var enableReactionsMutable: Boolean? = null, @Transient + private var enableReactionsSupergroupMutable: Boolean? = null, + @Transient private var enableVoiceMessageMutable: Boolean? = null, @Transient private var enableMultipleFilesMessageMutable: Boolean? = null, @@ -118,10 +122,14 @@ data class ChannelConfig internal constructor( @JvmStatic fun getEnableReactions(channelConfig: ChannelConfig, channel: BaseChannel): Boolean { return if (channel is GroupChannel) { - if (channel.isSuper || channel.isBroadcast || channel.isChatNotification) { + if (channel.isBroadcast || channel.isChatNotification) { false } else { - Available.isSupportReaction() && channelConfig.enableReactions + if (channel.isSuper) { + Available.isSupportReaction() && channelConfig.enableReactionsSupergroup + } else { + Available.isSupportReaction() && channelConfig.enableReactions + } } } else { false @@ -234,6 +242,9 @@ data class ChannelConfig internal constructor( * Only the values set in UIKit dashboard and UIKitConfig are affected. * If you want to get the value used when actually drawing in uikit, use [ChannelConfig.getEnableReactions(ChannelConfig, GroupChannel)]. * + * This works exclusively with [enableReactionsSupergroup]. In other words, it does not affect whether or not reactions are used in the supergroup channel. + * If you want to use reactions in a supergroup channel, adjust the [enableReactionsSupergroup] property. + * * @return true if the reactions is enabled, false otherwise * @since 3.6.0 */ @@ -247,6 +258,31 @@ data class ChannelConfig internal constructor( set(value) { enableReactionsMutable = value } + var enableReactionsSupergroup: Boolean + /** + * Returns a value that determines whether to display the reactions or not in the supergroup channel. + * true, if supergroup channel displays the reactions in the message. + * false, otherwise. + * + * Only the values set in UIKit dashboard and UIKitConfig are affected. + * If you want to get the value used when actually drawing in uikit, use [ChannelConfig.getEnableReactions(ChannelConfig, GroupChannel)]. + * + * This works exclusively with [enableReactions]. In other words, it only affects whether or not reactions are used in the supergroup channel. + * If you want to use reactions in a group channel, adjust the [enableReactions] property. + * + * @return true if the reactions is enabled in the supergroup channel, false otherwise + * @since 3.15.0 + */ + get() = enableReactionsSupergroupMutable ?: _enableReactionsSupergroup + /** + * Sets whether to display the reactions or not in the supergroup channel. + * + * @param value true if the reactions is enabled in the supergroup channel, false otherwise + * @since 3.15.0 + */ + set(value) { + enableReactionsSupergroupMutable = value + } var enableVoiceMessage: Boolean /** * Returns a value that determines whether to use the voice message or not. @@ -387,6 +423,7 @@ data class ChannelConfig internal constructor( this._enableTypingIndicator = config._enableTypingIndicator this._typingIndicatorTypes = config._typingIndicatorTypes this._enableReactions = config._enableReactions + this._enableReactionsSupergroup = config._enableReactionsSupergroup this._enableVoiceMessage = config._enableVoiceMessage this._enableMultipleFilesMessage = config._enableMultipleFilesMessage this._enableSuggestedReplies = config._enableSuggestedReplies @@ -406,6 +443,7 @@ data class ChannelConfig internal constructor( this.enableTypingIndicatorMutable = null this.typingIndicatorTypesMutable = null this.enableReactionsMutable = null + this.enableReactionsSupergroupMutable = null this.enableVoiceMessageMutable = null this.enableMultipleFilesMessageMutable = null this.threadReplySelectTypeMutable = null 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 525ba864..2f14b9bd 100644 --- a/uikit/src/main/java/com/sendbird/uikit/vm/FeedNotificationChannelViewModel.java +++ b/uikit/src/main/java/com/sendbird/uikit/vm/FeedNotificationChannelViewModel.java @@ -445,11 +445,25 @@ public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Ev * @param messages The list of messages to be sent * since 3.12.0 * + * @deprecated 3.15.0 + *

Use {@link #sendLogViewed(List)} instead.

*/ + @Deprecated public void sendLogImpression(@NonNull List messages) { - Logger.d(">> FeedNotificationChannelViewModel::sendLogImpression(), size=%s, isVisible", messages.size(), isVisible); + sendLogViewed(messages); + } + + /** + * Sends the log viewed to Sendbird server. + * It is working only when the channel is visible. + * + * @param messages The list of messages to be sent + * since 3.15.0 + */ + public void sendLogViewed(@NonNull List messages) { + Logger.d(">> FeedNotificationChannelViewModel::sendLogView(), size=%s, isVisible", messages.size(), isVisible); if (channel == null || !isVisible) return; - final boolean result = channel.logImpression(messages); + final boolean result = channel.logViewed(messages); Logger.d("++ sendlogView result=%s", result); } } diff --git a/uikit/src/main/java/com/sendbird/uikit/vm/MessageChangeLogsPager.java b/uikit/src/main/java/com/sendbird/uikit/vm/MessageChangeLogsPager.java index 47fbff67..d4966600 100644 --- a/uikit/src/main/java/com/sendbird/uikit/vm/MessageChangeLogsPager.java +++ b/uikit/src/main/java/com/sendbird/uikit/vm/MessageChangeLogsPager.java @@ -36,7 +36,7 @@ interface MessageChangeLogsResultHandler { this.lastSyncAt = lastSyncAt; this.params = MessageChangeLogsParams.from(params); this.messageListParams = params.clone(); - this.messageListParams.setPreviousResultSize(1); + this.messageListParams.setPreviousResultSize(0); this.messageListParams.setNextResultSize(100); }