feat:初步搭建房间内公聊
This commit is contained in:
@@ -0,0 +1,106 @@
|
|||||||
|
package com.chwl.app.avroom.adapter;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
import com.chwl.app.R;
|
||||||
|
import com.chwl.app.ui.widget.XRecyclerView.ScaleTransitionPagerTitleView;
|
||||||
|
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
|
||||||
|
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.abs.CommonNavigatorAdapter;
|
||||||
|
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
|
||||||
|
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.abs.IPagerTitleView;
|
||||||
|
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.indicators.GradientLineRoundPagerIndicator;
|
||||||
|
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.indicators.LinePagerIndicator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class RoomMessageIndicatorAdapter extends CommonNavigatorAdapter {
|
||||||
|
private final Context mContext;
|
||||||
|
private final List<? extends CharSequence> mTitleList;
|
||||||
|
|
||||||
|
private int textSize = 14;
|
||||||
|
private float minScale = 1f;
|
||||||
|
private boolean showIndicator = true;
|
||||||
|
private OnItemSelectListener mOnItemSelectListener;
|
||||||
|
|
||||||
|
public RoomMessageIndicatorAdapter(Context context, List<? extends CharSequence> charSequences) {
|
||||||
|
this.mContext = context;
|
||||||
|
this.mTitleList = charSequences;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return mTitleList == null ? 0 : mTitleList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPagerTitleView getTitleView(Context context, final int i) {
|
||||||
|
ScaleTransitionPagerTitleView scaleTransitionPagerTitleView = new ScaleTransitionPagerTitleView(context, true);
|
||||||
|
scaleTransitionPagerTitleView.setNormalColor(ContextCompat.getColor(context, R.color.color_4D415E));
|
||||||
|
scaleTransitionPagerTitleView.setSelectedColor(ContextCompat.getColor(context, R.color.color_FFFFFF));
|
||||||
|
scaleTransitionPagerTitleView.setMinScale(minScale);
|
||||||
|
scaleTransitionPagerTitleView.setTextSize(textSize);
|
||||||
|
int padding = UIUtil.dip2px(context, 13);
|
||||||
|
scaleTransitionPagerTitleView.setPadding(padding, 0, padding, 0);
|
||||||
|
scaleTransitionPagerTitleView.setText(mTitleList.get(i));
|
||||||
|
scaleTransitionPagerTitleView.setOnClickListener(view -> {
|
||||||
|
if (mOnItemSelectListener != null) {
|
||||||
|
mOnItemSelectListener.onItemSelect(i, scaleTransitionPagerTitleView);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
return scaleTransitionPagerTitleView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPagerIndicator getIndicator(Context context) {
|
||||||
|
LinePagerIndicator indicator = new LinePagerIndicator(context);
|
||||||
|
indicator.setMode(LinePagerIndicator.MODE_EXACTLY);
|
||||||
|
indicator.setLineHeight(UIUtil.dip2px(mContext, 1.5));
|
||||||
|
indicator.setRoundRadius(UIUtil.dip2px(mContext, 1));
|
||||||
|
indicator.setLineWidth(UIUtil.dip2px(mContext, 8));
|
||||||
|
indicator.setColors(context.getResources().getColor(R.color.color_10ECD6));
|
||||||
|
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
// lp.bottomMargin = mBottomMargin;
|
||||||
|
indicator.setLayoutParams(lp);
|
||||||
|
return indicator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTextSize() {
|
||||||
|
return textSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextSize(int textSize) {
|
||||||
|
this.textSize = textSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMinScale() {
|
||||||
|
return minScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinScale(float minScale) {
|
||||||
|
this.minScale = minScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShowIndicator() {
|
||||||
|
return showIndicator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShowIndicator(boolean showIndicator) {
|
||||||
|
this.showIndicator = showIndicator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnItemSelectListener(OnItemSelectListener onItemSelectListener) {
|
||||||
|
mOnItemSelectListener = onItemSelectListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnItemSelectListener {
|
||||||
|
void onItemSelect(int position, TextView view);
|
||||||
|
}
|
||||||
|
}
|
@@ -14,23 +14,21 @@ import android.text.TextUtils
|
|||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
import android.view.ViewStub
|
import android.view.ViewStub
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
|
import android.widget.TextView
|
||||||
import androidx.annotation.CallSuper
|
import androidx.annotation.CallSuper
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.withResumed
|
import androidx.lifecycle.withResumed
|
||||||
import com.netease.nim.uikit.common.antispam.AntiSpamEvent
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.netease.nimlib.sdk.StatusCode
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
import com.netease.nimlib.sdk.chatroom.ChatRoomMessageBuilder
|
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
|
||||||
import com.netease.nimlib.sdk.chatroom.model.ChatRoomKickOutEvent
|
import com.chad.library.adapter.base.BaseViewHolder
|
||||||
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage
|
|
||||||
import com.orhanobut.logger.Logger
|
|
||||||
import com.tbruyelle.rxpermissions2.RxPermissions
|
|
||||||
import com.trello.rxlifecycle3.android.FragmentEvent
|
|
||||||
import com.chwl.app.R
|
import com.chwl.app.R
|
||||||
import com.chwl.app.avroom.BottomViewListenerWrapper
|
import com.chwl.app.avroom.BottomViewListenerWrapper
|
||||||
import com.chwl.app.avroom.SoftKeyBoardListener
|
import com.chwl.app.avroom.SoftKeyBoardListener
|
||||||
@@ -38,10 +36,12 @@ import com.chwl.app.avroom.SoftKeyBoardListener.OnSoftKeyBoardChangeListener
|
|||||||
import com.chwl.app.avroom.activity.RoomInviteActivity
|
import com.chwl.app.avroom.activity.RoomInviteActivity
|
||||||
import com.chwl.app.avroom.activity.RoomTitleEditActivity
|
import com.chwl.app.avroom.activity.RoomTitleEditActivity
|
||||||
import com.chwl.app.avroom.adapter.OnMicroItemClickListener
|
import com.chwl.app.avroom.adapter.OnMicroItemClickListener
|
||||||
|
import com.chwl.app.avroom.adapter.RoomMessageIndicatorAdapter
|
||||||
import com.chwl.app.avroom.dialog.AttentionHintDialog
|
import com.chwl.app.avroom.dialog.AttentionHintDialog
|
||||||
import com.chwl.app.avroom.dialog.DatingVipRuleDialog
|
import com.chwl.app.avroom.dialog.DatingVipRuleDialog
|
||||||
import com.chwl.app.avroom.dialog.RoomOperationDialog
|
import com.chwl.app.avroom.dialog.RoomOperationDialog
|
||||||
import com.chwl.app.avroom.presenter.BaseRoomPresenter
|
import com.chwl.app.avroom.presenter.BaseRoomPresenter
|
||||||
|
import com.chwl.app.avroom.public_chat.PublicChatRoomMessageWidget
|
||||||
import com.chwl.app.avroom.room_album.RoomAlbumModel
|
import com.chwl.app.avroom.room_album.RoomAlbumModel
|
||||||
import com.chwl.app.avroom.view.IBaseRoomView
|
import com.chwl.app.avroom.view.IBaseRoomView
|
||||||
import com.chwl.app.avroom.widget.BottomView
|
import com.chwl.app.avroom.widget.BottomView
|
||||||
@@ -52,21 +52,24 @@ import com.chwl.app.base.BaseMvpFragment
|
|||||||
import com.chwl.app.event.OpenRoomIntroEvent
|
import com.chwl.app.event.OpenRoomIntroEvent
|
||||||
import com.chwl.app.friend.view.SelectFriendActivity
|
import com.chwl.app.friend.view.SelectFriendActivity
|
||||||
import com.chwl.app.home.adapter.RoomActAdapter
|
import com.chwl.app.home.adapter.RoomActAdapter
|
||||||
|
import com.chwl.app.music.widget.MusicPlayerView
|
||||||
|
import com.chwl.app.room_chat.activity.RoomMsgActivity
|
||||||
|
import com.chwl.app.ui.user.adapter.UserInfoIndicatorAdapter
|
||||||
import com.chwl.app.ui.widget.ButtonItem
|
import com.chwl.app.ui.widget.ButtonItem
|
||||||
import com.chwl.app.ui.widget.GiftDialog
|
import com.chwl.app.ui.widget.GiftDialog
|
||||||
import com.chwl.app.ui.widget.GiftDialog.OnGiftDialogBtnClickListener
|
import com.chwl.app.ui.widget.GiftDialog.OnGiftDialogBtnClickListener
|
||||||
import com.chwl.app.ui.widget.GiftDialog.SenGiftCallback
|
import com.chwl.app.ui.widget.GiftDialog.SenGiftCallback
|
||||||
import com.chwl.app.ui.widget.UserInfoDialog
|
import com.chwl.app.ui.widget.UserInfoDialog
|
||||||
import com.chwl.app.ui.widget.dynamicface.DynamicFaceDialog
|
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
|
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil
|
||||||
|
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.CommonNavigator
|
||||||
import com.chwl.app.ui.widget.rollviewpager.RollPagerView
|
import com.chwl.app.ui.widget.rollviewpager.RollPagerView
|
||||||
import com.chwl.app.ui.widget.rollviewpager.Util
|
import com.chwl.app.ui.widget.rollviewpager.Util
|
||||||
import com.chwl.app.ui.widget.rollviewpager.hintview.ColorPointHintView
|
import com.chwl.app.ui.widget.rollviewpager.hintview.ColorPointHintView
|
||||||
import com.chwl.app.utils.KeyBoardUtils
|
import com.chwl.app.utils.KeyBoardUtils
|
||||||
import com.chwl.app.music.widget.MusicPlayerView
|
|
||||||
import com.chwl.app.room_chat.activity.RoomMsgActivity
|
|
||||||
import com.chwl.core.XConstants
|
|
||||||
import com.chwl.core.Constants
|
import com.chwl.core.Constants
|
||||||
|
import com.chwl.core.XConstants
|
||||||
import com.chwl.core.auth.AuthModel
|
import com.chwl.core.auth.AuthModel
|
||||||
import com.chwl.core.bean.RoomMicInfo
|
import com.chwl.core.bean.RoomMicInfo
|
||||||
import com.chwl.core.gift.GiftModel
|
import com.chwl.core.gift.GiftModel
|
||||||
@@ -104,6 +107,14 @@ import com.chwl.library.common.util.LimitClickUtils
|
|||||||
import com.chwl.library.net.rxnet.utils.RxNetWorkUtils
|
import com.chwl.library.net.rxnet.utils.RxNetWorkUtils
|
||||||
import com.chwl.library.rxbus.RxBus
|
import com.chwl.library.rxbus.RxBus
|
||||||
import com.chwl.library.utils.*
|
import com.chwl.library.utils.*
|
||||||
|
import com.netease.nim.uikit.common.antispam.AntiSpamEvent
|
||||||
|
import com.netease.nimlib.sdk.StatusCode
|
||||||
|
import com.netease.nimlib.sdk.chatroom.ChatRoomMessageBuilder
|
||||||
|
import com.netease.nimlib.sdk.chatroom.model.ChatRoomKickOutEvent
|
||||||
|
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage
|
||||||
|
import com.orhanobut.logger.Logger
|
||||||
|
import com.tbruyelle.rxpermissions2.RxPermissions
|
||||||
|
import com.trello.rxlifecycle3.android.FragmentEvent
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -125,6 +136,7 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
|
|||||||
RoomView {
|
RoomView {
|
||||||
private var myUid: Long = 0
|
private var myUid: Long = 0
|
||||||
protected lateinit var messageView: MessageView
|
protected lateinit var messageView: MessageView
|
||||||
|
protected var publicChatMessageWidget: PublicChatRoomMessageWidget? = null
|
||||||
protected lateinit var bottomView: BottomView
|
protected lateinit var bottomView: BottomView
|
||||||
protected lateinit var inputLayout: RelativeLayout
|
protected lateinit var inputLayout: RelativeLayout
|
||||||
protected lateinit var inputEdit: EditText
|
protected lateinit var inputEdit: EditText
|
||||||
@@ -172,7 +184,8 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
|
|||||||
|
|
||||||
@CallSuper
|
@CallSuper
|
||||||
override fun onFindViews() {
|
override fun onFindViews() {
|
||||||
messageView = mView.findViewById(R.id.message_view)
|
initMessageView()
|
||||||
|
// messageView = mView.findViewById(R.id.message_view)
|
||||||
bottomView = mView.findViewById(R.id.bottom_view)
|
bottomView = mView.findViewById(R.id.bottom_view)
|
||||||
inputLayout = mView.findViewById(R.id.input_layout)
|
inputLayout = mView.findViewById(R.id.input_layout)
|
||||||
inputEdit = mView.findViewById(R.id.input_edit)
|
inputEdit = mView.findViewById(R.id.input_edit)
|
||||||
@@ -204,6 +217,75 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initMessageView() {
|
||||||
|
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))
|
||||||
|
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>() {
|
||||||
|
override fun onCreateViewHolder(
|
||||||
|
parent: ViewGroup,
|
||||||
|
viewType: Int
|
||||||
|
): RecyclerView.ViewHolder {
|
||||||
|
val view = if (viewType == 0) {
|
||||||
|
messageView
|
||||||
|
} else {
|
||||||
|
publicChatMessageWidget
|
||||||
|
}
|
||||||
|
view?.layoutParams = ViewGroup.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
)
|
||||||
|
return BaseViewHolder(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return tabList.size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemViewType(position: Int): Int {
|
||||||
|
return position
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val commonNavigator = CommonNavigator(context)
|
||||||
|
commonNavigator.setTitleWrapContent(false)
|
||||||
|
val magicIndicatorAdapter = RoomMessageIndicatorAdapter(context, tabList)
|
||||||
|
magicIndicatorAdapter.setOnItemSelectListener { position: Int, view: TextView? ->
|
||||||
|
messagePager.currentItem = position
|
||||||
|
}
|
||||||
|
commonNavigator.adapter = magicIndicatorAdapter
|
||||||
|
messageIndicator.navigator = commonNavigator
|
||||||
|
messagePager.registerOnPageChangeCallback(object : OnPageChangeCallback() {
|
||||||
|
override fun onPageScrolled(
|
||||||
|
position: Int,
|
||||||
|
positionOffset: Float,
|
||||||
|
positionOffsetPixels: Int
|
||||||
|
) {
|
||||||
|
messageIndicator.onPageScrolled(
|
||||||
|
position,
|
||||||
|
positionOffset,
|
||||||
|
positionOffsetPixels
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPageSelected(position: Int) {
|
||||||
|
messageIndicator.onPageSelected(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPageScrollStateChanged(state: Int) {
|
||||||
|
messageIndicator.onPageScrollStateChanged(state)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
@CallSuper
|
@CallSuper
|
||||||
override fun onSetListener() {
|
override fun onSetListener() {
|
||||||
bottomView.setMagicBtnEnable(true)
|
bottomView.setMagicBtnEnable(true)
|
||||||
@@ -815,7 +897,13 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
val buttonItem4 =
|
val buttonItem4 =
|
||||||
ButtonItem(ResUtil.getString(R.string.up_mic)) { toUpMicroPhone(micPosition, currentUid.toString() + "", false) }
|
ButtonItem(ResUtil.getString(R.string.up_mic)) {
|
||||||
|
toUpMicroPhone(
|
||||||
|
micPosition,
|
||||||
|
currentUid.toString() + "",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
//別問為什麽,ui調整了順序
|
//別問為什麽,ui調整了順序
|
||||||
//禁用超管的上麥和抱TA上麥
|
//禁用超管的上麥和抱TA上麥
|
||||||
if (!SuperAdminUtil.isSuperAdmin()) {
|
if (!SuperAdminUtil.isSuperAdmin()) {
|
||||||
@@ -1236,6 +1324,9 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
|
|||||||
|
|
||||||
open fun initWidget() {
|
open fun initWidget() {
|
||||||
|
|
||||||
|
publicChatMessageWidget?.let {
|
||||||
|
registerWidget(PublicChatRoomMessageWidget::class.java.simpleName, it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
@@ -0,0 +1,851 @@
|
|||||||
|
package com.chwl.app.avroom.public_chat;
|
||||||
|
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.text.Spannable;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.text.method.LinkMovementMethod;
|
||||||
|
import android.text.style.ForegroundColorSpan;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.core.content.res.ResourcesCompat;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||||
|
|
||||||
|
import com.chwl.app.R;
|
||||||
|
import com.chwl.app.UIHelper;
|
||||||
|
import com.chwl.app.avroom.activity.AVRoomActivity;
|
||||||
|
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.ui.utils.ImageLoadUtils;
|
||||||
|
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.magicindicator.buildins.UIUtil;
|
||||||
|
import com.chwl.app.utils.RegexUtil;
|
||||||
|
import com.chwl.core.DemoCache;
|
||||||
|
import com.chwl.core.XConstants;
|
||||||
|
import com.chwl.core.auth.AuthModel;
|
||||||
|
import com.chwl.core.bean.attachmsg.RoomQueueMsgAttachment;
|
||||||
|
import com.chwl.core.decoration.car.bean.CarInfo;
|
||||||
|
import com.chwl.core.helper.ImHelperUtils;
|
||||||
|
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.MonsterHuntingResultAttachment;
|
||||||
|
import com.chwl.core.im.custom.bean.MonsterStatusAttachment;
|
||||||
|
import com.chwl.core.im.custom.bean.RoomBoxPrizeAttachment;
|
||||||
|
import com.chwl.core.im.custom.bean.RoomFollowOwnerAttachment2;
|
||||||
|
import com.chwl.core.im.custom.bean.RoomTipAttachment;
|
||||||
|
import com.chwl.core.im.custom.bean.TarotAttachment;
|
||||||
|
import com.chwl.core.im.custom.bean.WelcomeAttachment;
|
||||||
|
import com.chwl.core.level.UserLevelResourceType;
|
||||||
|
import com.chwl.core.manager.AvRoomDataManager;
|
||||||
|
import com.chwl.core.manager.IMNetEaseManager;
|
||||||
|
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.room.bean.RoomInfo;
|
||||||
|
import com.chwl.core.room.bean.WelcomeInfo;
|
||||||
|
import com.chwl.core.room.model.AvRoomModel;
|
||||||
|
import com.chwl.core.room.pk.attachment.RoomPkAttachment;
|
||||||
|
import com.chwl.core.user.UserModel;
|
||||||
|
import com.chwl.core.user.bean.UserInfo;
|
||||||
|
import com.chwl.core.utils.ExtensionUtil;
|
||||||
|
import com.chwl.library.common.util.Utils;
|
||||||
|
import com.chwl.library.utils.JavaUtil;
|
||||||
|
import com.chwl.library.utils.ListUtils;
|
||||||
|
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.netease.nim.uikit.common.util.log.LogUtil;
|
||||||
|
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.constant.MsgTypeEnum;
|
||||||
|
import com.netease.nimlib.sdk.msg.constant.NotificationType;
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import io.reactivex.Single;
|
||||||
|
import io.reactivex.SingleSource;
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.disposables.Disposable;
|
||||||
|
import io.reactivex.functions.Consumer;
|
||||||
|
import io.reactivex.functions.Function;
|
||||||
|
import com.chwl.app.avroom.widget.MessageView.SpannableBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直播間消息界面
|
||||||
|
*
|
||||||
|
* @author xiaoyu
|
||||||
|
*/
|
||||||
|
public class PublicChatMessageView extends FrameLayout {
|
||||||
|
|
||||||
|
private static final String TAG = "PublicChatMessageView";
|
||||||
|
private final static int MAX_MESSAGE_SIZE = 2000;//公屏最多展示條數
|
||||||
|
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;
|
||||||
|
private TextView tvBottomTip;
|
||||||
|
private TextView tvAtTip;
|
||||||
|
private MessageAdapter mMessageAdapter;
|
||||||
|
private LinearLayoutManager layoutManger;
|
||||||
|
private int paddingWidth;
|
||||||
|
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 volatile boolean needAutoScroll = true;//是否自動滾動到底部
|
||||||
|
private Consumer<String> clickConsumer;
|
||||||
|
private OnClick onClick;
|
||||||
|
|
||||||
|
private OnMsgLongClickListener onLongClickListener;
|
||||||
|
private TemplateMessageAdapter templateMessageAdapter;
|
||||||
|
|
||||||
|
public PublicChatMessageView(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PublicChatMessageView(Context context, AttributeSet attr) {
|
||||||
|
this(context, attr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PublicChatMessageView(Context context, AttributeSet attr, int i) {
|
||||||
|
super(context, attr, i);
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
public void setOnLongClickListener(OnMsgLongClickListener onLongClickListener) {
|
||||||
|
this.onLongClickListener = onLongClickListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClickConsumer(Consumer<String> clickConsumer) {
|
||||||
|
this.clickConsumer = clickConsumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnClick(OnClick onClick) {
|
||||||
|
this.onClick = onClick;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToWindow() {
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDetachedFromWindow() {
|
||||||
|
super.onDetachedFromWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
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);
|
||||||
|
messageListView = new RecyclerViewNoViewpagerScroll(context);
|
||||||
|
messageListView.setLayoutParams(params);
|
||||||
|
messageListView.setFadingEdgeLength(60);
|
||||||
|
messageListView.setVerticalFadingEdgeEnabled(true);
|
||||||
|
messageListView.setOverScrollMode(OVER_SCROLL_NEVER);
|
||||||
|
messageListView.setHorizontalScrollBarEnabled(false);
|
||||||
|
addView(messageListView);
|
||||||
|
messageListView.setLayoutManager(layoutManger);
|
||||||
|
messageListView.addItemDecoration(new DividerItemDecoration(context, layoutManger.getOrientation(), 16, R.color.transparent));
|
||||||
|
mMessageAdapter = new MessageAdapter(getContext());
|
||||||
|
mMessageAdapter.setData(chatRoomMessages);
|
||||||
|
messageListView.setAdapter(mMessageAdapter);
|
||||||
|
messageListView.setItemAnimator(new MyItemAnimator());
|
||||||
|
messageListView.getItemAnimator().setAddDuration(0);
|
||||||
|
messageListView.getItemAnimator().setChangeDuration(0);
|
||||||
|
messageListView.getItemAnimator().setMoveDuration(0);
|
||||||
|
messageListView.getItemAnimator().setRemoveDuration(0);
|
||||||
|
((SimpleItemAnimator) messageListView.getItemAnimator()).setSupportsChangeAnimations(false);
|
||||||
|
if (AvRoomDataManager.get().isOpenGame()) {
|
||||||
|
messageListView.setOnTouchListener((v, event) -> {
|
||||||
|
if (messageListView.getScrollState() == RecyclerView.SCROLL_STATE_IDLE
|
||||||
|
&& event.getAction() == MotionEvent.ACTION_UP) {
|
||||||
|
ViewGroup.LayoutParams layoutParams = getLayoutParams();
|
||||||
|
int bigHeight = ScreenUtil.dip2px(200);
|
||||||
|
int littleHeight = ScreenUtil.dip2px(80);
|
||||||
|
layoutParams.height = layoutParams.height == littleHeight ? bigHeight : littleHeight;
|
||||||
|
setLayoutParams(layoutParams);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 底部有新消息
|
||||||
|
tvBottomTip = new TextView(context);
|
||||||
|
LayoutParams params1 = new LayoutParams(
|
||||||
|
Utils.dip2px(context, 115F), Utils.dip2px(context, 27));
|
||||||
|
params1.gravity = Gravity.BOTTOM;
|
||||||
|
params1.leftMargin = UIUtil.getScreenWidth(context) / 2 - UIUtil.dip2px(context, 115 / 2);
|
||||||
|
tvBottomTip.setBackgroundResource(R.drawable.bg_messge_view_bottom_tip);
|
||||||
|
tvBottomTip.setGravity(Gravity.CENTER);
|
||||||
|
tvBottomTip.setText(context.getString(R.string.message_view_bottom_tip));
|
||||||
|
tvBottomTip.setTextColor(context.getResources().getColor(R.color.appColor));
|
||||||
|
tvBottomTip.setLayoutParams(params1);
|
||||||
|
tvBottomTip.setVisibility(GONE);
|
||||||
|
tvBottomTip.setOnClickListener(v -> {
|
||||||
|
tvBottomTip.setVisibility(GONE);
|
||||||
|
needAutoScroll = true;
|
||||||
|
messageListView.smoothScrollToPosition(mMessageAdapter.getItemCount() - 1);
|
||||||
|
});
|
||||||
|
addView(tvBottomTip);
|
||||||
|
|
||||||
|
//有人@我
|
||||||
|
tvAtTip = new TextView(context);
|
||||||
|
LayoutParams params2 = new LayoutParams(
|
||||||
|
Utils.dip2px(context, 115F), Utils.dip2px(context, 27));
|
||||||
|
params2.gravity = Gravity.BOTTOM;
|
||||||
|
params2.leftMargin = UIUtil.getScreenWidth(context) / 2 - UIUtil.dip2px(context, 115 / 2);
|
||||||
|
tvAtTip.setBackgroundResource(R.drawable.bg_messge_view_bottom_tip);
|
||||||
|
tvAtTip.setGravity(Gravity.CENTER);
|
||||||
|
tvAtTip.setText(context.getString(R.string.message_view_bottom_tip));
|
||||||
|
tvAtTip.setTextColor(context.getResources().getColor(R.color.color_FD85C9));
|
||||||
|
tvAtTip.setLayoutParams(params2);
|
||||||
|
tvAtTip.setVisibility(GONE);
|
||||||
|
tvAtTip.setOnClickListener(v -> {
|
||||||
|
if (!atMessages.isEmpty()) {
|
||||||
|
int scrollIndex = chatRoomMessages.indexOf(atMessages.remove(0));
|
||||||
|
if (scrollIndex != -1 && scrollIndex < mMessageAdapter.getItemCount()) {
|
||||||
|
messageListView.smoothScrollToPosition(scrollIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
needAutoScroll = false;
|
||||||
|
checkShowAtTip();
|
||||||
|
});
|
||||||
|
addView(tvAtTip);
|
||||||
|
|
||||||
|
messageListView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||||
|
@Override
|
||||||
|
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScrollStateChanged(final RecyclerView recyclerView, int newState) {
|
||||||
|
super.onScrollStateChanged(recyclerView, newState);
|
||||||
|
if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
|
||||||
|
// Logger.e(TAG, "onScrollStateChanged: SCROLL_STATE_DRAGGING");
|
||||||
|
needAutoScroll = false;
|
||||||
|
}
|
||||||
|
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||||
|
// Logger.e(TAG, "onScrollStateChanged: SCROLL_STATE_IDLE");
|
||||||
|
|
||||||
|
int lastVisibleItemPosition = layoutManger.findLastVisibleItemPosition();
|
||||||
|
|
||||||
|
if (lastVisibleItemPosition == RecyclerView.NO_POSITION) {
|
||||||
|
// Logger.e(TAG, "lastCompletelyVisibleItemPosition : RecyclerView.NO_POSITION");
|
||||||
|
needAutoScroll = true;
|
||||||
|
} else if (!atMessages.isEmpty() && atMessages.remove(chatRoomMessages.get(lastVisibleItemPosition))) {
|
||||||
|
checkShowAtTip();
|
||||||
|
}
|
||||||
|
// Log.e(TAG, "lastVisibleItemPosition:" + lastVisibleItemPosition
|
||||||
|
// + " mMessageAdapter.getItemCount()-1:" + (recyclerView.getAdapter().getItemCount()-1)
|
||||||
|
// + " dis:"+ (lastVisibleItemPosition-(recyclerView.getAdapter().getItemCount()-1)));
|
||||||
|
if (lastVisibleItemPosition >= recyclerView.getAdapter().getItemCount() - 3) {
|
||||||
|
//最後一個顯示出來了
|
||||||
|
// Logger.e(TAG, ResUtil.getString(R.string.avroom_widget_messageview_01));
|
||||||
|
needAutoScroll = true;
|
||||||
|
tvBottomTip.setVisibility(GONE);
|
||||||
|
keepSizeUnderLimit();
|
||||||
|
} else {
|
||||||
|
// Logger.e(TAG, ResUtil.getString(R.string.avroom_widget_messageview_02));
|
||||||
|
// needAutoScroll = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private TemplateMessageAdapter getTemplateMessageAdapter() {
|
||||||
|
if (templateMessageAdapter == null) {
|
||||||
|
templateMessageAdapter = new TemplateMessageAdapter(uid -> {
|
||||||
|
if (clickConsumer != null) {
|
||||||
|
Single.just(String.valueOf(uid)).subscribe(clickConsumer);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return templateMessageAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCurrentRoomReceiveNewMsg(List<ChatRoomMessage> messages) {
|
||||||
|
if (messages == null) return;
|
||||||
|
if (messages.size() == 1) {
|
||||||
|
addMessages(messages.get(0));
|
||||||
|
} else {
|
||||||
|
addHistoryMessages(messages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加公屏消息請使用 {@link AvRoomDataManager#addChatRoomMessage(ChatRoomMessage)}
|
||||||
|
*/
|
||||||
|
private void addMessages(ChatRoomMessage msg) {
|
||||||
|
if (msg == null) return;
|
||||||
|
chatRoomMessages.add(msg);
|
||||||
|
//通知adapter 刷新
|
||||||
|
mMessageAdapter.notifyItemInserted(mMessageAdapter.getItemCount() - 1);
|
||||||
|
showTipsOrScrollToBottom();
|
||||||
|
checkAtMe(msg, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMessages(List<ChatRoomMessage> messages) {
|
||||||
|
if (messages == null) return;
|
||||||
|
chatRoomMessages.addAll(messages);
|
||||||
|
//通知adapter 刷新
|
||||||
|
mMessageAdapter.notifyItemInserted(mMessageAdapter.getItemCount() - 1);
|
||||||
|
showTipsOrScrollToBottom();
|
||||||
|
for (ChatRoomMessage message : messages) {
|
||||||
|
checkAtMe(message, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHistoryMessages(List<ChatRoomMessage> messages) {
|
||||||
|
chatRoomMessages.addAll(chatRoomMessages.size() > 0 ? 1 : 0, messages);
|
||||||
|
mMessageAdapter.notifyDataSetChanged();
|
||||||
|
messageListView.scrollToPosition(mMessageAdapter.getItemCount() - 1);
|
||||||
|
for (ChatRoomMessage message : messages) {
|
||||||
|
checkAtMe(message, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void keepSizeUnderLimit() {
|
||||||
|
while (chatRoomMessages.size() > MAX_MESSAGE_SIZE) {
|
||||||
|
Log.i("keepSizeUnderLimit", "size" + chatRoomMessages.size());
|
||||||
|
ChatRoomMessage message = chatRoomMessages.remove(0);
|
||||||
|
if (atMessages.remove(message)) {
|
||||||
|
checkShowAtTip();
|
||||||
|
}
|
||||||
|
mMessageAdapter.notifyItemRemoved(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkShowAtTip() {
|
||||||
|
tvAtTip.setText(getContext().getString(R.string.message_at_tip, atMessages.size()));
|
||||||
|
tvAtTip.setVisibility(atMessages.size() == 0 ? GONE : VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAtMe(ChatRoomMessage msg, boolean history) {
|
||||||
|
if (msg.getMsgType() != MsgTypeEnum.text) return;
|
||||||
|
List<String> atUids = ExtensionUtil.getListExtension(msg, UserInfo.AT_UIDS);
|
||||||
|
List<String> atNames = ExtensionUtil.getListExtension(msg, UserInfo.AT_NAMES);
|
||||||
|
if (!ListUtils.isListEmpty(atUids) && !ListUtils.isListEmpty(atNames)) {
|
||||||
|
for (int i = 0; i < atUids.size(); i++) {
|
||||||
|
String uid = atUids.get(i);
|
||||||
|
// 只有當被 @ 人的數組中包含自己的時候才會去變色
|
||||||
|
if (Objects.equals(uid, String.valueOf(AuthModel.get().getCurrentUid()))) {
|
||||||
|
Map<String, Long> atMap = DemoCache.readAtMsgUuid();
|
||||||
|
if (atMap == null || !atMap.containsKey(msg.getUuid())) {
|
||||||
|
if (!atMessages.contains(msg) && (!needAutoScroll || history)) {
|
||||||
|
atMessages.add(msg);
|
||||||
|
checkShowAtTip();
|
||||||
|
}
|
||||||
|
DemoCache.saveAtMsgUuid(msg.getUuid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showTipsOrScrollToBottom() {
|
||||||
|
if (!needAutoScroll) {
|
||||||
|
tvBottomTip.setVisibility(VISIBLE);
|
||||||
|
//超過某值後自動滾動下去
|
||||||
|
if (mMessageAdapter.getItemCount() > BLOCK_MAX_MESSAGE_SIZE) {
|
||||||
|
messageListView.smoothScrollToPosition(mMessageAdapter.getItemCount() - 1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
messageListView.smoothScrollToPosition(mMessageAdapter.getItemCount() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void release() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
if (mMessageAdapter != null) {
|
||||||
|
chatRoomMessages.clear();
|
||||||
|
mMessageAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
if (tvBottomTip != null) {
|
||||||
|
needAutoScroll = true;
|
||||||
|
tvBottomTip.setVisibility(GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnClick {
|
||||||
|
/**
|
||||||
|
* 點擊關註
|
||||||
|
*
|
||||||
|
* @param position
|
||||||
|
*/
|
||||||
|
void onFollowClick(int position);
|
||||||
|
|
||||||
|
void onJoinMiniWorldClick(int position);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公屏查看公告
|
||||||
|
*/
|
||||||
|
void onShowRoomIntroduction();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MessageViewHolder> implements OnClickListener {
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private List<ChatRoomMessage> data;
|
||||||
|
|
||||||
|
public MessageAdapter(Context mContext) {
|
||||||
|
this.mContext = mContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(List<ChatRoomMessage> data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getItemViewType(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
|
return new MessageViewHolder(LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.list_item_chatrrom_msg, parent, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(MessageViewHolder holder, int position) {
|
||||||
|
convert(holder, data.get(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void convert(MessageViewHolder baseViewHolder, ChatRoomMessage chatRoomMessage) {
|
||||||
|
if (chatRoomMessage == null) return;
|
||||||
|
TextView tvContent = baseViewHolder.tvContent;
|
||||||
|
tvContent.setLineSpacing(0, 1);
|
||||||
|
tvContent.setTextColor(Color.WHITE);
|
||||||
|
tvContent.setOnClickListener(this);
|
||||||
|
tvContent.setOnLongClickListener(null);
|
||||||
|
tvContent.setTag(chatRoomMessage);
|
||||||
|
tvContent.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
|
||||||
|
if (UiUtils.INSTANCE.isRtl(tvContent.getContext())) {
|
||||||
|
tvContent.setTextDirection(View.TEXT_DIRECTION_RTL);
|
||||||
|
}
|
||||||
|
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());
|
||||||
|
tvContent.setBackgroundResource(R.drawable.shape_room_message_tip_bg);
|
||||||
|
} else if (chatRoomMessage.getMsgType() == MsgTypeEnum.text) {
|
||||||
|
setMsgText(chatRoomMessage, tvContent);
|
||||||
|
setVIPMessageBackground(chatRoomMessage, tvContent);
|
||||||
|
} else if (chatRoomMessage.getMsgType() == MsgTypeEnum.notification) {
|
||||||
|
// 加上勛章
|
||||||
|
setMsgNotification(chatRoomMessage, tvContent, baseViewHolder.getAdapterPosition());
|
||||||
|
setVIPMessageBackground(chatRoomMessage, tvContent);
|
||||||
|
} else if (chatRoomMessage.getMsgType() == MsgTypeEnum.custom) {
|
||||||
|
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);
|
||||||
|
} else {
|
||||||
|
tvContent.setTextColor(Color.WHITE);
|
||||||
|
tvContent.setText(tvContent.getResources().getText(R.string.not_support_message_tip));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
clearBackground(tvContent);
|
||||||
|
tvContent.setTextColor(Color.WHITE);
|
||||||
|
tvContent.setText(tvContent.getResources().getText(R.string.not_support_message_tip));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearBackground(TextView textView) {
|
||||||
|
// 清除文字
|
||||||
|
textView.setText("");
|
||||||
|
// 清除聊天氣泡
|
||||||
|
textView.setBackgroundResource(R.drawable.shape_room_message_bg);
|
||||||
|
textView.setPadding(paddingWidth, paddingHeight, paddingWidth, paddingHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVIPMessageBackground(ChatRoomMessage chatRoomMessage, View view) {
|
||||||
|
String androidBubbleUrl = NobleUtil.getResource(UserInfo.BUBBLE_URL_ANDROID, chatRoomMessage);
|
||||||
|
if (TextUtils.isEmpty(androidBubbleUrl)) return;
|
||||||
|
view.setPadding(paddingWidth, ScreenUtil.dip2px(10), paddingWidth, ScreenUtil.dip2px(10));
|
||||||
|
ImageLoadUtils.loadNinePatchBg(view, androidBubbleUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {badge}{level}xxx: 文字內容
|
||||||
|
*
|
||||||
|
* @param chatRoomMessage -
|
||||||
|
* @param tvContent -
|
||||||
|
*/
|
||||||
|
private void setMsgText(ChatRoomMessage chatRoomMessage, TextView tvContent) {
|
||||||
|
ChatRoomMessageExtension extension = chatRoomMessage.getChatRoomMessageExtension();
|
||||||
|
SpannableBuilder text = new SpannableBuilder(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))
|
||||||
|
.append(": " + chatRoomMessage.getContent(), new ForegroundColorSpan(getResources().getColor(R.color.white)));
|
||||||
|
List<String> atUids = ExtensionUtil.getListExtension(chatRoomMessage, UserInfo.AT_UIDS);
|
||||||
|
List<String> atNames = ExtensionUtil.getListExtension(chatRoomMessage, UserInfo.AT_NAMES);
|
||||||
|
if (!ListUtils.isListEmpty(atUids) && !ListUtils.isListEmpty(atNames)) {
|
||||||
|
for (int i = 0; i < atUids.size(); i++) {
|
||||||
|
String name = atNames.get(i);
|
||||||
|
String uid = atUids.get(i);
|
||||||
|
// 只有當被 @ 人的數組中包含自己的時候才會去變色
|
||||||
|
if (Objects.equals(uid, String.valueOf(AuthModel.get().getCurrentUid()))) {
|
||||||
|
Pattern pattern = Pattern.compile(Pattern.quote(name));
|
||||||
|
Matcher matcher = pattern.matcher(text.build().toString());
|
||||||
|
while (matcher.find()) {
|
||||||
|
int start = matcher.start();
|
||||||
|
int end = matcher.end();
|
||||||
|
text.build().setSpan(new ForegroundColorSpan(getContext().getResources().getColor(R.color.color_FD85C9)),
|
||||||
|
start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Objects.equals(chatRoomMessage.getFromAccount(), String.valueOf(AuthModel.get().getCurrentUid()))) {
|
||||||
|
tvContent.setOnLongClickListener(null);
|
||||||
|
} else {
|
||||||
|
tvContent.setOnLongClickListener(v -> {
|
||||||
|
if (onLongClickListener != null) {
|
||||||
|
onLongClickListener.onLongClick(v, chatRoomMessage.getFromAccount(), nickName);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
tvContent.setText(text.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addCommonTag(ChatRoomMessage chatRoomMessage, @NonNull SpannableBuilder builder, TextView tvContent) {
|
||||||
|
ChatRoomMessageExtension extension = chatRoomMessage.getChatRoomMessageExtension();
|
||||||
|
String userLevel = NobleUtil.getLevel(UserLevelResourceType.EXPER_URL, chatRoomMessage);
|
||||||
|
boolean isOfficial = NobleUtil.getIsOfficial(UserInfo.IS_OFFICIAL, chatRoomMessage);
|
||||||
|
String vipIcon = NobleUtil.getResource(UserInfo.VIP_ICON, chatRoomMessage);
|
||||||
|
builder.append(vipIcon, expLevelHeight)
|
||||||
|
.append(isOfficial ? ResourcesCompat.getDrawable(getResources(),
|
||||||
|
R.mipmap.ic_user_official_13dp, null) : null,
|
||||||
|
badgeWidth, badgeHeight)
|
||||||
|
.append(getNewUserDrawable(chatRoomMessage), badgeWidth, badgeHeight)
|
||||||
|
.append(AvRoomDataManager.get().isSuperAdmin(chatRoomMessage.getFromAccount()) ? ResourcesCompat.getDrawable(getResources(),
|
||||||
|
R.drawable.ic_room_super_admin, null) : null,
|
||||||
|
SizeUtils.dp2px(tvContent.getContext(), 23), expLevelHeight);
|
||||||
|
|
||||||
|
// 官方主播認證
|
||||||
|
String tvOfficialMask = NobleUtil.getLevel(UserInfo.OAC_NAME, chatRoomMessage).trim();
|
||||||
|
String ivOfficialMask = NobleUtil.getLevel(UserInfo.OAC_ICON, chatRoomMessage);
|
||||||
|
if (!TextUtils.isEmpty(tvOfficialMask) && !TextUtils.isEmpty(ivOfficialMask) && extension != null) { // extension != null 表示自己
|
||||||
|
builder.appendBgAndContent(ivOfficialMask, tvOfficialMask);
|
||||||
|
} else if (!TextUtils.isEmpty(ivOfficialMask)) {
|
||||||
|
builder.append(ivOfficialMask, SizeUtils.dp2px(tvContent.getContext(), 62), expLevelHeight);
|
||||||
|
}
|
||||||
|
//等級
|
||||||
|
builder.append(userLevel, expLevelHeight);
|
||||||
|
//銘牌
|
||||||
|
String tvNamePlate = NobleUtil.getNamePlate(UserInfo.NAMEPLATE_WORD, chatRoomMessage).trim();
|
||||||
|
String ivNamePlate = NobleUtil.getNamePlate(UserInfo.NAMEPLATE_PIC, chatRoomMessage);
|
||||||
|
if (!TextUtils.isEmpty(tvNamePlate) && !TextUtils.isEmpty(ivNamePlate)) { // extension != null 表示自己
|
||||||
|
builder.appendBgAndContent(ivNamePlate, tvNamePlate);
|
||||||
|
} else if (!TextUtils.isEmpty(ivNamePlate)) {
|
||||||
|
builder.append(ivNamePlate, expLevelHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 暫時已拋棄
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
SpannableBuilder builder = new SpannableBuilder(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));
|
||||||
|
}
|
||||||
|
tvContent.setText(builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {badge}xxx來了
|
||||||
|
*
|
||||||
|
* @param chatRoomMessage -
|
||||||
|
* @param tvContent -
|
||||||
|
*/
|
||||||
|
private void setMsgNotification(ChatRoomMessage chatRoomMessage, TextView tvContent, int position) {
|
||||||
|
int fromType = 0;
|
||||||
|
String fromNick = "";
|
||||||
|
String fromUid = "";
|
||||||
|
Map<String, Object> remoteExtension = chatRoomMessage.getRemoteExtension();
|
||||||
|
if (remoteExtension != null) {
|
||||||
|
fromType = (int) remoteExtension.get("fromType");
|
||||||
|
fromNick = (String) remoteExtension.get("fromNick");
|
||||||
|
fromUid = (String) remoteExtension.get("fromUid");
|
||||||
|
}
|
||||||
|
ChatRoomNotificationAttachment attachment = (ChatRoomNotificationAttachment) chatRoomMessage.getAttachment();
|
||||||
|
String senderNick = "";
|
||||||
|
List<String> nicks = attachment.getTargetNicks();
|
||||||
|
if (nicks != null && nicks.size() > 0)
|
||||||
|
senderNick = RegexUtil.getPrintableString(attachment.getTargetNicks().get(0));
|
||||||
|
if (attachment.getType() != NotificationType.ChatRoomMemberIn) return;
|
||||||
|
|
||||||
|
// 座駕
|
||||||
|
String carName = NobleUtil.getCarName(CarInfo.CAR_NAME, chatRoomMessage);
|
||||||
|
carName = TextUtils.isEmpty(carName) ? "" : "\"" + carName + "\"";
|
||||||
|
|
||||||
|
SpannableBuilder text = new SpannableBuilder(tvContent);
|
||||||
|
addCommonTag(chatRoomMessage, text, tvContent);
|
||||||
|
text.append(senderNick, new ForegroundColorSpan(roomTipColor),
|
||||||
|
new OriginalDrawStatusClickSpan() {
|
||||||
|
@Override
|
||||||
|
public void onClick(@NonNull View view) {
|
||||||
|
if (clickConsumer != null) {
|
||||||
|
Single.just(chatRoomMessage.getFromAccount())
|
||||||
|
.doOnSuccess(clickConsumer).subscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
text.append(TextUtils.isEmpty(carName) ? "" : ResUtil.getString(R.string.avroom_widget_messageview_0150), new ForegroundColorSpan(greyColor))
|
||||||
|
.append(carName, new ForegroundColorSpan(roomTipColor));
|
||||||
|
String enterText = ResUtil.getString(R.string.avroom_widget_messageview_0151);
|
||||||
|
if (fromType == AVRoomActivity.FROM_TYPE_RECOMMEND) {
|
||||||
|
enterText = ResUtil.getString(R.string.avroom_widget_messageview_0152);
|
||||||
|
}
|
||||||
|
if (fromType == AVRoomActivity.FROM_TYPE_USER || fromType == AVRoomActivity.FROM_TYPE_HELLO) {
|
||||||
|
String finalFromUid = fromUid;
|
||||||
|
text.append(ResUtil.getString(R.string.avroom_widget_messageview_0153), new ForegroundColorSpan(whiteColor))
|
||||||
|
.append(fromNick, new ForegroundColorSpan(roomTipColor),
|
||||||
|
new OriginalDrawStatusClickSpan() {
|
||||||
|
@Override
|
||||||
|
public void onClick(@NonNull View view) {
|
||||||
|
if (clickConsumer != null) {
|
||||||
|
Single.just(finalFromUid).doOnSuccess(clickConsumer).subscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
enterText = ResUtil.getString(R.string.avroom_widget_messageview_0154);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fromType == AVRoomActivity.FROM_TYPE_GAME_RECOMMEND) {
|
||||||
|
String finalFromUid = fromUid;
|
||||||
|
text.append(ResUtil.getString(R.string.avroom_widget_messageview_0155), new ForegroundColorSpan(whiteColor))
|
||||||
|
.append(fromNick, new ForegroundColorSpan(roomTipColor),
|
||||||
|
new OriginalDrawStatusClickSpan() {
|
||||||
|
@Override
|
||||||
|
public void onClick(@NonNull View view) {
|
||||||
|
if (clickConsumer != null) {
|
||||||
|
Single.just(finalFromUid).doOnSuccess(clickConsumer).subscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
enterText = ResUtil.getString(R.string.avroom_widget_messageview_0156);
|
||||||
|
}
|
||||||
|
|
||||||
|
text.append(enterText, new ForegroundColorSpan(whiteColor));
|
||||||
|
tvContent.setText(text.build());
|
||||||
|
tvContent.setOnClickListener(null);
|
||||||
|
tvContent.setMovementMethod(new LinkMovementMethod());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Drawable getNewUserDrawable(ChatRoomMessage chatRoomMessage) {
|
||||||
|
boolean newUser = NobleUtil.getIsNewUser(UserInfo.IS_NEW_USER, chatRoomMessage);
|
||||||
|
boolean isHelloUser = NobleUtil.getIsNewUser(UserInfo.IS_FROM_SAY_HELLO_CHANNEL, chatRoomMessage);
|
||||||
|
if (newUser) {
|
||||||
|
return ResourcesCompat.getDrawable(getResources(),
|
||||||
|
isHelloUser ? R.drawable.ic_new_user_hello : R.drawable.ic_new_user,
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressLint("CheckResult")
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
String account = "";
|
||||||
|
ChatRoomMessage chatRoomMessage = (ChatRoomMessage) v.getTag();
|
||||||
|
if (chatRoomMessage.getMsgType() != MsgTypeEnum.tip) {
|
||||||
|
if (chatRoomMessage.getMsgType() == MsgTypeEnum.text) {
|
||||||
|
account = chatRoomMessage.getFromAccount();
|
||||||
|
} else if (chatRoomMessage.getMsgType() == MsgTypeEnum.notification) {
|
||||||
|
account = chatRoomMessage.getFromAccount();
|
||||||
|
} else if (chatRoomMessage.getMsgType() == MsgTypeEnum.custom) {
|
||||||
|
CustomAttachment attachment = (CustomAttachment) chatRoomMessage.getAttachment();
|
||||||
|
if (attachment.getFirst() == CustomAttachment.CUSTOM_MSG_HEADER_TYPE_ROOM_TIP) {
|
||||||
|
account = ((RoomTipAttachment) attachment).getUid() + "";
|
||||||
|
} else if (attachment.getFirst() == CustomAttachment.CUSTOM_MSG_BOX) {
|
||||||
|
account = String.valueOf(((RoomBoxPrizeAttachment) attachment).getUid());
|
||||||
|
} else if (attachment.getFirst() == CustomAttachment.CUSTOM_MSG_HEADER_TYPE_QUEUE) {
|
||||||
|
long handleUid = ((RoomQueueMsgAttachment) attachment).handleUid;
|
||||||
|
if (handleUid > 0) {
|
||||||
|
account = ((RoomQueueMsgAttachment) attachment).handleUid + "";
|
||||||
|
} else {
|
||||||
|
//ios沒用handleUid,導致iOS發的自定義消息,拿不到uid
|
||||||
|
account = chatRoomMessage.getFromAccount();
|
||||||
|
}
|
||||||
|
} else if (attachment.getFirst() == CustomAttachment.CUSTOM_MSG_HEADER_TYPE_MONSTER_HUNTING) {
|
||||||
|
switch (attachment.getSecond()) {
|
||||||
|
case CustomAttachment.CUSTOM_MSG_SUB_TYPE_MONSTER_HUNTING:
|
||||||
|
MonsterDataBean dataBean = ((MonsterStatusAttachment) attachment).getDataBean();
|
||||||
|
RoomInfo mCurrentRoomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
|
||||||
|
if (!Objects.equals(mCurrentRoomInfo.getUid(), dataBean.getAppearRoomUid())) {
|
||||||
|
AVRoomActivity.start(getContext(), dataBean.getAppearRoomUid());
|
||||||
|
} else {
|
||||||
|
SingleToastUtil.showToast("你已經在怪獸房間內");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CustomAttachment.CUSTOM_NOTI_SUB_GAME_RESULT:
|
||||||
|
MonsterHuntingResult result = ((MonsterHuntingResultAttachment) attachment).getResult();
|
||||||
|
UIHelper.showMonsterResult(getContext(), String.valueOf(result.getMonster().getMonsterId()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (attachment.getFirst() == CustomAttachment.CUSTOM_MESS_HEAD_ROOM_PK) {
|
||||||
|
if (attachment.getSecond() == CustomAttachment.CUSTOM_MESS_SUB_ROOM_PK_RESULT) {
|
||||||
|
PKResultDialog pkResultDialog = new PKResultDialog(getContext(), ((RoomPkAttachment) attachment).getRoomPkData());
|
||||||
|
pkResultDialog.show();
|
||||||
|
}
|
||||||
|
} else if (attachment instanceof RoomFollowOwnerAttachment2 && !AvRoomDataManager.get().isRoomFans) {
|
||||||
|
CollectionRoomModel.get().followRoom("1", ((RoomFollowOwnerAttachment2) attachment).getOwnerUid())
|
||||||
|
.subscribe(s -> {
|
||||||
|
AvRoomDataManager.get().isRoomFans = true;
|
||||||
|
SingleToastUtil.showToast("收藏成功!");
|
||||||
|
EventBus.getDefault().post(new FollowRoomEvent());
|
||||||
|
PraiseModel.get().setFollowRoomSuccessRoomTip(JavaUtil.str2long(chatRoomMessage.getFromAccount()));
|
||||||
|
});
|
||||||
|
} else if (attachment.getFirst() == CustomAttachment.CUSTOM_MESS_TAROT) {
|
||||||
|
if (attachment instanceof TarotAttachment) {
|
||||||
|
account = ((TarotAttachment) attachment).getTarotMsgBean().getUid() + "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (TextUtils.isEmpty(account)) return;
|
||||||
|
if (clickConsumer != null) {
|
||||||
|
Single.just(account).subscribe(clickConsumer);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String content = chatRoomMessage.getContent();
|
||||||
|
if (!TextUtils.isEmpty(content) && content.equals(XConstants.ROOM_INTRODUCTION))
|
||||||
|
if (onClick != null) {
|
||||||
|
onClick.onShowRoomIntroduction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
TextView tvContent;
|
||||||
|
|
||||||
|
public MessageViewHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
tvContent = itemView.findViewById(R.id.tv_content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,102 @@
|
|||||||
|
package com.chwl.app.avroom.public_chat
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import com.chwl.app.R
|
||||||
|
import com.chwl.app.public_chat.core.ChatRoomClient
|
||||||
|
import com.chwl.app.public_chat.core.ChatRoomClientManager
|
||||||
|
import com.chwl.core.initial.InitialModel
|
||||||
|
import com.chwl.core.support.room.FrameLayoutRoomWidget
|
||||||
|
import com.chwl.core.support.room.RoomView
|
||||||
|
import com.chwl.library.utils.SingleToastUtil
|
||||||
|
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 var chatRoomClient: ChatRoomClient? = null
|
||||||
|
|
||||||
|
constructor(context: Context) : super(context)
|
||||||
|
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
|
||||||
|
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
||||||
|
context,
|
||||||
|
attrs,
|
||||||
|
defStyleAttr
|
||||||
|
)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet?,
|
||||||
|
defStyleAttr: Int,
|
||||||
|
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
|
||||||
|
if (sessionId != null) {
|
||||||
|
chatRoomClient = ChatRoomClientManager.getClient(sessionId);
|
||||||
|
} else {
|
||||||
|
SingleToastUtil.showToast(R.string.public_chat_not_found)
|
||||||
|
}
|
||||||
|
chatRoomClient?.let {
|
||||||
|
initChatRoom(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onReceiveMessage(list: List<ChatRoomMessage>) {
|
||||||
|
messageListView.addMessages(list)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initChatRoom(chatRoomClient: ChatRoomClient) {
|
||||||
|
getCompositeDisposable().add(
|
||||||
|
chatRoomClient.enterChatRoom()
|
||||||
|
.subscribe({ requestHistory(chatRoomClient) },
|
||||||
|
{
|
||||||
|
if (it is NimException) {
|
||||||
|
SingleToastUtil.showToast(context.getString(R.string.avroom_fragment_homepartyroomfragment_011) + "(${it.code})")
|
||||||
|
} else {
|
||||||
|
SingleToastUtil.showToast(R.string.avroom_fragment_homepartyroomfragment_011)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
getCompositeDisposable().add(chatRoomClient.messageObservable.subscribe {
|
||||||
|
onReceiveMessage(it)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun requestHistory(chatRoomClient: ChatRoomClient) {
|
||||||
|
val typeEnums = arrayOf(MsgTypeEnum.text, MsgTypeEnum.image)
|
||||||
|
getCompositeDisposable().add(
|
||||||
|
chatRoomClient.requestRemoteMessageType(
|
||||||
|
0,
|
||||||
|
50,
|
||||||
|
QueryDirectionEnum.QUERY_OLD,
|
||||||
|
typeEnums
|
||||||
|
).subscribe({
|
||||||
|
messageListView.addHistoryMessages(it.reversed())
|
||||||
|
}, {
|
||||||
|
it.printStackTrace()
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
chatRoomClient = null
|
||||||
|
}
|
||||||
|
}
|
@@ -115,17 +115,35 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true" />
|
android:layout_alignParentBottom="true" />
|
||||||
|
|
||||||
<com.chwl.app.avroom.widget.MessageView
|
<com.chwl.app.ui.widget.magicindicator.MagicIndicator
|
||||||
android:id="@+id/message_view"
|
android:id="@+id/message_indicator"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/dp_44"
|
||||||
|
android:layout_below="@id/micro_view"
|
||||||
|
android:layout_marginTop="@dimen/dp_5" />
|
||||||
|
|
||||||
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
|
android:id="@+id/message_pager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_above="@id/bottom_view"
|
android:layout_above="@id/bottom_view"
|
||||||
android:layout_below="@id/micro_view"
|
android:layout_below="@id/message_indicator"
|
||||||
android:layout_marginStart="12dp"
|
android:layout_marginStart="12dp"
|
||||||
android:layout_marginTop="@dimen/dp_5"
|
|
||||||
android:layout_marginEnd="90dp"
|
android:layout_marginEnd="90dp"
|
||||||
android:layout_marginBottom="@dimen/dp_10" />
|
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
|
<com.coorchice.library.SuperTextView
|
||||||
android:id="@+id/tv_dating_next"
|
android:id="@+id/tv_dating_next"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@@ -725,4 +725,6 @@
|
|||||||
<color name="color_FFF45E">#FFF45E</color>
|
<color name="color_FFF45E">#FFF45E</color>
|
||||||
<color name="color_FFE44E">#FFE44E</color>
|
<color name="color_FFE44E">#FFE44E</color>
|
||||||
|
|
||||||
|
<color name="color_10ECD6">#10ECD6</color>
|
||||||
|
<color name="color_4D415E">#4D415E</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
package com.chwl.app.public_chat.core
|
package com.chwl.app.public_chat.core
|
||||||
|
|
||||||
|
import com.chwl.core.user.UserModel
|
||||||
|
import com.chwl.core.utils.ExtensionUtils
|
||||||
import com.chwl.core.utils.net.RxHelper
|
import com.chwl.core.utils.net.RxHelper
|
||||||
import com.example.lib_utils.ICleared
|
import com.example.lib_utils.ICleared
|
||||||
import com.example.lib_utils.log.ILog
|
import com.example.lib_utils.log.ILog
|
||||||
@@ -14,6 +16,8 @@ import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage
|
|||||||
import com.netease.nimlib.sdk.chatroom.model.ChatRoomStatusChangeData
|
import com.netease.nimlib.sdk.chatroom.model.ChatRoomStatusChangeData
|
||||||
import com.netease.nimlib.sdk.chatroom.model.EnterChatRoomData
|
import com.netease.nimlib.sdk.chatroom.model.EnterChatRoomData
|
||||||
import com.netease.nimlib.sdk.chatroom.model.EnterChatRoomResultData
|
import com.netease.nimlib.sdk.chatroom.model.EnterChatRoomResultData
|
||||||
|
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum
|
||||||
|
import com.netease.nimlib.sdk.msg.model.QueryDirectionEnum
|
||||||
import io.reactivex.BackpressureStrategy
|
import io.reactivex.BackpressureStrategy
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@@ -25,7 +29,8 @@ open class ChatRoomClient(val sessionId: String) : ICleared, ILog {
|
|||||||
|
|
||||||
private var isLogin = false
|
private var isLogin = false
|
||||||
private var loginData: EnterChatRoomResultData? = null
|
private var loginData: EnterChatRoomResultData? = null
|
||||||
private val messagePublishSubject: PublishSubject<List<ChatRoomMessage>> = PublishSubject.create()
|
private val messagePublishSubject: PublishSubject<List<ChatRoomMessage>> =
|
||||||
|
PublishSubject.create()
|
||||||
val messageObservable: Observable<List<ChatRoomMessage>> = messagePublishSubject
|
val messageObservable: Observable<List<ChatRoomMessage>> = messagePublishSubject
|
||||||
.toFlowable(BackpressureStrategy.BUFFER)
|
.toFlowable(BackpressureStrategy.BUFFER)
|
||||||
.toObservable()
|
.toObservable()
|
||||||
@@ -90,6 +95,13 @@ open class ChatRoomClient(val sessionId: String) : ICleared, ILog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun sendMessage(message: ChatRoomMessage): Single<Any> {
|
fun sendMessage(message: ChatRoomMessage): Single<Any> {
|
||||||
|
val map: Map<String?, Any?> = message.localExtension ?: HashMap()
|
||||||
|
val userInfo = UserModel.get().cacheLoginUserInfo
|
||||||
|
if (userInfo != null) {
|
||||||
|
ExtensionUtils.setupExtension(map, userInfo)
|
||||||
|
}
|
||||||
|
message.localExtension = map
|
||||||
|
message.remoteExtension = map
|
||||||
return Single.create<Any> {
|
return Single.create<Any> {
|
||||||
logD("sendMessage() message:${message}")
|
logD("sendMessage() message:${message}")
|
||||||
NIMClient.getService<ChatRoomService>(ChatRoomService::class.java)
|
NIMClient.getService<ChatRoomService>(ChatRoomService::class.java)
|
||||||
@@ -124,6 +136,36 @@ open class ChatRoomClient(val sessionId: String) : ICleared, ILog {
|
|||||||
.observeOnlineStatus(onlineStatusObserver, register)
|
.observeOnlineStatus(onlineStatusObserver, register)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun requestRemoteMessageType(
|
||||||
|
startTime: Long,
|
||||||
|
count: Int,
|
||||||
|
direction: QueryDirectionEnum,
|
||||||
|
typeEnums: Array<MsgTypeEnum>
|
||||||
|
): Single<List<ChatRoomMessage>> {
|
||||||
|
return Single.create<List<ChatRoomMessage>> {
|
||||||
|
NIMClient.getService<ChatRoomService>(ChatRoomService::class.java)
|
||||||
|
.pullMessageHistoryExType(
|
||||||
|
sessionId,
|
||||||
|
startTime,
|
||||||
|
count,
|
||||||
|
direction,
|
||||||
|
typeEnums
|
||||||
|
).setCallback(object : RequestCallback<List<ChatRoomMessage>> {
|
||||||
|
override fun onSuccess(param: List<ChatRoomMessage>?) {
|
||||||
|
it.onSuccess(param ?: emptyList())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailed(code: Int) {
|
||||||
|
it.onError(NimException(code))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onException(exception: Throwable) {
|
||||||
|
it.onError(exception)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}.compose(RxHelper.handleSchedulers())
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
super.onCleared()
|
super.onCleared()
|
||||||
ChatRoomClientManager.onClientCleared(this)
|
ChatRoomClientManager.onClientCleared(this)
|
||||||
|
@@ -218,9 +218,9 @@ public class ChatRoomMessageAdapter extends BaseMultiItemFetchLoadAdapter<ChatRo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean hideTimeAlways(IMMessage message) {
|
private boolean hideTimeAlways(IMMessage message) {
|
||||||
if (message.getSessionType() == SessionTypeEnum.ChatRoom) {
|
// if (message.getSessionType() == SessionTypeEnum.ChatRoom) {
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
switch (message.getMsgType()) {
|
switch (message.getMsgType()) {
|
||||||
case notification:
|
case notification:
|
||||||
return true;
|
return true;
|
||||||
|
@@ -24,9 +24,8 @@ class PublicChatRoomMessageActivity : BaseBindingActivity<PublicChatMessageActiv
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun start(context: Context): Boolean {
|
fun start(context: Context): Boolean {
|
||||||
val partitionId = UserModel.get().partitionId.toString()
|
|
||||||
val sessionId =
|
val sessionId =
|
||||||
InitialModel.get().cacheInitInfo?.publicChatRoomIdMap?.get(partitionId)
|
InitialModel.get().publicChatSessionId
|
||||||
if (sessionId.isNullOrEmpty()) {
|
if (sessionId.isNullOrEmpty()) {
|
||||||
SingleToastUtil.showToast(R.string.public_chat_not_found)
|
SingleToastUtil.showToast(R.string.public_chat_not_found)
|
||||||
return false
|
return false
|
||||||
|
@@ -48,4 +48,6 @@ public interface IInitialModel extends IModel {
|
|||||||
FairyOpenInfo getFairyOpenInfo();
|
FairyOpenInfo getFairyOpenInfo();
|
||||||
|
|
||||||
void regionCheck();
|
void regionCheck();
|
||||||
|
|
||||||
|
String getPublicChatSessionId();
|
||||||
}
|
}
|
||||||
|
@@ -53,6 +53,7 @@ import java.io.File;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
@@ -482,6 +483,19 @@ public class InitialModel extends BaseModel implements IInitialModel {
|
|||||||
return fairyOpenInfo;
|
return fairyOpenInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPublicChatSessionId() {
|
||||||
|
long partitionId = UserModel.get().getPartitionId();
|
||||||
|
if (cacheInitInfo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Map<String, String> idMap = cacheInitInfo.getPublicChatRoomIdMap();
|
||||||
|
if (idMap == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return idMap.get(partitionId + "");
|
||||||
|
}
|
||||||
|
|
||||||
private interface Api {
|
private interface Api {
|
||||||
/**
|
/**
|
||||||
* 客户端初始化
|
* 客户端初始化
|
||||||
|
@@ -19,6 +19,7 @@ import androidx.annotation.Nullable;
|
|||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.chwl.core.gift.bean.GiftType;
|
import com.chwl.core.gift.bean.GiftType;
|
||||||
|
import com.chwl.core.initial.InitialModel;
|
||||||
import com.chwl.core.monsterhunting.bean.MonsterDataBean;
|
import com.chwl.core.monsterhunting.bean.MonsterDataBean;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
@@ -619,6 +620,9 @@ public final class IMNetEaseManager {
|
|||||||
if (Objects.equals(sessionId, String.valueOf(PublicChatHallDataManager.get().getPublicChatHallId()))) {
|
if (Objects.equals(sessionId, String.valueOf(PublicChatHallDataManager.get().getPublicChatHallId()))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (Objects.equals(sessionId, InitialModel.get().getPublicChatSessionId())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
RoomInfo currentRoomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
|
RoomInfo currentRoomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
|
||||||
if (currentRoomInfo == null) {
|
if (currentRoomInfo == null) {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -41,6 +41,8 @@ public class UserInfo implements Serializable {
|
|||||||
public static String IS_NEW_USER = "newUser";
|
public static String IS_NEW_USER = "newUser";
|
||||||
public static String IS_FROM_SAY_HELLO_CHANNEL = "fromSayHelloChannel";
|
public static String IS_FROM_SAY_HELLO_CHANNEL = "fromSayHelloChannel";
|
||||||
public static String GENDER = "gender";
|
public static String GENDER = "gender";
|
||||||
|
public static String NICK = "nick";
|
||||||
|
public static String AVATAR = "avatar";
|
||||||
public static String IS_OFFICIAL = "official";
|
public static String IS_OFFICIAL = "official";
|
||||||
public static String DEF_USER = "defUser";
|
public static String DEF_USER = "defUser";
|
||||||
public static String HAS_PRETTY = "hasPrettyErbanNo";
|
public static String HAS_PRETTY = "hasPrettyErbanNo";
|
||||||
@@ -662,6 +664,8 @@ public class UserInfo implements Serializable {
|
|||||||
if (map == null) {
|
if (map == null) {
|
||||||
map = new HashMap<>();
|
map = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
map.put(NICK, userInfo.getNick());
|
||||||
|
map.put(AVATAR, userInfo.getNewAvatar());
|
||||||
map.put(GENDER, userInfo.getGender());
|
map.put(GENDER, userInfo.getGender());
|
||||||
map.put(IS_OFFICIAL, userInfo.getDefUser() == USER_TYPE_OFFICIAL);
|
map.put(IS_OFFICIAL, userInfo.getDefUser() == USER_TYPE_OFFICIAL);
|
||||||
map.put(IS_NEW_USER, isNewUser());
|
map.put(IS_NEW_USER, isNewUser());
|
||||||
|
Reference in New Issue
Block a user