feat:完成房间公聊功能

This commit is contained in:
max
2024-05-10 21:07:05 +08:00
parent a7a04c2950
commit f121ef5ad1
28 changed files with 556 additions and 160 deletions

View File

@@ -11,6 +11,7 @@ import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
@@ -22,6 +23,8 @@ import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.CallSuper
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.withResumed
@@ -53,13 +56,15 @@ import com.chwl.app.event.OpenRoomIntroEvent
import com.chwl.app.friend.view.SelectFriendActivity
import com.chwl.app.home.adapter.RoomActAdapter
import com.chwl.app.music.widget.MusicPlayerView
import com.chwl.app.public_chat.ui.message.HeadlineViewModel
import com.chwl.app.room_chat.activity.RoomMsgActivity
import com.chwl.app.ui.user.adapter.UserInfoIndicatorAdapter
import com.chwl.app.ui.pay.ChargeActivity
import com.chwl.app.ui.widget.ButtonItem
import com.chwl.app.ui.widget.GiftDialog
import com.chwl.app.ui.widget.GiftDialog.OnGiftDialogBtnClickListener
import com.chwl.app.ui.widget.GiftDialog.SenGiftCallback
import com.chwl.app.ui.widget.UserInfoDialog
import com.chwl.app.ui.widget.dialog.CommonTipDialog
import com.chwl.app.ui.widget.dynamicface.DynamicFaceDialog
import com.chwl.app.ui.widget.magicindicator.MagicIndicator
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil
@@ -68,6 +73,7 @@ import com.chwl.app.ui.widget.rollviewpager.RollPagerView
import com.chwl.app.ui.widget.rollviewpager.Util
import com.chwl.app.ui.widget.rollviewpager.hintview.ColorPointHintView
import com.chwl.app.utils.KeyBoardUtils
import com.chwl.app.vip.dialog.SelectPayTypeDialog
import com.chwl.core.Constants
import com.chwl.core.XConstants
import com.chwl.core.auth.AuthModel
@@ -102,6 +108,7 @@ import com.chwl.core.support.room.RoomWidget
import com.chwl.core.user.UserModel
import com.chwl.core.user.bean.BaseInfo
import com.chwl.core.user.bean.UserInfo
import com.chwl.core.utils.net.BalanceNotEnoughExeption
import com.chwl.core.utils.net.VipLevelNotEnoughException
import com.chwl.library.common.util.LimitClickUtils
import com.chwl.library.net.rxnet.utils.RxNetWorkUtils
@@ -117,6 +124,7 @@ import com.tbruyelle.rxpermissions2.RxPermissions
import com.trello.rxlifecycle3.android.FragmentEvent
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
@@ -135,12 +143,14 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
View.OnClickListener, OnGiftDialogBtnClickListener, IBaseRoomView, OnMicroItemClickListener,
RoomView {
private var myUid: Long = 0
protected lateinit var messagePager: ViewPager2
protected lateinit var messageView: MessageView
protected var publicChatMessageWidget: PublicChatRoomMessageWidget? = null
protected lateinit var bottomView: BottomView
protected lateinit var inputLayout: RelativeLayout
protected lateinit var inputEdit: EditText
protected lateinit var inputSend: ImageView
protected lateinit var inputHeadlineSend: ImageView
protected lateinit var microView: MicroView
private var musicPlayerView: MusicPlayerView? = null
private var mVsMusicPlayer: ViewStub? = null
@@ -182,10 +192,11 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
// 房间小组件
private var widgets: HashMap<String, RoomWidget> = HashMap()
private val headlineViewModel by activityViewModels<HeadlineViewModel>()
@CallSuper
override fun onFindViews() {
initMessageView()
// messageView = mView.findViewById(R.id.message_view)
bottomView = mView.findViewById(R.id.bottom_view)
inputLayout = mView.findViewById(R.id.input_layout)
inputEdit = mView.findViewById(R.id.input_edit)
@@ -198,6 +209,7 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
false
}
inputSend = mView.findViewById(R.id.input_send)
inputHeadlineSend = mView.findViewById(R.id.input_headline_send)
microView = mView.findViewById(R.id.micro_view)
mVsMusicPlayer = mView.findViewById(R.id.vs_music_player)
messageView.setClickConsumer {
@@ -218,12 +230,12 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
}
private fun initMessageView() {
messagePager = mView.findViewById<ViewPager2>(R.id.message_pager)
messageView = MessageView(context)
publicChatMessageWidget = PublicChatRoomMessageWidget(requireContext())
val tabList: MutableList<String> = java.util.ArrayList(2)
tabList.add(getString(R.string.room))
tabList.add(getString(R.string.public_chat_room))
val messagePager = mView.findViewById<ViewPager2>(R.id.message_pager)
val messageIndicator = mView.findViewById<MagicIndicator>(R.id.message_indicator)
messagePager.offscreenPageLimit = tabList.size
messagePager.adapter = object : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
@@ -290,6 +302,7 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
override fun onSetListener() {
bottomView.setMagicBtnEnable(true)
inputSend.setOnClickListener(this)
inputHeadlineSend.setOnClickListener(this)
inputLayout.setOnTouchListener { _: View?, _: MotionEvent? ->
inputEdit.clearFocus()
inputLayout.visibility = View.GONE
@@ -353,6 +366,44 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
//获取免费礼物详情
mvpPresenter?.queryFreeFlower()
initRoomAlbum()
initHeadline()
}
private fun initHeadline() {
headlineViewModel.loadingLiveData.observe(this) {
if (it) dialogManager?.showProgressDialog(context)
else dialogManager?.dismissDialog()
}
lifecycleScope.launch(Dispatchers.Main) {
headlineViewModel.sendHeadlineFlow.collect {
if (it.isSuccess) {
SingleToastUtil.showToast(R.string.sent_success)
inputEdit.setText("")
KeyBoardUtils.hideKeyBoard(activity, inputEdit)
} else {
if (it.code == BalanceNotEnoughExeption.code) {
showBalanceNotEnoughDialog()
} else {
SingleToastUtil.showToast(it.message)
}
}
}
}
headlineViewModel.getHeadlinePayMoneyIsNull()
}
private fun showBalanceNotEnoughDialog() {
val tipDialog = CommonTipDialog(context)
tipDialog.setTipMsg(ResUtil.getString(R.string.insufficient_balance_recharge_tips))
tipDialog.setOkText(getString(R.string.charge))
tipDialog.setOnActionListener(
object : CommonTipDialog.OnActionListener {
override fun onOk() {
ChargeActivity.start(context)
}
}
)
tipDialog.show()
}
@SuppressLint("CheckResult")
@@ -724,6 +775,10 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
messageView.clear()
}
private fun isPublicMessageTab(): Boolean {
return messagePager.currentItem == 1
}
@CallSuper
override fun onClick(v: View) {
if (mClickLimit.checkForTime(500)) return
@@ -731,11 +786,54 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
R.id.input_send -> {
sendMsg()
}
R.id.input_headline_send -> {
sendHeadline()
}
}
}
private fun sendMsg() {
sendMsg(inputEdit.text.toString())
val message = inputEdit.text.toString().trim()
if (isPublicMessageTab()) {
sendPublicChatMessage(message)
} else {
sendMsg(message)
}
}
private fun sendHeadline() {
val message = inputEdit.text.toString().trim()
if (TextUtils.isEmpty(message)) {
SingleToastUtil.showToast(ResUtil.getString(R.string.avroom_fragment_baseroomfragment_08))
return
}
if (message.length > 100) {
toast(R.string.headline_input_length_limit_tips)
return
}
val money = headlineViewModel.headlinePayMoneyLiveData.value
if (money != null) {
showHeadlinePayDialog(money, message)
} else {
SingleToastUtil.showToast(R.string.ui_setting_modifypwdactivity_01)
headlineViewModel.getHeadlinePayMoney()
}
}
private fun showHeadlinePayDialog(money: Long, message: String) {
KeyBoardUtils.hideKeyBoard(activity, inputEdit)
SelectPayTypeDialog.newInstance(
money.toString(),
false,
money.toDouble()
).apply {
setOnDiamondChargeClick {
headlineViewModel.sendHeadline(message)
}
setOnChargeClick {
ChargeActivity.start(context)
}
}.show(context)
}
@SuppressLint("CheckResult")
@@ -758,6 +856,20 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
inputEdit.setText("")
}
private fun sendPublicChatMessage(message: String){
if (!AuthModel.get().isImLogin) {
SingleToastUtil.showToast(ResUtil.getString(R.string.avroom_fragment_baseroomfragment_07))
return
}
if (TextUtils.isEmpty(message)) {
SingleToastUtil.showToast(ResUtil.getString(R.string.avroom_fragment_baseroomfragment_08))
return
}
mvpPresenter?.sendPublicChatTextMessage(message)
publicChatMessageWidget?.getMessageView()?.setNeedAutoScroll(true) // 發送後自動滾動公屏列表
inputEdit.setText("")
}
/**
* 軟鍵盤顯示與隱藏的監聽
*/
@@ -1069,6 +1181,12 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
KeyBoardUtils.hideKeyBoard(activity, inputEdit)
}
override fun onSendPublicChatMsgSuccess(msg: ChatRoomMessage) {
publicChatMessageWidget?.getMessageView()?.addMessages(msg)
inputEdit.setText("")
KeyBoardUtils.hideKeyBoard(activity, inputEdit)
}
/**
* 顯示資料卡片
*/
@@ -1089,7 +1207,7 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
return
}
if (AvRoomDataManager.get().isSelfGamePlaying) {
SingleToastUtil.showToast("遊戲中不可以換麥!")
SingleToastUtil.showToast(R.string.avroom_presenter_baseroompresenter_01)
return
}
UserModel.get().cacheLoginUserInfo?.gameStatus = GameStatus.STATUS_NOT_JOIN
@@ -1098,9 +1216,13 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
if (result) {
mvpPresenter?.upMicroPhone(micPosition, currentUid, b)
} else {
toast("請給予麥克風權限後再試!")
toast(R.string.permission_mic_tips)
}
}, { _: Throwable? -> toast("發生一些異常,請稍後重試!") })
}, { error: Throwable? ->
error?.let {
toast(it.message)
} ?: toast(R.string.exception_try_again)
})
}
/**
@@ -1164,7 +1286,9 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
}
override fun onFollowFail(msg: String?) {
toast("關註失敗,請稍後重試")
msg?.let {
toast(msg)
}
}
override fun updateMicView() {
@@ -1323,7 +1447,6 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
}
open fun initWidget() {
publicChatMessageWidget?.let {
registerWidget(PublicChatRoomMessageWidget::class.java.simpleName, it)
}
@@ -1344,6 +1467,7 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
* 打开公屏输入
*/
fun openMessageInput(text: String?) {
inputHeadlineSend.isVisible = isPublicMessageTab()
inputLayout.visibility = View.VISIBLE
if (text != null) {
inputEdit.setText(text)

View File

@@ -6,6 +6,9 @@ import android.util.Log;
import androidx.annotation.Nullable;
import com.chwl.app.public_chat.core.ChatRoomClient;
import com.chwl.app.public_chat.core.ChatRoomClientManager;
import com.chwl.core.initial.InitialModel;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@@ -26,7 +29,6 @@ import com.chwl.core.im.custom.bean.RoomInfoAttachment;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.manager.IMNetEaseManager;
import com.chwl.core.praise.PraiseModel;
import com.chwl.core.room.bean.RoomContributeDataInfo;
import com.chwl.core.room.bean.RoomInfo;
import com.chwl.core.room.exception.AntiSpamHitException;
import com.chwl.core.room.game.GameStatus;
@@ -34,7 +36,6 @@ import com.chwl.core.room.giftvalue.helper.GiftValueMrg;
import com.chwl.core.room.model.AvRoomModel;
import com.chwl.core.room.model.HomePartyModel;
import com.chwl.core.room.model.RoomBaseModel;
import com.chwl.core.room.model.RoomContributeListModel;
import com.chwl.core.room.queue.bean.MicMemberInfo;
import com.chwl.core.super_admin.model.SuperAdminModel;
import com.chwl.core.super_admin.util.SuperAdminUtil;
@@ -52,7 +53,6 @@ import com.chwl.library.utils.SingleToastUtil;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.BiConsumer;
@@ -562,4 +562,25 @@ public class BaseRoomPresenter<V extends IBaseRoomView> extends BaseMvpPresenter
.subscribe();
}
@SuppressLint("CheckResult")
public void sendPublicChatTextMessage(String message) {
if (TextUtils.isEmpty(message)) return;
String sessionId = InitialModel.get().getPublicChatSessionId();
if (sessionId == null) {
SingleToastUtil.showToast(R.string.public_chat_not_found);
return;
}
ChatRoomClient client = ChatRoomClientManager.INSTANCE.getClient(sessionId);
ChatRoomMessage textMessage = ChatRoomMessageBuilder.createChatRoomTextMessage(sessionId, message);
client.sendMessage(textMessage).compose(bindToLifecycle()).subscribe(new BiConsumer<Object, Throwable>() {
@Override
public void accept(Object o, Throwable throwable) throws Exception {
if (throwable != null) {
SingleToastUtil.showToast(throwable.getMessage());
} else {
getMvpView().onSendPublicChatMsgSuccess(textMessage);
}
}
});
}
}

View File

@@ -2,6 +2,7 @@ package com.chwl.app.avroom.public_chat;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
@@ -17,6 +18,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
@@ -34,12 +36,17 @@ import com.chwl.app.avroom.dialog.PKResultDialog;
import com.chwl.app.avroom.widget.OnMsgLongClickListener;
import com.chwl.app.avroom.widget.TemplateMessageAdapter;
import com.chwl.app.common.widget.OriginalDrawStatusClickSpan;
import com.chwl.app.photo.BigPhotoActivity;
import com.chwl.app.photo.PagerOption;
import com.chwl.app.public_chat.core.viewholder.ChatRoomMessageViewHolderThumbBase;
import com.chwl.app.ui.utils.ImageLoadUtils;
import com.chwl.app.ui.utils.ImageLoadUtilsV2;
import com.chwl.app.ui.widget.DividerItemDecoration;
import com.chwl.app.ui.widget.MyItemAnimator;
import com.chwl.app.ui.widget.RecyclerViewNoViewpagerScroll;
import com.chwl.app.ui.widget.TextSpannableBuilder;
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
import com.chwl.app.utils.ObjectTypeHelper;
import com.chwl.app.utils.RegexUtil;
import com.chwl.core.DemoCache;
import com.chwl.core.XConstants;
@@ -48,8 +55,8 @@ import com.chwl.core.bean.attachmsg.RoomQueueMsgAttachment;
import com.chwl.core.decoration.car.bean.CarInfo;
import com.chwl.core.home.event.FollowRoomEvent;
import com.chwl.core.home.model.CollectionRoomModel;
import com.chwl.core.im.custom.bean.AuctionAttachment;
import com.chwl.core.im.custom.bean.CustomAttachment;
import com.chwl.core.im.custom.bean.HeadlineChangedAttachment;
import com.chwl.core.im.custom.bean.MonsterHuntingResultAttachment;
import com.chwl.core.im.custom.bean.MonsterStatusAttachment;
import com.chwl.core.im.custom.bean.RoomBoxPrizeAttachment;
@@ -62,6 +69,7 @@ import com.chwl.core.monsterhunting.bean.MonsterDataBean;
import com.chwl.core.monsterhunting.bean.MonsterHuntingResult;
import com.chwl.core.noble.NobleUtil;
import com.chwl.core.praise.PraiseModel;
import com.chwl.core.public_chat_hall.bean.HeadlineBean;
import com.chwl.core.room.bean.RoomInfo;
import com.chwl.core.room.pk.attachment.RoomPkAttachment;
import com.chwl.core.user.bean.UserInfo;
@@ -73,12 +81,13 @@ import com.chwl.library.utils.ResUtil;
import com.chwl.library.utils.SingleToastUtil;
import com.chwl.library.utils.SizeUtils;
import com.example.lib_utils.UiUtils;
import com.netease.nim.uikit.business.uinfo.UserInfoHelper;
import com.example.lib_utils.spannable.SpannableTextBuilder;
import com.netease.nim.uikit.common.util.media.ImageUtil;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessageExtension;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomNotificationAttachment;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.netease.nimlib.sdk.msg.attachment.ImageAttachment;
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
import com.netease.nimlib.sdk.msg.constant.NotificationType;
@@ -103,10 +112,8 @@ import io.reactivex.functions.Consumer;
public class PublicChatMessageView extends FrameLayout {
private static final String TAG = "PublicChatMessageView";
private final static int MAX_MESSAGE_SIZE = 2000;//公屏最多展示條數
private final static int MAX_MESSAGE_SIZE = 100;//公屏最多展示條數
private final static int BLOCK_MAX_MESSAGE_SIZE = MAX_MESSAGE_SIZE * 3 / 2;//在查看消息停住的時候 最多消息條數.
private static final int LOAD_MESSAGE_COUNT = 10;
private final int textColor = 0x80ffffff;
private final List<ChatRoomMessage> atMessages = new ArrayList<>();
private final List<ChatRoomMessage> chatRoomMessages = new LinkedList<>();
private RecyclerView messageListView;
@@ -118,17 +125,11 @@ public class PublicChatMessageView extends FrameLayout {
private int paddingHeight;
private int whiteColor;
private int greyColor;
private int roomTipNickColor;
private int roomTipColor;
private int roomBlueColor;
private int badgeWidth;
private int badgeHeight;
private int sysIconHeight;
private int smallFace;
private int bigFace;
private int expLevelWidth;
private int expLevelHeight;
private int giftLength;
private int defTextSize = 12;
private volatile boolean needAutoScroll = true;//是否自動滾動到底部
private Consumer<String> clickConsumer;
private OnClick onClick;
@@ -148,6 +149,7 @@ public class PublicChatMessageView extends FrameLayout {
super(context, attr, i);
init(context);
}
public void setOnLongClickListener(OnMsgLongClickListener onLongClickListener) {
this.onLongClickListener = onLongClickListener;
}
@@ -174,20 +176,13 @@ public class PublicChatMessageView extends FrameLayout {
private void init(Context context) {
whiteColor = ContextCompat.getColor(context, R.color.white);
greyColor = ContextCompat.getColor(context, R.color.white_transparent_50);
roomTipNickColor = ContextCompat.getColor(context, R.color.color_FEE057);
roomTipColor = ContextCompat.getColor(context, R.color.color_FEE057);
roomBlueColor = ContextCompat.getColor(context, R.color.color_00EAFF);
paddingWidth = Utils.dip2px(context, 11);
paddingHeight = Utils.dip2px(context, 6);
badgeWidth = Utils.dip2px(context, 15);
badgeHeight = Utils.dip2px(context, 15);
sysIconHeight = Utils.dip2px(context, 14);
smallFace = Utils.dip2px(context, 22);
bigFace = Utils.dip2px(context, 30);
//經驗等級圖片後臺已經更換尺寸了公屏同步下尺寸是36:18
expLevelHeight = Utils.dip2px(context, 18);
expLevelWidth = expLevelHeight * 36 / 18;//expLevelHeight * 114 / 45
giftLength = Utils.dip2px(context, 35);
// 內容區域
layoutManger = new LinearLayoutManager(context, RecyclerView.VERTICAL, false);
LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
@@ -238,7 +233,9 @@ public class PublicChatMessageView extends FrameLayout {
tvBottomTip.setOnClickListener(v -> {
tvBottomTip.setVisibility(GONE);
needAutoScroll = true;
if (mMessageAdapter.getItemCount() > 0) {
messageListView.smoothScrollToPosition(mMessageAdapter.getItemCount() - 1);
}
});
addView(tvBottomTip);
@@ -332,7 +329,7 @@ public class PublicChatMessageView extends FrameLayout {
/**
* 添加公屏消息請使用 {@link AvRoomDataManager#addChatRoomMessage(ChatRoomMessage)}
*/
private void addMessages(ChatRoomMessage msg) {
public void addMessages(ChatRoomMessage msg) {
if (msg == null) return;
chatRoomMessages.add(msg);
//通知adapter 刷新
@@ -345,7 +342,7 @@ public class PublicChatMessageView extends FrameLayout {
if (messages == null) return;
chatRoomMessages.addAll(messages);
//通知adapter 刷新
mMessageAdapter.notifyItemInserted(mMessageAdapter.getItemCount() - 1);
mMessageAdapter.notifyDataSetChanged();
showTipsOrScrollToBottom();
for (ChatRoomMessage message : messages) {
checkAtMe(message, true);
@@ -399,17 +396,21 @@ public class PublicChatMessageView extends FrameLayout {
}
}
private void showTipsOrScrollToBottom() {
public void showTipsOrScrollToBottom() {
if (!needAutoScroll) {
tvBottomTip.setVisibility(VISIBLE);
//超過某值後自動滾動下去
if (mMessageAdapter.getItemCount() > BLOCK_MAX_MESSAGE_SIZE) {
if (mMessageAdapter.getItemCount() > 0) {
messageListView.smoothScrollToPosition(mMessageAdapter.getItemCount() - 1);
}
}
return;
}
if (mMessageAdapter.getItemCount() > 0) {
messageListView.smoothScrollToPosition(mMessageAdapter.getItemCount() - 1);
}
}
public void release() {
@@ -427,16 +428,11 @@ public class PublicChatMessageView extends FrameLayout {
}
}
public void setNeedAutoScroll(boolean needAutoScroll) {
this.needAutoScroll = needAutoScroll;
}
public interface OnClick {
/**
* 點擊關註
*
* @param position
*/
void onFollowClick(int position);
void onJoinMiniWorldClick(int position);
/**
* 公屏查看公告
*/
@@ -450,6 +446,8 @@ public class PublicChatMessageView extends FrameLayout {
private Context mContext;
private List<ChatRoomMessage> data;
private int ITEM_TYPE_IMAGE = 1;
public MessageAdapter(Context mContext) {
this.mContext = mContext;
}
@@ -461,13 +459,8 @@ public class PublicChatMessageView extends FrameLayout {
@Override
public int getItemViewType(int position) {
ChatRoomMessage chatRoomMessage = data.get(position);
if (chatRoomMessage.getMsgType() == MsgTypeEnum.custom) {
MsgAttachment attachment = chatRoomMessage.getAttachment();
if (attachment instanceof CustomAttachment) {
if (((CustomAttachment) attachment).getFirst() == CustomAttachment.CUSTOM_MSG_ROOM_ALBUM) {
return CustomAttachment.CUSTOM_MSG_ROOM_ALBUM;
}
}
if (chatRoomMessage.getMsgType() == MsgTypeEnum.image) {
return ITEM_TYPE_IMAGE;
}
return super.getItemViewType(position);
@@ -475,25 +468,80 @@ public class PublicChatMessageView extends FrameLayout {
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == ITEM_TYPE_IMAGE) {
return new MessageAdapter.MessageViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_chatroom_msg_image, parent, false));
}
return new MessageViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_chatrrom_msg, parent, false));
}
@Override
public void onBindViewHolder(MessageViewHolder holder, int position) {
if (getItemViewType(position) == ITEM_TYPE_IMAGE) {
convertImage(holder, data.get(position));
} else {
convert(holder, data.get(position));
}
}
@Override
public int getItemCount() {
return data.size();
}
protected void convertImage(MessageViewHolder baseViewHolder, ChatRoomMessage chatRoomMessage) {
TextView tvContent = baseViewHolder.tvContent;
tvContent.setLineSpacing(0, 1);
tvContent.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
tvContent.setOnClickListener(this);
tvContent.setTag(chatRoomMessage);
if (UiUtils.INSTANCE.isRtl(tvContent.getContext())) {
tvContent.setTextDirection(View.TEXT_DIRECTION_RTL);
}
try {
setVIPMessageBackground(chatRoomMessage, baseViewHolder.itemView);
ChatRoomMessageExtension extension = chatRoomMessage.getChatRoomMessageExtension();
TextSpannableBuilder text = new TextSpannableBuilder(tvContent);
addCommonTag(chatRoomMessage, text, tvContent);
String nickName = extension == null ? ResUtil.getString(R.string.avroom_widget_messageview_0116) : RegexUtil.getPrintableString(extension.getSenderNick());
text.append(nickName, new ForegroundColorSpan(greyColor));
tvContent.setText(text.build());
ImageView imageView = baseViewHolder.itemView.findViewById(R.id.iv_image);
ImageAttachment msgAttachment = (ImageAttachment) chatRoomMessage.getAttachment();
String path = msgAttachment.getThumbPath();
if (TextUtils.isEmpty(path)) {
path = msgAttachment.getPath();
}
if (TextUtils.isEmpty(path)) {
path = "";
}
ImageLoadUtilsV2.loadImage(imageView, path);
int[] bounds = new int[]{msgAttachment.getWidth(), msgAttachment.getHeight()};
ImageUtil.ImageSize imageSize = ImageUtil.getThumbnailDisplaySize(bounds[0], bounds[1], ChatRoomMessageViewHolderThumbBase.getImageMaxEdge(), ChatRoomMessageViewHolderThumbBase.getImageMinEdge());
ViewGroup.LayoutParams maskParams = imageView.getLayoutParams();
maskParams.width = imageSize.width;
maskParams.height = imageSize.height;
imageView.setLayoutParams(maskParams);
String finalPath = path;
imageView.setOnClickListener(v -> {
BigPhotoActivity.start((Activity) mContext, ObjectTypeHelper.pathToCustomItems(finalPath),
0, new PagerOption());
});
} catch (Exception e) {
e.printStackTrace();
}
}
protected void convert(MessageViewHolder baseViewHolder, ChatRoomMessage chatRoomMessage) {
if (chatRoomMessage == null) return;
TextView tvContent = baseViewHolder.tvContent;
tvContent.setLineSpacing(0, 1);
tvContent.setTextColor(Color.WHITE);
tvContent.setTextSize(defTextSize);
tvContent.setOnClickListener(this);
tvContent.setOnLongClickListener(null);
tvContent.setTag(chatRoomMessage);
@@ -504,7 +552,6 @@ public class PublicChatMessageView extends FrameLayout {
clearBackground(tvContent);
try {
if (chatRoomMessage.getMsgType() == MsgTypeEnum.tip) {
String contentText = chatRoomMessage.getContent();
// 房間通告
tvContent.setTextColor(ContextCompat.getColor(mContext, R.color.color_92F9E8));
tvContent.setText(chatRoomMessage.getContent());
@@ -520,8 +567,10 @@ public class PublicChatMessageView extends FrameLayout {
CustomAttachment attachment = (CustomAttachment) chatRoomMessage.getAttachment();
int first = attachment.getFirst();
int second = attachment.getSecond();
if (first == CustomAttachment.CUSTOM_MSG_HEADER_TYPE_AUCTION) {
setMsgAuction(chatRoomMessage, tvContent, attachment);
if (first == CustomAttachment.CUSTOM_MSG_HEADLINE_CHANGED) {
if (second == CustomAttachment.CUSTOM_MSG_HEADLINE_CHANGED_SUB) {
setHeadlineMsg(chatRoomMessage, tvContent, attachment);
}
} else {
tvContent.setTextColor(Color.WHITE);
tvContent.setText(tvContent.getResources().getText(R.string.not_support_message_tip));
@@ -543,6 +592,12 @@ public class PublicChatMessageView extends FrameLayout {
textView.setPadding(paddingWidth, paddingHeight, paddingWidth, paddingHeight);
}
private void setNullBackground(TextView textView) {
// 清除聊天氣泡
textView.setBackground(null);
textView.setPadding(0, 0, 0, 0);
}
public void setVIPMessageBackground(ChatRoomMessage chatRoomMessage, View view) {
String androidBubbleUrl = NobleUtil.getResource(UserInfo.BUBBLE_URL_ANDROID, chatRoomMessage);
if (TextUtils.isEmpty(androidBubbleUrl)) return;
@@ -630,34 +685,24 @@ public class PublicChatMessageView extends FrameLayout {
}
}
/**
* 暫時已拋棄
*
* @param chatRoomMessage -
* @param tvContent -
* @param attachment -
*/
private void setMsgAuction(ChatRoomMessage chatRoomMessage, TextView tvContent, CustomAttachment attachment) {
String senderNick = chatRoomMessage.getChatRoomMessageExtension().getSenderNick();
senderNick = senderNick == null ? "" : senderNick;
AuctionAttachment auctionAttachment = (AuctionAttachment) attachment;
TextSpannableBuilder builder = new TextSpannableBuilder(tvContent);
if (attachment.getSecond() == CustomAttachment.CUSTOM_MSG_SUB_TYPE_AUCTION_START) {
builder.append(ResUtil.getString(R.string.avroom_widget_messageview_0117), new ForegroundColorSpan(roomTipNickColor));
} else if (attachment.getSecond() == CustomAttachment.CUSTOM_MSG_SUB_TYPE_AUCTION_FINISH) {
if (auctionAttachment.getAuctionInfo().getCurMaxUid() > 0) {
senderNick = UserInfoHelper.getUserDisplayName(auctionAttachment.getAuctionInfo().getCurMaxUid() + "");
String voiceActorNick = UserInfoHelper.getUserDisplayName(auctionAttachment.getAuctionInfo().getAuctUid() + "");
builder.append(senderNick, new ForegroundColorSpan(roomTipNickColor))
.append(ResUtil.getString(R.string.avroom_widget_messageview_0118) + auctionAttachment.getAuctionInfo().getRivals().get(0).getAuctMoney() + ResUtil.getString(R.string.avroom_widget_messageview_0119))
.append(voiceActorNick, new ForegroundColorSpan(roomTipNickColor));
} else
builder.append(ResUtil.getString(R.string.avroom_widget_messageview_0120), new ForegroundColorSpan(roomTipNickColor));
} else {
builder.append(senderNick, new ForegroundColorSpan(roomTipNickColor))
.append(ResUtil.getString(R.string.avroom_widget_messageview_0121) + auctionAttachment.getAuctionInfo().getRivals().get(0).getAuctMoney() + ResUtil.getString(R.string.avroom_widget_messageview_027));
private void setHeadlineMsg(ChatRoomMessage chatRoomMessage, TextView tvContent, CustomAttachment attachment) {
HeadlineChangedAttachment headlineAttachment = (HeadlineChangedAttachment) attachment;
SpannableTextBuilder builder = new SpannableTextBuilder(tvContent);
if (attachment.getSecond() == CustomAttachment.CUSTOM_MSG_HEADLINE_CHANGED_SUB) {
HeadlineBean data = headlineAttachment.getHeadlineData();
String nick = null;
if (data != null) {
nick = data.getNick();
}
if (nick == null) {
nick = "";
}
builder.appendText(String.format(ResUtil.getString(R.string.headline_message_format), nick), null, null, null, null, null, null);
builder.setTextStyle(nick, ContextCompat.getColor(getContext(), R.color.color_DE3446), null, null, null, null, null);
}
tvContent.setText(builder.build());
tvContent.setTextSize(9);
setNullBackground(tvContent);
}
/**

View File

@@ -2,11 +2,18 @@ package com.chwl.app.avroom.public_chat
import android.content.Context
import android.util.AttributeSet
import android.view.ViewGroup
import android.view.LayoutInflater
import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil
import com.chwl.app.R
import com.chwl.app.databinding.RoomPublicChatMessageWidgetBinding
import com.chwl.app.public_chat.core.ChatRoomClient
import com.chwl.app.public_chat.core.ChatRoomClientManager
import com.chwl.core.im.custom.bean.CustomAttachment
import com.chwl.core.im.custom.bean.HeadlineChangedAttachment
import com.chwl.core.initial.InitialModel
import com.chwl.core.public_chat_hall.bean.HeadlineBean
import com.chwl.core.public_chat_hall.model.PublicChatModel
import com.chwl.core.support.room.FrameLayoutRoomWidget
import com.chwl.core.support.room.RoomView
import com.chwl.library.utils.SingleToastUtil
@@ -14,11 +21,15 @@ import com.netease.nim.uikit.api.model.NimException
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum
import com.netease.nimlib.sdk.msg.model.QueryDirectionEnum
import java.util.Collections
class PublicChatRoomMessageWidget : FrameLayoutRoomWidget {
private var messageListView: PublicChatMessageView = PublicChatMessageView(context)
private val binding: RoomPublicChatMessageWidgetBinding =
DataBindingUtil.inflate(
LayoutInflater.from(
context
), R.layout.room_public_chat_message_widget, this, true
)
private var chatRoomClient: ChatRoomClient? = null
@@ -37,13 +48,6 @@ class PublicChatRoomMessageWidget : FrameLayoutRoomWidget {
defStyleRes: Int
) : super(context, attrs, defStyleAttr, defStyleRes)
init {
addView(
messageListView,
LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
)
}
override fun onStart(roomView: RoomView) {
super.onStart(roomView)
val sessionId = InitialModel.get().publicChatSessionId
@@ -55,10 +59,26 @@ class PublicChatRoomMessageWidget : FrameLayoutRoomWidget {
chatRoomClient?.let {
initChatRoom(it)
}
requestCurrentHeadline()
}
private fun onReceiveMessage(list: List<ChatRoomMessage>) {
messageListView.addMessages(list)
private fun onReceiveMessage(message: ChatRoomMessage) {
if (!filterMessageForMessageList(message)) {
binding.messageView.addMessages(message)
}
if (message.msgType == MsgTypeEnum.custom) {
val attachment: CustomAttachment = (message.attachment as? CustomAttachment) ?: return
when (attachment.first) {
CustomAttachment.CUSTOM_MSG_HEADLINE_CHANGED -> {
when (attachment.second) {
CustomAttachment.CUSTOM_MSG_HEADLINE_CHANGED_SUB -> {
val data = (attachment as? HeadlineChangedAttachment) ?: return
updateHeadline(data.headlineData)
}
}
}
}
}
}
private fun initChatRoom(chatRoomClient: ChatRoomClient) {
@@ -75,7 +95,9 @@ class PublicChatRoomMessageWidget : FrameLayoutRoomWidget {
)
getCompositeDisposable().add(chatRoomClient.messageObservable.subscribe {
onReceiveMessage(it)
it.forEach { message ->
onReceiveMessage(message)
}
})
}
@@ -88,13 +110,44 @@ class PublicChatRoomMessageWidget : FrameLayoutRoomWidget {
QueryDirectionEnum.QUERY_OLD,
typeEnums
).subscribe({
messageListView.addHistoryMessages(it.reversed())
binding.messageView.addHistoryMessages(it.reversed())
}, {
it.printStackTrace()
})
)
}
private fun requestCurrentHeadline() {
safeLaunch {
val data = PublicChatModel.getCurrentHeadline()
updateHeadline(data)
}
}
private fun updateHeadline(data: HeadlineBean?) {
val content = data?.content
if (content.isNullOrEmpty()) {
binding.tvHeadlineContent.isVisible = false
} else {
binding.tvHeadlineContent.text = content
binding.tvHeadlineContent.isVisible = true
}
}
private fun filterMessageForMessageList(message: ChatRoomMessage): Boolean {
if (message.msgType == MsgTypeEnum.notification) {
return true
}
if (message.attachment is HeadlineChangedAttachment) {
if ((message.attachment as HeadlineChangedAttachment).headlineData == null) {
return true
}
}
return false
}
fun getMessageView() = binding.messageView
override fun onStop() {
super.onStop()
chatRoomClient = null

View File

@@ -3,6 +3,7 @@ package com.chwl.app.avroom.view
import com.chwl.core.bean.RoomMicInfo
import com.chwl.core.room.bean.RoomContributeUserInfo
import com.chwl.library.base.IMvpBaseView
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage
/**
*
@@ -32,6 +33,7 @@ interface IBaseRoomView : IMvpBaseView {
fun chatRoomReConnectView()
fun showToast(msg: String?)
fun onSendMsgSuccess(msg: String?)
fun onSendPublicChatMsgSuccess(msg: ChatRoomMessage)
/**
* 上麦请求

View File

@@ -5,7 +5,6 @@ import android.view.MotionEvent
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.view.GestureDetectorCompat
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.RecyclerView
@@ -166,7 +165,6 @@ class ContactsListFragment : BaseViewBindingFragment<FragmentContactListBinding>
publicChatAdapter.setNewData(newList)
switchPublicChatMessageScrollState(true)
}
binding.layoutPublicChat.isVisible = (publicChatAdapter.getRealItemCount() > 0)
}
}
@@ -190,6 +188,9 @@ class ContactsListFragment : BaseViewBindingFragment<FragmentContactListBinding>
}
private fun switchPublicChatMessageScrollState(showOrHide: Boolean) {
if (_binding == null) {
return
}
if (showOrHide && publicChatAdapter.getRealItemCount() > 0) {
autoScrollTask.start()
} else {

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="7dp" />
<solid android:color="#593742" />
</shape>

View File

@@ -117,8 +117,9 @@
<com.chwl.app.ui.widget.magicindicator.MagicIndicator
android:id="@+id/message_indicator"
android:layout_alignParentStart="true"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_44"
android:layout_height="@dimen/dp_35"
android:layout_below="@id/micro_view"
android:layout_marginTop="@dimen/dp_5" />
@@ -132,18 +133,6 @@
android:layout_marginEnd="90dp"
android:layout_marginBottom="@dimen/dp_10" />
<!-- <com.chwl.app.avroom.widget.MessageView-->
<!-- android:visibility="gone"-->
<!-- android:id="@+id/message_view"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:layout_above="@id/bottom_view"-->
<!-- android:layout_below="@id/micro_view"-->
<!-- android:layout_marginStart="12dp"-->
<!-- android:layout_marginTop="@dimen/dp_5"-->
<!-- android:layout_marginEnd="90dp"-->
<!-- android:layout_marginBottom="@dimen/dp_10" />-->
<com.coorchice.library.SuperTextView
android:id="@+id/tv_dating_next"
android:layout_width="wrap_content"
@@ -314,6 +303,16 @@
android:background="@drawable/click_white_gray_selector"
android:scaleType="center"
android:src="@android:drawable/ic_menu_send" />
<ImageView
android:visibility="gone"
tools:visibility="visible"
android:id="@+id/input_headline_send"
android:layout_width="50dp"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:src="@drawable/room_ic_headline_send" />
</LinearLayout>
</RelativeLayout>

View File

@@ -14,8 +14,6 @@
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:visibility="gone"
tools:visibility="visible"
android:id="@+id/layout_public_chat"
android:layout_width="match_parent"
android:layout_height="0dp"

View File

@@ -72,18 +72,25 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.chwl.app.avroom.widget.MessageView
android:id="@+id/message_view"
<com.chwl.app.ui.widget.magicindicator.MagicIndicator
android:id="@+id/message_indicator"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_35"
android:layout_marginTop="@dimen/dp_8"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier_micro" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/message_pager"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="12dp"
android:layout_marginTop="@dimen/dp_8"
android:layout_marginEnd="90dp"
android:layout_marginBottom="@dimen/dp_10"
app:layout_constraintBottom_toTopOf="@id/bottom_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier_micro" />
app:layout_constraintTop_toBottomOf="@id/message_indicator" />
<com.chwl.app.avroom.gameplay.RoomGameplayWidget
android:id="@+id/gameplay_widget"
@@ -131,7 +138,7 @@
android:layout_weight="1"
android:background="@android:color/white"
android:hint="@string/layout_fragment_single_room_08"
android:paddingLeft="10dp"
android:paddingStart="10dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:textColor="#888889"
@@ -142,10 +149,19 @@
android:id="@+id/input_send"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:background="@drawable/click_white_gray_selector"
android:scaleType="center"
android:src="@android:drawable/ic_menu_send" />
<ImageView
android:visibility="gone"
tools:visibility="visible"
android:id="@+id/input_headline_send"
android:layout_width="50dp"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:src="@drawable/room_ic_headline_send" />
</LinearLayout>
</RelativeLayout>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_room_message_bg"
android:orientation="vertical"
android:paddingHorizontal="@dimen/dp_11"
android:paddingVertical="@dimen/dp_6">
<com.chwl.app.avroom.widget.FixRoomTitleTextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:gravity="start|center_vertical"
android:textColor="@android:color/white"
android:textSize="12dp"
tools:text="@string/layout_list_item_chatrrom_msg_01"
tools:textColor="#000" />
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/iv_image"
android:layout_width="@dimen/dp_140"
android:layout_height="@dimen/dp_140"
android:layout_marginTop="@dimen/dp_4"
android:scaleType="centerCrop"
app:shapeAppearance="@style/shape_corner_8dp" />
</LinearLayout>

View File

@@ -13,7 +13,7 @@
android:background="@drawable/shape_room_message_bg"
android:gravity="start|center_vertical"
android:textColor="@android:color/white"
android:textSize="12sp"
android:textSize="12dp"
tools:text="@string/layout_list_item_chatrrom_msg_01"
tools:textColor="#000" />

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<layout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_headline_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape_593722_7dp"
android:paddingHorizontal="@dimen/dp_10"
android:paddingTop="@dimen/dp_9"
android:paddingBottom="@dimen/dp_13"
android:textColor="#FDF4D5"
android:textSize="@dimen/dp_13"
tools:text="Content" />
<com.chwl.app.avroom.public_chat.PublicChatMessageView
android:id="@+id/message_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</layout>

View File

@@ -5261,4 +5261,6 @@
<string name="gift_message_07">{0} محظوظ للغاية! تم فتح {3} بقيمة {2} من العملات الذهبية في {1}</string>
<string name="gift_message_08">{0} محظوظ للغاية! تم فتح {4}X{3} بقيمة {2} من العملات الذهبية في {1}</string>
<string name="send_gift_vip_level_tips">أنت لم تصل إلى المستوى الـ VIP المطلوب لإرسال %1$s. المستوى الـ VIP المطلوب: %2$s</string>
<string name="exception_try_again">حدثت بعض الاستثناءات، يرجى المحاولة مرة أخرى لاحقًا!</string>
<string name="permission_mic_tips">يرجى السماح بإذن الميكروفون والمحاولة مرة أخرى</string>
</resources>

View File

@@ -5203,4 +5203,5 @@
<string name="send_gift_vip_level_tips">尚未達到贈送%1$s所需VIP等級,所需VIP等級:%2$s</string>
<string name="gift_message_07">{0}運氣爆表!在{1}中開出了價值{2}金币的{3}</string>
<string name="gift_message_08">{0}運氣爆表!在{1}中開出了價值{2}金币的{3}X{4}</string>
<string name="exception_try_again">發生一些異常,請稍後重試!</string>
</resources>

View File

@@ -5240,6 +5240,9 @@
<string name="gift_message_07">{0} Amazing Luck! Opened a {1} worth {2} Coins in {3}</string>
<string name="gift_message_08">{0} Amazing Luck! Opened a {1} worth {2} Coins in {3} X{4}</string>
<string name="exception_try_again">Some exceptions occurred, please try again later!</string>
<string name="permission_mic_tips">Please allow microphone permission and try again</string>
</resources>

View File

@@ -610,4 +610,8 @@
<item name="cornerSize">@dimen/dp_6</item>
</style>
<style name="shape_corner_8dp">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">@dimen/dp_8</item>
</style>
</resources>

View File

@@ -1,9 +1,16 @@
package com.chwl.app.public_chat.core
import com.chwl.core.initial.InitialModel
object ChatRoomClientManager {
private val clients = HashMap<String, ChatRoomClient>()
fun getPublicChatClient(): ChatRoomClient? {
val sessionId = InitialModel.get().publicChatSessionId
return getClient(sessionId)
}
fun getClient(sessionId: String): ChatRoomClient {
var finalClient = clients[sessionId]
if (finalClient?.sessionId == sessionId) {

View File

@@ -0,0 +1,37 @@
package com.chwl.app.public_chat.ui.message
import androidx.lifecycle.MutableLiveData
import com.chwl.app.base.BaseViewModel
import com.chwl.core.bean.response.BeanResult
import com.chwl.core.public_chat_hall.model.PublicChatModel
import kotlinx.coroutines.flow.MutableSharedFlow
class HeadlineViewModel : BaseViewModel() {
val sendHeadlineFlow = MutableSharedFlow<BeanResult<Any>>()
val headlinePayMoneyLiveData = MutableLiveData<Long?>()
fun sendHeadline(message: String) {
safeLaunch(needLoading = true, onError = {
sendHeadlineFlow.emit(BeanResult.failed(it))
}) {
PublicChatModel.sendHeadline(message)
sendHeadlineFlow.emit(BeanResult.success(true))
}
}
fun getHeadlinePayMoneyIsNull() {
if (headlinePayMoneyLiveData.value == null) {
getHeadlinePayMoney()
}
}
fun getHeadlinePayMoney() {
safeLaunch(needLoading = false, onError = {
}) {
val value = PublicChatModel.getHeadlinePayMoney()
headlinePayMoneyLiveData.postValue(value)
}
}
}

View File

@@ -260,7 +260,6 @@ public class PublicChatRoomMessageListPanel {
}
public void onIncomingMessage(List<ChatRoomMessage> messages) {
Log.d("MAAAX", "onIncomingMessage messages.size:" + messages.size());
boolean needScrollToBottom = isLastMessageVisible();
boolean needRefresh = false;
List<ChatRoomMessage> addedListItems = new ArrayList<>(messages.size());

View File

@@ -1,17 +1,16 @@
package com.chwl.app.public_chat.ui.message
import android.annotation.SuppressLint
import androidx.lifecycle.MutableLiveData
import com.chwl.app.base.BaseViewModel
import com.chwl.app.public_chat.core.ChatRoomClient
import com.chwl.app.public_chat.core.ChatRoomClientManager
import com.chwl.core.bean.response.BeanResult
import com.chwl.core.im.custom.bean.CustomAttachment
import com.chwl.core.im.custom.bean.HeadlineChangedAttachment
import com.chwl.core.public_chat_hall.bean.HeadlineBean
import com.chwl.core.public_chat_hall.model.PublicChatModel
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum
import kotlinx.coroutines.flow.MutableSharedFlow
class PublicChatRoomViewModel : BaseViewModel() {
@@ -19,20 +18,17 @@ class PublicChatRoomViewModel : BaseViewModel() {
val headlineLiveData = MutableLiveData<HeadlineBean?>()
val sendHeadlineFlow = MutableSharedFlow<BeanResult<Any>>()
val headlinePayMoneyLiveData = MutableLiveData<Long?>()
fun init(sessionId: String) {
val client = ChatRoomClientManager.getClient(sessionId)
chatRoomClient = client
registerReceiveMessage(client)
}
@SuppressLint("CheckResult")
fun sendMessage(message: ChatRoomMessage) {
chatRoomClient?.sendMessage(message)?.doOnError {
it.printStackTrace()
}?.subscribe({}, {})
chatRoomClient?.sendMessage(message)?.subscribe({}, {})?.let {
addDisposable(it)
}
}
fun getCurrentHeadline() {
@@ -47,23 +43,6 @@ class PublicChatRoomViewModel : BaseViewModel() {
headlineLiveData.postValue(headline)
}
fun sendHeadline(message: String) {
safeLaunch(needLoading = true, onError = {
sendHeadlineFlow.emit(BeanResult.failed(it))
}) {
PublicChatModel.sendHeadline(message)
sendHeadlineFlow.emit(BeanResult.success(true))
}
}
fun getHeadlinePayMoney() {
safeLaunch(needLoading = false, onError = {
}) {
val value = PublicChatModel.getHeadlinePayMoney()
headlinePayMoneyLiveData.postValue(value)
}
}
private fun registerReceiveMessage(chatRoomClient: ChatRoomClient) {
addDisposable(chatRoomClient.messageObservable.subscribe {
it.forEach {
@@ -87,8 +66,4 @@ class PublicChatRoomViewModel : BaseViewModel() {
}
}
}
override fun onCleared() {
super.onCleared()
}
}

View File

@@ -2,12 +2,14 @@ package com.chwl.app.public_chat.ui.message.headline
import android.view.Gravity
import android.view.WindowManager
import android.widget.Toast
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import com.chwl.app.R
import com.chwl.app.base.BaseDialog
import com.chwl.app.common.widget.dialog.DialogManager
import com.chwl.app.databinding.HeadlineSendDialogBinding
import com.chwl.app.public_chat.ui.message.HeadlineViewModel
import com.chwl.app.public_chat.ui.message.PublicChatRoomViewModel
import com.chwl.app.ui.pay.ChargeActivity
import com.chwl.app.ui.widget.dialog.CommonTipDialog
@@ -20,7 +22,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class HeadlineSendDialog : BaseDialog<HeadlineSendDialogBinding>() {
private val viewModel by activityViewModels<PublicChatRoomViewModel>()
private val viewModel by activityViewModels<HeadlineViewModel>()
override var width = WindowManager.LayoutParams.MATCH_PARENT
override var height = WindowManager.LayoutParams.WRAP_CONTENT
@@ -31,7 +33,7 @@ class HeadlineSendDialog : BaseDialog<HeadlineSendDialogBinding>() {
lifecycleScope.launch(Dispatchers.Main) {
viewModel.sendHeadlineFlow.collect {
if (it.isSuccess) {
SingleToastUtil.showToast("success")
SingleToastUtil.showToast(R.string.sent_success)
dismissAllowingStateLoss()
} else {
if (it.code == BalanceNotEnoughExeption.code) {

View File

@@ -7,4 +7,6 @@
<string name="headline_message_format">~عزيزي%s، هيا تصدر العناوين </string>
<string name="insufficient_balance_recharge_tips">رصيد العملات الذهبية غير كافي ،هل تريد إعادة الشحن علي الفور؟</string>
<string name="headline_input_hint">الرجاء إدخال المحتوي الذي تريد أن تتصدر عناوينهّ~ (يقتصر على 100 كلمة)</string>
<string name="headline_input_length_limit_tips">頭條字數請勿超過100字~</string>
<string name="sent_success">發送成功</string>
</resources>

View File

@@ -8,4 +8,7 @@
<string name="headline_message_format">尊貴的%s上頭條啦~</string>
<string name="insufficient_balance_recharge_tips">金幣餘額不足,是否立即儲值?</string>
<string name="headline_input_hint">請輸入想上頭條的內容呀~僅限100字</string>
<string name="headline_input_length_limit_tips">頭條字數請勿超過100字~</string>
<string name="permission_mic_tips">請給予麥克風權限後再試</string>
<string name="sent_success">發送成功</string>
</resources>

View File

@@ -7,4 +7,6 @@
<string name="headline_message_format">Honorable %s sent a broadcast~</string>
<string name="insufficient_balance_recharge_tips">The coin is insufficientWould you like to recharge?</string>
<string name="headline_input_hint">Please enter the content you want to broadcast~(100 characters)</string>
<string name="headline_input_length_limit_tips">頭條字數請勿超過100字~</string>
<string name="sent_success">發送成功</string>
</resources>

View File

@@ -5,7 +5,15 @@ import android.util.AttributeSet
import android.widget.FrameLayout
import androidx.annotation.CallSuper
import androidx.lifecycle.Observer
import androidx.lifecycle.viewModelScope
import com.chwl.core.utils.extension.toast
import com.chwl.library.net.rxnet.exception.ExceptionHandle
import io.reactivex.disposables.CompositeDisposable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import java.lang.Exception
/**
* Created by Max on 2023/10/30 18:20
@@ -14,6 +22,7 @@ import io.reactivex.disposables.CompositeDisposable
**/
abstract class FrameLayoutRoomWidget : FrameLayout, RoomWidget {
protected val widgetScope = MainScope()
protected var roomView: RoomView? = null
// 当前房间UID
@@ -77,6 +86,11 @@ abstract class FrameLayoutRoomWidget : FrameLayout, RoomWidget {
open fun onUnbindContext() {
compositeDisposable?.dispose()
compositeDisposable = null
try {
widgetScope.cancel()
} catch (e: Exception) {
e.printStackTrace()
}
}
/**
@@ -92,4 +106,26 @@ abstract class FrameLayoutRoomWidget : FrameLayout, RoomWidget {
}
return disposable
}
protected fun safeLaunch(
onError: suspend(e: Throwable) -> Unit = {
if (it.message != "Job was cancelled") {
val message = ExceptionHandle.handleException(it)
message.toast()
}
},
onComplete: (() -> Unit)? = null,
block: suspend CoroutineScope.() -> Unit
) {
widgetScope.launch {
try {
block()
} catch (e: Throwable) {
e.printStackTrace()
onError(e)
} finally {
onComplete?.invoke()
}
}
}
}

View File

@@ -5,7 +5,6 @@ import com.chwl.core.bean.response.ServiceResult
import com.chwl.core.public_chat_hall.bean.HeadlineBean
import com.chwl.core.public_chat_hall.bean.PublicChatMessageBean
import com.chwl.core.utils.net.launchRequest
import com.chwl.core.vip.bean.VipPageInfo
import com.chwl.library.net.rxnet.RxNet
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded