Skip to content

Commit

Permalink
Merge pull request #36 from sendbird/release/3.17.1
Browse files Browse the repository at this point in the history
3.17.1
  • Loading branch information
sendbird-sdk-deployment authored Jun 7, 2024
2 parents 797e0b1 + 334383d commit f0a101b
Show file tree
Hide file tree
Showing 21 changed files with 543 additions and 74 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Changelog
### v3.17.0 (May 23, 2024) with Chat SDK `v4.16.3`
### v3.17.1 (Jun 7, 2024) with Chat SDK `v4.16.4`
* Fixed an intermittent crash due to variable initialization when entering a notification channel.
* Optimized ChatBot streaming message animation.### v3.17.0 (May 23, 2024) with Chat SDK `v4.16.3`
* Deprecated `notifyStatusUpdated(GroupChannel, StatusFrameView)` in `MessageThreadInputComponent`
* Added a new interface to set the enable state of the message input field
* Added `boolean tryToChangeEnableInputView(boolean, String)` in `ChannelFragment`, `MessageThreadFragment`, `OpenChannelFragment`
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ org.gradle.jvmargs=-Xmx1536m
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true

UIKIT_VERSION = 3.17.0
UIKIT_VERSION = 3.17.1
UIKIT_VERSION_CODE = 1
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import com.sendbird.uikit.samples.customization.global.showAdapterProvidersSampl
import com.sendbird.uikit.samples.customization.global.showFragmentProvidersSample
import com.sendbird.uikit.samples.customization.global.showModuleProvidersSample
import com.sendbird.uikit.samples.customization.global.showViewModelProvidersSample
import com.sendbird.uikit.samples.customization.moderation.showModerationGroupChannelSample
import com.sendbird.uikit.samples.customization.moderation.showModerationOpenChannelSample
import com.sendbird.uikit.samples.customization.userlist.showCustomMemberContextMenuSample
import com.sendbird.uikit.samples.customization.userlist.showUserItemDataSourceSample
import com.sendbird.uikit.samples.customization.userlist.showUserItemFilteringSample
Expand Down Expand Up @@ -177,7 +179,22 @@ class CustomizationHomeActivity : ComponentActivity() {
CustomizationItem(
title = getString(R.string.text_title_custom_member_context_menu),
description = getString(R.string.text_desc_custom_member_context_menu),
) { showCustomMemberContextMenuSample(this) }
) { showCustomMemberContextMenuSample(this) },
// endregion

// region user list customization
CustomizationItem(
isHeader = true,
title = getString(R.string.text_title_moderation)
),
CustomizationItem(
title = getString(R.string.text_title_moderation_group_channel),
description = getString(R.string.text_moderation_custom_group_channel_sample),
) { showModerationGroupChannelSample(activity = this) },
CustomizationItem(
title = getString(R.string.text_title_moderation_open_channel),
description = getString(R.string.text_moderation_custom_open_channel_sample),
) { showModerationOpenChannelSample(activity = this) },
// endregion
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.sendbird.uikit.samples.customization

import android.app.Activity
import com.sendbird.android.channel.OpenChannel
import com.sendbird.android.params.OpenChannelListQueryParams
import com.sendbird.uikit.samples.common.widgets.WaitingDialog
import com.sendbird.uikit.utils.ContextUtils
import java.util.concurrent.Executors

internal object OpenChannelRepository {
private val worker = Executors.newSingleThreadExecutor()
private var channelCache = mutableListOf<OpenChannel>()

fun getRandomChannel(activity: Activity, callback: (OpenChannel) -> Unit) {
if (channelCache.isNotEmpty()) {
callback(channelCache.random())
return
}
WaitingDialog.show(activity)
worker.submit {
OpenChannel.createOpenChannelListQuery(OpenChannelListQueryParams()).next { channels, e ->
WaitingDialog.dismiss()
if (e != null || channels.isNullOrEmpty()) {
ContextUtils.toastError(activity, "No channels")
return@next
}
channelCache.addAll(channels)
activity.runOnUiThread { callback(channelCache.random()) }
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package com.sendbird.uikit.samples.customization.moderation

import android.app.Activity
import android.content.Context
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.sendbird.android.channel.ReportCategory
import com.sendbird.android.exception.SendbirdException
import com.sendbird.android.message.BaseMessage
import com.sendbird.android.message.SendingStatus
import com.sendbird.uikit.activities.ChannelActivity
import com.sendbird.uikit.activities.viewholder.MessageType
import com.sendbird.uikit.activities.viewholder.MessageViewHolderFactory
import com.sendbird.uikit.fragments.ChannelFragment
import com.sendbird.uikit.interfaces.OnCompleteHandler
import com.sendbird.uikit.interfaces.providers.ChannelFragmentProvider
import com.sendbird.uikit.interfaces.providers.ChannelViewModelProvider
import com.sendbird.uikit.model.DialogListItem
import com.sendbird.uikit.providers.FragmentProviders
import com.sendbird.uikit.providers.ViewModelProviders
import com.sendbird.uikit.samples.R
import com.sendbird.uikit.samples.customization.GroupChannelRepository
import com.sendbird.uikit.utils.MessageUtils
import com.sendbird.uikit.vm.ChannelViewModel
import com.sendbird.uikit.vm.ViewModelFactory
import java.util.Arrays
import java.util.Objects

fun showModerationGroupChannelSample(activity: Activity) {
setModerationGroupChannelViewModelProviders()

FragmentProviders.channel = ChannelFragmentProvider { channelUrl, args ->
ChannelFragment.Builder(channelUrl).withArguments(args)
.setCustomFragment(ModerationGroupChannelFragment())
.setUseHeader(true)
.build()
}

GroupChannelRepository.getRandomChannel(activity) { channel ->
activity.startActivity(
ChannelActivity.newIntent(activity, channel.url)
)
}
}

class ModerationGroupChannelFragment : ChannelFragment() {
override fun makeMessageContextMenu(message: BaseMessage): MutableList<DialogListItem> {
val items: MutableList<DialogListItem> = super.makeMessageContextMenu(message)
val status = message.sendingStatus
if (status == SendingStatus.PENDING) return items

val type = MessageViewHolderFactory.getMessageType(message)
val report = DialogListItem(R.string.text_report, R.drawable.icon_error)

when (type) {
MessageType.VIEW_TYPE_USER_MESSAGE_ME -> if (status == SendingStatus.SUCCEEDED) {
items.add(report)
}
MessageType.VIEW_TYPE_USER_MESSAGE_OTHER -> {
items.add(report)
}
else -> {}
}

return items
}

override fun onMessageContextMenuItemClicked(message: BaseMessage, view: View, position: Int, item: DialogListItem): Boolean {
val key = item.key

if (key == R.string.text_report) {
showSelectReportCategory(message)
return true
}

super.onMessageContextMenuItemClicked(message, view, position, item)

return false
}

private fun showSelectReportCategory(message: BaseMessage) {
if (context == null) return

val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext())
var category: ReportCategory

builder.setTitle(getString(R.string.text_choose_report_category_dialog))
.setNegativeButton(R.string.text_cancel) { dialog, which ->
dialog.dismiss()
}
.setItems(
arrayOf(
getString(R.string.text_report_suspicious),
getString(R.string.text_report_harassing),
getString(R.string.text_report_spam),
getString(R.string.text_report_inappropriate)
)) { dialog, which ->
when (which) {
0 -> {
category = ReportCategory.SUSPICIOUS
}

1 -> {
category = ReportCategory.HARASSING
}

2 -> {
category = ReportCategory.SPAM
}

else -> {
category = ReportCategory.INAPPROPRIATE
}
}

reportMessage(message, category, "")
}

val dialog: AlertDialog = builder.create()
dialog.show()
}

private fun reportMessage(message: BaseMessage, reportCategory: ReportCategory, reason: String) {
(viewModel as ModerationGroupChannelViewModel).reportMessage(
message,
reportCategory,
reason
) { e: SendbirdException? ->
if (e == null) {
toastSuccess(R.string.sb_view_toast_success_description, false)
} else {
toastError(R.string.text_report_error, false)
}
}
}
}

class ModerationGroupChannelViewModel(channelUrl: String) : ChannelViewModel(channelUrl, null) {
fun reportMessage(message: BaseMessage, reportCategory: ReportCategory, reason: String, handler: OnCompleteHandler?) {
if (channel == null) return
channel?.let {
it.reportMessage(message, reportCategory, reason) { e: SendbirdException? -> handler?.onComplete(e) }
}
}
}


fun setModerationGroupChannelViewModelProviders() {
@Suppress("UNCHECKED_CAST")
class ModerationGroupChannelViewModelFactory(private vararg val params: Any?) : ViewModelFactory(*params) {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass == ModerationGroupChannelViewModel::class.java) {
return ModerationGroupChannelViewModel(
(Objects.requireNonNull(params)[0] as String)
) as T
}

return super.create(modelClass)
}
}

ViewModelProviders.channel = ChannelViewModelProvider { owner, channelUrl, _, _ ->
ViewModelProvider(
owner,
ModerationGroupChannelViewModelFactory(channelUrl)
)[channelUrl, ModerationGroupChannelViewModel::class.java]
}
}
Loading

0 comments on commit f0a101b

Please sign in to comment.