1.新增游戏房 2.接入小游戏SDK 3.游戏房麦位

This commit is contained in:
huangjian
2021-12-06 18:53:52 +08:00
parent 4749f25229
commit 8d1125cc14
34 changed files with 3584 additions and 314 deletions

View File

@@ -5,7 +5,7 @@ android {
compileSdkVersion 29
defaultConfig {
minSdkVersion 19
minSdkVersion 21
targetSdkVersion 29
testApplicationId 'com.soundcloud.android.crop.test'

Binary file not shown.

View File

@@ -14,7 +14,7 @@ android {
defaultConfig {
applicationId "com.mango.yinyou"
minSdkVersion 19
minSdkVersion 21
targetSdkVersion 29
versionCode Integer.valueOf(version_code)
versionName version_name
@@ -294,6 +294,8 @@ dependencies {
implementation files('libs/humesdk-1.0.0.aar')
implementation(name: 'SudMGP-v1.1.31.181', ext: 'aar')
// xplan flutter module
if (useFlutterAar) {
implementation 'com.mango.flutter.xplan:flutter_release:1.0'

View File

@@ -89,6 +89,7 @@
android:supportsRtl="true"
android:theme="@style/MyMaterialTheme"
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"
tools:replace="android:name, android:allowBackup">
<meta-data

View File

@@ -2,6 +2,7 @@ package com.yizhuan.erban.avroom.adapter;
import android.content.Context;
import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.RecyclerView;
@@ -56,9 +57,11 @@ public abstract class BaseMicroViewAdapter extends RecyclerView.Adapter<Recycler
public static final String MICRO_TYPE_NORMAL = "normal";
public static final String MICRO_TYPE_DATING = "dating";
public static final String MICRO_TYPE_DATING_VIP = "dating_vip";
protected static final int TYPE_KING = 2;
protected static final int TYPE_BOSS = 1;
protected static final int TYPE_NORMAL = 0;
protected static final int TYPE_INVALID = -2;
protected OnMicroItemClickListener onMicroItemClickListener;
protected Context context;
public BaseMicroViewAdapter(Context context) {
@@ -85,11 +88,6 @@ public abstract class BaseMicroViewAdapter extends RecyclerView.Adapter<Recycler
return 9;
}
protected static final int TYPE_KING = 2;
protected static final int TYPE_BOSS = 1;
protected static final int TYPE_NORMAL = 0;
protected static final int TYPE_INVALID = -2;
@Override
public int getItemViewType(int position) {
return (position == 0) ? TYPE_BOSS : TYPE_NORMAL;
@@ -100,17 +98,53 @@ public abstract class BaseMicroViewAdapter extends RecyclerView.Adapter<Recycler
return position;
}
public void clear(NormalMicroViewHolder holder) {
holder.clear();
}
public abstract void bindToRecyclerView(RecyclerView recyclerView);
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
onMicroItemClickListener = null;
super.onDetachedFromRecyclerView(recyclerView);
}
public void setBossViewGender(TextView tvNick, boolean isMale) {
if (AvRoomDataManager.get().isOpenPKMode()) { // pk模式不加性别背景
tvNick.setCompoundDrawablePadding(4);
tvNick.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
} else {
if (isMale) {
tvNick.setCompoundDrawablePadding(4);
tvNick.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_gender_male, 0);
} else {
tvNick.setCompoundDrawablePadding(4);
tvNick.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_gender_female, 0);
}
}
}
public class NormalMicroViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView tvNick;
ImageView ivUpImage;
ImageView ivLockImage;
ImageView ivMuteImage;
ImageView ivHeadWear;
CircleImageView ivAvatar;
ImageView ivHalo;
@Nullable
ImageView ivHeadWear;
@Nullable
TextView tvNumber;
@Nullable
ImageView ivCharmLevelTag;
RoomQueueInfo info;
int position = TYPE_INVALID;
NormalMicroViewHolder(View itemView) {
super(itemView);
ivHalo = itemView.findViewById(R.id.iv_halo);
@@ -128,16 +162,12 @@ public abstract class BaseMicroViewAdapter extends RecyclerView.Adapter<Recycler
ivAvatar.setOnClickListener(this);
}
RoomQueueInfo info;
int position = TYPE_INVALID;
public void clear() {
info = null;
position = TYPE_INVALID;
ivHalo.setBackground(null);
ivHalo.clearAnimation();
ivHeadWear.setImageDrawable(null);
clearHeadWear();
ivUpImage.setVisibility(View.VISIBLE);
ivLockImage.setVisibility(View.GONE);
ivMuteImage.setVisibility(View.GONE);
@@ -162,7 +192,9 @@ public abstract class BaseMicroViewAdapter extends RecyclerView.Adapter<Recycler
ivLockImage.setVisibility(View.GONE);
ivMuteImage.setVisibility(View.GONE);
ivAvatar.setVisibility(View.GONE);
ivCharmLevelTag.setVisibility(View.GONE);
if (ivCharmLevelTag != null) {
ivCharmLevelTag.setVisibility(View.GONE);
}
setDefalutText(position);
return;
}
@@ -183,7 +215,9 @@ public abstract class BaseMicroViewAdapter extends RecyclerView.Adapter<Recycler
clearHeadWear();
ivUpImage.setVisibility(View.VISIBLE);
ivAvatar.setVisibility(View.GONE);
ivCharmLevelTag.setVisibility(View.GONE);
if (ivCharmLevelTag != null) {
ivCharmLevelTag.setVisibility(View.GONE);
}
setDefalutText(position);
}
} else {
@@ -192,10 +226,6 @@ public abstract class BaseMicroViewAdapter extends RecyclerView.Adapter<Recycler
ivHalo.clearAnimation();
// 清除头饰
clearHeadWear();
ivHeadWear.clearAnimation();
ivHeadWear.setImageDrawable(null);
ivHeadWear.setVisibility(View.GONE);
ivHeadWear.setTag(R.id.mic_item_head_wear, null);
//锁坑
ivMuteImage.setVisibility(roomMicInfo.isMicMute() ? View.VISIBLE : View.GONE);
if (roomMicInfo.isMicLock()) {
@@ -214,7 +244,7 @@ public abstract class BaseMicroViewAdapter extends RecyclerView.Adapter<Recycler
}
private void clearHeadWear() {
GlideApp.with(context).clear(ivHeadWear);
if (ivHeadWear == null) return;
ivHeadWear.clearAnimation();
ivHeadWear.setImageDrawable(null);
ivHeadWear.setTag(R.id.mic_item_head_wear, null);
@@ -252,6 +282,7 @@ public abstract class BaseMicroViewAdapter extends RecyclerView.Adapter<Recycler
//优先使用MicMemberInfo里面的头饰
private void updateNobleView(MicMemberInfo chatRoomMember) {
if (ivHeadWear == null) return;
String headWear = chatRoomMember.getHeadWearUrl();
if (TextUtils.isEmpty(headWear)) {
headWear = NobleUtil.getHeadResource(HeadWearInfo.EFFECT, chatRoomMember) != null ?
@@ -292,11 +323,11 @@ public abstract class BaseMicroViewAdapter extends RecyclerView.Adapter<Recycler
}
}
class BasicMicroViewHolder extends NormalMicroViewHolder {
public class BasicMicroViewHolder extends NormalMicroViewHolder {
TextView tvPkMark;
BasicMicroViewHolder(View itemView) {
public BasicMicroViewHolder(View itemView) {
super(itemView);
tvPkMark = (TextView) itemView.findViewById(R.id.tv_pk_mark);
}
@@ -477,7 +508,6 @@ public abstract class BaseMicroViewAdapter extends RecyclerView.Adapter<Recycler
}
}
public class BossMicroViewHolder extends MicroViewAdapter.GiftValueViewHolder {
/**
* 主席位特有
@@ -605,33 +635,4 @@ public abstract class BaseMicroViewAdapter extends RecyclerView.Adapter<Recycler
}
}
public void clear(NormalMicroViewHolder holder) {
holder.clear();
}
public abstract void bindToRecyclerView(RecyclerView recyclerView);
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
onMicroItemClickListener = null;
super.onDetachedFromRecyclerView(recyclerView);
}
public void setBossViewGender(TextView tvNick, boolean isMale) {
if (AvRoomDataManager.get().isOpenPKMode()) { // pk模式不加性别背景
tvNick.setCompoundDrawablePadding(4);
tvNick.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
} else {
if (isMale) {
tvNick.setCompoundDrawablePadding(4);
tvNick.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_gender_male, 0);
} else {
tvNick.setCompoundDrawablePadding(4);
tvNick.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_gender_female, 0);
}
}
}
}

View File

@@ -118,7 +118,7 @@ class DatingMicroViewAdapter(context: Context?) : BaseMicroViewAdapter(context)
ivVipWear.isVisible = it.isVipMic
if (it.isVipMic) {
ivHeadWear.isVisible = false
ivHeadWear?.isVisible = false
}
} ?: run {
tvSelectedStatus.isVisible = false
@@ -148,7 +148,7 @@ class DatingMicroViewAdapter(context: Context?) : BaseMicroViewAdapter(context)
ivVipWear.isVisible = false
} else {
if (info.mChatRoomMember.isVipMic) {
ivHeadWear.isVisible = false
ivHeadWear?.isVisible = false
ivVipWear.isVisible = true
} else {
ivVipWear.isVisible = false
@@ -220,7 +220,7 @@ class DatingMicroViewAdapter(context: Context?) : BaseMicroViewAdapter(context)
override fun bind(info: RoomQueueInfo, position: Int) {
super.bind(info, position)
ivVipWear.isVisible = true
ivHeadWear.isVisible = false
ivHeadWear?.isVisible = false
}
}

View File

@@ -0,0 +1,59 @@
package com.yizhuan.erban.avroom.adapter
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.yizhuan.erban.R
import com.yizhuan.xchat_android_core.bean.RoomQueueInfo
/**
* @author xiaoyu
* @date 2017/12/18
*/
class GameMicroViewAdapter(context: Context?) : BaseMicroViewAdapter(context) {
/**
* Set LayoutManager and bind this to RecyclerView
*/
override fun bindToRecyclerView(recyclerView: RecyclerView) {
val layoutManager = GridLayoutManager(context, 6)
layoutManager.orientation = LinearLayoutManager.VERTICAL
recyclerView.layoutManager = layoutManager
recyclerView.adapter = this
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return GameMicroViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_micro_game, parent, false)
)
}
override fun microType() = MICRO_TYPE_DATING
inner class GameMicroViewHolder constructor(itemView: View) :
GiftValueViewHolder(itemView) {
@SuppressLint("SetTextI18n")
public override fun bind(info: RoomQueueInfo, position: Int) {
super.bind(info, position)
}
}
override fun getItemCount(): Int {
return 6
}
}

View File

@@ -0,0 +1,57 @@
package com.yizhuan.erban.avroom.adapter
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.yizhuan.erban.R
import com.yizhuan.xchat_android_core.bean.RoomQueueInfo
/**
* @author xiaoyu
* @date 2017/12/18
*/
class GameMiniMicroViewAdapter(context: Context?) : BaseMicroViewAdapter(context) {
/**
* Set LayoutManager and bind this to RecyclerView
*/
override fun bindToRecyclerView(recyclerView: RecyclerView) {
val layoutManager = LinearLayoutManager(context,LinearLayoutManager.HORIZONTAL,false)
recyclerView.layoutManager = layoutManager
recyclerView.adapter = this
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return GameMicroViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_micro_game_mini, parent, false)
)
}
override fun microType() = MICRO_TYPE_DATING
inner class GameMicroViewHolder constructor(itemView: View) :
NormalMicroViewHolder(itemView) {
@SuppressLint("SetTextI18n")
public override fun bind(info: RoomQueueInfo, position: Int) {
super.bind(info, position)
}
}
override fun getItemCount(): Int {
return 6
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -213,8 +213,13 @@ public class HomePartyFragment extends AbsRoomFragment implements View.OnClickLi
@SuppressLint("CheckResult")
@Override
public void initiate() {
roomFragment = HomePartyRoomFragment.newInstance(isRoomMin);
getChildFragmentManager().beginTransaction().replace(R.id.container, roomFragment).commitAllowingStateLoss();
roomFragment = GameRoomFragment.newInstance(isRoomMin);
//roomFragment = HomePartyRoomFragment.newInstance(isRoomMin);
getChildFragmentManager()
.beginTransaction()
.replace(R.id.container, roomFragment)
.commitAllowingStateLoss();
if (!AvRoomDataManager.get().haveSelfChange && AvRoomDataManager.get().mCurrentRoomInfo != null) {
AvRoomDataManager.get().mIsNeedGiftEffect = AvRoomDataManager.get().mCurrentRoomInfo.isHasAnimationEffect();

View File

@@ -372,8 +372,6 @@ public class HomePartyRoomFragment extends BaseMvpFragment<IHomePartyView, HomeP
bottomView.setBottomViewListener(new GameRoomBottomViewWrapper());
bottomView.setMagicBtnEnable(true);
inputSend.setOnClickListener(this);
microView.findViewById(R.id.desc_layout).setOnClickListener(v -> onRoomSettingsClick());
microView.findViewById(R.id.ll_ktv_top).setOnClickListener(v -> onRoomSettingsClick());
inputLayout.setOnTouchListener((v, event) -> {
inputEdit.clearFocus();

View File

@@ -0,0 +1,19 @@
/*
Copyright © Sud.Tech
https://sud.tech
*/
package com.yizhuan.erban.avroom.game;
public class AppConfig {
protected static final String APP_ID = "1467745235064848385";
protected static final String APP_KEY = "BvjLDpWol7OihaYeFebuepx1bZu6cxU5";
protected static boolean isTestEnv = true;
// 请接入方自己设置 RoomID, 只有在同一房间里,才能一起玩游戏
protected static final String mRoomID = "9009";//房间ID同一个房间ID可对战
protected static final String mLanguage = "zh-CN";//语言
protected static final String GET_APP_CODE = "https://fat-mgp-hello.sudden.ltd/login";
}

View File

@@ -0,0 +1,518 @@
package com.yizhuan.erban.avroom.game
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.widget.FrameLayout
import com.yizhuan.xchat_android_core.auth.AuthModel
import com.yizhuan.xchat_android_core.room.game.GameModel
import com.yizhuan.xchat_android_core.utils.LogUtils
import com.yizhuan.xchat_android_core.utils.net.RxHelper
import com.yizhuan.xchat_android_library.utils.SingleToastUtil
import okhttp3.*
import org.json.JSONException
import org.json.JSONObject
import tech.sud.mgp.core.*
import java.io.IOException
import java.util.*
class GameDelegate(val activity: Activity, val container: FrameLayout) {
companion object {
const val MG_ID_BUMPER_CAR = 1461227817776713818L //游戏ID:碰碰车
const val MG_ID_FLY_CUTTER = 1461228379255603251L //游戏ID:飞刀达人
const val MG_ID_DRAW_GUESS = 1461228410184400899L //游戏ID:你画我猜
const val MG_ID_GO_BANG = 1461297734886621238L //游戏ID:五子棋
}
private val TAG = "GameActivity"
private var APP_CODE = ""
private val mRoomID = "9009" //房间ID同一个房间ID可对战
private val mLanguage = "zh-CN" //语言
private val mCurrentSeat = 1 //当前用户需要上几号麦位
//调用游戏SDK的接口,成功加载游戏后可用:
private var iSudFSTAPP: ISudFSTAPP? = null
//小游戏ID
private var mMGID = MG_ID_BUMPER_CAR
//通用状态-游戏,关键词
private var mKeyWord: String? = null
private val mUid = AuthModel.get().currentUid.toString()
private val loginCallback: AppLoginListener =
object : AppLoginListener {
override fun onLoginFailure(err: String?) {
SingleToastUtil.showToast(err)
}
override fun onLoginSuccess(new_code: String, expire_Date: Long) {
APP_CODE = new_code
Handler(Looper.getMainLooper()).post {
//初始化游戏SDK
initGameSDK(
activity,
AppConfig.APP_ID,
AppConfig.APP_KEY,
AppConfig.isTestEnv
)
}
}
}
init {
login(loginCallback)
}
/**
* "接入方客户端"登陆接口, 从"接入方服务端"获得Code
* "接入方服务端"是通过"服务端接入SDK"获得Code来返回给"接入方客户端"的
* @param listener
*/
@SuppressLint("CheckResult")
private fun login(listener: AppLoginListener) {
GameModel.getGameCode()
.compose(RxHelper.bindContext(activity))
.subscribe({
listener.onLoginSuccess(it.code, it.expireDate)
}, {
listener.onLoginFailure(it.message)
})
}
/**
* 1初始化游戏SDK
*
* @param context 上下文
* @param appID appID
* @param appKey appKey
* @param isTestEnv 是否是测试环境true测试环境false正式环境
*/
private fun initGameSDK(context: Context, appID: String, appKey: String, isTestEnv: Boolean) {
SudMGP.initSDK(context, appID, appKey, isTestEnv, object : ISudListenerInitSDK {
override fun onSuccess() {
loadMG(activity, mUid, mRoomID, APP_CODE, mMGID, mLanguage)
}
override fun onFailure(code: Int, errInfo: String) {
showToast("初始化游戏SDK失败:$code--errInfo:$errInfo")
}
})
}
/**
* 2加载游戏
*
* @param activity 上下文Activity
* @param userID 用户ID业务系统保证每个用户拥有唯一ID
* @param roomID 房间ID进入同一房间内的
* @param code 令牌
* @param mgID 小游戏ID
* @param language 游戏语言 现支持简体zh-CN 繁体zh-TW 英语en-US 马来语ms-MY
*/
private fun loadMG(
activity: Activity,
userID: String,
roomID: String,
code: String,
mgID: Long,
language: String
) {
iSudFSTAPP = SudMGP.loadMG(activity, userID, roomID, code, mgID, language, mISudFSMMG)
addGameView(iSudFSTAPP!!.gameView)
}
/**
* 3将游戏view添加到我们的布局当中
*
* @param gameView
*/
private fun addGameView(gameView: View) {
container.addView(gameView)
}
private fun showToast(content: String) {
SingleToastUtil.showToast(content)
}
/**
* 例如"你画我猜"游戏的文字命中
*/
private fun hitTheMark() {
val keyWord = mKeyWord
if (TextUtils.isEmpty(keyWord)) {
return
}
notifySelfTextHit(keyWord)
}
/**
* 通知"文字命中状态"到游戏端
*
* @param iSudFSTAPP
* @param keyWord
*/
private fun notifySelfTextHit(keyWord: String?) {
try {
//状态名称
val state: String = SudMGPAPPState.APP_COMMON_SELF_TEXT_HIT
//状态数据
val jsonObject = JSONObject()
jsonObject.put("isHit", true) // true 命中false 未命中
jsonObject.put("keyWord", keyWord) // true 命中false 未命中
jsonObject.put("text", "我猜这是:$keyWord") // 聊天原始内容,这里的值只是一个示例,意指内容当中包含关键词则命中,具体按业务规则定。
val dataJson = jsonObject.toString()
//状态通知回调
val iSudListenerNotifyStateChange: ISudListenerNotifyStateChange? = null
//调用接口
iSudFSTAPP?.notifyStateChange(state, dataJson, iSudListenerNotifyStateChange)
} catch (e: Exception) {
e.printStackTrace()
}
}
/**
* 设置当前关键词
*
* @param keyWord
*/
private fun setKeyWord(keyWord: String?) {
mKeyWord = keyWord
}
/**
* 游戏SDK调用app的接口
*/
private val mISudFSMMG: ISudFSMMG = object : ISudFSMMG {
override fun onGameLog(p0: String?) {
LogUtils.d(p0)
}
override fun onGameStarted() {
}
override fun onGameDestroyed() {
}
/**
* 回调此方法表示令牌过期此时需要刷新令牌并使用ISudFSMStateHandle回调
* @param handle
* @param dataJson
*/
override fun onExpireCode(handle: ISudFSMStateHandle, dataJson: String) {
login(object : AppLoginListener {
override fun onLoginFailure(err: String?) {
}
override fun onLoginSuccess(new_code: String, expire_Date: Long) {
APP_CODE = new_code
try {
val jsonObject = JSONObject()
jsonObject.put("ret_code", 0)
jsonObject.put("ret_msg", "success")
handle.success(jsonObject.toString())
} catch (e: JSONException) {
e.printStackTrace()
}
iSudFSTAPP?.updateCode(APP_CODE, null)
}
})
}
/**
* 处理获取游戏视图信息
* @param handle
* @param dataJson
*/
override fun onGetGameViewInfo(handle: ISudFSMStateHandle, dataJson: String) {
//拿到游戏View的宽高
val gameViewWidth = container.measuredWidth
val gameViewHeight = container.measuredHeight
if (gameViewWidth > 0 && gameViewHeight > 0) {
notifyGameViewInfo(handle, gameViewWidth, gameViewHeight)
return
}
//如果游戏View未加载完成则监听加载完成时回调
container.viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
override fun onGlobalLayout() {
container.viewTreeObserver.removeOnGlobalLayoutListener(this)
val width = container.measuredWidth
val height = container.measuredHeight
notifyGameViewInfo(handle, width, height)
}
})
}
override fun onGetGameCfg(p0: ISudFSMStateHandle?, p1: String?) {
}
/**
* 通知游戏,游戏视图信息
* @param handle
* @param gameViewWidth
* @param gameViewHeight
*/
private fun notifyGameViewInfo(
handle: ISudFSMStateHandle,
gameViewWidth: Int,
gameViewHeight: Int
) {
try {
val jsonObject = JSONObject()
jsonObject.put("ret_code", 0)
jsonObject.put("ret_msg", "success")
//游戏View大小
val viewSize = JSONObject()
viewSize.put("width", gameViewWidth)
viewSize.put("height", gameViewHeight)
jsonObject.put("view_size", viewSize)
//游戏安全操作区域
val viewGameRect = JSONObject()
viewGameRect.put("left", 0)
viewGameRect.put("top", 600)
viewGameRect.put("right", 0)
viewGameRect.put("bottom", 600)
jsonObject.put("view_game_rect", viewGameRect)
//通知游戏
val json = jsonObject.toString()
Log.d(TAG, "notifyGameViewInfo:$json")
handle.success(json)
} catch (e: JSONException) {
e.printStackTrace()
}
}
/**
* 游戏状态变化
* @param handle
* @param state 状态名
* @param dataJson 状态数据json字符串
*/
override fun onGameStateChange(
handle: ISudFSMStateHandle,
state: String,
dataJson: String
) {
Log.d(TAG, "onGameStateChange state:$state--dataJson:$dataJson")
when (state) {
SudMGPMGState.MG_COMMON_PUBLIC_MESSAGE -> showToast("游戏:公屏消息")
SudMGPMGState.MG_COMMON_KEY_WORD_TO_HIT -> {
showToast("游戏:关键词状态")
if (TextUtils.isEmpty(dataJson)) {
setKeyWord(null)
} else {
try {
val jsonObject = JSONObject(dataJson)
if (jsonObject.isNull("word")) {
setKeyWord(null)
} else {
val keyWord = jsonObject.getString("word")
setKeyWord(keyWord)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
}
/**
* 玩家状态变化
* @param handle
* @param userId 玩家用户ID
* @param state 状态名
* @param dataJson 状态数据json字符串。参考文档
*/
override fun onPlayerStateChange(
handle: ISudFSMStateHandle,
userId: String,
state: String,
dataJson: String
) {
Log.d(TAG, "onPlayerStateChange userId:$userId--state:$state--dataJson:$dataJson")
when (state) {
SudMGPMGState.MG_COMMON_PLAYER_IN -> handlePlayerIn(userId, dataJson)
SudMGPMGState.MG_COMMON_PLAYER_READY -> handlePlayerReady(userId, dataJson)
SudMGPMGState.MG_COMMON_PLAYER_CAPTAIN -> handlePlayerCaptain(userId, dataJson)
SudMGPMGState.MG_COMMON_PLAYER_PLAYING -> handlePlayerPlaying(userId, dataJson)
}
}
}
private fun handlePlayerIn(userId: String, dataJson: String) {
try {
val jsonObject = JSONObject(dataJson)
val retCode = jsonObject.getInt("retCode")
val isIn = jsonObject.getBoolean("isIn")
if (retCode != 0) {
if (retCode == 100201) {
showToast("100201: 战斗时房间不能加入")
} else {
showToast("mg_common_player_in 状态失败, 错误码:$retCode")
}
return
}
if (isIn) { // 已加入
var teamId = 0
if (jsonObject.has("teamId")) {
teamId = jsonObject.getInt("teamId")
}
showToast("加入游戏分组:$teamId")
} else { // 未加入
var reason = 0
if (jsonObject.has("reason")) {
reason = jsonObject.getInt("reason")
}
if (reason == 0) {
showToast("主动退出游戏")
} else if (reason == 1) {
val userid = jsonObject.getString("kickUID")
showToast(userid + "将我踢出游戏")
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun handlePlayerReady(userId: String, dataJson: String) {
try {
val jsonObject = JSONObject(dataJson)
val retCode = jsonObject.getInt("retCode")
val isReady = jsonObject.getBoolean("isReady")
if (retCode != 0) {
showToast("mg_common_player_ready 操作失败, 错误码:$retCode")
return
}
if (isReady) { // 已准备
} else { // 未准备
}
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun handlePlayerCaptain(userId: String, dataJson: String) {
try {
val jsonObject = JSONObject(dataJson)
val retCode = jsonObject.getInt("retCode")
val isCaptain = jsonObject.getBoolean("isCaptain")
if (retCode != 0) {
showToast("mg_common_player_captain 操作失败, 错误码:$retCode")
return
}
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun handlePlayerPlaying(userId: String, dataJson: String) {
try {
val jsonObject = JSONObject(dataJson)
val retCode = jsonObject.getInt("retCode")
if (retCode != 0) {
if (retCode == 100503) {
showToast("100503: 有人未准备")
} else if (retCode == 100504) {
showToast("100504: 开始游戏的人数不足")
} else {
showToast("mg_common_player_playing 操作失败, 错误码:$retCode")
}
return
}
val isPlaying = jsonObject.getBoolean("isPlaying")
if (!isPlaying) { // 未在游戏中
var reason = 0
if (jsonObject.has("reason")) {
reason = jsonObject.getInt("reason")
}
if (reason == 0) {
showToast("正常结束")
} else if (reason == 1) {
showToast("提前结束(自己不玩了)")
} else if (reason == 2) {
showToast("无真人可以提前结束(无真人,只有机器人)")
} else if (reason == 3) {
showToast("所有人都提前结束")
} else {
showToast("未在游戏中, reason = $reason")
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
fun onStart() {
iSudFSTAPP?.startMG() //启动游戏
}
fun onResume() {
iSudFSTAPP?.playMG() //开始游戏
}
fun onPause() {
iSudFSTAPP?.pauseMG() //暂停游戏
}
fun onStop() {
iSudFSTAPP?.stopMG() //停止游戏
}
fun onDestroy() {
iSudFSTAPP?.destroyMG()
}
}
internal interface AppLoginListener {
/**
* App Server 登陆失败, App Server 不能返回CODE
*/
fun onLoginFailure(err: String?)
/**
* App Server 登陆成功, App Server调用服务端接入SDK的API获取Code 返回给 App
* App 就要用CODE和自己生成的UserID去调用SDK的初始化函数登陆小游戏
* 小游戏登陆成功后其UserID就是App传的UserID
*/
fun onLoginSuccess(new_code: String, expire_Date: Long)
}

View File

@@ -0,0 +1,82 @@
/*
Copyright © Sud.Tech
https://sud.tech
*/
package com.yizhuan.erban.avroom.game;
/**
* Time:2021/10/19
* Description: APP to MG 的状态定义
*/
public class SudMGPAPPState {
// region 通用状态
/**
* 加入状态
* 最低版本: v1.1.30.xx
*/
public static final String APP_COMMON_SELF_IN = "app_common_self_in";
/**
* 准备状态
* 最低版本: v1.1.30.xx
*/
public static final String APP_COMMON_SELF_READY = "app_common_self_ready";
/**
* 游戏状态
* 最低版本: v1.1.30.xx
*/
public static final String APP_COMMON_SELF_PLAYING = "app_common_self_playing";
/**
* 队长状态
* 最低版本: v1.1.30.xx
*/
public static final String APP_COMMON_SELF_CAPTAIN = "app_common_self_captain";
/**
* 踢人
* v1.1.30.xx
*/
public static final String APP_COMMON_SELF_KICK = "app_common_self_kick";
/**
* 结束游戏
* v1.1.30.xx
*/
public static final String APP_COMMON_SELF_END = "app_common_self_end";
/**
* 房间状态, (depreated 已废弃v1.1.30.xx)
*/
public static final String APP_COMMON_SELF_ROOM = "app_common_self_room";
/**
* 麦位状态, (depreated 已废弃v1.1.30.xx)
*/
public static final String APP_COMMON_SELF_SEAT = "app_common_self_seat";
/**
* 麦克风状态
*/
public static final String APP_COMMON_SELF_MICROPHONE = "app_common_self_microphone";
/**
* 文字命中状态
*/
public static final String APP_COMMON_SELF_TEXT_HIT = "app_common_self_text_hit";
// endregion 通用状态
// region 碰碰我最强
// endregion 碰碰我最强
// region 飞刀达人
// endregion 飞刀达人
// region 你画我猜
// endregion 你画我猜
}

View File

@@ -0,0 +1,93 @@
/*
Copyright © Sud.Tech
https://sud.tech
*/
package com.yizhuan.erban.avroom.game;
/**
* Time:2021/10/19
* Description: MG to APP 的状态定义
*/
public class SudMGPMGState {
// region 通用状态-游戏
/**
* 公屏消息 (已修改)
* 最低版本: v1.1.30.xx
*/
public static final String MG_COMMON_PUBLIC_MESSAGE = "mg_common_public_message";
/**
* 关键词状态
*/
public static final String MG_COMMON_KEY_WORD_TO_HIT = "mg_common_key_word_to_hit";
// endregion 通用状态-游戏
// region 通用状态-玩家
/**
* 加入状态 (已修改)
* 最低版本: v1.1.30.xx
*/
public static final String MG_COMMON_PLAYER_IN = "mg_common_player_in";
/**
* 准备状态 (已修改)
* 最低版本: v1.1.30.xx
*/
public static final String MG_COMMON_PLAYER_READY = "mg_common_player_ready";
/**
* 队长状态 (已修改)
* 最低版本: v1.1.30.xx
*/
public static final String MG_COMMON_PLAYER_CAPTAIN = "mg_common_player_captain";
/**
* 游戏状态 (已修改)
* 最低版本: v1.1.30.xx
*/
public static final String MG_COMMON_PLAYER_PLAYING = "mg_common_player_playing";
// endregion 通用状态-玩家
// region 碰碰我最强
// endregion 碰碰我最强
// region 飞刀达人
// endregion 飞刀达人
// region 你画我猜
/**
* 选词中
*/
public static final String MG_DG_SELECTING = "mg_dg_selecting";
/**
* 作画中
*/
public static final String MG_DG_PAINTING = "mg_dg_painting";
/**
* 错误答案
*/
public static final String MG_DG_ERRORANSWER = "mg_dg_erroranswer";
/**
* 总积分
*/
public static final String MG_DG_TOTALSCORE = "mg_dg_totalscore";
/**
* 本次积分
*/
public static final String MG_DG_SCORE = "mg_dg_score";
// endregion 你画我猜
}

View File

@@ -0,0 +1,598 @@
package com.yizhuan.erban.avroom.presenter;
import android.annotation.SuppressLint;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.ResponseCode;
import com.netease.nimlib.sdk.chatroom.ChatRoomMessageBuilder;
import com.netease.nimlib.sdk.chatroom.ChatRoomService;
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 com.netease.nimlib.sdk.util.Entry;
import com.orhanobut.logger.Logger;
import com.yizhuan.erban.avroom.view.IGameRoomView;
import com.yizhuan.erban.base.BaseMvpPresenter;
import com.yizhuan.xchat_android_core.Constants;
import com.yizhuan.xchat_android_core.auth.AuthModel;
import com.yizhuan.xchat_android_core.bean.RoomQueueInfo;
import com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.FaceAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomInfoAttachment;
import com.yizhuan.xchat_android_core.initial.InitialModel;
import com.yizhuan.xchat_android_core.initial.bean.InitInfo;
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager;
import com.yizhuan.xchat_android_core.manager.IMNetEaseManager;
import com.yizhuan.xchat_android_core.pay.bean.WalletInfo;
import com.yizhuan.xchat_android_core.praise.PraiseModel;
import com.yizhuan.xchat_android_core.room.bean.RoomInfo;
import com.yizhuan.xchat_android_core.room.exception.AntiSpamHitException;
import com.yizhuan.xchat_android_core.room.face.FaceReceiveInfo;
import com.yizhuan.xchat_android_core.room.giftvalue.helper.GiftValueMrg;
import com.yizhuan.xchat_android_core.room.model.AvRoomModel;
import com.yizhuan.xchat_android_core.room.model.HomePartyModel;
import com.yizhuan.xchat_android_core.room.model.RoomBaseModel;
import com.yizhuan.xchat_android_core.room.queue.bean.MicMemberInfo;
import com.yizhuan.xchat_android_core.super_admin.model.SuperAdminModel;
import com.yizhuan.xchat_android_core.super_admin.util.SuperAdminUtil;
import com.yizhuan.xchat_android_core.user.UserModel;
import com.yizhuan.xchat_android_core.user.bean.BaseInfo;
import com.yizhuan.xchat_android_core.user.bean.UserInfo;
import com.yizhuan.xchat_android_core.utils.net.DontWarnObserver;
import com.yizhuan.xchat_android_core.utils.net.RxHelper;
import com.yizhuan.xchat_android_library.base.PresenterEvent;
import com.yizhuan.xchat_android_library.net.rxnet.callback.CallBack;
import com.yizhuan.xchat_android_library.utils.ListUtils;
import com.yizhuan.xchat_android_library.utils.SingleToastUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.BiConsumer;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
/**
* <p> </p>
*
* @author jiahui
* @date 2017/12/8
*/
public class GameRoomPresenter extends BaseMvpPresenter<IGameRoomView> {
/**
* 显示关注房主的时间
*/
public static final int SHOW_FOLLOW_TIME = 3 * 60 * 1000;
private final HomePartyModel mHomePartyMode;
private final AvRoomModel mAvRoomModel;
private final SuperAdminModel mSuperAdminModel;
protected WalletInfo walletInfo;
/**
* 判断所坑服务端是否响应回来了
*/
private boolean mIsLockMicPosResultSuccess = true;
private boolean mIsUnLockMicPosResultSuccess = true;
private Gson gson = new Gson();
public GameRoomPresenter() {
mHomePartyMode = new HomePartyModel();
mAvRoomModel = AvRoomModel.get();
mSuperAdminModel = new SuperAdminModel();
}
/**
* 麦坑点击处理,麦上没人的时候
*
* @param micPosition 麦序位置
* @param chatRoomMember 坑上的用户
*/
public void microPhonePositionClick(final int micPosition, MicMemberInfo chatRoomMember) {
final RoomInfo currentRoom = AvRoomDataManager.get().mCurrentRoomInfo;
if (currentRoom == null) {
return;
}
final String currentUid = String.valueOf(AuthModel.get().getCurrentUid());
if (AvRoomDataManager.get().isRoomOwner(currentUid) || AvRoomDataManager.get().isRoomAdmin(currentUid)
|| SuperAdminUtil.isSuperAdmin()) {
if (AvRoomDataManager.get().isRoomOwner(currentUid) && currentRoom.isLeaveMode()) {
SingleToastUtil.showToast("请先关闭离开模式");
return;
}
onOwnerUpMicroClick(micPosition, Long.parseLong(currentUid));
} else {
if (AvRoomDataManager.get().getRoomQueueMemberInfoByMicPosition(micPosition).mRoomMicInfo.isMicLock()) {
if (AvRoomDataManager.get().isQueuingMicro()) {
String msg;
if (AvRoomDataManager.get().isOnMic(AuthModel.get().getCurrentUid())) {
msg = "你已经在麦上啦";
} else {
msg = "要排麦才可以上麦哦~";
}
SingleToastUtil.showToast(msg);
}
return;
}
if (AvRoomDataManager.get().isQueuingMicro() && AvRoomDataManager.get().myIsInQueue) {
SingleToastUtil.showToast("取消报名才可以上麦哦!");
return;
}
getMvpView().toUpMicroPhone(micPosition, currentUid, false);
}
}
private void onOwnerUpMicroClick(final int micPosition, final long currentUid) {
RoomQueueInfo roomQueueInfo = AvRoomDataManager.get().getRoomQueueMemberInfoByMicPosition(micPosition);
if (roomQueueInfo == null) return;
if (getMvpView() != null)
getMvpView().showOwnerClickDialog(roomQueueInfo.mRoomMicInfo, micPosition, currentUid);
}
public void lockMicroPhone(int micPosition) {
if (!mIsLockMicPosResultSuccess) {
return;
}
mIsLockMicPosResultSuccess = false;
RoomInfo currentRoom = AvRoomDataManager.get().mCurrentRoomInfo;
if (currentRoom == null) {
return;
}
final String currentUid = String.valueOf(currentRoom.getUid());
mHomePartyMode.lockMicroPhone(micPosition, currentUid, AuthModel.get().getTicket())
.doOnSuccess(data -> {
Logger.i("用户%1$s锁坑成功: %2$s", String.valueOf(currentUid), data);
mIsLockMicPosResultSuccess = true;
})
.doOnError(throwable -> {
Logger.i("用户%1$s锁坑失败: %2$s", String.valueOf(currentUid),
RxHelper.getNotEmptyError(throwable));
mIsLockMicPosResultSuccess = true;
})
.subscribe();
}
/**
* 坑位释放锁
*/
public void unLockMicroPhone(int micPosition) {
if (!mIsUnLockMicPosResultSuccess) {
return;
}
mIsUnLockMicPosResultSuccess = false;
RoomInfo currentRoom = AvRoomDataManager.get().mCurrentRoomInfo;
if (currentRoom == null) {
return;
}
final String currentUid = String.valueOf(currentRoom.getUid());
if (AvRoomDataManager.get().isRoomAdmin() || AvRoomDataManager.get().isRoomOwner(currentUid)) {
mHomePartyMode.unLockMicroPhone(micPosition, currentUid, AuthModel.get().getTicket())
.subscribe(new Consumer<String>() {
@Override
public void accept(String data) throws Exception {
Logger.i("用户%1$s解麦成功: %2$s", String.valueOf(currentUid), data);
mIsUnLockMicPosResultSuccess = true;
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Logger.i("用户%1$s解麦失败: %2$s", String.valueOf(currentUid), throwable.getMessage());
mIsUnLockMicPosResultSuccess = true;
}
});
}
}
/**
* 下麦
*
* @param micPosition
* @param isKick 是否是主动的
*/
public void downMicroPhone(int micPosition, final boolean isKick) {
final RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo == null) {
return;
}
final String currentUid = String.valueOf(AuthModel.get());
mHomePartyMode.downMicroPhone(micPosition, new CallBack<String>() {
@Override
public void onSuccess(String data) {
Logger.i("用户%1$s下麦成功%2$s", currentUid, data);
if (!isKick) {
//被踢了
if (getMvpView() != null) {
getMvpView().kickDownMicroPhoneSuccess();
}
}
}
@Override
public void onFail(int code, String error) {
Logger.i("用户%1$s下麦失败%2$s----", currentUid, error);
}
});
}
/**
* 上麦
*
* @param micPosition
* @param uId
* @param isInviteUpMic 是否是主动的false主动
* @param isReconnect 是否需要清除礼物值普通情况下上麦传false断网重连传ture
*/
public void upMicroPhone(final int micPosition, final String uId, boolean isInviteUpMic, boolean isReconnect) {
final RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo == null) {
return;
}
if (!isInviteUpMic) {
upMicroPhone(micPosition, uId, isInviteUpMic, roomInfo, isReconnect);
} else {
AvRoomDataManager.get().haveStartDragon = false;
upMicroPhone(micPosition, uId, isInviteUpMic, roomInfo, isReconnect);
}
}
public void upMicroPhone(final int micPosition, final String uId, boolean isInviteUpMic) {
upMicroPhone(micPosition, uId, isInviteUpMic, false);
}
public void upMicroPhone(int micPosition, String uId, boolean isInviteUpMic, RoomInfo roomInfo,
boolean isReconnect) {
mHomePartyMode.upMicroPhone(micPosition, uId, String.valueOf(roomInfo.getRoomId()),
isInviteUpMic, new CallBack<String>() {
@Override
public void onSuccess(String data) {
Logger.i("用户%1$s上麦成功%2$s", uId, data);
if (!isReconnect) {
GiftValueMrg.get().requestUpMic(micPosition, uId);
} else {
GiftValueMrg.get().handleReconnect(true);
}
}
@Override
public void onFail(int code, String error) {
if (code == RoomBaseModel.CODE_UPDATE_MIC) {
if (getMvpView() != null) {
getMvpView().updateMicView();
}
}
Logger.i("用户%1$s上麦失败%2$s----", uId, error);
}
});
}
/**
* 邀请用户上麦
*
* @param micInfo 要邀请的用户
* @param position 坑位
*/
public void inviteMicroPhone(final BaseInfo micInfo, final int position) {
final long micUid = micInfo.getUid();
if (AvRoomDataManager.get().isOnMic(micUid)) {
return;
}
//如果点击的就是自己,那这里就是自己上麦
if (AvRoomDataManager.get().isOwner(micUid)) {
upMicroPhone(position, String.valueOf(micUid), true);
return;
}
mHomePartyMode.inviteMicroPhone(micInfo, position)
.compose(bindUntilEvent(PresenterEvent.DESTROY))
.subscribe(new BiConsumer<ChatRoomMessage, Throwable>() {
@Override
public void accept(ChatRoomMessage chatRoomMessage,
Throwable throwable) throws Exception {
if (throwable != null) {
Logger.i("邀请用户%d上麦失败!!!" + micUid);
} else
Logger.i("邀请用户%d上麦成功!!!" + micUid);
}
});
}
/**
* 开麦
*
* @param micPosition
*/
public void openMicroPhone(int micPosition) {
final RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo == null) {
return;
}
mHomePartyMode.openMicroPhone(micPosition, roomInfo.getUid())
.subscribe(new DontWarnObserver<String>() {
@Override
public void accept(String data, String error) {
super.accept(data, error);
if (error != null) {
Logger.i("用户%1$s开麦失败: %2$s", String.valueOf(roomInfo.getUid()), error);
} else {
Logger.i("用户%1$s开麦成功: %2$s", String.valueOf(roomInfo.getUid()), data);
}
}
});
}
/**
* 闭麦
*
* @param micPosition
*/
public void closeMicroPhone(int micPosition) {
final RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo == null) {
return;
}
mHomePartyMode.closeMicroPhone(micPosition, roomInfo.getUid())
.doOnSuccess(data -> {
Logger.i("用户%1$s闭麦成功: %2$s", String.valueOf(roomInfo.getUid()), data);
})
.doOnError(throwable -> {
Logger.i("用户%1$s闭麦失败: %2$s", String.valueOf(roomInfo.getUid()),
RxHelper.getNotEmptyError(throwable));
})
.subscribe();
}
public void roomOperate(int operate) {
mSuperAdminModel.roomOperate(operate)
.subscribe();
}
/***
* 发送房间消息
* @param message
*/
@SuppressLint("CheckResult")
public void sendTextMsg(String message) {
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo == null || TextUtils.isEmpty(message)) return;
IMNetEaseManager.get().sendTextMsg(roomInfo.getRoomId(), message)
.subscribe(new BiConsumer<ChatRoomMessage, Throwable>() {
@Override
public void accept(ChatRoomMessage chatRoomMessage,
Throwable throwable) throws Exception {
if (throwable != null) {
if (throwable instanceof AntiSpamHitException) {
Log.e("sendTextMsg", throwable.getMessage());
} else {
Logger.i("发送房间信息失败:" + throwable.getMessage());
}
} else {
getMvpView().onSendMsgSuccess();
IMNetEaseManager.get().addMessagesImmediately(chatRoomMessage);
Logger.i("发送房间信息成功:" + chatRoomMessage.getUuid());
}
}
});
}
@SuppressLint("CheckResult")
public void chatRoomReConnect(final RoomQueueInfo queueInfo) {
final RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo == null) return;
mHomePartyMode.queryRoomMicInfo(String.valueOf(roomInfo.getRoomId()))
.delay(1, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(entries -> {
if (!ListUtils.isListEmpty(entries)) {
JsonParser jsonParser = new JsonParser();
MicMemberInfo chatRoomMember;
for (Entry<String, String> entry : entries) {
RoomQueueInfo roomQueueInfo = AvRoomDataManager.get().mMicQueueMemberMap.get(Integer.parseInt(entry.key));
if (roomQueueInfo != null) {
JsonObject valueJsonObj = jsonParser.parse(entry.value).getAsJsonObject();
if (valueJsonObj != null) {
chatRoomMember = gson.fromJson(valueJsonObj, MicMemberInfo.class);
roomQueueInfo.mChatRoomMember = chatRoomMember;
}
AvRoomDataManager.get().addRoomQueueInfo(entry.key, roomQueueInfo);
}
}
} else {
//麦上都没有人
AvRoomDataManager.get().resetMicMembers();
}
if (getMvpView() != null)
getMvpView().chatRoomReConnectView();
//之前在麦上
if (queueInfo != null && queueInfo.mChatRoomMember != null && queueInfo.mRoomMicInfo != null) {
RoomQueueInfo roomQueueInfo = AvRoomDataManager.get()
.getRoomQueueMemberInfoByMicPosition(queueInfo.mRoomMicInfo.getPosition());
//麦上没人
String account = queueInfo.mChatRoomMember.getAccount();
if (roomQueueInfo != null && (roomQueueInfo.mChatRoomMember == null ||
Objects.equals(account, roomQueueInfo.mChatRoomMember.getAccount()))) {
roomQueueInfo.mChatRoomMember = null;
//断网重连,不要清除麦上的礼物值
upMicroPhone(queueInfo.mRoomMicInfo.getPosition(), account, true, true);
}
}
IMNetEaseManager.get().mCacheRoomQueueInfo = null;
Logger.i("断网重连获取队列信息成功...." + entries);
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
throwable.printStackTrace();
Logger.i("断网重连获取队列信息失败....");
}
});
}
public void userRoomIn() {
final RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo == null) return;
long currentUid = AuthModel.get().getCurrentUid();
mAvRoomModel.userRoomIn(String.valueOf(currentUid), roomInfo.getUid(), 0, "")
.delay(1, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread()).subscribe();
}
@NonNull
private ChatRoomMessage getChatRoomMessage(RoomInfo roomInfo, List<Integer> integers, int second) {
UserInfo userInfo = UserModel.get().getCacheLoginUserInfo();
List<FaceReceiveInfo> faceReceiveInfos = new ArrayList<>();
FaceReceiveInfo faceReceiveInfo = new FaceReceiveInfo();
faceReceiveInfo.setNick(userInfo.getNick());
faceReceiveInfo.setFaceId(Constants.DRAGON_BAR_ID);
faceReceiveInfo.setUid(userInfo.getUid());
faceReceiveInfo.setResultIndexes(integers);
faceReceiveInfos.add(faceReceiveInfo);
// 发送云信信息给所有人
FaceAttachment faceAttachment =
new FaceAttachment(CustomAttachment.CUSTOM_MSG_DRAGON_BAR, second);
faceAttachment.setUid(userInfo.getUid());
faceAttachment.setFaceReceiveInfos(faceReceiveInfos);
return ChatRoomMessageBuilder.createChatRoomCustomMessage(
// 聊天室id
roomInfo.getRoomId() + "",
// 自定义消息
faceAttachment
);
}
public void updateScreen(boolean isCloseScreen) {
String contentText;
if (isCloseScreen) {
ChatRoomMessage firstMsg = IMNetEaseManager.get().getFirstMessageContent();
IMNetEaseManager.get().addCloseScreenMessages(firstMsg);
if (AvRoomDataManager.get().closeScreenBySAdmin()) {
contentText = "系统检测涉嫌违规,予以关闭公屏消息警告";
} else {
contentText = "管理员已关闭聊天公屏";
}
} else {
contentText = "管理员已开启聊天公屏";
}
RoomInfoAttachment attachment = new RoomInfoAttachment(CustomAttachment.CUSTOM_MSG_UPDATE_ROOM_INFO,
CustomAttachment.CUSTOM_MSG_UPDATE_ROOM_INFO_CLOSE_SCREEN);
ChatRoomMessage screenMsg = ChatRoomMessageBuilder.createChatRoomCustomMessage(
String.valueOf(AvRoomDataManager.get().getRoomId()),
attachment
);
screenMsg.setContent(contentText);
IMNetEaseManager.get().addCloseScreenMessages(screenMsg);
}
/**
* 检查是否关注了这个用户
*
* @param uid
*/
@SuppressLint("CheckResult")
public void checkFollow(long uid) {
Single.just("")
.delay(SHOW_FOLLOW_TIME, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.flatMap(new Function<String, SingleSource<Boolean>>() {
@Override
public SingleSource<Boolean> apply(String s) throws Exception {
return PraiseModel.get().isPraised(AuthModel.get().getCurrentUid(), uid);
}
})
.compose(bindUntilEvent(PresenterEvent.DESTROY))
.compose(RxHelper.handleSchAndExce())
.subscribe(new BiConsumer<Boolean, Throwable>() {
@Override
public void accept(Boolean aBoolean, Throwable throwable) throws Exception {
if (throwable != null || getMvpView() == null) {
return;
}
//如果没有关注
if (!aBoolean) {
getMvpView().noFollow();
}
}
});
Observable.interval(1, 5, TimeUnit.MINUTES)
.compose(bindUntilEvent(PresenterEvent.DESTROY))
.map(aLong -> AvRoomDataManager.get().isRoomFans)
.takeUntil(aBoolean -> aBoolean)
.subscribe(aBoolean -> {
if (!aBoolean && getMvpView() != null) {
getMvpView().noFollow2();
}
});
}
/**
* 公屏历史消息
*/
public void loadMessageHistory() {
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo == null) return;
if (!roomInfo.isCloseScreen()) {
int count = 10;
InitInfo initInfo = InitialModel.get().getCacheInitInfo();
if (initInfo != null) count = initInfo.getRoomMessageCount();
NIMClient.getService(ChatRoomService.class)
.pullMessageHistoryExType(String.valueOf(roomInfo.getRoomId()), 0,
count, QueryDirectionEnum.QUERY_OLD, new MsgTypeEnum[]{MsgTypeEnum.text})
.setCallback(new RequestCallbackWrapper<List<ChatRoomMessage>>() {
@Override
public void onResult(int code, List<ChatRoomMessage> result, Throwable exception) {
if (code == ResponseCode.RES_SUCCESS && result != null && result.size() > 0) {
Collections.reverse(result);
if (getMvpView() != null) {
getMvpView().showMessageHistory(result);
}
}
}
});
}
}
/**
* 关注房主
*
* @param position
* @param ownerUid
*/
@SuppressLint("CheckResult")
public void followOwner(int position, long ownerUid) {
PraiseModel.get().praise(ownerUid, true).subscribe(new BiConsumer<String, Throwable>() {
@Override
public void accept(String s, Throwable throwable) throws Exception {
if (getMvpView() == null) {
return;
}
if (throwable == null) {
getMvpView().onFollowSuccess(position);
} else {
getMvpView().onFollowFail(throwable.getMessage());
}
}
});
}
}

View File

@@ -0,0 +1,83 @@
package com.yizhuan.erban.avroom.view;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage;
import com.yizhuan.erban.avroom.widget.ViewItem;
import com.yizhuan.xchat_android_core.bean.RoomMicInfo;
import com.yizhuan.xchat_android_core.miniworld.bean.MiniWorldInWorldInfo;
import com.yizhuan.xchat_android_core.room.bean.RoomInfo;
import com.yizhuan.xchat_android_library.base.IMvpBaseView;
import java.util.List;
/**
* <p> 轰趴房View层 </p>
*
* @author jiahui
* @date 2017/12/8
*/
public interface IGameRoomView extends IMvpBaseView {
/**
* 被踢下麦成功
*/
void kickDownMicroPhoneSuccess();
/**
* 麦上没人点击坑位处理
*
* @param roomMicInfo 坑位信息
* @param micPosition
* @param currentUid
*/
void showOwnerClickDialog(RoomMicInfo roomMicInfo, int micPosition, long currentUid);
/**
* 断网重连回调
*/
void chatRoomReConnectView();
void showToast(String msg);
void onSendMsgSuccess();
/**
* 上麦请求
*
* @param micPosition
* @param currentUid
* @param b
*/
void toUpMicroPhone(int micPosition, String currentUid, boolean b);
/**
* 没有关注用户的监听
*/
void noFollow();
/**
* 鬼知道之前有一个,现在又要加一个
*/
void noFollow2();
/**
* 没有关注用户的监听
*/
void showMessageHistory(List<ChatRoomMessage> messages);
/**
* 关注成功
* @param position
*/
void onFollowSuccess(int position);
/**
* 关注失败
* @param msg
*/
void onFollowFail(String msg);
void updateMicView();
}

View File

@@ -11,7 +11,6 @@ import android.text.Spanned;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
@@ -161,7 +160,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import lombok.Setter;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_RED_PACKAGE;
import static com.yizhuan.xchat_android_core.redpackage.RedPackageTypeKt.ALL_DIAMOND;
@@ -202,11 +200,17 @@ public class MessageView extends FrameLayout {
private int expLevelHeight;
private int giftLength;
private volatile boolean needAutoScroll = true;//是否自动滚动到底部
@Setter
private Consumer<String> clickConsumer;
@Setter
private OnClick onClick;
public void setClickConsumer(Consumer<String> clickConsumer) {
this.clickConsumer = clickConsumer;
}
public void setOnClick(OnClick onClick) {
this.onClick = onClick;
}
public MessageView(Context context) {
this(context, null);
}

View File

@@ -5,42 +5,32 @@ import android.content.Context;
import android.graphics.Point;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.RecyclerView;
import com.yizhuan.erban.R;
import com.yizhuan.erban.avroom.adapter.BaseMicroViewAdapter;
import com.yizhuan.erban.avroom.adapter.CpMicroViewAdapter;
import com.yizhuan.erban.avroom.adapter.DatingMicroViewAdapter;
import com.yizhuan.erban.avroom.adapter.KtvMicroViewAdapter;
import com.yizhuan.erban.avroom.adapter.MicroViewAdapter;
import com.yizhuan.erban.avroom.adapter.OnMicroItemClickListener;
import com.yizhuan.erban.avroom.ktv.KtvView;
import com.yizhuan.erban.databinding.LayoutMicroViewBinding;
import com.yizhuan.erban.ui.anim.AnimFactory;
import com.yizhuan.erban.ui.widget.magicindicator.buildins.UIUtil;
import com.yizhuan.erban.ui.widget.recyclerview.decoration.DatingItemDecoration;
import com.yizhuan.erban.utils.RegexUtil;
import com.yizhuan.xchat_android_core.bean.RoomQueueInfo;
import com.yizhuan.xchat_android_core.im.custom.bean.FaceAttachment;
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager;
import com.yizhuan.xchat_android_core.manager.IMNetEaseManager;
import com.yizhuan.xchat_android_core.manager.RoomEvent;
import com.yizhuan.xchat_android_core.manager.AudioEngineManager;
import com.yizhuan.xchat_android_core.noble.NobleResourceType;
import com.yizhuan.xchat_android_core.noble.NobleUtil;
import com.yizhuan.xchat_android_core.room.bean.RoomInfo;
import com.yizhuan.xchat_android_core.room.event.ReceiveFaceEvent;
import com.yizhuan.xchat_android_core.room.face.FaceReceiveInfo;
import com.yizhuan.xchat_android_library.utils.config.BasicConfig;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@@ -56,23 +46,17 @@ import io.reactivex.disposables.Disposable;
* @author xiaoyu
* @date 2017/12/20
*/
public class MicroView extends RelativeLayout implements View.OnLayoutChangeListener {
public class MicroView extends FrameLayout implements View.OnLayoutChangeListener {
private static final String TAG = "MicroView";
public RecyclerView recyclerView;
private SparseArray<ImageView> faceImageViews;
private SparseArray<ImageView> dragonBarImageViews;
private int[] realPositions = {1, 5, 2, 6, 0, 3, 7, 4, 8};
private Context mContext;
private int giftWidth;
private int giftHeight;
private Disposable subscribe;
private KtvView ktvView;
private LayoutMicroViewBinding mBinding;
private boolean isNeedResetMicCenterPoint = true;
private DatingItemDecoration datingItemDecoration;
@@ -206,7 +190,7 @@ public class MicroView extends RelativeLayout implements View.OnLayoutChangeList
int y = (location[1] + child.getHeight() / 2) - giftHeight / 2;
// 放置表情占位image view
ImageView face = array.get(micPosition);
LayoutParams params = new LayoutParams(giftHeight, giftHeight);
LayoutParams params = new LayoutParams(giftWidth, giftHeight);
child.getLocationInWindow(location);
int[] containerLocation = new int[2];
this.getLocationInWindow(containerLocation);
@@ -232,7 +216,6 @@ public class MicroView extends RelativeLayout implements View.OnLayoutChangeList
private void init(final Context context) {
this.mContext = context;
inflate(mContext, R.layout.layout_micro_view, this);
mBinding = DataBindingUtil.bind(findViewById(R.id.container));
recyclerView = findViewById(R.id.recycler_view);
recyclerView.addOnLayoutChangeListener(this);
if (AvRoomDataManager.get().isCpRoom()) {
@@ -240,42 +223,16 @@ public class MicroView extends RelativeLayout implements View.OnLayoutChangeList
} else {
bindAdapter(new MicroViewAdapter(mContext));
}
ktvView = findViewById(R.id.view_ktv);
ViewGroup.LayoutParams ktvParam = ktvView.getLayoutParams();
ktvParam.height = (UIUtil.getScreenWidth(context) - UIUtil.dip2px(context, 24)) * 198 / 352;
giftWidth = UIUtil.dip2px(mContext, 80);
giftHeight = UIUtil.dip2px(mContext, 80);
giftWidth = UIUtil.dip2px(mContext, 16);
giftHeight = UIUtil.dip2px(mContext, 16);
faceImageViews = new SparseArray<>(10);
dragonBarImageViews = new SparseArray<>(9);
mBinding.setRoomInfo(AvRoomDataManager.get().mCurrentRoomInfo);
}
public void updateRoomInfo() {
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo == null) return;
mBinding.setRoomInfo(roomInfo);
mBinding.setKtvModel(roomInfo.isOpenKTV);
if (!TextUtils.isEmpty(roomInfo.getRoomDesc())) {
mBinding.tvRoomDesc.setText(RegexUtil.getPrintableString(roomInfo.getRoomDesc()));
} else {
if (AvRoomDataManager.get().isManager()) {
mBinding.tvRoomDesc.setText(BasicConfig.INSTANCE.getAppContext().getString(R.string.room_manager_edit_desc));
} else {
mBinding.tvRoomDesc.setText(BasicConfig.INSTANCE.getAppContext().getString(R.string.room_no_desc));
}
}
if (AvRoomDataManager.get().isManager()) {
mBinding.ivRoomCanEdit.setVisibility(VISIBLE);
} else {
mBinding.ivRoomCanEdit.setVisibility(GONE);
}
mBinding.tvRoomType.setText(roomInfo.getRoomTag());
}
@SuppressLint("CheckResult")
@@ -388,31 +345,16 @@ public class MicroView extends RelativeLayout implements View.OnLayoutChangeList
}
}
private boolean isKtvMode;
public void openKtvMode() {
isKtvMode = true;
mBinding.setKtvModel(isKtvMode);
ktvView.setVisibility(VISIBLE);
//修复成员刚进房间变ktv模式后关闭按钮没出现的问题
ktvView.updateCloseBtnNoSong();
if (!AvRoomDataManager.get().isCpRoom()) {
bindAdapter(new KtvMicroViewAdapter(mContext));
} else {
resetPoint();
}
if (!AudioEngineManager.get().isOpenKtv()) {
AudioEngineManager.get().openKtvModel();
}
}
public void resetPoint() {
/* recyclerView.postDelayed(() -> {
faceImageViews = setMicCenterPoint(faceImageViews);
dragonBarImageViews = setMicCenterPoint(dragonBarImageViews);
}, 500);*/
public void closeKtvMode() {
}
public void bindAdapter(BaseMicroViewAdapter adapter) {
if (adapter instanceof DatingMicroViewAdapter) {
if (datingItemDecoration == null) datingItemDecoration = new DatingItemDecoration();
@@ -422,19 +364,6 @@ public class MicroView extends RelativeLayout implements View.OnLayoutChangeList
}
adapter.bindToRecyclerView(recyclerView);
adapter.setOnMicroItemClickListener(onMicroItemClickListener);
resetPoint();
}
public void closeKtvMode() {
isKtvMode = false;
mBinding.setKtvModel(false);
ktvView.setVisibility(GONE);
if (AvRoomDataManager.get().isCpRoom()) {
bindAdapter(new CpMicroViewAdapter(mContext));
} else {
bindAdapter(new MicroViewAdapter(mContext));
}
AudioEngineManager.get().closeKtvModel();
}
public void switchToDatingMode() {
@@ -452,25 +381,4 @@ public class MicroView extends RelativeLayout implements View.OnLayoutChangeList
imageView.clearAnimation();
}
private int getRealPosition(int position) {
return isKtvMode && !AvRoomDataManager.get().isCpRoom() ? realPositions[position] : position;
}
/**
* 根据坑位查找recyclerView的子View
* 如果是ktv模式的话要额外处理
*
* @param position 就是坑位(-1到7的值+1
* @return 坑位对应的recyclerView的子View
*/
private int getWavePosition(int position) {
if (isKtvMode && !AvRoomDataManager.get().isCpRoom()) {
for (int i = 0; i < realPositions.length; i++) {
if (position == realPositions[i]) {
return i;
}
}
}
return position;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 B

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/black_transparent_20"/>
<corners android:bottomRightRadius="0dp"
android:topRightRadius="0dp"
android:bottomLeftRadius="13dp"
android:topLeftRadius="13dp"/>
</shape>

View File

@@ -22,6 +22,11 @@
android:orientation="vertical"
tools:background="#000">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/room_back"
android:layout_width="42dp"
@@ -165,13 +170,6 @@
android:scaleType="center"
android:src="@drawable/ic_share_white" />
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/ll_room_info"
android:layout_marginTop="4dp" />
<ViewStub
android:id="@+id/vs_gift_view"
android:layout_width="match_parent"

View File

@@ -0,0 +1,221 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
android:layout_height="wrap_content"
tools:background="@color/color_activity_blue_bg"
tools:layout_width="60dp">
<FrameLayout
android:id="@+id/micro_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/iv_halo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" />
<ImageView
android:id="@+id/up_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="@dimen/dp_10"
android:scaleType="fitXY"
android:src="@drawable/icon_room_up_micro" />
<ImageView
android:id="@+id/lock_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="@dimen/dp_10"
android:scaleType="fitXY"
android:src="@drawable/icon_room_lock_micro"
android:visibility="invisible"
tools:visibility="gone" />
<View
android:id="@+id/view_gender_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="@dimen/dp_10"
android:background="@drawable/shape_circle_micro_man_bg" />
<com.yizhuan.erban.common.widget.CircleImageView
android:id="@+id/avatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="@dimen/dp_10"
android:src="@drawable/default_avatar"
android:visibility="gone"
tools:visibility="visible" />
<ImageView
android:id="@+id/iv_vip_wear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="2dp"
android:src="@drawable/icon_room_dating_vip"
android:visibility="gone" />
<ImageView
android:id="@+id/iv_head_wear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="2dp" />
<ImageView
android:id="@+id/iv_cap"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="1.5dp"
tools:visibility="gone" />
<TextView
android:id="@+id/tv_selected_status"
android:layout_width="37dp"
android:layout_height="14dp"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="4dp"
android:background="@drawable/selector_dating_select_man_bg"
android:gravity="center"
android:includeFontPadding="false"
android:text="未选择"
android:textColor="@color/white"
android:textSize="9sp"
android:visibility="gone"
tools:visibility="visible" />
<ImageView
android:id="@+id/mute_image"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_gravity="bottom|end"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:scaleType="fitCenter"
android:src="@drawable/icon_room_mute_micro"
android:visibility="visible"
tools:visibility="visible" />
</FrameLayout>
<LinearLayout
android:id="@+id/ll_nick"
android:layout_width="0dp"
android:layout_height="15dp"
android:layout_marginLeft="@dimen/dp_5"
android:layout_marginRight="@dimen/dp_5"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/micro_layout">
<TextView
android:id="@+id/tv_number"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_marginRight="2dp"
android:background="@drawable/shape_circle_white33"
android:gravity="center"
android:includeFontPadding="false"
android:text="1"
android:textColor="@color/white"
android:textSize="9dp" />
<TextView
android:id="@+id/nick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:textColor="@color/white"
android:textSize="10dp"
tools:text="狐嘎" />
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_parent_gift_value"
android:layout_width="0dp"
android:layout_height="@dimen/dp_50"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<View
android:id="@+id/view_center"
android:layout_width="1dp"
android:layout_height="1dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/view_center_of_charm"
android:layout_width="1dp"
android:layout_height="1dp"
android:layout_marginStart="18dp"
android:layout_marginTop="15dp"
app:layout_constraintStart_toEndOf="@id/view_center"
app:layout_constraintTop_toBottomOf="@id/view_center"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/ll_charm_click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="@dimen/dp_5"
android:paddingBottom="@dimen/dp_5"
android:layout_marginEnd="5dp"
app:layout_constraintBottom_toBottomOf="@id/view_center_of_charm"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/view_center_of_charm">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="14dp"
android:background="@drawable/shape_bg_of_mic_charm"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_value_icon"
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="3dp"
android:scaleType="fitCenter"
android:src="@drawable/icon_gift_value" />
<TextView
android:id="@+id/tv_charm_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="3dp"
android:layout_marginEnd="3dp"
android:gravity="center"
android:textColor="@color/white"
android:textSize="10dp"
tools:text="126" />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="16dp"
android:layout_height="16dp"
android:layout_marginStart="1dp"
android:layout_marginEnd="1dp"
tools:background="@color/color_activity_blue_bg"
>
<FrameLayout
android:id="@+id/micro_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/iv_halo"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" />
<ImageView
android:id="@+id/up_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:scaleType="fitXY"
android:src="@drawable/icon_room_up_micro" />
<ImageView
android:id="@+id/lock_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:scaleType="fitXY"
android:src="@drawable/icon_room_lock_micro"
android:visibility="invisible"
tools:visibility="gone" />
<com.yizhuan.erban.common.widget.CircleImageView
android:id="@+id/avatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:src="@drawable/default_avatar"
android:visibility="gone"
tools:visibility="visible" />
<ImageView
android:id="@+id/iv_head_wear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
/>
<ImageView
android:id="@+id/mute_image"
android:layout_width="5dp"
android:layout_height="5dp"
android:layout_gravity="bottom|end"
android:scaleType="fitCenter"
android:src="@drawable/icon_room_mute_micro"
android:visibility="visible"
tools:visibility="visible" />
</FrameLayout>
<LinearLayout
android:id="@+id/ll_nick"
android:layout_width="0dp"
android:visibility="gone"
android:layout_height="15dp"
android:layout_marginLeft="@dimen/dp_5"
android:layout_marginRight="@dimen/dp_5"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/micro_layout">
<TextView
android:id="@+id/tv_number"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_marginRight="2dp"
android:background="@drawable/shape_circle_white33"
android:gravity="center"
android:includeFontPadding="false"
android:text="1"
android:textColor="@color/white"
android:textSize="9dp" />
<TextView
android:id="@+id/nick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="3dp"
android:ellipsize="end"
android:gravity="center"
android:includeFontPadding="false"
android:maxLines="1"
android:textColor="@color/white"
android:textSize="10dp"
tools:text="狐仙嘎嘎" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,137 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never" />
<data>
<variable
name="roomInfo"
type="com.yizhuan.xchat_android_core.room.bean.RoomInfo" />
<variable
name="ktvModel"
type="Boolean" />
</data>
<RelativeLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.yizhuan.erban.avroom.ktv.KtvView
android:id="@+id/view_ktv"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginLeft="@dimen/dp_12"
android:layout_marginTop="@dimen/dp_5"
android:layout_marginRight="@dimen/dp_12"
android:visibility="gone" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/view_ktv"
android:layout_centerHorizontal="true"
android:overScrollMode="never" />
<FrameLayout
android:id="@+id/fl_head"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/recycler_view">
<LinearLayout
android:id="@+id/ll_ktv_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:visibility="gone">
<TextView
android:id="@+id/iv_ktv_contribute_list"
shape_color="@{@color/white_tran_10}"
shape_radius="@{10}"
android:layout_width="40dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/dp_15"
android:gravity="center"
android:text="公告"
android:textColor="@color/white"
android:textSize="12dp"
tools:contentDescription="ktv模式下的房间排行榜入口" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="5dp"
android:text="为避免噪音 请麦上用户佩戴耳机"
android:textColor="@color/white_transparent_50"
android:textSize="@dimen/sp_12" />
</LinearLayout>
<LinearLayout
android:id="@+id/desc_layout"
android:gravity="center_vertical"
visible="@{(!ktvModel &amp;&amp; roomInfo.type==5)}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingStart="12dp"
android:paddingEnd="12dp">
<TextView
android:id="@+id/tv_room_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_bg_room_tag"
android:gravity="center"
android:paddingStart="3dp"
android:paddingEnd="3dp"
android:paddingBottom="1dp"
android:textColor="@color/appColor"
android:textSize="@dimen/sp_10"
tools:text="交友" />
<TextView
android:id="@+id/tv_room_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginBottom="1px"
android:ellipsize="end"
android:gravity="center"
android:maxLength="15"
android:maxLines="1"
android:text="@string/room_manager_edit_desc"
android:textColor="#7FFFFFFF"
android:textSize="@dimen/sp_13"
tools:text="请点击设置编辑房间话题设置编辑房间话题设置编辑房间话题设置编辑房间话题" />
<ImageView
android:id="@+id/iv_room_can_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginBottom="4.5dp"
android:src="@drawable/icon_room_desc_edit" />
</LinearLayout>
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="25dp"
android:layout_marginLeft="15dp"
android:background="@drawable/shape_room_message_bg"
android:gravity="center"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="房主退出房间房间将在120s后关闭"
android:textColor="#ffffffff"
android:textSize="13sp"
android:visibility="gone" />
</FrameLayout>
</RelativeLayout>
</layout>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
<domain-config cleartextTrafficPermitted="true">
<!-- fengkongcloud.com 为默认值,如果通过 option.setUtl 设置的 url 为 http 连接(下小节将介绍),需要将此 url 如 proxy.example.com 添加到 domain-config 中 -->
<domain includeSubdomains="true">fengkongcloud.com</domain>
</domain-config>
</network-security-config>

View File

@@ -30,6 +30,7 @@
android:id="@+id/ll_ktv_top"
android:layout_width="match_parent"
android:layout_height="32dp"
android:layout_marginTop="100dp"
android:orientation="horizontal"
android:visibility="@{(ktvModel || roomInfo.type==5) ? View.VISIBLE : View.GONE}">

View File

@@ -0,0 +1,175 @@
<?xml version="1.0" encoding="utf-8"?>
<layout 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"
tools:context="com.yizhuan.erban.avroom.fragment.HomePartyRoomFragment">
<data>
<variable
name="click"
type="android.view.View.OnClickListener" />
<variable
name="roomInfo"
type="com.yizhuan.xchat_android_core.room.bean.RoomInfo" />
<variable
name="ktvModel"
type="Boolean" />
<import type="android.view.View" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/fl_game_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/contribute_list"
android:layout_width="wrap_content"
android:layout_height="24dp"
android:layout_marginTop="75dp"
android:background="@drawable/bg_contribute_entrance"
android:gravity="center"
android:onClick="@{click}"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:text="房间榜"
android:textColor="@color/white"
android:textSize="12dp" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="2dp"
android:src="@drawable/icon_contribute_left" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="75dp"
android:orientation="vertical">
<TextView
android:id="@+id/tv_show_mini_mic"
android:layout_width="26dp"
android:layout_height="23dp"
android:layout_gravity="end"
android:background="@drawable/bg_mini_mic_entrance"
android:drawableStart="@drawable/ic_room_mic_right"
android:gravity="center"
android:paddingEnd="3dp" />
<LinearLayout
android:id="@+id/ll_mic_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:gravity="end|center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_show_mic"
android:layout_width="12dp"
android:layout_height="22dp"
android:rotation="180"
android:layout_marginStart="5dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_room_mic_right"
android:visibility="gone" />
<com.yizhuan.erban.avroom.widget.MicroView
android:id="@+id/micro_view"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
<com.yizhuan.erban.avroom.widget.BottomView
android:id="@+id/bottom_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp" />
<com.yizhuan.erban.avroom.widget.MessageView
android:id="@+id/message_view"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_above="@id/bottom_view"
android:layout_marginStart="12dp"
android:layout_marginTop="@dimen/dp_5"
android:layout_marginEnd="90dp"
android:layout_marginBottom="@dimen/dp_10" />
<com.yizhuan.erban.ui.widget.rollviewpager.RollPagerView
android:id="@+id/activity_img"
android:layout_width="65dp"
android:layout_height="70dp"
android:layout_alignTop="@id/message_view"
android:layout_alignParentEnd="true"
android:layout_marginTop="@dimen/dp_5"
android:layout_marginEnd="16dp"
app:rollviewpager_hint_gravity="center" />
<RelativeLayout
android:id="@+id/input_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
tools:visibility="visible">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:background="@android:color/white"
android:gravity="center_vertical"
android:orientation="horizontal">
<EditText
android:id="@+id/input_edit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:color/white"
android:hint="在此输入你要说的话!"
android:paddingLeft="10dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:textColor="#888889"
android:textColorHint="#c8c8c8"
android:textSize="12sp" />
<ImageView
android:id="@+id/input_send"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:background="@drawable/click_white_gray_selector"
android:scaleType="center"
android:src="@android:drawable/ic_menu_send" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
</layout>

View File

@@ -6,7 +6,7 @@ apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
defaultConfig {
minSdkVersion 19
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"

View File

@@ -11,9 +11,7 @@ import com.yizhuan.xchat_android_core.utils.net.RxHelper
import com.yizhuan.xchat_android_core.utils.net.launchRequest
import com.yizhuan.xchat_android_library.net.rxnet.RxNet
import io.reactivex.Single
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Query
import retrofit2.http.*
object HomeModel : BaseModel() {
@@ -85,6 +83,23 @@ object HomeModel : BaseModel() {
}.compose(RxHelper.handleSchAndExce())
}
fun getGameCode(): Single<Int> {
return api.getCode("https://fat-mgp-hello.sudden.ltd/login", AuthModel.get().currentUid)
.flatMap { unReadCountInfoServiceResult ->
if (unReadCountInfoServiceResult.isSuccess) {
val unReadCountInfo = unReadCountInfoServiceResult.data
if (unReadCountInfo != null) {
Single.just(unReadCountInfoServiceResult.data?.total ?: 0)
} else {
Single.just(0)
}
} else {
Single.just(0)
}
}.compose(RxHelper.handleSchAndExce())
}
suspend fun getHomeBanner(type: String): List<BannerInfo>? =
launchRequest {
api.apiHomeBanner(
@@ -171,6 +186,18 @@ object HomeModel : BaseModel() {
@POST("interactive/unreadCount")
fun getUnreadCount(@Query("uid") uid: Long): Single<ServiceResult<UnReadCountInfo>>
/**
* 获取互动消息未读数量
*
* @param uid
* @return
*/
@POST
fun getCode(
@Url url: String,
@Query("user_id") uid: Long
): Single<ServiceResult<UnReadCountInfo>>
/**
* 首页Banner
*

View File

@@ -0,0 +1,6 @@
package com.yizhuan.xchat_android_core.room.game
data class GameCodeInfo(
val code: String,
val expireDate: Long
)

View File

@@ -0,0 +1,69 @@
package com.yizhuan.xchat_android_core.room.game
import com.yizhuan.xchat_android_core.auth.AuthModel
import com.yizhuan.xchat_android_core.base.BaseModel
import com.yizhuan.xchat_android_core.bean.response.ServiceResult
import com.yizhuan.xchat_android_core.community.CommunityConstant
import com.yizhuan.xchat_android_core.community.bean.UnReadCountInfo
import com.yizhuan.xchat_android_core.home.bean.BannerInfo
import com.yizhuan.xchat_android_core.utils.net.RxHelper
import com.yizhuan.xchat_android_core.utils.net.launchRequest
import com.yizhuan.xchat_android_library.net.rxnet.RxNet
import io.reactivex.Single
import retrofit2.http.*
object GameModel : BaseModel() {
private val api = RxNet.create(Api::class.java)
fun getGameCode(): Single<GameCodeInfo> {
return api.getGameCode(AuthModel.get().currentUid)
//.compose(RxHelper.handleBeanData())
.compose(RxHelper.handleSchAndExce())
}
suspend fun getHomeBanner(type: String): List<BannerInfo>? =
launchRequest {
api.apiHomeBanner(
type, AuthModel.get().currentUid.toString(),
CommunityConstant.VERSION_VALID_TYPE,
AuthModel.get().ticket
)
}
private interface Api {
/**
*
*
* @param uid
* @return
*/
@FormUrlEncoded
@POST("/miniGame/getCode")
fun getGameCode(
@Field("uid") uid: Long
): Single<GameCodeInfo>
/**
* 首页Banner
*
* @param type
* @param uid
* @param types
* @param ticket
* @return
*/
@GET("/home/banner")
suspend fun apiHomeBanner(
@Query("type") type: String,
@Query("uid") uid: String,
@Query("types") types: String,
@Query("ticket") ticket: String
): ServiceResult<List<BannerInfo>>
}
}

View File

@@ -4,7 +4,7 @@ apply plugin: 'kotlin-android'
android {
compileSdkVersion 29
defaultConfig {
minSdkVersion 19
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"

View File

@@ -7,7 +7,7 @@ android {
buildToolsVersion '28.0.3'
defaultConfig {
minSdkVersion 19
minSdkVersion 21
targetSdkVersion 29
renderscriptTargetApi 26