Skip to content

Commit

Permalink
Merge pull request #25 from sendbird/release/3.13.0
Browse files Browse the repository at this point in the history
3.13.0
  • Loading branch information
sendbird-sdk-deployment authored Feb 1, 2024
2 parents 09c81c2 + 4f9e265 commit 60cd795
Show file tree
Hide file tree
Showing 42 changed files with 689 additions and 53 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
# Changelog
### 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`.
* Added `OnFeedbackRatingClickListener` which is a callback to be invoked when a feedback rating is clicked.
* Added `getFeedbackRatingClickListener()` and `setFeedbackRatingClickListener(OnFeedbackRatingClickListener)` in `BaseMessageListAdapter`.
* Added `setOnFeedbackRatingClickListener(OnFeedbackRatingClickListener)` and `onFeedbackRatingClicked(BaseMessage, FeedbackRating)` in `BaseMessageListComponent`.
* Added `onFeedbackRatingClicked(BaseMessage, FeedbackRating)` in `ChannelFragment`.
* Added `submitFeedback(BaseMessage, FeedbackRating, String)` and `removeFeedback(BaseMessage)` in `ChannelViewModel`.
* Added `onFeedbackSubmitted()`, `onFeedbackUpdated()` and `onFeedbackDelete` in `ChannelViewModel`. They allow you to observe feedback events for submitting, updating and deleting feedback.
### v3.12.1 (Jan 18, 2024) with Chat SDK `v4.14.1`
* Fix memory leaks in UIKit.
### v3.12.0 (Jan, 2024) with Chat SDK `v4.13.0`
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.12.1
UIKIT_VERSION = 3.13.0
UIKIT_VERSION_CODE = 1
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,58 @@ class BaseApplication : MultiDexApplication() {
}
}
}, context)

// set theme mode
SendbirdUIKit.setDefaultThemeMode(PreferenceUtils.themeMode)
// register push notification
SendbirdPushHelper.registerPushHandler(MyFirebaseMessagingService())
// set logger
SendbirdUIKit.setLogLevel(SendbirdUIKit.LogLevel.ALL)
}

/**
* In a sample app, different contextual settings are used in a single app.
* These are only used in the sample, because if the app kills and resurrects due to low memory, the last used sample settings should be preserved.
*/
fun setupConfigurations() {
when (PreferenceUtils.selectedSampleType) {
SampleType.Basic -> {
// set whether to use user profile
UIKitConfig.common.enableUsingDefaultUserProfile = true
// set whether to use typing indicators in channel list
UIKitConfig.groupChannelListConfig.enableTypingIndicator = true
// set whether to use read/delivery receipt in channel list
UIKitConfig.groupChannelListConfig.enableMessageReceiptStatus = true
// set whether to use user mention
UIKitConfig.groupChannelConfig.enableMention = true
// set reply type
UIKitConfig.groupChannelConfig.replyType = ReplyType.THREAD
UIKitConfig.groupChannelConfig.threadReplySelectType = ThreadReplySelectType.THREAD
// set whether to use voice message
UIKitConfig.groupChannelConfig.enableVoiceMessage = true
// set typing indicator types
UIKitConfig.groupChannelConfig.typingIndicatorTypes = setOf(TypingIndicatorType.BUBBLE, TypingIndicatorType.TEXT)
// set whether to use feedback
UIKitConfig.groupChannelConfig.enableFeedback = true
// set custom params
SendbirdUIKit.setCustomParamsHandler(object : CustomParamsHandler {
override fun onBeforeCreateOpenChannel(params: OpenChannelCreateParams) {
// You can set OpenChannelCreateParams globally before creating a open channel.
params.customType = StringSet.SB_COMMUNITY_TYPE
}
})
}
SampleType.Notification -> {}
SampleType.Customization -> {}
SampleType.AiChatBot -> {
// set typing indicator types
UIKitConfig.groupChannelConfig.typingIndicatorTypes = setOf(TypingIndicatorType.BUBBLE)
// set whether to use feedback
UIKitConfig.groupChannelConfig.enableFeedback = true
}
else -> {
}
}
}
}

Expand All @@ -78,49 +130,4 @@ class BaseApplication : MultiDexApplication() {
// setup uikit configurations
setupConfigurations()
}

/**
* In a sample app, different contextual settings are used in a single app.
* These are only used in the sample, because if the app kills and resurrects due to low memory, the last used sample settings should be preserved.
*/
private fun setupConfigurations() {
// set theme mode
SendbirdUIKit.setDefaultThemeMode(PreferenceUtils.themeMode)
// register push notification
SendbirdPushHelper.registerPushHandler(MyFirebaseMessagingService())
// set logger
SendbirdUIKit.setLogLevel(SendbirdUIKit.LogLevel.ALL)

when (PreferenceUtils.selectedSampleType) {
SampleType.Basic -> {
// set whether to use user profile
UIKitConfig.common.enableUsingDefaultUserProfile = true
// set whether to use typing indicators in channel list
UIKitConfig.groupChannelListConfig.enableTypingIndicator = true
// set whether to use read/delivery receipt in channel list
UIKitConfig.groupChannelListConfig.enableMessageReceiptStatus = true
// set whether to use user mention
UIKitConfig.groupChannelConfig.enableMention = true
// set reply type
UIKitConfig.groupChannelConfig.replyType = ReplyType.THREAD
UIKitConfig.groupChannelConfig.threadReplySelectType = ThreadReplySelectType.THREAD
// set whether to use voice message
UIKitConfig.groupChannelConfig.enableVoiceMessage = true
// set typing indicator types
UIKitConfig.groupChannelConfig.typingIndicatorTypes = setOf(TypingIndicatorType.BUBBLE, TypingIndicatorType.TEXT)

// set custom params
SendbirdUIKit.setCustomParamsHandler(object : CustomParamsHandler {
override fun onBeforeCreateOpenChannel(params: OpenChannelCreateParams) {
// You can set OpenChannelCreateParams globally before creating a open channel.
params.customType = StringSet.SB_COMMUNITY_TYPE
}
})
}
SampleType.Notification -> {}
SampleType.Customization -> {}
else -> {
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.sendbird.uikit.samples.common.preferences

import android.content.Context
import com.sendbird.uikit.SendbirdUIKit.ThemeMode
import com.sendbird.uikit.samples.BaseApplication
import com.sendbird.uikit.samples.common.consts.SampleType

/**
Expand Down Expand Up @@ -69,6 +70,7 @@ internal object PreferenceUtils {
} else {
pref.putString(PREFERENCE_KEY_LATEST_USED_SAMPLE, value.name)
}
BaseApplication.setupConfigurations()
}

fun clearAll() = pref.clear()
Expand Down
2 changes: 1 addition & 1 deletion uikit/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])

// Sendbird
api 'com.sendbird.sdk:sendbird-chat:4.14.1'
api 'com.sendbird.sdk:sendbird-chat:4.14.2'

implementation 'com.github.bumptech.glide:glide:4.13.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.13.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.sendbird.uikit.interfaces.OnIdentifiableItemLongClickListener;
import com.sendbird.uikit.interfaces.OnItemClickListener;
import com.sendbird.uikit.interfaces.OnMessageListUpdateHandler;
import com.sendbird.uikit.internal.interfaces.OnFeedbackRatingClickListener;
import com.sendbird.uikit.internal.singleton.MessageDisplayDataManager;
import com.sendbird.uikit.internal.ui.viewholders.MyUserMessageViewHolder;
import com.sendbird.uikit.internal.ui.viewholders.OtherUserMessageViewHolder;
Expand Down Expand Up @@ -70,6 +71,9 @@ abstract public class BaseMessageListAdapter extends BaseMessageAdapter<BaseMess
@Nullable
protected OnItemClickListener<User> mentionClickListener;

@Nullable
protected OnFeedbackRatingClickListener feedbackRatingClickListener;

@NonNull
private final MessageListUIParams messageListUIParams;
@Nullable
Expand Down Expand Up @@ -286,6 +290,12 @@ public void onBindViewHolder(@NonNull MessageViewHolder holder, final int positi
mentionClickListener.onItemClick(view, messagePosition, mentionedUser);
}
});

otherUserMessageViewHolder.setOnFeedbackRatingClickListener((message, rating) -> {
if (feedbackRatingClickListener != null) {
feedbackRatingClickListener.onFeedbackClicked(message, rating);
}
});
}

if (channel != null) {
Expand Down Expand Up @@ -554,6 +564,27 @@ public OnItemClickListener<User> getMentionClickListener() {
return mentionClickListener;
}

/**
* Returns a callback to be invoked when the feedback rating is clicked.
*
* @return {@link OnFeedbackRatingClickListener} to be invoked when the feedback rating is clicked.
* since 3.13.0
*/
@Nullable
public OnFeedbackRatingClickListener getFeedbackRatingClickListener() {
return feedbackRatingClickListener;
}

/**
* Register a callback to be invoked when the feedback rating is clicked.
*
* @param feedbackRatingClickListener The callback that will run
* since 3.13.0
*/
public void setFeedbackRatingClickListener(@Nullable OnFeedbackRatingClickListener feedbackRatingClickListener) {
this.feedbackRatingClickListener = feedbackRatingClickListener;
}

/**
* Sets {@link MessageDisplayDataProvider}, which is used to generate data before they are sent or rendered.
* The generated value is primarily used when the view is rendered.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return false;
}

if (oldMessage.getMyFeedbackStatus() != newMessage.getMyFeedbackStatus()) {
return false;
}

if (oldMessage.getMyFeedback() != newMessage.getMyFeedback()) {
return false;
}

if (oldMessage instanceof TypingIndicatorMessage && newMessage instanceof TypingIndicatorMessage) {
return ((TypingIndicatorMessage) oldMessage).getTypingUsers().equals(((TypingIndicatorMessage) newMessage).getTypingUsers()) ;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@

import com.sendbird.android.channel.GroupChannel;
import com.sendbird.android.channel.Role;
import com.sendbird.android.exception.SendbirdException;
import com.sendbird.android.message.BaseMessage;
import com.sendbird.android.message.Feedback;
import com.sendbird.android.message.FeedbackRating;
import com.sendbird.android.message.FileMessage;
import com.sendbird.android.message.Form;
import com.sendbird.android.message.SendingStatus;
Expand All @@ -37,6 +40,7 @@
import com.sendbird.uikit.activities.adapter.SuggestedMentionListAdapter;
import com.sendbird.uikit.activities.viewholder.MessageType;
import com.sendbird.uikit.activities.viewholder.MessageViewHolderFactory;
import com.sendbird.uikit.consts.DialogEditTextParams;
import com.sendbird.uikit.consts.KeyboardDisplayType;
import com.sendbird.uikit.consts.ReplyType;
import com.sendbird.uikit.consts.StringSet;
Expand All @@ -45,6 +49,7 @@
import com.sendbird.uikit.interfaces.LoadingDialogHandler;
import com.sendbird.uikit.interfaces.MessageDisplayDataProvider;
import com.sendbird.uikit.interfaces.OnConsumableClickListener;
import com.sendbird.uikit.interfaces.OnEditTextResultListener;
import com.sendbird.uikit.interfaces.OnEmojiReactionClickListener;
import com.sendbird.uikit.interfaces.OnEmojiReactionLongClickListener;
import com.sendbird.uikit.interfaces.OnInputModeChangedListener;
Expand Down Expand Up @@ -265,6 +270,7 @@ protected void onBindMessageListComponent(@NonNull MessageListComponent messageL
messageListComponent.setOnEmojiReactionMoreButtonClickListener(emojiReactionMoreButtonClickListener != null ? emojiReactionMoreButtonClickListener : (view, position, message) -> showEmojiListDialog(message));
messageListComponent.setSuggestedRepliesClickListener((view, position, data) -> onSuggestedRepliesClicked(data));
messageListComponent.setFormSubmitButtonClickListener(this::onFormSubmitButtonClicked);
messageListComponent.setOnFeedbackRatingClickListener(this::onFeedbackRatingClicked);
messageListComponent.setOnTooltipClickListener(tooltipClickListener != null ? tooltipClickListener : this::onMessageTooltipClicked);

messageListComponent.setOnQuoteReplyMessageLongClickListener(this::onQuoteReplyMessageLongClicked);
Expand Down Expand Up @@ -380,6 +386,38 @@ protected void onBindMessageListComponent(@NonNull MessageListComponent messageL
}
}
});

viewModel.onFeedbackSubmitted().observe(getViewLifecycleOwner(), result -> {
if (result == null) return;
final BaseMessage message = result.first;
final SendbirdException e = result.second;
if (e == null) {
if (message != null) {
showUpdateFeedbackCommentDialog(message);
}
} else {
toastError(R.string.sb_text_toast_failure_feedback_submit);
}
});

viewModel.onFeedbackUpdated().observe(getViewLifecycleOwner(), result -> {
if (result == null) return;
final SendbirdException e = result.second;

if (e == null) {
toastSuccess(R.string.sb_text_toast_success_feedback_update);
} else {
toastError(R.string.sb_text_toast_failure_feedback_update);
}
});

viewModel.onFeedbackDeleted().observe(getViewLifecycleOwner(), result -> {
if (result == null) return;
final SendbirdException e = result.second;
if (e != null) {
toastError(R.string.sb_text_toast_failure_feedback_delete);
}
});
}

/**
Expand Down Expand Up @@ -540,6 +578,37 @@ protected void onFormSubmitButtonClicked(@NonNull BaseMessage message, @NonNull
});
}

/**
* Called when the feedback rating of the message is clicked.
*
* @param message The message that contains feedback
* @param feedbackRating The clicked feedback rating
* since 3.13.0
*/
protected void onFeedbackRatingClicked(@NonNull BaseMessage message, @NonNull FeedbackRating feedbackRating) {
Feedback currentFeedback = message.getMyFeedback();
if (currentFeedback != null) {
DialogListItem[] dialogListItems = {
new DialogListItem(R.string.sb_text_feedback_edit_comment),
new DialogListItem(R.string.sb_text_feedback_remove_comment, 0, true)
};

DialogUtils.showListBottomDialog(
requireContext(),
dialogListItems,
(view, position, data) -> {
if (position == 0) {
showUpdateFeedbackCommentDialog(message);
} else if (position == 1) {
getViewModel().removeFeedback(message);
}
}
);
} else {
getViewModel().submitFeedback(message, feedbackRating, null);
}
}

/**
* Find the same message as the message ID and move it to the matching message.
*
Expand Down Expand Up @@ -835,6 +904,33 @@ private void redirectMessageThreadIfNeeded(@Nullable Bundle args) {
}
}

private void showUpdateFeedbackCommentDialog(@NonNull BaseMessage message) {
final boolean hasFeedbackComment = message.getMyFeedback() != null && message.getMyFeedback().getComment() != null;
final String positiveButtonText = hasFeedbackComment ? getString(R.string.sb_text_button_save) : getString(R.string.sb_text_button_submit);
final OnEditTextResultListener listener = text -> {
final Feedback feedback = message.getMyFeedback();
if (feedback == null) return;
getViewModel().submitFeedback(message, feedback.getRating(), text);
};

final DialogEditTextParams params = new DialogEditTextParams(getString(R.string.sb_text_feedback_comment_hint));
final Feedback currentFeedback = message.getMyFeedback();
if (currentFeedback != null) {
params.setText(currentFeedback.getComment());
}
params.setEnableSingleLine(true);
DialogUtils.showInputDialog(
requireContext(),
getString(R.string.sb_text_feedback_comment_title),
params,
listener,
positiveButtonText,
null,
getString(R.string.sb_text_button_cancel),
null
);
}

@SuppressWarnings("unused")
public static class Builder {
@NonNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.os.Bundle
import androidx.fragment.app.Fragment
import com.sendbird.android.params.MessageListParams
import com.sendbird.uikit.internal.model.notifications.NotificationConfig
import com.sendbird.uikit.internal.singleton.NotificationChannelManager.checkAndInit
import com.sendbird.uikit.internal.singleton.NotificationChannelManager.getGlobalNotificationChannelSettings
import com.sendbird.uikit.internal.ui.notifications.ChatNotificationChannelModule
import com.sendbird.uikit.internal.ui.notifications.FeedNotificationChannelModule
Expand All @@ -13,13 +14,15 @@ import com.sendbird.uikit.vm.ChatNotificationChannelViewModel
import com.sendbird.uikit.vm.FeedNotificationChannelViewModel

internal fun Fragment.createFeedNotificationChannelModule(args: Bundle): FeedNotificationChannelModule {
checkAndInit(requireContext())
val config = getGlobalNotificationChannelSettings()?.let {
NotificationConfig.from(it)
}
return ModuleProviders.feedNotificationChannel.provide(requireContext(), args, config)
}

internal fun Fragment.createChatNotificationChannelModule(args: Bundle): ChatNotificationChannelModule {
checkAndInit(requireContext())
val config = getGlobalNotificationChannelSettings()?.let {
NotificationConfig.from(it)
}
Expand Down
Loading

0 comments on commit 60cd795

Please sign in to comment.