Compare commits

..

28 Commits

Author SHA1 Message Date
Max
c8d16ad331 feat:修改接口加密KEY 2024-04-28 09:45:36 +08:00
Max
dc4b5fec82 feat:调整TRTC相关参数 2024-04-19 10:17:11 +08:00
Max
67d5d12cb8 fix:文件上传改为默认主线程回调 2024-04-12 14:39:09 +08:00
Max
8299cc29fe feat:调整易盾KEY 2024-04-08 10:26:14 +08:00
Max
f4f7361184 fix:GitModel初始化加载礼物接口 补加登录状态判断 2024-04-03 17:19:20 +08:00
Max
7bd8b4c653 fix:修复动态上传失败后非主线程更新UI问题 2024-04-03 10:29:06 +08:00
Max
beb083c896 feat:支持自定义域名替换 2024-04-02 20:05:09 +08:00
Max
56942bf545 fix:修复动态发布失败时按钮状态未恢复问题 2024-04-02 20:04:39 +08:00
Max
a1891718f5 feat:移除七牛云改用腾讯COS 2024-04-02 20:04:09 +08:00
Max
68723cd47f fix:修复贵族中心空指针隐患 2024-04-02 16:47:31 +08:00
Max
6f49eca7b9 fix:修复贵族google渠道开通接口传参问题
fix:移除开通按钮错误的状态更新
2024-04-01 18:58:10 +08:00
Max
1478973d42 feat:送礼接口调整 2024-04-01 16:20:57 +08:00
Max
688dc3bc3d feat:去掉贵族返利列表的波纹动效 2024-04-01 10:40:17 +08:00
Max
8096ce0ff5 feat:初步完成送礼可刷金币功能(待测试) 2024-04-01 10:19:19 +08:00
Max
f2b083d7a7 feat:完成贵族购买需求 2024-03-29 19:41:50 +08:00
Max
e326dabc13 feat:PK更新值忽略超级幸运礼物 2024-03-25 23:05:11 +08:00
Max
794a24f332 fix:修复通用模版消息解析json问题 2024-03-25 19:00:12 +08:00
Max
3a6ccd0e97 fix:修复房间在线列表-点击神秘人弹出资料卡问题 2024-03-25 15:28:06 +08:00
Max
87da2a9f18 feat:通用飘屏协议号变更(105老版本有崩溃问题) 2024-03-25 14:53:30 +08:00
Max
9d8118e331 fix:修复通用公屏异常(FastJson解析DataClass问题)
feat:增加trycatch避免直接崩溃
2024-03-25 14:52:02 +08:00
Max
ed6e247de7 fix:修复超级幸运礼物-全麦送礼时未屏蔽公屏问题 2024-03-25 09:57:43 +08:00
Max
3864efcc4c feat:完成超级幸运礼物功能 2024-03-21 20:03:26 +08:00
Max
cae5ccce7a fix:修复正式包json解析问题(com.alibaba.fastjson.JSONException: default constructor not found) 2024-03-20 20:52:17 +08:00
Max
6bd857b97d feat:完成通用飘屏对接 2024-03-20 14:20:22 +08:00
Max
502a2f20b9 feat:初步完成房间内的通用模版飘屏(待测试) 2024-03-20 14:20:22 +08:00
Max
74a7ccecfc feat:分享邀请支持动态配置:标题、图片 2024-03-20 14:19:57 +08:00
Max
d4f65da89e feat:分享邀请生成图片UI新调整
feat:新增JS方法->直接保存图片
2024-03-20 14:19:55 +08:00
Max
bbb6a21cb9 feat:初步分享邀请弹窗部分(假数据) 2024-03-20 14:19:54 +08:00
110 changed files with 3833 additions and 479 deletions

View File

@@ -478,6 +478,7 @@ public class XChatApplication extends BaseApp {
ChannelModel.get();
MarketVerifyModel.get();
GiftModel.get();
GiftModel.get().tryLoadGiftList();
PublicChatHallModel.get();
// 模厅
HallDataManager.get().application();

View File

@@ -16,6 +16,8 @@ import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUS
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_BOX_ALL_ROOM_NOTIFY_BY_SVGA;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_DRAW_GIFT_L5;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_ROOM_PK_NOTIFY;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY_ALL;
import android.annotation.SuppressLint;
import android.app.Activity;
@@ -46,6 +48,7 @@ import androidx.viewpager2.widget.ViewPager2;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.netease.nim.uikit.StatusBarUtil;
import com.netease.nimlib.sdk.NIMSDK;
import com.netease.nimlib.sdk.Observer;
@@ -109,6 +112,8 @@ import com.yizhuan.xchat_android_core.im.custom.bean.RoomLuckySeaMsgBean;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomPKAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomPkBean;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomReceivedLuckyGiftAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomTemplateNotifyAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomTemplateNotifyMsgBean;
import com.yizhuan.xchat_android_core.im.custom.bean.TarotAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.TarotMsgBean;
import com.yizhuan.xchat_android_core.initial.InitialModel;
@@ -1295,6 +1300,14 @@ public class AVRoomActivity extends BaseMvpActivity<IAvRoomView, AvRoomPresenter
IMNetEaseManager.get().noticeRoomEvent(message, RoomEvent.CRAZY_ZOO_ALL_ROOM_NOTIFY);
}
break;
case CUSTOM_MSG_TEMPLATE_NOTIFY://通用飘屏
if (baseProtocol.getSecond() == CUSTOM_MSG_TEMPLATE_NOTIFY_ALL) {
RoomTemplateNotifyAttachment attachment = new RoomTemplateNotifyAttachment(CUSTOM_MSG_TEMPLATE_NOTIFY, CUSTOM_MSG_TEMPLATE_NOTIFY_ALL);
attachment.setMsgBean(new Gson().fromJson(String.valueOf(baseProtocol.getData()), RoomTemplateNotifyMsgBean.class));
ChatRoomMessage message = ChatRoomMessageBuilder.createChatRoomCustomMessage(String.valueOf(AvRoomDataManager.get().getRoomId()), attachment);
IMNetEaseManager.get().noticeRoomEvent(message, RoomEvent.TEMPLATE_NOTIFY);
}
break;
case CUSTOM_MSG_LUCKY_GIFT://福袋
if (baseProtocol.getSecond() == CUSTOM_MSG_LUCKY_GIFT_SERVER_NOTIFY || baseProtocol.getSecond() == CUSTOM_MSG_LUCKY_GIFT_SERVER_ALL) {
RoomReceivedLuckyGiftAttachment attachment = new RoomReceivedLuckyGiftAttachment(CUSTOM_MSG_LUCKY_GIFT_SERVER_NOTIFY);
@@ -1449,21 +1462,25 @@ public class AVRoomActivity extends BaseMvpActivity<IAvRoomView, AvRoomPresenter
String contentStr = broadcastMessage.getContent();
Logger.i(ResUtil.getString(R.string.avroom_activity_avroomactivity_014) + contentStr);
if (TextUtils.isEmpty(contentStr)) return;
AVRoomActivity activity = mReference.get();
if (activity == null) return;
if (activity.isValid()) {
JSONObject jsonObject;
try {
jsonObject = JSON.parseObject(contentStr);
} catch (Exception e) {
jsonObject = null;
}
if (jsonObject == null) return;
if (jsonObject.containsKey("body")) {
String body = jsonObject.getString("body");
if (TextUtils.isEmpty(body)) return;
activity.onReceivedGiftBroadcastMessage(body);
try {
AVRoomActivity activity = mReference.get();
if (activity == null) return;
if (activity.isValid()) {
JSONObject jsonObject;
try {
jsonObject = JSON.parseObject(contentStr);
} catch (Exception e) {
jsonObject = null;
}
if (jsonObject == null) return;
if (jsonObject.containsKey("body")) {
String body = jsonObject.getString("body");
if (TextUtils.isEmpty(body)) return;
activity.onReceivedGiftBroadcastMessage(body);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -16,6 +16,7 @@ import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.core.content.ContextCompat;
import androidx.core.util.Consumer;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.LiveData;
@@ -39,7 +40,9 @@ import com.yizhuan.erban.base.BaseFragment;
import com.yizhuan.erban.databinding.FragmentChatroomGameMainBinding;
import com.yizhuan.erban.friend.view.SelectFriendActivity;
import com.yizhuan.erban.home.helper.OpenRoomHelper;
import com.yizhuan.erban.ui.widget.GiftDialog;
import com.yizhuan.erban.ui.widget.ShareDialog;
import com.yizhuan.erban.ui.widget.UserInfoDialog;
import com.yizhuan.erban.utils.RegexUtil;
import com.yizhuan.xchat_android_core.gift.bean.GiftMultiReceiverInfo;
import com.yizhuan.xchat_android_core.gift.bean.GiftReceiveInfo;
@@ -216,7 +219,17 @@ public class HomePartyFragment extends BaseFragment implements View.OnClickListe
ivRoomShare.setOnClickListener(this);
gameMainBinding.llRoomInfo.setOnClickListener(this);
gameMainBinding.ivBack.setOnClickListener(this);
mRoomEffectView.setShowUserCardAction(s -> {
if (roomFragment instanceof GiftDialog.OnGiftDialogBtnClickListener) {
UserInfoDialog.showNewUserInfoDialog(
mContext,
JavaUtil.str2long(s),
true,
true,
true, (GiftDialog.OnGiftDialogBtnClickListener) roomFragment
);
}
});
mRoomEffectView.setPlayNotifyStateListener(playNotifyStateLiveData);
mRoomEffectView.setOnPlayAnimCallback(new Function0<Boolean>() {
@Override

View File

@@ -18,6 +18,7 @@ import com.yizhuan.erban.avroom.view.IHomePartyUserListView;
import com.yizhuan.erban.base.BaseMvpFragment;
import com.yizhuan.erban.ui.widget.UserInfoDialog;
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager;
import com.yizhuan.xchat_android_core.room.bean.OnlineChatMember;
import com.yizhuan.xchat_android_core.room.bean.RoomInfo;
import com.yizhuan.xchat_android_core.room.bean.RoomOnlineUserBean;
import com.yizhuan.xchat_android_library.base.factory.CreatePresenter;
@@ -123,6 +124,9 @@ public class OnlineUserFragment extends BaseMvpFragment<IHomePartyUserListView,
if (ListUtils.isListEmpty(chatRoomMembers)) return;
RoomOnlineUserBean onlineChatMember = chatRoomMembers.get(position);
if (onlineChatMember != null) {
if (onlineChatMember.getItemType() == OnlineChatMember.NOBLE) {
return;
}
UserInfoDialog.showNewUserInfoDialog(mContext,
onlineChatMember.getUid(),
true,

View File

@@ -251,7 +251,7 @@ class UploadRoomAlbumDialogFragment : BottomSheetDialogFragment() {
}
if (requestCode == 200) {
PhotoProvider.getResultPathListAsync(data) {
it?.let { paths ->
it?.mapNotNull { it.path }?.let { paths ->
compressPhotos(paths.toMutableList())
}
}

View File

@@ -20,6 +20,7 @@ import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUS
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_DRAW_GIFT_L5;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_FANS_TEAM_JOIN;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_GIFT_COMPOUND;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUPER_LUCKY_GIFT_TEMPLATE;
import static com.yizhuan.xchat_android_core.redpackage.RedPackageTypeKt.ALL_DIAMOND;
import static com.yizhuan.xchat_android_core.redpackage.RedPackageTypeKt.ALL_GIFT;
import static com.yizhuan.xchat_android_core.redpackage.RedPackageTypeKt.ROOM_DIAMOND;
@@ -1089,6 +1090,13 @@ public class MessageView extends FrameLayout {
} else {
getTemplateMessageAdapter().convert(tvContent, null);
}
} else if (first == CUSTOM_MSG_SUPER_LUCKY_GIFT_TEMPLATE) {
TemplateMessageAttachment templateMessageAttachment = (TemplateMessageAttachment) chatRoomMessage.getAttachment();
if (templateMessageAttachment != null) {
getTemplateMessageAdapter().convert(tvContent, templateMessageAttachment.getTemplateMessage());
} else {
getTemplateMessageAdapter().convert(tvContent, null);
}
} else {
tvContent.setTextColor(Color.WHITE);
tvContent.setText(tvContent.getResources().getText(R.string.not_support_message_tip));

View File

@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.text.Layout
import android.text.StaticLayout
import android.text.TextPaint
@@ -20,13 +21,18 @@ import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.NonNull
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.text.HtmlCompat
import androidx.core.util.Consumer
import androidx.lifecycle.MutableLiveData
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.chuhai.utils.UiUtils
import com.chuhai.utils.ktx.setPadding2
import com.coorchice.library.SuperTextView
import com.netease.nim.uikit.common.util.sys.ScreenUtil
import com.netease.nim.uikit.support.glide.GlideApp
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage
import com.netease.nimlib.sdk.chatroom.model.ChatRoomNotificationAttachment
import com.opensource.svgaplayer.*
@@ -49,12 +55,14 @@ import com.yizhuan.erban.ui.widget.SimpleAnimListener
import com.yizhuan.erban.ui.widget.dialog.AllServiceGiftGoRoomTipsDialog
import com.yizhuan.erban.ui.widget.dialog.AllServiceGiftGoRoomTipsDialog.Companion.isNeedTips
import com.yizhuan.erban.ui.widget.drawgift.DrawGiftPlayHelper
import com.yizhuan.erban.utils.CommonJumpHelper
import com.yizhuan.erban.utils.MsgBuilder
import com.yizhuan.erban.utils.RegexUtil
import com.yizhuan.erban.utils.SpannableBuilder
import com.yizhuan.xchat_android_constants.XChatConstants
import com.yizhuan.xchat_android_core.auth.AuthModel
import com.yizhuan.xchat_android_core.decoration.car.bean.CarInfo
import com.yizhuan.xchat_android_core.home.bean.BannerInfo
import com.yizhuan.xchat_android_core.im.custom.bean.*
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager
import com.yizhuan.xchat_android_core.manager.IMNetEaseManager
@@ -144,6 +152,15 @@ class RoomEffectView @JvmOverloads constructor(
private var playNotifyStateLiveData: MutableLiveData<Boolean>? = null
private var showUserCardAction: ((String) -> Unit)? = null
private val templateMessageAdapter =
TemplateMessageAdapter(listener = object : TemplateMessageAdapter.Listener {
override fun onShowUserCard(uid: String) {
showUserCardAction?.invoke(uid)
}
})
private var onPlayAnimCallback: (() -> Boolean)? = null
fun setPlayNotifyStateListener(stateLiveData: MutableLiveData<Boolean>) {
this.playNotifyStateLiveData = stateLiveData
@@ -153,6 +170,12 @@ class RoomEffectView @JvmOverloads constructor(
this.onPlayAnimCallback = onPlayAnimCallback
}
fun setShowUserCardAction(call: Consumer<String>) {
this.showUserCardAction = {
call.accept(it)
}
}
@NonNull
private fun isShowingGiftNotify(): Boolean {
return onPlayAnimCallback?.invoke() ?: false
@@ -218,6 +241,10 @@ class RoomEffectView @JvmOverloads constructor(
addPlayNotify(roomEvent.event, roomEvent.chatRoomMessage)
}
RoomEvent.TEMPLATE_NOTIFY -> {// 通用模版飘屏
addPlayNotify(roomEvent.event, roomEvent.chatRoomMessage)
}
RoomEvent.FAIRY_DRAW_GIFT_L4,
RoomEvent.FAIRY_DRAW_GIFT_L5,
RoomEvent.FAIRY_CONVERT_L1,
@@ -314,6 +341,9 @@ class RoomEffectView @JvmOverloads constructor(
if (binding.flPlayNotify.childCount != 0) {
return@subscribe
}
if (binding.flTemplateNotify.childCount != 0) {
return@subscribe
}
if (binding.flLuckyBagNotify.childCount != 0) {
return@subscribe
}
@@ -412,6 +442,12 @@ class RoomEffectView @JvmOverloads constructor(
)
}
RoomEvent.TEMPLATE_NOTIFY -> {//通用模版飘屏
resetPlayNotifyMargin()
showTemplateNotify(
messagesPlay.removeAt(0)
)
}
RoomEvent.FAIRY_DRAW_GIFT_L4,
RoomEvent.FAIRY_DRAW_GIFT_L5,
RoomEvent.FAIRY_CONVERT_L1,
@@ -780,6 +816,155 @@ class RoomEffectView @JvmOverloads constructor(
)
}
private fun showTemplateNotify(roomPlayBean: RoomPlayBean) {
val chatRoomMessage = roomPlayBean.chatRoomMessage
val attachment =
chatRoomMessage.attachment as? RoomTemplateNotifyAttachment
val msgBean = attachment?.getTemplateMsg()
val resourceType = msgBean?.resourceType
if (resourceType == "IMAGE") {
showTemplateImageNotify(msgBean)
} else if (resourceType == "SVGA") {
showTemplateSvgaNotify(msgBean)
}
}
private fun showTemplateImageNotify(msgBean: RoomTemplateNotifyMsgBean) {
if (msgBean.resourceType != "IMAGE") {
return
}
val resourceContent = msgBean.resourceContent
if (resourceContent.isNullOrEmpty()) {
return
}
playNotifyStateLiveData?.value = true
val rootView = LayoutInflater.from(mContext)
.inflate(R.layout.layout_room_template_notify_image, null)
val textView = rootView.findViewById<TextView>(R.id.tv_text)
val textSize = msgBean.fontSize?.toFloat() ?: 12f
val textColor =
templateMessageAdapter.parseColor(msgBean.textColor) ?: Color.WHITE
textView.textSize = textSize
textView.setTextColor(textColor)
val bgView = rootView.findViewById<ImageView>(R.id.iv_bg)
val params = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.MATCH_PARENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
)
binding.flTemplateNotify.addView(rootView, params)
val endAction = {
playNotifyStateLiveData?.value = false
binding.flTemplateNotify.removeView(rootView)
}
GlideApp.with(bgView)
.load(resourceContent).into(object : CustomTarget<Drawable>() {
override fun onResourceReady(
resource: Drawable,
transition: Transition<in Drawable>?
) {
templateMessageAdapter.convert(textView, msgBean)
bgView.setImageDrawable(resource)
animationPlay = AnimationUtils.loadAnimation(mContext, R.anim.anim_box_notify)
rootView.startAnimation(animationPlay)
val skipType = msgBean.skipType
if (skipType != null) {
val clickAction = View.OnClickListener {
if (skipType == BannerInfo.SKIP_TYPE_ROOM_USER_CARD) {
showUserCardAction?.invoke(msgBean.skipContent ?: "")
} else {
CommonJumpHelper.bannerJump(context, skipType, msgBean.skipContent)
}
}
rootView.setOnClickListener(clickAction)
textView.setOnClickListener(clickAction)
}
binding.flTemplateNotify.postDelayed(endAction, SHOW_TIME.toLong())
}
override fun onLoadCleared(placeholder: Drawable?) {
endAction.invoke()
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
endAction.invoke()
}
})
}
private fun showTemplateSvgaNotify(msgBean: RoomTemplateNotifyMsgBean) {
if (msgBean.resourceType != "SVGA") {
return
}
val resourceContent = msgBean.resourceContent
if (resourceContent.isNullOrEmpty()) {
return
}
playNotifyStateLiveData?.value = true
val svgaImageView = SVGAImageView(mContext)
val endAction = {
playNotifyStateLiveData?.value = false
binding.flTemplateNotify.removeView(svgaImageView)
}
svgaImageView.loops = 1
svgaImageView.clearsAfterDetached = true
val params = ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT, 0)
params.dimensionRatio = msgBean.getDimensionRatio() ?: "75:11"
svgaImageView.layoutParams = params
svgaImageView.callback = object : SimpleSvgaCallback() {
override fun onFinished() {
endAction.invoke()
}
}
binding.flTemplateNotify.addView(svgaImageView)
shareParser().decodeFromURL(
URL(resourceContent),
object : SVGAParser.ParseCompletion {
override fun onComplete(videoItem: SVGAVideoEntity) {
val text = templateMessageAdapter.parse(context, msgBean) ?: ""
val textKey = msgBean.getSvgaTextKey()
val textSize = msgBean.fontSize?.toFloat() ?: 24f
val textColor =
templateMessageAdapter.parseColor(msgBean.textColor) ?: Color.WHITE
val dynamicEntity = SVGADynamicEntity()
val textPaint = TextPaint()
textPaint.color = textColor //字體顏色
textPaint.textSize = textSize //字體大小
dynamicEntity.setDynamicText(
StaticLayout(
text,
0,
text.length,
textPaint,
0,
Layout.Alignment.ALIGN_CENTER,
1.0f,
0.0f,
false
), textKey
)
val skipType = msgBean.skipType
if (skipType != null) {
svgaImageView.setOnClickListener {
if (skipType == BannerInfo.SKIP_TYPE_ROOM_USER_CARD) {
showUserCardAction?.invoke(msgBean.skipContent?:"")
} else {
CommonJumpHelper.bannerJump(context, skipType, msgBean.skipContent)
}
}
}
val drawable = SVGADrawable(videoItem, dynamicEntity)
svgaImageView.setImageDrawable(drawable)
svgaImageView.stepToFrame(0, true)
}
override fun onError() {
endAction.invoke()
}
},
null
)
}
private fun showLuckySeaNotifyBySVGA(roomPlayBean: RoomPlayBean) {
val chatRoomMessage = roomPlayBean.chatRoomMessage

View File

@@ -2,6 +2,7 @@ package com.yizhuan.erban.avroom.widget
import android.content.Context
import android.graphics.Color
import android.text.SpannableStringBuilder
import android.text.method.LinkMovementMethod
import android.text.style.ForegroundColorSpan
import android.view.View
@@ -9,6 +10,7 @@ import android.widget.TextView
import com.chuhai.utils.UiUtils
import com.yizhuan.erban.common.widget.OriginalDrawStatusClickSpan
import com.yizhuan.erban.utils.CommonJumpHelper
import com.yizhuan.erban.utils.SpannableBuilder
import com.yizhuan.xchat_android_core.home.bean.BannerInfo
import com.yizhuan.xchat_android_core.im.custom.bean.TemplateMessage
import com.yizhuan.xchat_android_core.im.custom.bean.TemplateMessage.TemplateNode
@@ -17,7 +19,47 @@ import com.yizhuan.xchat_android_core.im.custom.bean.TemplateMessage.TemplateNod
* Created by Max on 2024/2/22 17:20
* Desc:模版消息适配器
**/
class TemplateMessageAdapter(val listener: Listener) {
class TemplateMessageAdapter(val listener: Listener?) {
/**
* 解析为文本子节点只支持TEXT类型
*/
fun parse(context: Context, attachment: TemplateMessage?): SpannableStringBuilder? {
val builder = SpannableBuilder()
if (attachment == null) {
return null
}
val nodeList = attachment.getNodeList()
nodeList.forEach {
if (it is TemplateNode.NormalNode) {
val textColor = parseColor(it.textColor)
if (textColor != null) {
builder.append(it.text, ForegroundColorSpan(textColor))
} else {
builder.append(it.text)
}
} else if (it is TemplateNode.SpecialNode) {
when (it.content.type) {
TemplateMessage.Content.TEXT -> {
val text = it.content.text?.getFirstText()
if (!text.isNullOrEmpty()) {
val textColor = parseColor(it.content.textColor)
val clickSpan = createClickSpan(context, it.content, listener)
val list = ArrayList<Any>()
if (textColor != null) {
list.add(ForegroundColorSpan(textColor))
}
if (clickSpan != null) {
list.add(clickSpan)
}
builder.append(text, *list.toArray())
}
}
}
}
}
return builder.build()
}
fun convert(textView: TextView, attachment: TemplateMessage?) {
if (attachment == null) {
@@ -40,7 +82,7 @@ class TemplateMessageAdapter(val listener: Listener) {
val text = it.content.text?.getFirstText()
if (!text.isNullOrEmpty()) {
val textColor = parseColor(it.content.textColor)
val clickSpan = createClickSpan(textView.context, it.content)
val clickSpan = createClickSpan(textView.context, it.content, listener)
val list = ArrayList<Any>()
if (textColor != null) {
list.add(ForegroundColorSpan(textColor))
@@ -56,7 +98,7 @@ class TemplateMessageAdapter(val listener: Listener) {
val image = it.content.image
val width = it.content.width ?: 0
val height = it.content.height ?: 0
val clickSpan = createClickSpan(textView.context, it.content)
val clickSpan = createClickSpan(textView.context, it.content, listener)
if (height > 0 && width == 0) {
if (clickSpan != null) {
textBuilder.append(
@@ -99,7 +141,8 @@ class TemplateMessageAdapter(val listener: Listener) {
private fun createClickSpan(
context: Context,
content: TemplateMessage.Content
content: TemplateMessage.Content,
listener: Listener?
): OriginalDrawStatusClickSpan? {
val skipType = content.getSkipType()
val skipUri = content.getSkipUri()
@@ -107,7 +150,7 @@ class TemplateMessageAdapter(val listener: Listener) {
return object : OriginalDrawStatusClickSpan() {
override fun onClick(widget: View) {
if (skipType == BannerInfo.SKIP_TYPE_ROOM_USER_CARD) {
listener.onShowUserCard(skipUri)
listener?.onShowUserCard(skipUri)
} else {
CommonJumpHelper.bannerJump(context, content)
}
@@ -118,7 +161,10 @@ class TemplateMessageAdapter(val listener: Listener) {
}
}
private fun parseColor(color: String?): Int? {
fun parseColor(color: String?): Int? {
if (color == null) {
return null
}
try {
return Color.parseColor(color)
} catch (e: java.lang.Exception) {

View File

@@ -19,6 +19,8 @@ import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUS
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_BOX_ALL_ROOM_NOTIFY_BY_SVGA;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_DRAW_GIFT_L5;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_RED_PACKAGE_RECEIVE_ALL_DIAMOND;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY_ALL;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_VIP;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_VIP_USER_ALL_UPGRADE;
import static com.yizhuan.xchat_android_library.utils.UIUtils.getActivityByContext;
@@ -107,6 +109,7 @@ import com.yizhuan.xchat_android_core.im.custom.bean.NotifyH5Info;
import com.yizhuan.xchat_android_core.im.custom.bean.PlayEffectInfo;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomBoxPrizeInfo;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomLuckySeaMsgBean;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomTemplateNotifyMsgBean;
import com.yizhuan.xchat_android_core.im.custom.bean.TarotMsgBean;
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager;
import com.yizhuan.xchat_android_core.manager.IMNetEaseManager;
@@ -885,6 +888,10 @@ public abstract class BaseActivity extends RxAppCompatActivity
return rxPermissions.request(mPerms);
}
public RxPermissions getRxPermissions(){
return rxPermissions;
}
/**
* 接收到全局广播信息
*
@@ -1146,6 +1153,35 @@ public abstract class BaseActivity extends RxAppCompatActivity
}
}
break;
case CUSTOM_MSG_TEMPLATE_NOTIFY://通用飘屏
if (!isValid() || getWindow().getDecorView().getVisibility() != View.VISIBLE) return;
if (this instanceof AddUserInfoActivity || this instanceof AVRoomActivity
|| this instanceof TreasureBoxActivity || this instanceof HomeFairyActivity
|| UserUtils.getUserInfo() == null)
return;
if (playEffectList == null) {
playEffectList = new LinkedList<>();
}
if (baseProtocol.getSecond() == CUSTOM_MSG_TEMPLATE_NOTIFY_ALL) {
RoomTemplateNotifyMsgBean templateNotifyMsgBean = new Gson().fromJson(String.valueOf(baseProtocol.getData()), RoomTemplateNotifyMsgBean.class);
if (templateNotifyMsgBean == null) return;
PlayEffectInfo playEffectInfo = new PlayEffectInfo();
playEffectInfo.setSecond(baseProtocol.getSecond());
playEffectInfo.setTemplateNotifyMsgBean(templateNotifyMsgBean);
playEffectList.add(playEffectInfo);
if (playEffectDialog != null && playEffectDialog.isShowing()) {
// 如果当前以及有礼物弹窗在展示,则需要等到他 dismiss 后再显示下一个
PlayEffectInfo dataBean = playEffectList.peekFirst();
if (dataBean != null) {
return;
} else {
playEffectDialog.dismiss();
}
} else {
showPlayEffectDialog();
}
}
break;
case CUSTOM_MSG_LUCKY_GIFT://福袋
if (!isValid() || getWindow().getDecorView().getVisibility() != View.VISIBLE) return;
if (this instanceof AddUserInfoActivity || this instanceof AVRoomActivity
@@ -1467,14 +1503,15 @@ public abstract class BaseActivity extends RxAppCompatActivity
JSONObject jsonObject;
try {
jsonObject = JSON.parseObject(contentStr);
if (jsonObject == null) return;
if (jsonObject.containsKey("body")) {
String body = jsonObject.getString("body");
if (TextUtils.isEmpty(body)) return;
baseMvpActivity.onReceivedNimBroadcastMessage(body);
}
} catch (Exception e) {
jsonObject = null;
}
if (jsonObject == null) return;
if (jsonObject.containsKey("body")) {
String body = jsonObject.getString("body");
if (TextUtils.isEmpty(body)) return;
baseMvpActivity.onReceivedNimBroadcastMessage(body);
e.printStackTrace();
}
}
}

View File

@@ -207,7 +207,7 @@ class PhotoDialog : BaseDialogFragment<PhotoDialogBinding>(), EasyPermissions.Pe
REQUEST_CODE_OPEN_CAMERA_PROVIDER -> {
if (mOnResultCallBack == null || data == null) return
PhotoProvider.getResultPathListAsync(data) { paths ->
val list = paths?.toMutableList() ?: ArrayList()
val list = paths?.mapNotNull { it.path }?.toMutableList() ?: ArrayList()
val path = list[0]
if (!TextUtils.isEmpty(path)) {
mJob?.cancel()
@@ -233,7 +233,7 @@ class PhotoDialog : BaseDialogFragment<PhotoDialogBinding>(), EasyPermissions.Pe
REQUEST_CODE_OPEN_PHOTO_PROVIDER -> {
if (mOnResultCallBack == null || data == null) return
PhotoProvider.getResultPathListAsync(data) { list ->
val paths = list?.toMutableList() ?: ArrayList()
val paths = list?.mapNotNull { it.path }?.toMutableList() ?: ArrayList()
if (paths.isEmpty()) {
mOnResultCallBack?.choicePhotoCallBack(paths)
} else {

View File

@@ -86,13 +86,25 @@ object PhotoProvider {
@JvmStatic
@JvmOverloads
fun photoProvider(activity: FragmentActivity, maxSelect: Int = 1, canChooseGif: Boolean = false, resultCode: Int, isClearCache: Boolean = true) {
fun photoProvider(
activity: FragmentActivity,
maxSelect: Int = 1,
canChooseGif: Boolean = false,
resultCode: Int,
isClearCache: Boolean = true,
useWidth: Boolean = false
) {
cancelJop()
mPhotoJob = MainScope().launch {
if (isClearCache && isClearByTime()) {
withContext(Dispatchers.IO) { clearCache() }
}
EasyPhotos.createAlbum(activity, false, false, GlideEngine())//参数说明上下文是否显示相机按钮是否使用宽高数据false时宽高数据为0扫描速度更快[配置Glide为图片加载引擎](https://github.com/HuanTanSheng/EasyPhotos/wiki/12-%E9%85%8D%E7%BD%AEImageEngine%EF%BC%8C%E6%94%AF%E6%8C%81%E6%89%80%E6%9C%89%E5%9B%BE%E7%89%87%E5%8A%A0%E8%BD%BD%E5%BA%93)
EasyPhotos.createAlbum(
activity,
false,
useWidth,
GlideEngine()
)//参数说明上下文是否显示相机按钮是否使用宽高数据false时宽高数据为0扫描速度更快[配置Glide为图片加载引擎](https://github.com/HuanTanSheng/EasyPhotos/wiki/12-%E9%85%8D%E7%BD%AEImageEngine%EF%BC%8C%E6%94%AF%E6%8C%81%E6%89%80%E6%9C%89%E5%9B%BE%E7%89%87%E5%8A%A0%E8%BD%BD%E5%BA%93)
.setCount(maxSelect)//参数说明最大可选数默认1
.setGif(canChooseGif)
.setPuzzleMenu(false)
@@ -131,7 +143,7 @@ object PhotoProvider {
}
@JvmStatic
fun getResultPathListAsync(data: Intent?, resultListener: ((List<String>?) -> Unit)) {
fun getResultPathListAsync(data: Intent?, resultListener: ((List<Photo>?) -> Unit)) {
cancelJop()
mPhotoJob = MainScope().launch {
val list: List<Photo>? = data?.getParcelableArrayListExtra(EasyPhotos.RESULT_PHOTOS)
@@ -151,22 +163,21 @@ object PhotoProvider {
* 1. 项目使用到BitmapFactory.decodeFile(imgPath, options)之类的方法该方法在android Q直接使用外部path测试中发现获取图片信息失败
*
*/
private fun copyToInternalCache(photos: List<Photo>?): List<String>? {
private fun copyToInternalCache(photos: List<Photo>?): List<Photo>? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val foldPath = getInternalPath() + File.separator
val newPaths = ArrayList<String>()
photos?.forEach {
if (it.uri != null && !it.name.isNullOrEmpty()) {
val path = "$foldPath${it.name}"
if (FileHelper.copyFileFromUri(it.uri, path, true)) {
newPaths.add(path)
it.path = path
Logger.debug(TAG, "path: ${it.path} , displayName: ${it.name} , newPath: $path ")
}
}
}
newPaths
photos
} else {
photos?.takeIf { it.isNotEmpty() }?.map { it.path }
photos
}
}

View File

@@ -552,6 +552,23 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
.noticeRoomEvent(message, RoomEvent.CRAZY_ZOO_ALL_ROOM_NOTIFY)
}
CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY -> if (baseProtocol.second == CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY_ALL) {
val attachment = RoomTemplateNotifyAttachment(
CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY,
CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY_ALL
)
attachment.msgBean = JSON.parseObject(
baseProtocol.data.toString(),
RoomTemplateNotifyMsgBean::class.java
)
val message = ChatRoomMessageBuilder.createChatRoomCustomMessage(
AvRoomDataManager.get().roomId.toString(),
attachment
)
IMNetEaseManager.get()
.noticeRoomEvent(message, RoomEvent.TEMPLATE_NOTIFY)
}
CustomAttachment.CUSTOM_MSG_LUCKY_GIFT -> if (baseProtocol.second == CustomAttachment.CUSTOM_MSG_LUCKY_GIFT_SERVER_NOTIFY || baseProtocol.second == CustomAttachment.CUSTOM_MSG_LUCKY_GIFT_SERVER_ALL) {
val attachment =
RoomReceivedLuckyGiftAttachment(CustomAttachment.CUSTOM_MSG_LUCKY_GIFT_SERVER_NOTIFY)

View File

@@ -9,6 +9,7 @@ import androidx.databinding.ObservableField;
import com.yizhuan.erban.R;
import com.yizhuan.erban.vip.util.VipHelper;
import com.yizhuan.xchat_android_core.gift.bean.GiftInfo;
import com.yizhuan.xchat_android_core.gift.bean.GiftType;
import com.yizhuan.xchat_android_core.gift.bean.SimpleVipInfo;
import com.yizhuan.xchat_android_library.bindinglist.BaseItem;
import com.yizhuan.xchat_android_library.utils.TimeUtils;
@@ -65,6 +66,11 @@ public class GiftInfoVm extends BaseItem<GiftInfo> {
*/
public boolean isFreeGift;
/**
* 是否超级幸运礼物
*/
public boolean isSuperLuckyGift;
public GiftInfoVm(Context context, GiftInfo data, boolean select, boolean isKnap) {
super(context, data);
this.isSelect.set(select);
@@ -100,6 +106,7 @@ public class GiftInfoVm extends BaseItem<GiftInfo> {
if (data.getConsumeType() == GiftInfo.CONSUME_TYPE_FREE_GIFT) {
isFreeGift = true;
}
isSuperLuckyGift = (data.getGiftType() == GiftType.GIFT_TYPE_SUPER_LUCKY);
SimpleVipInfo vipInfo = data.getGiftVipInfo();
isLocked = vipInfo != null && VipHelper.getMyVipLevel() < vipInfo.getVipLevel();
vipIcon = vipInfo == null ? "" : vipInfo.getVipIcon();

View File

@@ -0,0 +1,196 @@
package com.yizhuan.erban.ui.invite
import android.Manifest
import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
import android.view.LayoutInflater
import android.view.View
import androidx.core.view.drawToBitmap
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.lifecycleScope
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.chuhai.utils.ktx.saveToAlbum
import com.netease.nim.uikit.support.glide.GlideApp
import com.tbruyelle.rxpermissions2.RxPermissions
import com.yizhuan.erban.R
import com.yizhuan.erban.common.widget.dialog.DialogManager
import com.yizhuan.erban.databinding.ShareInviteImageLayoutBinding
import com.yizhuan.erban.ui.widget.magicindicator.buildins.UIUtil
import com.yizhuan.xchat_android_library.utils.SingleToastUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.jvm.Throws
/**
* Created by Max on 2024/3/11 15:57
* Desc:邀请图片
**/
class InviteImageHelper {
fun saveToAlbum(
activity: FragmentActivity,
rxPermissions: RxPermissions,
data: ShareInviteInfo,
success: (() -> Unit)? = null
) {
checkStoragePermissions(rxPermissions) {
if (it) {
saveToAlbumImpl(activity, activity.lifecycleScope, data, success)
} else {
SingleToastUtil.showToast(activity.getString(R.string.ask_again))
}
}
}
private fun checkStoragePermissions(rxPermissions: RxPermissions, call: (Boolean) -> Unit) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
call.invoke(true)
} else {
val permissions = arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
val d = rxPermissions.request(*permissions)?.subscribe({
if (it) {
call.invoke(true)
} else {
call.invoke(false)
}
}, {
it.printStackTrace()
})
}
}
private fun saveToAlbumImpl(
context: Activity,
lifecycleCoroutineScope: LifecycleCoroutineScope,
data: ShareInviteInfo,
success: (() -> Unit)? = null
) {
lifecycleCoroutineScope.launch {
val dialogManager = DialogManager(context)
dialogManager.showProgressDialog(context, false)
try {
val result = saveToAlbum(context, data)
if (result) {
SingleToastUtil.showToast(R.string.community_photo_bigphotoactivity_05)
success?.invoke()
} else {
SingleToastUtil.showToast(R.string.community_photo_bigphotoactivity_06)
}
} catch (e: Exception) {
e.printStackTrace()
SingleToastUtil.showToast(e.message)
} finally {
dialogManager.dismissDialog()
}
}
}
@Throws
suspend fun saveToAlbum(context: Context, data: ShareInviteInfo): Boolean {
val bitmap = generateBitmap(context, data)
return saveToAlbum(context, bitmap)
}
@Throws
suspend fun generateBitmap(context: Context, data: ShareInviteInfo): Bitmap {
val qrcodeUrl = data.qrCodeUrl
if (qrcodeUrl.isNullOrEmpty()) {
throw IllegalArgumentException(context.getString(R.string.utils_net_beanobserver_05))
}
val bitmap: Bitmap
withContext(Dispatchers.IO) {
val qrCode = loadQrcode(context, data.qrCodeUrl)
data.qrcodeDrawable = qrCode
val binding = createView(context)
withContext(Dispatchers.Main) {
bindView(binding, data)
}
bitmap = viewToBitmap(binding.root, UIUtil.dip2px(context, 375.0))
}
return bitmap
}
suspend fun saveToAlbum(context: Context, bitmap: Bitmap): Boolean {
val uri: Uri?
withContext(Dispatchers.IO) {
val fileName = "piko_invite_${System.currentTimeMillis()}.jpg"
uri = bitmap.saveToAlbum(
context = context,
fileName = fileName,
relativePath = null,
quality = 90
)
}
return uri != null
}
private fun bindView(
binding: ShareInviteImageLayoutBinding,
data: ShareInviteInfo
) {
binding.ivQrcode.setImageDrawable(data.qrcodeDrawable)
if (data.text.isNullOrEmpty()) {
binding.tvQrcodeTips.isVisible = false
} else {
binding.tvQrcodeTips.isVisible = true
binding.tvQrcodeTips.text = data.text
}
binding.tvCode.text =
binding.tvCode.context.getString(R.string.invite_code) + data.invitationCode
}
private suspend fun loadQrcode(context: Context, url: String): Drawable? {
return suspendCancellableCoroutine {
val target = GlideApp.with(context.applicationContext).load(url)
.into(object : CustomTarget<Drawable>() {
override fun onResourceReady(
resource: Drawable,
transition: Transition<in Drawable>?
) {
it.resume(resource)
}
override fun onLoadCleared(placeholder: Drawable?) {
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
it.resumeWithException(Exception(context.getString(R.string.utils_net_beanobserver_03)))
}
})
it.invokeOnCancellation {
it?.printStackTrace()
GlideApp.with(context.applicationContext).clear(target)
}
}
}
private fun createView(context: Context): ShareInviteImageLayoutBinding {
return ShareInviteImageLayoutBinding.inflate(LayoutInflater.from(context))
}
private fun viewToBitmap(view: View, width: Int): Bitmap {
val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY)
val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
view.measure(widthMeasureSpec, heightMeasureSpec)
val measureWidth = view.measuredWidth
val measureHeight = view.measuredHeight
view.layout(0, 0, measureWidth, measureHeight)
return view.drawToBitmap()
}
}

View File

@@ -0,0 +1,134 @@
package com.yizhuan.erban.ui.invite
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import cn.sharesdk.facebook.Facebook
import cn.sharesdk.framework.Platform
import cn.sharesdk.framework.PlatformActionListener
import cn.sharesdk.line.Line
import com.chuhai.utils.ktx.singleClick
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.tbruyelle.rxpermissions2.RxPermissions
import com.yizhuan.erban.R
import com.yizhuan.erban.databinding.ShareInviteDialogBinding
import com.yizhuan.xchat_android_library.utils.ResUtil
import com.yizhuan.xchat_android_library.utils.SingleToastUtil
/**
* Created by Max on 2024/3/11 15:29
* Desc:分享邀请
**/
class ShareInviteDialog(val data: ShareInviteInfo) : BottomSheetDialogFragment() {
private var binding: ShareInviteDialogBinding? = null
private var rxPermissions: RxPermissions? = null
private val inviteImageHelper = InviteImageHelper()
override fun onAttach(context: Context) {
super.onAttach(context)
rxPermissions = RxPermissions(this)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initEvent()
}
private fun initEvent() {
binding?.let { binding ->
binding.tvCancel.singleClick {
dismissAllowingStateLoss()
}
binding.tvSaveToAlbum.singleClick {
rxPermissions?.let {
inviteImageHelper.saveToAlbum(requireActivity(), it, data) {
dismissAllowingStateLoss()
}
}
}
binding.tvShareLink.singleClick {
copyLink(data.toUrl ?: "")
}
binding.tvLine.singleClick {
share(Line(), data)
}
binding.tvFacebook.singleClick {
share(Facebook(), data)
}
}
}
private fun copyLink(data: String) {
try {
val cm =
requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager
cm?.setPrimaryClip(ClipData.newPlainText("text", data))
SingleToastUtil.showToast(R.string.have_copy)
dismissAllowingStateLoss()
} catch (e: Exception) {
e.printStackTrace()
SingleToastUtil.showToast(R.string.avroom_activity_roomblacklistactivity_015)
}
}
private fun share(platform: Platform, data: ShareInviteInfo) {
val url = data.toUrl
val sp = Platform.ShareParams()
sp.imageUrl = data.shareImg
when (platform.name) {
Facebook.NAME -> {
sp.title = data.shareTitle
sp.text = data.shareText
sp.url = url
sp.shareType = Platform.SHARE_WEBPAGE
}
Line.NAME -> {
sp.text = "${data.shareTitle}[$url]"
}
}
platform.platformActionListener = object : PlatformActionListener {
override fun onComplete(platform: Platform, i: Int, hashMap: HashMap<String, Any>) {
SingleToastUtil.showToast(R.string.xchat_android_core_share_sharemodel_01)
dismissAllowingStateLoss()
}
override fun onError(platform: Platform, i: Int, throwable: Throwable) {
val errorMsg: String
if (throwable.message?.contains("not installed") == true) {
errorMsg =
ResUtil.getString(R.string.not_install_app)
} else {
errorMsg =
ResUtil.getString(R.string.xchat_android_core_share_sharemodel_02)
}
SingleToastUtil.showToast(errorMsg)
}
override fun onCancel(platform: Platform, i: Int) {
SingleToastUtil.showToast(R.string.xchat_android_core_share_sharemodel_03)
}
}
platform.share(sp)
}
override fun getTheme(): Int {
return R.style.ErbanBottomSheetDialog
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = ShareInviteDialogBinding.inflate(inflater)
return binding?.root
}
}

View File

@@ -0,0 +1,31 @@
package com.yizhuan.erban.ui.invite
import android.graphics.drawable.Drawable
import androidx.annotation.Keep
import java.io.Serializable
/**
* Created by Max on 2024/3/11 18:56
* Desc:分享邀请相关信息
**/
@Keep
data class ShareInviteInfo(
// 二维码图片
val qrCodeUrl: String? = null,
// 邀请码
val invitationCode: String? = null,
// 页面文案
val text: String? = null,
// 分享文案
val shareText: String? = null,
// 分享图片
val shareImg: String? = null,
// 分享标题
val shareTitle: String? = null,
// 跳转网页地址
val toUrl: String? = null,
// 1分享2保存
val type: Int? = null,
@Transient
var qrcodeDrawable: Drawable? = null
) : Serializable

View File

@@ -6,7 +6,9 @@ import android.os.Build
import android.os.Environment
import android.text.SpannableString
import android.view.View
import com.alibaba.fastjson.JSON
import com.chuhai.utils.log.ILog
import com.google.gson.Gson
import com.netease.nim.uikit.StatusBarUtil
import com.tongdaxing.erban.upgrade.AppUpgradeHelper
import com.yizhuan.erban.BuildConfig
@@ -16,6 +18,8 @@ import com.yizhuan.erban.base.BaseViewBindingActivity
import com.yizhuan.erban.common.widget.dialog.DialogManager.OkCancelDialogListener
import com.yizhuan.erban.databinding.ActivitySettingBinding
import com.yizhuan.erban.ui.im.avtivity.BlackListManageActivity
import com.yizhuan.erban.ui.invite.ShareInviteDialog
import com.yizhuan.erban.ui.invite.ShareInviteInfo
import com.yizhuan.erban.ui.login.BindPhoneActivity
import com.yizhuan.erban.ui.login.ShowBindPhoneActivity
import com.yizhuan.erban.ui.login.helper.LogoutHelper
@@ -24,6 +28,7 @@ import com.yizhuan.erban.ui.webview.CommonWebViewActivity
import com.yizhuan.xchat_android_core.UriProvider
import com.yizhuan.xchat_android_core.auth.AuthModel
import com.yizhuan.xchat_android_core.auth.event.LogoutEvent
import com.yizhuan.xchat_android_core.im.custom.bean.RoomTemplateNotifyMsgBean
import com.yizhuan.xchat_android_core.user.UserModel
import com.yizhuan.xchat_android_core.user.bean.UserInfo
import com.yizhuan.xchat_android_core.utils.SharedPreferenceUtils
@@ -43,7 +48,8 @@ import kotlin.random.Random
* 设置页
* Created by wushaocheng on 2023/2/1.
*/
class SettingActivity : BaseViewBindingActivity<ActivitySettingBinding>(), View.OnClickListener,ILog {
class SettingActivity : BaseViewBindingActivity<ActivitySettingBinding>(), View.OnClickListener,
ILog {
override fun init() {
EventBus.getDefault().register(this)
initWhiteTitleBar(ResUtil.getString(R.string.ui_setting_settingactivity_01))
@@ -217,6 +223,24 @@ class SettingActivity : BaseViewBindingActivity<ActivitySettingBinding>(), View.
}
private fun debug() {
test()
// CommonWebViewActivity.start(
// this,
// "http://192.168.19.136:5502/view/peko/activity/2024-invitationFission/share.html"
// )
val qrcodeUrl =
"https://img0.baidu.com/it/u=4220524728,2310074610&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1710349200&t=39faa005691f3ebde5b8bf2b99708f1b"
val data = ShareInviteInfo(
qrCodeUrl = qrcodeUrl,
invitationCode = Random.nextInt().toString(),
text = "扫码下载PiKO并填写我的邀请码立得1000钻石!!",
shareTitle = "分享标题",
shareText = "分享文本",
shareImg = qrcodeUrl,
toUrl = "https://www.baidu.com",
)
// InviteImageHelper().saveToAlbum(this, rxPermissions, data)
// ShareInviteDialog(data).show(supportFragmentManager, "A")
// val json = "{\"data\":{\"diamonds\":225000,\"itemId\":32,\"itemMultiple\":45,\"nick\":\"XG001\",\"roomUid\":2881,\"uid\":2881},\"first\":95,\"second\":955}"
// RedPackageOpenDialog2().show(this)
// val json = "{\"first\":85,\"second\":855,\"data\":{\"nick\":\"66丢丢丢丢丢多多多的hhhh\",\"preVipName\":\"子爵\",\"floatPic\":\"https://image.hfighting.com/Fq3JtbK2acO3FN-3vWZo8ldtHfse\",\"uid\":2735,\"currVipName\":\"侯爵\",\"erbanNo\":66,\"roomUid\":2734,\"avatar\":\"https://img.pekolive.com/default_avatar.png\",\"currVipLevel\":5}}"
@@ -224,4 +248,29 @@ class SettingActivity : BaseViewBindingActivity<ActivitySettingBinding>(), View.
// CommonWebViewActivity.start(this,"https://api.anan.chat/anan_vestBag/modules/rank/index.html#/rank")
// CommonWebViewActivity.start(this,"https://api.anan.chat/anan_vestBag/modules/myincome/index.html#/DiamondLog")
}
private fun test(){
logD("test()")
val json = "{\"fontSize\":12,\"resourceType\":\"IMAGE\",\"resourceContent\":\"https://piko-1320554189.cos.ap-singapore.myqcloud.com/gYWPkyh3s6FG1Cc4lfKowGUgyTYDaNPBYwXfcy79fnA2i1U4LFJJR.png\",\"resourceWidth\":750,\"resourceHeight\":121,\"svgaTextKey\":\"noble_text_tx\",\"template\":{\"zh-CN\":\"恭喜{senderNick}赠送{giftName},爆出{outputValue}钻石大奖!\"},\"textColor\":\"#FFFFFF\",\"contents\":[{\"text\":{\"zh-CN\":\"[2813]\"},\"fontSize\":12,\"textColor\":\"#FFFF00\",\"type\":\"TEXT\",\"key\":\"senderNick\"},{\"text\":{\"zh-CN\":\"[守護之星]\"},\"fontSize\":12,\"textColor\":\"#FFFF00\",\"type\":\"TEXT\",\"key\":\"giftName\"},{\"text\":{\"zh-CN\":\"597\"},\"fontSize\":12,\"textColor\":\"#FFFF00\",\"type\":\"TEXT\",\"key\":\"outputValue\"}]}"
try {
val data = JSON.parseObject(json, RoomTemplateNotifyMsgBean::class.java)
logD("data:${data}")
logD("data0:${data.contents?.size}")
logD("data1:${data.contents?.firstOrNull()?.key}")
logD("data2:${data.contents?.firstOrNull()?.text}")
}catch (e:Exception){
logD("test() error")
e.printStackTrace()
}
try {
val data2 = Gson().fromJson<RoomTemplateNotifyMsgBean>(json, RoomTemplateNotifyMsgBean::class.java)
logD("data:${data2}")
logD("data0:${data2.contents?.size}")
logD("data1:${data2.contents?.firstOrNull()?.key}")
logD("data2:${data2.contents?.firstOrNull()?.text}")
}catch (e:Exception){
logD("test() error2")
e.printStackTrace()
}
}
}

View File

@@ -16,6 +16,7 @@ import android.webkit.WebView;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.orhanobut.logger.Logger;
import com.yizhuan.erban.UIHelper;
@@ -27,6 +28,9 @@ import com.yizhuan.erban.family.view.activity.FamilyHomeActivity;
import com.yizhuan.erban.public_chat_hall.activity.PublicChatHallHomeActivity;
import com.yizhuan.erban.ui.im.RouterHandler;
import com.yizhuan.erban.ui.im.avtivity.NimP2PMessageActivity;
import com.yizhuan.erban.ui.invite.InviteImageHelper;
import com.yizhuan.erban.ui.invite.ShareInviteDialog;
import com.yizhuan.erban.ui.invite.ShareInviteInfo;
import com.yizhuan.erban.ui.pay.ChargeActivity;
import com.yizhuan.erban.ui.webview.event.H5NotifyClientEvent;
import com.yizhuan.erban.ui.webview.event.ShowNavEvent;
@@ -63,6 +67,7 @@ import org.greenrobot.eventbus.EventBus;
import java.io.File;
import java.util.HashMap;
/**
* <p> html js 与webview 交互接口</p>
* Created by ${user} on 2017/11/6.
@@ -179,6 +184,31 @@ public class JSInterface {
}
}
@JavascriptInterface
public void savePictureShare(String json) {
Logger.e("savePictureShare: " + json);
try {
CommonWebViewActivity activity = mActivity;
if (activity == null) {
return;
}
ShareInviteInfo info = new Gson().fromJson(json,ShareInviteInfo.class);
if (info.getType() != null) {
if (info.getType() == 1) {
activity.runOnUiThread(() -> {
new ShareInviteDialog(info).show(activity.getSupportFragmentManager(), "SHARE_INVITE#JS");
});
} else if (info.getType() == 2) {
activity.runOnUiThread(() -> {
new InviteImageHelper().saveToAlbum(activity, activity.getRxPermissions(), info, null);
});
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 调转钱包页
*/

View File

@@ -110,6 +110,8 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -162,7 +164,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
private View flLuckyDesc;
private RecyclerView rvLuckyMsg;
private ImageView ivOpenNoble;
private View ivFirstRecharge;
private View tvFirstRecharge;
private TextView tvLuckyBagIntro;
private TextView tvGiftValue;
private EditText etSendMessage;
@@ -207,6 +209,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
private BaseQuickAdapter<LuckyBagNoticeInfo, BaseViewHolder> luckyMsgAdapter;
private BannerViewPager<SimpleUserInfo> mStarWeekBanner;
private ImageView ivSuperLuckyGiftTips;
public GiftDialog(Context context, int giftId) {
this(context, 0, true, false, true, giftId);
@@ -394,6 +397,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
ivDrawGiftClose = root.findViewById(R.id.iv_draw_gift_close);
flLuckyDesc = findViewById(R.id.fl_lucky_desc);
rvLuckyMsg = findViewById(R.id.rv_lucky_msg);
ivSuperLuckyGiftTips = findViewById(R.id.iv_super_lucky_gift_tips);
ivDrawGiftClose.setOnClickListener(this);
ivDrawGiftRemoveLast.setOnClickListener(this);
ivDrawGiftRemoveAll.setOnClickListener(this);
@@ -460,12 +464,12 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
ivOpenNoble.setOnClickListener(this);
sendContainer = root.findViewById(R.id.send_container);
layoutEmpty.setVisibility(View.GONE);
ivFirstRecharge = root.findViewById(R.id.iv_first_recharge);
tvFirstRecharge = root.findViewById(R.id.tv_first_recharge);
tvLuckyBagIntro = findViewById(R.id.tv_lucky_bag_intro);
tvGiftValue = root.findViewById(R.id.tv_gift_value);
mStarWeekBanner = findViewById(R.id.star_week_list);
ivFirstRecharge.setOnClickListener(this);
tvFirstRecharge.setOnClickListener(this);
tvLuckyBagIntro.setOnClickListener(this);
if (giftId == 0) {
// 更新所有礼物
@@ -541,11 +545,16 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
.compose(RxHelper.bindContext(context))
.subscribe(userInfo -> {
if (userInfo.isFirstCharge()) {
ivFirstRecharge.setVisibility(View.VISIBLE);
tvFirstRecharge.setVisibility(View.VISIBLE);
}
});
}
PayModel.get().getMyRemoteWalletInfo().compose(RxHelper.bindContext(context))
.subscribe(info -> {
goldWalletInfo = info;
setGoldOrRadishText(lastSelectedItem);
});
}
private void showLoadingAnimation() {
@@ -592,12 +601,20 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
if (goldWalletInfo == null) {
return;
}
String goldNumText = getContext().getString(R.string.gold_num_text, goldWalletInfo.getDiamondNum());
SpannableBuilder builder = new SpannableBuilder();
builder.append(context.getText(R.string.gift_wallet_overage), new ForegroundColorSpan(
context.getResources().getColor(R.color.white_transparent_50)))
.append(goldNumText);
tvTextGold.setText(builder.build());
if (goldWalletInfo.canGoldSendGift) {
findViewById(R.id.iv_plus).setVisibility(View.VISIBLE);
findViewById(R.id.iv_gold).setVisibility(View.VISIBLE);
BigDecimal total = BigDecimal.valueOf(goldWalletInfo.getDiamondNum());
total = total.add(BigDecimal.valueOf(goldWalletInfo.getGoldNum()));
total = total.setScale(0, RoundingMode.DOWN);
tvTextGold.setText(total.toPlainString());
} else {
findViewById(R.id.iv_plus).setVisibility(View.GONE);
findViewById(R.id.iv_gold).setVisibility(View.GONE);
BigDecimal total = BigDecimal.valueOf(goldWalletInfo.getDiamondNum());
total = total.setScale(0, RoundingMode.DOWN);
tvTextGold.setText(total.toPlainString());
}
}
private void setUpdateTipsText() {
@@ -657,6 +674,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
updateWeekStarDesc();
isShowDrawGiftModel = false;
updateDrawGift();
updateSuperLuckyGiftTips();
} else {
showLoadFailedView();
}
@@ -677,6 +695,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
}
}
updateLuckyBagIntro();
updateSuperLuckyGiftTips();
updateWeekStarDesc();
isShowDrawGiftModel = false;
updateDrawGift();
@@ -689,6 +708,20 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
});
}
private void updateSuperLuckyGiftTips(){
if (currentGiftInfo == null || TextUtils.isEmpty(currentGiftInfo.getBannerUrl()) || currentGiftInfo.getGiftType() != GiftType.GIFT_TYPE_SUPER_LUCKY) {
ivSuperLuckyGiftTips.setVisibility(View.GONE);
} else {
ivSuperLuckyGiftTips.setVisibility(View.VISIBLE);
ImageLoadUtils.loadImage(getContext(), currentGiftInfo.getBannerUrl(), ivSuperLuckyGiftTips);
ivSuperLuckyGiftTips.setOnClickListener(v -> {
if (!TextUtils.isEmpty(currentGiftInfo.getSkipUrl())) {
DialogWebViewActivity.start(context, currentGiftInfo.getSkipUrl(), true);
}
});
}
}
private void updateLuckyBagIntro() {
if (currentGiftInfo == null ||
(TextUtils.isEmpty(currentGiftInfo.getGiftExplainUrl()) && currentGiftInfo.getGiftType() != GiftType.GIFT_TYPE_LUCKY)) {
@@ -1024,6 +1057,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
currentGiftInfo = item.data;
setGoldOrRadishText(lastSelectedItem);
updateLuckyBagIntro();
updateSuperLuckyGiftTips();
updateWeekStarDesc();
isShowDrawGiftModel = true;
updateDrawGift();
@@ -1355,7 +1389,7 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
ReportManager.get().reportEvent(IReportConstants.PAYPAGE_SHOW, map);
break;
case R.id.iv_first_recharge:
case R.id.tv_first_recharge:
FirstChargeDialog.start(context);
break;
@@ -1506,8 +1540,8 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
@Subscribe(threadMode = ThreadMode.MAIN)
public void onFirstRechargeEvent(FirstChargeEvent event) {
if (ivFirstRecharge != null) {
ivFirstRecharge.setVisibility(View.GONE);
if (tvFirstRecharge != null) {
tvFirstRecharge.setVisibility(View.GONE);
}
}

View File

@@ -9,6 +9,7 @@ import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUS
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.Layout;
import android.text.Spanned;
@@ -28,10 +29,14 @@ import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import androidx.core.text.HtmlCompat;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.netease.nim.uikit.support.glide.GlideApp;
import com.opensource.svgaplayer.SVGADrawable;
import com.opensource.svgaplayer.SVGADynamicEntity;
import com.opensource.svgaplayer.SVGAImageView;
@@ -39,10 +44,12 @@ import com.opensource.svgaplayer.SVGAParser;
import com.opensource.svgaplayer.SVGAVideoEntity;
import com.yizhuan.erban.R;
import com.yizhuan.erban.avroom.activity.AVRoomActivity;
import com.yizhuan.erban.avroom.widget.TemplateMessageAdapter;
import com.yizhuan.erban.common.svga.SimpleSvgaCallback;
import com.yizhuan.erban.databinding.DialogAllPlayEffectBinding;
import com.yizhuan.erban.ui.utils.ImageLoadUtilsV2;
import com.yizhuan.erban.ui.webview.CommonWebViewActivity;
import com.yizhuan.erban.utils.CommonJumpHelper;
import com.yizhuan.erban.utils.RegexUtil;
import com.yizhuan.erban.utils.SpannableBuilder;
import com.yizhuan.xchat_android_core.gift.bean.LuckyBagNoticeInfo;
@@ -51,14 +58,17 @@ import com.yizhuan.xchat_android_core.im.custom.bean.NotifyH5Info;
import com.yizhuan.xchat_android_core.im.custom.bean.PlayEffectInfo;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomBoxPrizeInfo;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomLuckySeaMsgBean;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomTemplateNotifyMsgBean;
import com.yizhuan.xchat_android_core.im.custom.bean.TarotMsgBean;
import com.yizhuan.xchat_android_core.treasurefairy.FairyMsgInfoBean;
import com.yizhuan.xchat_android_library.utils.ResUtil;
import com.yizhuan.xchat_android_library.utils.StringUtils;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
public class AllPlayEffectDialog extends BaseDialog {
@@ -122,6 +132,9 @@ public class AllPlayEffectDialog extends BaseDialog {
case CustomAttachment.CUSTOM_MSG_NOTIFY_H5_SUB_WHOLE_SERVICE:
showNotifyH5BySvga(playEffectInfo.getNotifyH5());
break;
case CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY_ALL:
showTemplateNotify(playEffectInfo.getTemplateNotifyMsgBean());
break;
default:
break;
}
@@ -421,11 +434,11 @@ public class AllPlayEffectDialog extends BaseDialog {
binding.flSvgaNotify.addView(roomView,params);
Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.anim_box_notify);
roomView.startAnimation(animation);
disposable.add(Observable.timer(6500, TimeUnit.MILLISECONDS).subscribe(aLong -> {
disposable.add(Observable.timer(6500, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(aLong -> {
Animation animation1 = AnimationUtils.loadAnimation(getContext(), R.anim.anim_box_notify_close);
roomView.startAnimation(animation1);
}));
disposable.add(Observable.timer(7000, TimeUnit.MILLISECONDS).subscribe(aLong -> closeSelf()));
disposable.add(Observable.timer(7000, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(aLong -> closeSelf()));
}
private void showNotifyH5BySvga(NotifyH5Info info) {
@@ -588,6 +601,181 @@ public class AllPlayEffectDialog extends BaseDialog {
}
}
private void showTemplateNotify(RoomTemplateNotifyMsgBean msgBean) {
if (msgBean == null) {
closeSelf();
return;
}
String resourceType = msgBean.getResourceType();
if (resourceType == null) {
closeSelf();
return;
}
if (resourceType.equals("IMAGE")) {
showTemplateImageNotify(msgBean);
} else if (resourceType.equals("SVGA")) {
showTemplateSvgaNotify(msgBean);
}
}
private void showTemplateImageNotify(@NonNull RoomTemplateNotifyMsgBean msgBean) {
if (msgBean.getResourceType() == null || !msgBean.getResourceType().equals("IMAGE")) {
closeSelf();
return;
}
String resourceContent = msgBean.getResourceContent();
if (resourceContent == null || resourceContent.isEmpty()) {
closeSelf();
return;
}
Runnable endAction = new Runnable() {
@Override
public void run() {
closeSelf();
}
};
View rootView = LayoutInflater.from(getContext())
.inflate(R.layout.layout_room_template_notify_image, null);
TemplateMessageAdapter adapter = new TemplateMessageAdapter(null);
TextView textView = rootView.findViewById(R.id.tv_text);
Integer textSize = msgBean.getFontSize();
if (textSize == null) {
textSize = 12;
}
textView.setTextSize(textSize);
Integer textColor = adapter.parseColor(msgBean.getTextColor());
if (textColor == null) {
textColor = Color.WHITE;
}
textView.setTextColor(textColor);
ImageView bgView = rootView.findViewById(R.id.iv_bg);
ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT, ConstraintLayout.LayoutParams.WRAP_CONTENT);
binding.flTemplateNotify.addView(rootView, params);
GlideApp.with(bgView)
.load(resourceContent).into(new CustomTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
adapter.convert(textView, msgBean);
bgView.setImageDrawable(resource);
Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.anim_box_notify);
rootView.startAnimation(animation);
View.OnClickListener clickAction = v -> {
Integer skipType = msgBean.getSkipType();
if (skipType == null) {
return;
}
CommonJumpHelper.bannerJump(getContext(), skipType, msgBean.getSkipContent());
};
rootView.setOnClickListener(clickAction);
textView.setOnClickListener(clickAction);
disposable.add(Observable.timer(6500, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(aLong -> {
Animation animation1 = AnimationUtils.loadAnimation(getContext(), R.anim.anim_box_notify_close);
rootView.startAnimation(animation1);
}));
disposable.add(Observable.timer(7000, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(aLong -> endAction.run()));
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
endAction.run();
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
super.onLoadFailed(errorDrawable);
endAction.run();
}
});
}
private void showTemplateSvgaNotify(@NonNull RoomTemplateNotifyMsgBean msgBean) {
if (msgBean.getResourceType() == null || !msgBean.getResourceType().equals("SVGA")) {
closeSelf();
return;
}
String resourceContent = msgBean.getResourceContent();
if (resourceContent == null || resourceContent.isEmpty()) {
closeSelf();
return;
}
Runnable endAction = new Runnable() {
@Override
public void run() {
closeSelf();
}
};
SVGAImageView svgaImageView = new SVGAImageView(getContext());
svgaImageView.setLoops(1);
svgaImageView.setClearsAfterDetached(true);
svgaImageView.setCallback(new SimpleSvgaCallback() {
@Override
public void onFinished() {
endAction.run();
}
});
ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT, 0);
params.dimensionRatio = msgBean.getDimensionRatio();
if (params.dimensionRatio == null) {
params.dimensionRatio = "75:11";
}
binding.flTemplateNotify.addView(svgaImageView, params);
try {
SVGAParser.Companion.shareParser().decodeFromURL(new URL(resourceContent), new SVGAParser.ParseCompletion() {
@Override
public void onComplete(@NonNull SVGAVideoEntity svgaVideoEntity) {
TemplateMessageAdapter adapter = new TemplateMessageAdapter(null);
CharSequence text = adapter.parse(getContext(), msgBean);
if (text == null) {
text = "";
}
String textKey = msgBean.getSvgaTextKey();
int textSize = 24;
if (msgBean.getFontSize() != null) {
textSize = msgBean.getFontSize();
}
int textColor = Color.WHITE;
Integer color = adapter.parseColor(msgBean.getTextColor());
if (color != null) {
textColor = color;
}
SVGADynamicEntity dynamicEntity = new SVGADynamicEntity();
TextPaint textPaint = new TextPaint();
textPaint.setColor(textColor);//字体颜色
textPaint.setTextSize(textSize);//字体大小
dynamicEntity.setDynamicText(new StaticLayout(
text,
0,
text.length(),
textPaint,
0,
Layout.Alignment.ALIGN_CENTER,
1.0f,
0.0f,
false
), textKey);
svgaImageView.setOnClickListener(v -> {
Integer skipType = msgBean.getSkipType();
if (skipType == null) {
return;
}
CommonJumpHelper.bannerJump(getContext(), skipType, msgBean.getSkipContent());
});
SVGADrawable drawable = new SVGADrawable(svgaVideoEntity, dynamicEntity);
svgaImageView.setImageDrawable(drawable);
svgaImageView.stepToFrame(0, true);
}
@Override
public void onError() {
endAction.run();
}
}, null);
} catch (Exception e) {
e.printStackTrace();
endAction.run();
}
}
private String subAndReplaceDot(String nick, int maxLength) {
if (nick.length() > maxLength) {
return nick.substring(0, maxLength) + "...";

View File

@@ -29,4 +29,6 @@ public interface IPagerNavigator {
* ViewPager内容改变时需要先调用此方法自定义的IPagerNavigator应当遵守此约定
*/
void notifyDataSetChanged();
int getCurrentIndex();
}

View File

@@ -303,6 +303,11 @@ public class CircleNavigator extends View implements IPagerNavigator {
mCircleClickListener = circleClickListener;
}
@Override
public int getCurrentIndex(){
return mCurrentIndex;
}
public interface OnCircleClickListener {
void onClick(int index);
}

View File

@@ -483,6 +483,11 @@ public class CommonNavigator extends FrameLayout implements IPagerNavigator, Nav
mScrollView.setFadingEdgeLength(fadingLength);
}
@Override
public int getCurrentIndex(){
return mNavigatorHelper.getCurrentIndex();
}
public interface NavigatorSelectedListener {
void navigatorSelected(int position);
}

View File

@@ -29,37 +29,47 @@ public class CommonJumpHelper {
* @param context
*/
public static void bannerJump(Context context, IRouterData bannerInfo) {
int skipType = bannerInfo.getSkipType();
if (skipType == SKIP_TYPE_ROUTER) {
bannerJump(context, JavaUtil.str2int(bannerInfo.getRouterType()), bannerInfo.getRouterValue());
} else {
bannerJump(context, skipType, bannerInfo.getSkipUri());
}
}
if (null == context || null == bannerInfo) {
/**
* 通用跳转
*
* @param context
*/
public static void bannerJump(Context context, int skipType, String skipContent) {
if (null == context) {
return;
}
int skipType = bannerInfo.getSkipType();
String url = bannerInfo.getSkipUri();
switch (skipType) {
case SKIP_TYP_APP:
if (TextUtils.isEmpty(url)) {
if (TextUtils.isEmpty(skipContent)) {
return;
}
RouterHandler.handle(context, JavaUtil.str2int(url), null);
RouterHandler.handle(context, JavaUtil.str2int(skipContent), null);
break;
case SKIP_TYP_CHAT_ROOM:
if (TextUtils.isEmpty(url)) {
if (TextUtils.isEmpty(skipContent)) {
return;
}
AVRoomActivity.start(context, JavaUtil.str2long(url));
AVRoomActivity.start(context, JavaUtil.str2long(skipContent));
break;
case SKIP_TYP_H5:
if (TextUtils.isEmpty(url)) {
if (TextUtils.isEmpty(skipContent)) {
return;
}
Intent intent = new Intent(context, CommonWebViewActivity.class);
intent.putExtra("url", url);
intent.putExtra("url", skipContent);
context.startActivity(intent);
break;
case SKIP_TYPE_ROUTER:
RouterHandler.handle(context, JavaUtil.str2int(bannerInfo.getRouterType()), bannerInfo.getRouterValue());
RouterHandler.handle(context, skipType, skipContent);
break;
default:
break;

View File

@@ -42,6 +42,27 @@ public class SpannableBuilder {
return this;
}
/**
* 支持多個spannable 對同一段文字修改
*
* @param text
* @param what
* @return
*/
public SpannableBuilder append(CharSequence text, Object... what) {
if (TextUtils.isEmpty(text)) return this;
int start = builder.length();
builder.append(text);
for (int i = 0; i < what.length; i++) {
Object o = what[i];
if (o == null) {
continue;
}
builder.setSpan(what[i], start, builder.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
return this;
}
public SpannableStringBuilder build() {
return builder;
}

View File

@@ -9,8 +9,10 @@ import android.widget.LinearLayout
import android.widget.TextView
import androidx.activity.viewModels
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.children
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import com.android.billingclient.api.BillingClient
import com.android.billingclient.api.BillingResult
@@ -25,6 +27,7 @@ import com.opensource.svgaplayer.SVGADrawable
import com.opensource.svgaplayer.SVGAImageView
import com.opensource.svgaplayer.SVGAParser
import com.opensource.svgaplayer.SVGAVideoEntity
import com.yizhuan.erban.BuildConfig
import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseViewBindingActivity
import com.yizhuan.erban.base.TitleBar
@@ -39,12 +42,12 @@ import com.yizhuan.erban.ui.webview.CommonWebViewActivity
import com.yizhuan.erban.ui.widget.magicindicator.buildins.commonnavigator.CommonNavigator
import com.yizhuan.erban.vip.adapter.VipAuthAdapter
import com.yizhuan.erban.vip.adapter.VipMagicIndicatorAdapter
import com.yizhuan.erban.vip.adapter.VipRebateAdapter
import com.yizhuan.erban.vip.dialog.SelectPayTypeDialog
import com.yizhuan.erban.vip.dialog.VipAuthDetailsDialog
import com.yizhuan.erban.vip.dialog.VipRemainTimeDialog
import com.yizhuan.xchat_android_core.Constants
import com.yizhuan.xchat_android_core.UriProvider
import com.yizhuan.xchat_android_core.auth.AuthModel
import com.yizhuan.xchat_android_core.pay.PayModel
import com.yizhuan.xchat_android_core.pay.bean.ChargeBean
import com.yizhuan.xchat_android_core.pay.bean.PayRecordId
@@ -56,6 +59,8 @@ import com.yizhuan.xchat_android_core.vip.VipOpenEvent
import com.yizhuan.xchat_android_library.common.util.DeviceUtil
import com.yizhuan.xchat_android_library.utils.AppMetaDataUtil
import com.yizhuan.xchat_android_library.utils.SingleToastUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
@@ -81,8 +86,9 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
private lateinit var rvDelegate: RVDelegate<VipAuthInfo>
private val vipViewModel: VipViewModel by viewModels()
private var billingManager: BillingManager? = null
private var googleChargeBean: ChargeBean? = null//google
private var chargeInfo: ChargeBean? = null//official
private var currentChargeInfo: ChargeBean? = null
private var chargeList: List<ChargeBean>? = null
private val rebateAdapter = VipRebateAdapter()
@SuppressLint("SetTextI18n")
override fun init() {
@@ -93,7 +99,8 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
CommonWebViewActivity.start(this@VipMainActivity, UriProvider.getVipHelpUrl())
}
})
initView()
initObserve()
binding.ivRankList.setOnClickListener {
CommonWebViewActivity.start(this@VipMainActivity, UriProvider.getRankListUrl())
}
@@ -142,8 +149,8 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
vipViewModel.myVipInfoLiveData.observe(this) {
it?.let {
binding.llMyVipInfo.isVisible = true
binding.tvOpenVip.isVisible = false
binding.layoutLevelInfo.isVisible = true
binding.layoutLevelProgress.isVisible = true
binding.tvNotOpen.text =
"${getString(R.string.me_current_power_value)}${it.currScore}"
binding.tvCurrValue.text = "${getString(R.string.me_current)}${it.currScore}"
@@ -185,16 +192,10 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
}
} ?: run {
binding.llMyVipInfo.isVisible = false
binding.tvOpenVip.isVisible = true
binding.layoutLevelInfo.isVisible = false
binding.layoutLevelProgress.isVisible = false
binding.slAuth.isVisible = true
binding.tvNotOpen.text = getString(R.string.me_no_aristocracy_yet)
val channel = AppMetaDataUtil.getChannelID()
if (channel.equals(Constants.GOOGLE)) {
initBilling()
} else {
loadData()
}
}
}
@@ -203,10 +204,12 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
if (it.comingSoon == 2) {
binding.llNotOpen.isVisible = true
binding.slAuth.isVisible = false
binding.layoutBottomPanel.isVisible = false
loadSVGA(binding.ivNotOpenIcon, it.vipLogo)
} else {
binding.slAuth.isVisible = true
binding.llNotOpen.isVisible = false
binding.layoutBottomPanel.isVisible = true
val myVipInfo = vipViewModel.myVipInfoLiveData.value
binding.ivMyLevel.isInvisible = it.vipLevel != myVipInfo?.vipLevel
binding.tvNotOpen.isInvisible =
@@ -216,6 +219,8 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
"${it.ownAuthTypes?.size ?: 0}/${vipViewModel.authInfosLiveData.value?.size ?: 0}"
authAdapter.setVipInfo(it)
authAdapter.notifyDataSetChanged()
loadRebateData(it)
refreshOpenVipState()
}
} ?: run {
getString(R.string.me_failed_to_get_aristocrat_data).toast()
@@ -232,78 +237,24 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
}
binding.tvOpenVip.setOnClickListener {
if (AppMetaDataUtil.getChannelID().equals(Constants.GOOGLE)) {
if ((googleChargeBean?.productDetails?.oneTimePurchaseOfferDetails?.priceAmountMicros ?: "0") == "0") {
toast(getString(R.string.Recharge_failure))
return@setOnClickListener
}
SelectPayTypeDialog.newInstance(
googleChargeBean?.productDetails?.oneTimePurchaseOfferDetails?.formattedPrice ?: "0",
true,
googleChargeBean?.getMoney() ?: 0.0
)
.apply {
setOnDiamondChargeClick {
vipViewModel.openVipWithDiamond()
}
setOnGoogleChargeClick {
googleChargeBean?.let { charge ->
buyProduct(charge.productDetails)
}
}
setOnChargeClick {
if (AppMetaDataUtil.getChannelID().equals(Constants.GOOGLE)) {
ChargeActivity.start(this@VipMainActivity)
} else {
CommonWebViewActivity.start(
this@VipMainActivity, UriProvider.getOfficialPay(
4,
DeviceUtil.getDeviceId(this@VipMainActivity)
)
)
}
}
}
.show(context)
} else {
SelectPayTypeDialog.newInstance(
((chargeInfo?.getMoney() ?: 0.0) * 1000).toInt().toString(),
false,
chargeInfo?.getMoney() ?: 0.0
)
.apply {
setOnDiamondChargeClick {
vipViewModel.openVipWithDiamond()
}
setOnChargeClick {
if (AppMetaDataUtil.getChannelID().equals(Constants.GOOGLE)) {
ChargeActivity.start(this@VipMainActivity)
} else {
CommonWebViewActivity.start(
this@VipMainActivity, UriProvider.getOfficialPay(
4,
DeviceUtil.getDeviceId(this@VipMainActivity)
)
)
}
}
}
.show(context)
checkBuyVip {
buyVip()
}
}
if (isGoogleChannel()) {
initBilling()
} else {
loadData()
}
}
@SuppressLint("CheckResult", "SetTextI18n")
private fun loadData() {
PayModel.get().getChargeList(2, AuthModel.get().currentUid)
.compose(bindToLifecycle())
PayModel.get().vipList.compose(bindToLifecycle())
.subscribe(
{
chargeInfo = it.list.getOrNull(0)
chargeInfo?.let { chargeBean ->
binding.tvOpenVip.text =
"${chargeBean.getMoney()}${getString(R.string.me_immediately_become_a_Peko_nobleman)}"
}
loadChargeList(it)
}, {
it.printStackTrace()
}
@@ -330,17 +281,13 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
* 初始化推荐和派对tab
*/
private fun initTitleTab(vipInfos: List<VipInfo>) {
val tagList: MutableList<String> = ArrayList()
vipInfos.forEach {
tagList.add(it.vipName)
}
val commonNavigator = CommonNavigator(context)
commonNavigator.isEnablePivotScroll = true
commonNavigator.isFollowTouch = false
val magicIndicatorAdapter =
VipMagicIndicatorAdapter(
context,
tagList
vipInfos
)
magicIndicatorAdapter.setOnItemSelectListener(this)
commonNavigator.adapter = magicIndicatorAdapter
@@ -388,39 +335,33 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
@SuppressLint("CheckResult", "SetTextI18n")
override fun onBillingClientSetupFinished() {
Log.i(TAG, "onBillingClientSetupFinished")
PayModel.get().getChargeList(2, AuthModel.get().currentUid)
.compose(bindToLifecycle())
PayModel.get().vipList.compose(bindToLifecycle())
.subscribe(
{
val chargeInfo = it.list.getOrNull(0)
chargeInfo?.let { chargeBean ->
val productKeys: MutableList<String> = ArrayList()
productKeys.add(chargeBean.getChargeProdId())
billingManager?.querySkuDetailsAsync(productKeys) { billingResult: BillingResult, productDetails: List<ProductDetails> ->
if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
Log.w(
TAG,
"Unsuccessful query for type: " + BillingClient.SkuType.INAPP
+ ". Error code: " + billingResult.responseCode
)
} else if (productDetails.isNotEmpty()) {
val showChargeList: MutableList<ChargeBean> = ArrayList()
val list = it
loadChargeList(list)
val productKeys = ArrayList<String>()
list.forEach {
productKeys.add(it.getChargeProdId())
}
billingManager?.querySkuDetailsAsync(productKeys) { billingResult: BillingResult, productDetails: List<ProductDetails> ->
if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
Log.w(
TAG,
"Unsuccessful query for type: " + BillingClient.SkuType.INAPP
+ ". Error code: " + billingResult.responseCode
)
} else if (productDetails.isNotEmpty()) {
for (item in list) {
for (skuDetails in productDetails) {
if (skuDetails.productId == chargeBean.getChargeProdId()) {
chargeBean.productDetails = skuDetails
showChargeList.add(chargeBean)
if (skuDetails.productId == item.getChargeProdId()) {
item.productDetails = skuDetails
break
}
}
if (showChargeList.size > 0) {
googleChargeBean = showChargeList[0]
binding.tvOpenVip.text = "${
googleChargeBean?.getMoney()
}${getString(R.string.me_immediately_become_a_Peko_nobleman)}"
}
}
loadChargeList(list)
}
}
}, {
it.printStackTrace()
@@ -447,18 +388,20 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
//L.i("token=" + token);
billingManager?.consumeAsync(token)
var skuDetails: ProductDetails? = null
if (googleChargeBean?.getChargeProdId() == purchase.products[0]) {
skuDetails = googleChargeBean?.productDetails
if (currentChargeInfo?.getChargeProdId() == purchase.products[0]) {
skuDetails = currentChargeInfo?.productDetails
}
if (skuDetails != null) {
val eventValue: MutableMap<String, Any> =
HashMap()
eventValue[AFInAppEventParameterName.CONTENT_TYPE] = "Gold"
eventValue[AFInAppEventParameterName.QUANTITY] = 1
eventValue[AFInAppEventParameterName.CONTENT_ID] = purchase.orderId!!
eventValue[AFInAppEventParameterName.CONTENT_ID] =
purchase.orderId!!
eventValue[AFInAppEventParameterName.REVENUE] =
skuDetails.oneTimePurchaseOfferDetails?.priceAmountMicros!! / 1000000f
eventValue["Price"] = skuDetails.oneTimePurchaseOfferDetails?.formattedPrice!!
eventValue["Price"] =
skuDetails.oneTimePurchaseOfferDetails?.formattedPrice!!
eventValue[AFInAppEventParameterName.CURRENCY] =
skuDetails.oneTimePurchaseOfferDetails?.priceCurrencyCode!!
AppsFlyerLib.getInstance().logEvent(
@@ -521,8 +464,7 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
super.onDestroy()
EventBus.getDefault().unregister(this)
billingManager?.destroy()
googleChargeBean = null
chargeInfo = null
currentChargeInfo = null
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@@ -536,5 +478,179 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
}
}
private fun initView() {
binding.tvTabPrivilege.setOnClickListener {
showPrivilegeTab()
}
binding.tvTabRebate.setOnClickListener {
showRebateTab()
}
rebateAdapter.onGetListener = {
vipViewModel.getVipRebate(it)
}
binding.rvRebate.isNestedScrollingEnabled = false
binding.rvRebate.adapter = rebateAdapter
}
private fun initObserve(){
lifecycleScope.launch(Dispatchers.Main) {
vipViewModel.getVipRebateSuccessFlow.collect {
rebateAdapter.notifyItemRangeChanged(0, rebateAdapter.itemCount, true)
}
}
}
private fun showPrivilegeTab() {
binding.layoutRebate.isInvisible = true
binding.groupPrivilege.isInvisible = false
binding.tvTabPrivilege.setBackgroundResource(R.drawable.vip_bg_tab_selected)
binding.tvTabRebate.setBackgroundResource(R.drawable.vip_bg_tab_unselected)
}
private fun showRebateTab() {
binding.groupPrivilege.isInvisible = true
binding.layoutRebate.isInvisible = false
binding.tvTabPrivilege.setBackgroundResource(R.drawable.vip_bg_tab_unselected)
binding.tvTabRebate.setBackgroundResource(R.drawable.vip_bg_tab_selected)
}
private fun loadChargeList(list: List<ChargeBean>) {
this.chargeList = list
refreshOpenVipState()
}
private fun loadRebateData(info: VipInfo) {
binding.tvTableLevelName.text = info.vipName
binding.tvRebateTips1.text =
context.getString(R.string.vip_buy_tips_format).format(info.vipName)
rebateAdapter.setNewData(info.returnProfits)
val isNormalStatus = info.isRebate()
binding.layoutRebate.children.forEach {
if(it == binding.tvRebateDisableStatus){
it.isVisible = !isNormalStatus
}else{
it.isVisible = isNormalStatus
}
}
}
private fun refreshOpenVipState() {
val currentVipInfo = vipViewModel.currVipInfoLiveData.value
val myVipInfo = vipViewModel.myVipInfoLiveData.value
if (currentVipInfo != null) {
currentChargeInfo = chargeList?.firstOrNull {
it.prodDesc?.toIntOrNull() == currentVipInfo.vipLevel
}
if (currentChargeInfo != null && (myVipInfo == null || myVipInfo.vipLevel < currentVipInfo.vipLevel)) {
binding.tvOpenVip.text =
"${currentChargeInfo?.getMoney()} ${
getString(R.string.vip_buy_format).format(
currentVipInfo.vipName
)
}"
binding.tvOpenVip.isVisible = true
} else {
binding.tvOpenVip.isVisible = false
}
} else {
currentChargeInfo = null
binding.tvOpenVip.isVisible = false
}
if (binding.tvOpenVip.isVisible && binding.layoutLevelProgress.isVisible) {
binding.layoutBottomPanel.setBackgroundDrawable(binding.layoutLevelProgress.background)
} else {
binding.layoutBottomPanel.setBackgroundDrawable(null)
}
}
private fun checkBuyVip(block: () -> Unit) {
val myVipInfo = vipViewModel.myVipInfoLiveData.value
val currentVipInfo = vipViewModel.currVipInfoLiveData.value
if (currentVipInfo != null && myVipInfo != null && currentVipInfo.vipLevel > myVipInfo.vipLevel) {
val message = context.getString(R.string.vip_buy_tips).format(
myVipInfo.vipName,currentVipInfo.vipName
)
dialogManager.showOkCancelDialog(message,
context.getString(R.string.miniworld_activity_mwteamroommessageact_07),
context.getString(R.string.miniworld_activity_mwteamroommessageact_08),
true
) { block.invoke() }
} else {
block.invoke()
}
}
private fun buyVip(){
if (isGoogleChannel()) {
if ((currentChargeInfo?.productDetails?.oneTimePurchaseOfferDetails?.priceAmountMicros
?: "0") == "0"
) {
toast(getString(R.string.Recharge_failure))
return
}
SelectPayTypeDialog.newInstance(
currentChargeInfo?.productDetails?.oneTimePurchaseOfferDetails?.formattedPrice
?: "0",
true,
currentChargeInfo?.getMoney() ?: 0.0
)
.apply {
setOnDiamondChargeClick {
vipViewModel.openVipWithDiamond(
currentChargeInfo?.getProdDesc()?.toIntOrNull() ?: -1)
}
setOnGoogleChargeClick {
currentChargeInfo?.let { charge ->
buyProduct(charge.productDetails)
}
}
setOnChargeClick {
if (isGoogleChannel()) {
ChargeActivity.start(this@VipMainActivity)
} else {
CommonWebViewActivity.start(
this@VipMainActivity, UriProvider.getOfficialPay(
4,
DeviceUtil.getDeviceId(this@VipMainActivity)
)
)
}
}
}
.show(context)
} else {
SelectPayTypeDialog.newInstance(
((currentChargeInfo?.getMoney() ?: 0.0) * 1000).toInt().toString(),
false,
currentChargeInfo?.getMoney() ?: 0.0
)
.apply {
setOnDiamondChargeClick {
vipViewModel.openVipWithDiamond(
currentChargeInfo?.getProdDesc()?.toIntOrNull() ?: -1
)
}
setOnChargeClick {
if (isGoogleChannel()) {
ChargeActivity.start(this@VipMainActivity)
} else {
CommonWebViewActivity.start(
this@VipMainActivity, UriProvider.getOfficialPay(
4,
DeviceUtil.getDeviceId(this@VipMainActivity)
)
)
}
}
}
.show(context)
}
}
private fun isGoogleChannel(): Boolean {
if (BuildConfig.DEBUG) {
return false
}
return AppMetaDataUtil.getChannelID().equals(Constants.GOOGLE)
}
}

View File

@@ -5,8 +5,6 @@ import androidx.lifecycle.MutableLiveData
import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseViewModel
import com.yizhuan.xchat_android_core.bean.response.BeanResult
import com.yizhuan.xchat_android_core.home.model.HomeModel
import com.yizhuan.xchat_android_core.module_hall.hall.HallModel
import com.yizhuan.xchat_android_core.user.UserInfoUiMgr
import com.yizhuan.xchat_android_core.user.UserModel
import com.yizhuan.xchat_android_core.utils.toast
@@ -14,21 +12,23 @@ import com.yizhuan.xchat_android_core.vip.VipAuthInfo
import com.yizhuan.xchat_android_core.vip.VipBroadcastInfo
import com.yizhuan.xchat_android_core.vip.VipInfo
import com.yizhuan.xchat_android_core.vip.VipModel
import com.yizhuan.xchat_android_core.vip.VipRebateInfo
import com.yizhuan.xchat_android_library.utils.ResUtil
import kotlinx.coroutines.flow.MutableSharedFlow
class VipViewModel : BaseViewModel() {
val userId: Long by lazy {
UserInfoUiMgr.get().uid
}
private val _authInfosLiveData = MutableLiveData<List<VipAuthInfo>>()
val authInfosLiveData: LiveData<List<VipAuthInfo>> = _authInfosLiveData
private val _authInfosLiveData = MutableLiveData<List<VipAuthInfo>?>()
val authInfosLiveData: LiveData<List<VipAuthInfo>?> = _authInfosLiveData
private val _vipInfosLiveData = MutableLiveData<List<VipInfo>>()
val vipInfosLiveData: LiveData<List<VipInfo>> = _vipInfosLiveData
private val _vipInfosLiveData = MutableLiveData<List<VipInfo>?>()
val vipInfosLiveData: LiveData<List<VipInfo>?> = _vipInfosLiveData
private val _myVipInfoLiveData = MutableLiveData<VipInfo>()
val myVipInfoLiveData: LiveData<VipInfo> = _myVipInfoLiveData
private val _myVipInfoLiveData = MutableLiveData<VipInfo?>()
val myVipInfoLiveData: LiveData<VipInfo?> = _myVipInfoLiveData
private val _currVipInfoLiveData = MutableLiveData<VipInfo>()
val currVipInfoLiveData: LiveData<VipInfo> = _currVipInfoLiveData
@@ -48,6 +48,8 @@ class VipViewModel : BaseViewModel() {
private val _enterHideLiveData = MutableLiveData<Boolean>()
val enterHideLiveData: LiveData<Boolean> = _enterHideLiveData
val getVipRebateSuccessFlow = MutableSharedFlow<VipRebateInfo>()
// private val _sendBroadcastLiveData = MutableLiveData<Boolean>()
// val sendBroadcastLiveData: LiveData<Boolean> = _sendBroadcastLiveData
@@ -166,10 +168,17 @@ class VipViewModel : BaseViewModel() {
_pageLiveData.value = position
}
fun openVipWithDiamond() {
fun openVipWithDiamond(vipLevel: Int) {
safeLaunch(true) {
VipModel.openVipWithDiamond()
VipModel.openVipWithDiamond(vipLevel)
}
}
fun getVipRebate(rebateInfo: VipRebateInfo) {
safeLaunch(true) {
VipModel.getVipRebate(rebateInfo.returnProfitRecordId ?: 0L)
rebateInfo.isReceive = true
getVipRebateSuccessFlow.emit(rebateInfo)
}
}
}

View File

@@ -2,30 +2,32 @@ package com.yizhuan.erban.vip.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 com.yizhuan.erban.ui.widget.XRecyclerView.ScaleTransitionPagerTitleView;
import com.yizhuan.erban.ui.widget.magicindicator.buildins.UIUtil;
import com.yizhuan.erban.ui.widget.magicindicator.buildins.commonnavigator.abs.CommonNavigatorAdapter;
import com.yizhuan.erban.ui.widget.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
import com.yizhuan.erban.ui.widget.magicindicator.buildins.commonnavigator.abs.IPagerTitleView;
import com.yizhuan.erban.ui.widget.magicindicator.buildins.commonnavigator.indicators.LinePagerIndicator;
import com.yizhuan.erban.vip.view.VipTabView;
import com.yizhuan.xchat_android_core.vip.VipInfo;
import java.util.List;
import kotlin.random.Random;
public class VipMagicIndicatorAdapter extends CommonNavigatorAdapter {
private final Context mContext;
private final List<? extends CharSequence> mTitleList;
private final List<VipInfo> mTitleList;
private int textSize = 15;
private float minScale = 1f;
private boolean showIndicator = true;
private OnItemSelectListener mOnItemSelectListener;
public VipMagicIndicatorAdapter(Context context, List<? extends CharSequence> charSequences) {
public VipMagicIndicatorAdapter(Context context, List<VipInfo> charSequences) {
this.mContext = context;
this.mTitleList = charSequences;
}
@@ -37,22 +39,15 @@ public class VipMagicIndicatorAdapter extends CommonNavigatorAdapter {
@Override
public IPagerTitleView getTitleView(Context context, final int i) {
ScaleTransitionPagerTitleView scaleTransitionPagerTitleView = new ScaleTransitionPagerTitleView(context, true);
scaleTransitionPagerTitleView.setNormalColor(Color.parseColor("#FFBC9E66"));
scaleTransitionPagerTitleView.setSelectedColor(Color.parseColor("#FFFFE3AF"));
scaleTransitionPagerTitleView.setMinScale(minScale);
scaleTransitionPagerTitleView.setTextSize(textSize);
scaleTransitionPagerTitleView.setGravity(Gravity.START);
int padding = UIUtil.dip2px(context, 12);
scaleTransitionPagerTitleView.setPadding(padding, 0, padding, 0);
scaleTransitionPagerTitleView.setText(mTitleList.get(i));
scaleTransitionPagerTitleView.setOnClickListener(view -> {
VipTabView tabView = new VipTabView(context);
VipInfo item = mTitleList.get(i);
tabView.setData(item.getVipName(), item.isRebate());
tabView.setOnClickListener(view -> {
if (mOnItemSelectListener != null) {
mOnItemSelectListener.onItemSelect(i, scaleTransitionPagerTitleView);
mOnItemSelectListener.onItemSelect(i, tabView.getTextView());
}
});
return scaleTransitionPagerTitleView;
return tabView;
}
@Override

View File

@@ -0,0 +1,68 @@
package com.yizhuan.erban.vip.adapter
import android.view.View
import android.widget.TextView
import androidx.core.view.isVisible
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.chuhai.utils.ktx.getColorById
import com.yizhuan.erban.R
import com.yizhuan.xchat_android_core.vip.VipRebateInfo
/**
* Created by Max on 2024/3/28 11:19
* Desc:
**/
class VipRebateAdapter : BaseQuickAdapter<VipRebateInfo, BaseViewHolder>(R.layout.item_vip_rebate) {
var onGetListener: ((VipRebateInfo) -> Unit)? = null
override fun convertPayloads(
helper: BaseViewHolder,
item: VipRebateInfo,
payloads: MutableList<Any>
) {
super.convertPayloads(helper, item, payloads)
convertStatus(helper, item)
}
override fun convert(helper: BaseViewHolder, item: VipRebateInfo) {
if (item.profitDate == 0L) {
helper.setText(
R.id.tv_date, R.string.vip_rebate_now
)
} else {
helper.setText(
R.id.tv_date,
helper.itemView.context.getString(R.string.vip_rebate_day_format)
.format("${item.profitDate}")
)
}
helper.setText(R.id.tv_num, "${item.profitAmount}")
convertStatus(helper, item)
helper.getView<View>(R.id.v_line).isVisible =
(helper.absoluteAdapterPosition != itemCount - 1)
}
private fun convertStatus(helper: BaseViewHolder, item: VipRebateInfo) {
val statusView = helper.getView<TextView>(R.id.tv_status)
val statusLayout = helper.getView<View>(R.id.layout_status)
statusLayout.setOnClickListener(null)
if (item.isReceive == true) {
statusView.setBackgroundResource(R.drawable.shape_47ffffff_9dp)
statusView.setTextColor(statusView.context.getColorById(R.color.color_B3B3C3))
statusView.setText(R.string.vip_rebate_received)
} else if (item.isReach == true) {
statusView.setBackgroundResource(R.drawable.shape_f6ad3f_9dp)
statusView.setTextColor(statusView.context.getColorById(R.color.color_white))
statusView.setText(R.string.vip_rebate_get)
statusLayout.setOnClickListener {
onGetListener?.invoke(item)
}
} else {
statusView.setBackgroundResource(R.drawable.shape_726041_9dp)
statusView.setTextColor(statusView.context.getColorById(R.color.color_white))
statusView.setText(R.string.vip_rebate_no_get)
}
}
}

View File

@@ -0,0 +1,48 @@
package com.yizhuan.erban.vip.view
import android.content.Context
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isInvisible
import com.yizhuan.erban.R
import com.yizhuan.erban.ui.widget.magicindicator.buildins.commonnavigator.abs.IPagerTitleView
/**
* Created by Max on 2024/3/28 17:05
* Desc:
**/
class VipTabView(context: Context) : ConstraintLayout(context), IPagerTitleView {
val textView: TextView
private val rebateView: View
private var selectedColor = Color.parseColor("#FFBC9E66")
private var normalColor = Color.parseColor("#FFFFE3AF")
init {
LayoutInflater.from(context).inflate(R.layout.vip_tab_item, this)
textView = findViewById(R.id.tv_title)
rebateView = findViewById(R.id.iv_rebate)
}
override fun onSelected(index: Int, totalCount: Int) {
textView.setTextColor(selectedColor)
}
override fun onDeselected(index: Int, totalCount: Int) {
textView.setTextColor(normalColor)
}
override fun onLeave(index: Int, totalCount: Int, leavePercent: Float, leftToRight: Boolean) {
}
override fun onEnter(index: Int, totalCount: Int, enterPercent: Float, leftToRight: Boolean) {
}
fun setData(title: CharSequence, isRebate: Boolean) {
textView.text = title
rebateView.isInvisible = !isRebate
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="0"
android:endColor="#FFB059"
android:startColor="#FF3B3D" />
<stroke
android:width="@dimen/dp_1"
android:color="#FCDA7B" />
<corners android:radius="@dimen/dp_8" />
</shape>

View File

@@ -0,0 +1,26 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:viewportWidth="14"
android:viewportHeight="14">
<path
android:pathData="M0,0h14v14h-14z"
android:strokeAlpha="0"
android:strokeWidth="1"
android:fillColor="#000000"
android:fillType="nonZero"
android:strokeColor="#00000000"
android:fillAlpha="0"/>
<path
android:pathData="M6.59,2.078L7.41,2.078C7.483,2.078 7.52,2.115 7.52,2.188L7.52,11.813C7.52,11.885 7.483,11.922 7.41,11.922L6.59,11.922C6.517,11.922 6.48,11.885 6.48,11.813L6.48,2.188C6.48,2.115 6.517,2.078 6.59,2.078Z"
android:strokeWidth="1"
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:strokeColor="#00000000"/>
<path
android:pathData="M2.406,6.48L11.594,6.48C11.667,6.48 11.703,6.517 11.703,6.59L11.703,7.41C11.703,7.483 11.667,7.52 11.594,7.52L2.406,7.52C2.333,7.52 2.297,7.483 2.297,7.41L2.297,6.59C2.297,6.517 2.333,6.48 2.406,6.48Z"
android:strokeWidth="1"
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:strokeColor="#00000000"/>
</vector>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="@dimen/dp_1"
android:color="#33FFAA36" />
<corners android:radius="6dp" />
</shape>

View File

@@ -26,4 +26,10 @@
app:layout_constraintTop_toBottomOf="@id/v_gift_notify_placeholder"
app:layout_goneMarginTop="0dp" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/fl_template_notify"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/fl_svga_notify" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -6,6 +6,16 @@
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<ImageView
android:visibility="gone"
android:id="@+id/iv_super_lucky_gift_tips"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
app:layout_constraintBottom_toTopOf="@id/ll_dialog_bottom_gift"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<RelativeLayout
android:id="@+id/fl_lucky_desc"
android:layout_width="0dp"
@@ -481,21 +491,56 @@
android:layout_toEndOf="@+id/tv_text_gold"
android:drawablePadding="@dimen/dp_5"
android:gravity="center"
android:paddingStart="@dimen/dp_13"
android:paddingEnd="@dimen/dp_13"
android:paddingStart="@dimen/dp_10"
android:paddingEnd="@dimen/dp_10"
android:text="@string/charge"
android:textColor="@color/color_FACB4D"
android:textSize="@dimen/sp_13"
app:drawableEndCompat="@drawable/ic_arrow_recharge" />
<ImageView
android:id="@+id/iv_first_recharge"
<TextView
android:id="@+id/tv_first_recharge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="@dimen/dp_16"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/tv_recharge"
android:scaleType="fitCenter"
android:src="@drawable/ic_first_charge_gift_dialog_enter"
android:background="@drawable/gift_dialog_bg_first_recharge"
android:gravity="center"
android:minWidth="@dimen/dp_34"
android:paddingHorizontal="@dimen/dp_5"
android:text="@string/first_recharge"
android:textColor="@color/white"
android:textSize="@dimen/dp_10"
android:visibility="gone"
tools:visibility="visible" />
<ImageView
android:id="@+id/iv_diamond"
android:layout_width="@dimen/dp_16"
android:layout_height="@dimen/dp_16"
android:layout_centerVertical="true"
android:layout_marginStart="@dimen/dp_16"
android:src="@drawable/ic_gift_diamond" />
<ImageView
android:id="@+id/iv_plus"
android:layout_width="@dimen/dp_14"
android:layout_height="@dimen/dp_14"
android:layout_centerVertical="true"
android:layout_marginStart="@dimen/dp_1"
android:layout_toEndOf="@id/iv_diamond"
android:src="@drawable/gift_dialog_ic_plus"
android:visibility="gone"
tools:visibility="visible" />
<ImageView
android:id="@+id/iv_gold"
android:layout_width="@dimen/dp_14"
android:layout_height="@dimen/dp_14"
android:layout_centerVertical="true"
android:layout_marginStart="@dimen/dp_2"
android:layout_toEndOf="@id/iv_plus"
android:src="@drawable/ic_gold"
android:visibility="gone"
tools:visibility="visible" />
@@ -504,14 +549,14 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="@dimen/dp_15"
android:drawablePadding="3dp"
android:layout_marginStart="@dimen/dp_2"
android:layout_toEndOf="@id/iv_gold"
android:gravity="center"
android:includeFontPadding="false"
android:text="0"
android:textColor="@color/white"
android:textSize="@dimen/sp_14"
app:drawableEndCompat="@drawable/ic_gift_diamond" />
android:textSize="@dimen/dp_14"
tools:text="10000" />
<LinearLayout
android:id="@+id/send_container"

View File

@@ -52,6 +52,12 @@
app:layout_constraintDimensionRatio="75:11"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/fl_template_notify"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/fl_lucky_bag_notify"
android:layout_width="match_parent"

View File

@@ -0,0 +1,35 @@
<?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">
<ImageView
android:id="@+id/iv_bg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/bg_zoo_notice" />
<com.coorchice.library.SuperTextView
android:id="@+id/tv_text"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_gravity="center"
android:ellipsize="end"
android:gravity="center"
android:includeFontPadding="false"
android:lineSpacingExtra="0dp"
android:lineSpacingMultiplier="0.8"
android:maxLines="2"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@id/iv_bg"
app:layout_constraintEnd_toEndOf="@id/iv_bg"
app:layout_constraintStart_toStartOf="@id/iv_bg"
app:layout_constraintTop_toTopOf="@id/iv_bg"
app:layout_constraintWidth_percent="0.626"
tools:layout_height="wrap_content"
tools:text="@string/layout_layout_room_box_notify_01" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -37,6 +37,15 @@
android:layout_marginTop="@dimen/dp_16"
android:alpha="@{item.isLocked?0.5f:1f}" />
<ImageView
android:id="@+id/iv_super_lucky_gift"
android:layout_width="@dimen/dp_46"
android:layout_height="@dimen/dp_12"
android:layout_alignBottom="@id/gift_image"
android:layout_marginStart="@dimen/dp_5"
android:src="@drawable/gift_ic_super_luck_logo"
android:visibility="@{item.isSuperLuckyGift ? View.VISIBLE : View.GONE}" />
<TextView
android:id="@+id/gift_name"
android:layout_width="wrap_content"
@@ -81,8 +90,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_marginEnd="@dimen/dp_4"
android:layout_marginTop="4dp"
android:layout_marginEnd="@dimen/dp_4"
android:gravity="center"
android:orientation="horizontal">

View File

@@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_dialog_share"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/dp_15"
android:text="@string/share_to_friends"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp_14" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="7dp"
android:layout_marginBottom="@dimen/dp_10"
android:gravity="center"
android:text="@string/title_share_dialog"
android:textColor="@color/color_999999"
android:textSize="13sp"
android:visibility="gone"
tools:ignore="SpUsage" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:gravity="center_vertical"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/transparent"
android:gravity="center"
android:orientation="horizontal"
android:weightSum="4">
<TextView
android:id="@+id/tv_line"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_17"
android:layout_marginBottom="19dp"
android:layout_weight="1"
android:drawablePadding="9dp"
android:gravity="center"
android:text="@string/share_line"
android:textColor="@color/color_999999"
android:textSize="@dimen/font_medium"
app:drawableTopCompat="@drawable/icon_line" />
<TextView
android:id="@+id/tv_facebook"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_17"
android:layout_marginBottom="19dp"
android:layout_weight="1"
android:drawablePadding="9dp"
android:gravity="center"
android:text="@string/share_facebook"
android:textColor="@color/color_999999"
android:textSize="@dimen/font_medium"
app:drawableTopCompat="@drawable/icon_facebook" />
<TextView
android:id="@+id/tv_share_link"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_17"
android:layout_marginBottom="19dp"
android:layout_weight="1"
android:drawablePadding="9dp"
android:gravity="center"
android:text="@string/share_link"
android:textColor="@color/color_999999"
android:textSize="@dimen/font_medium"
app:drawableTopCompat="@drawable/ic_share_link" />
<TextView
android:id="@+id/tv_save_to_album"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_17"
android:layout_marginBottom="19dp"
android:layout_weight="1"
android:drawablePadding="9dp"
android:gravity="center"
android:text="@string/save_invite_image"
android:textColor="@color/color_999999"
android:textSize="@dimen/font_medium"
app:drawableTopCompat="@drawable/ic_share_save_to_album" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/tv_cancel"
android:layout_width="match_parent"
android:layout_height="@dimen/common_item_view_height_big"
android:layout_gravity="center"
android:background="@color/color_F5F5F5"
android:gravity="center"
android:text="@string/cancel"
android:textColor="@color/color_999999"
android:textSize="@dimen/sp_14"
tools:ignore="SpUsage" />
</LinearLayout>

View File

@@ -0,0 +1,129 @@
<?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:layout_marginHorizontal="40dp">
<ImageView
android:id="@+id/iv_bg"
android:layout_width="match_parent"
android:layout_height="0dp"
android:src="@drawable/share_invite_bg"
app:layout_constraintDimensionRatio="375:812"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/line_title_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.162" />
<ImageView
android:id="@+id/iv_title"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@drawable/share_invite_ic_text"
app:layout_constraintDimensionRatio="297:32.5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/line_title_top"
app:layout_constraintWidth_percent="0.792" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/line_qrcode_bg_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.432" />
<ImageView
android:id="@+id/iv_qrcode_bg"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/shape_white_20dp_round"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.53"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/line_qrcode_bg_top"
app:layout_constraintWidth_percent="0.92" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/line_qrcode_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.55" />
<ImageView
android:id="@+id/iv_qrcode"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/line_qrcode_top"
app:layout_constraintWidth_percent="0.533"
tools:src="@mipmap/app_logo" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/line_code_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.869" />
<TextView
android:id="@+id/tv_code"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/share_invite_bg_code"
android:gravity="center"
android:textColor="@color/color_FFFFFF"
android:textSize="@dimen/dp_16"
app:layout_constraintDimensionRatio="241:46"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/line_code_top"
app:layout_constraintWidth_percent="0.642"
tools:text="邀请码ABCD" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/line_code_tips_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.827" />
<TextView
android:id="@+id/tv_code_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/invite_code_tips"
android:textColor="#999999"
android:textSize="@dimen/dp_10"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/line_code_tips_top" />
<TextView
android:id="@+id/tv_qrcode_tips"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/share_invite_bg_qrcode_tips"
android:gravity="center"
android:includeFontPadding="false"
android:paddingHorizontal="@dimen/dp_20"
android:textColor="@color/color_white"
android:textSize="@dimen/dp_12"
app:layout_constraintDimensionRatio="290:43"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/line_qrcode_bg_top"
app:layout_constraintWidth_percent="0.773"
tools:text="扫码下载PiKO并填写我的邀请码立得1000钻石!!" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dp_10"
android:textColor="#FFFFE3AF"
android:textSize="@dimen/dp_15"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="Name" />
<ImageView
android:id="@+id/iv_rebate"
android:layout_width="@dimen/dp_41"
android:layout_height="@dimen/dp_16"
android:layout_marginStart="@dimen/dp_6"
android:src="@drawable/vip_ic_rebate"
app:layout_constraintBottom_toTopOf="@id/tv_title"
app:layout_constraintStart_toStartOf="@id/tv_title" />
</merge>

View File

@@ -541,6 +541,7 @@
<string name="tab_title_fans">粉絲</string>
<string name="title_share_dialog">每天第一次分享免費領紅包不包含分享至Piko好友</string>
<string name="text_share_erban_friends">好友</string>
<string name="save_invite_image">保存邀請圖片</string>
<string name="text_share_Google">Google</string>
<string name="tab_title_team"></string>
<string name="text_team_join_auth_on">開啟身份驗證</string>
@@ -1049,6 +1050,7 @@
<string name="share_facebook">Facebook</string>
<string name="me_open_nobleman_click_event">開通貴族點擊事件</string>
<string name="me_immediately_become_a_Peko_nobleman">立即開通貴族特權</string>
<string name="vip_buy_format">購買%s等級特權</string>
<string name="me_opening_of_the_aristocracy_successful">恭喜開通貴族成功!</string>
<string name="me_failed_to_get_aristocrat_data">獲取貴族數據失敗,請重試</string>
<string name="me_no_aristocracy_yet">尚未開通貴族</string>
@@ -5199,4 +5201,27 @@
<string name="all_service_gift_room_go_ignore">下次不再出現此提示</string>
<string name="all_service_gift_room_go_cancel">留在這</string>
<string name="all_service_gift_room_go_go">立即前往</string>
<string name="invite_code">邀請碼:</string>
<string name="invite_code_tips">記得註冊時填寫邀請碼哦~</string>
<string name="first_recharge">首充</string>
<string name="vip_privilege">贵族特權</string>
<string name="vip_rebate">返钻特權</string>
<string name="vip_buy_tips_format">用戶直接購買%s等級除了直接享有等級對應的所有特權還能獲得額外返鑽。</string>
<string name="vip_rebate_tips">具體返利日期以及返利鑽石數量如下:</string>
<string name="vip_level_name">等級名稱</string>
<string name="vip_rebate_date">返利日期</string>
<string name="vip_rebate_number">返利鑽石數量</string>
<string name="vip_rebate_operation">操作</string>
<string name="vip_rebate_tips2">注:\n返利鑽石需在貴族開通後30天內領取完畢逾期失效 領取後的返利鑽石可到【我的-收益記錄-鑽石明細-收入記錄】中查看。</string>
<string name="vip_rebate_day_format">第%s天</string>
<string name="vip_rebate_get">領取</string>
<string name="vip_rebate_received">已領取</string>
<string name="vip_rebate_no_get">未達到領取標準</string>
<string name="vip_rebate_disable">當前等級不享有該特權~</string>
<string name="vip_rebate_now">立即返利</string>
<string name="vip_buy_tips">您當前是%s等級確認購買更高%s等級</string>
</resources>

View File

@@ -36,6 +36,10 @@ public class CustomItem implements Parcelable, Serializable {
private String format;
private int width;
private int height;
public String getPath(){
return path;
}
@@ -66,7 +70,7 @@ public class CustomItem implements Parcelable, Serializable {
}
public CustomItem(String path, int fileType) {
this(path, fileType, "jpeg");
this(path, fileType, "jpeg", 0, 0);
}
public CustomItem() {
@@ -82,12 +86,16 @@ public class CustomItem implements Parcelable, Serializable {
dest.writeString(this.path);
dest.writeInt(this.fileType);
dest.writeString(this.format);
dest.writeInt(this.width);
dest.writeInt(this.height);
}
protected CustomItem(Parcel in) {
this.path = in.readString();
this.fileType = in.readInt();
this.format = in.readString();
this.width = in.readInt();
this.height = in.readInt();
}
public static final Creator<CustomItem> CREATOR = new Creator<CustomItem>() {

View File

@@ -22,6 +22,7 @@ import com.yizhuan.xchat_android_library.utils.ListUtils;
import com.yizhuan.xchat_android_library.utils.ResUtil;
import com.yizhuan.xchat_android_library.utils.file.JXFileUtils;
import com.yizhuan.xchat_android_library.utils.image.JXImageUtils;
import com.zhihu.matisse.internal.entity.CustomItem;
import java.util.ArrayList;
import java.util.List;
@@ -48,9 +49,9 @@ public class PublishPresenter extends BaseMvpPresenter<IPublishView> {
private MiniWorldChooseInfo miniWorldChooseInfo = new MiniWorldChooseInfo();
public void publishDy(List<String> list, long worldId, String content, boolean isOriginalImage) {
public void publishDy(List<DynamicMedia> list, long worldId, String content, boolean isOriginalImage) {
publishBody = new PublishBody();
List<String> uploadList = new ArrayList<>(list);
List<DynamicMedia> uploadList = new ArrayList<>(list);
int type = ListUtils.isListEmpty(uploadList) ? 0 : 2;
publishBody.setType(type);
publishBody.setUid(AuthModel.get().getCurrentUid());
@@ -67,6 +68,7 @@ public class PublishPresenter extends BaseMvpPresenter<IPublishView> {
public void acceptThrowable(String s, Throwable throwable) {
super.acceptThrowable(s, throwable);
if (throwable != null) {
throwable.printStackTrace();
dealUploadFileError(throwable);
} else {
if (getMvpView() != null) {
@@ -77,7 +79,7 @@ public class PublishPresenter extends BaseMvpPresenter<IPublishView> {
});
}
private Single<String> uploadImage(List<String> imagePaths) {
private Single<String> uploadImage(List<DynamicMedia> imagePaths) {
upload(imagePaths);
return Single.create(emitter ->
mImageUploadSubscribe = Observable.interval(500, TimeUnit.MILLISECONDS)
@@ -91,22 +93,34 @@ public class PublishPresenter extends BaseMvpPresenter<IPublishView> {
}));
}
private void upload(List<String> imagePaths) {
private void upload(List<DynamicMedia> imagePaths) {
if (imagePaths == null || imagePaths.size() == 0) {
return;
}
String file = imagePaths.get(0);
DynamicMedia item = imagePaths.get(0);
String file = item.getLocalFilePath();
Single.create((SingleOnSubscribe<String>) e -> {
long fileLength = JXFileUtils.getFileLength(file);
LogUtil.print(ResUtil.getString(R.string.publish_presenter_publishpresenter_01) + fileLength);
String compressFile = null;
if (!isOriginalImage && fileLength > ImageUploadConfig.MAX_FILE_SIZE) {
compressFile = JXImageUtils.compressImagePxAndQuality(
JXImageUtils.CompressResult result = JXImageUtils.compressImagePxAndQuality(
file, DirectoryHelper.get().getDynamicDir(),
"dynamic_" + System.currentTimeMillis() + ".jpg",
ImageUploadConfig.EXPECT_MIN_WIDTH,
ImageUploadConfig.EXPECT_COMPRESS_SIZE);
if (result != null) {
compressFile = result.getPath();
if (result.getWidth() > 0 && item.getWidth() != result.getWidth()) {
item.setWidth(result.getWidth());
}
if (result.getHeight() > 0 && item.getHeight() != result.getHeight()) {
item.setHeight(result.getHeight());
}
if (result.getFormat() != null) {
item.setFormat(result.getFormat());
}
}
LogUtil.print(ResUtil.getString(R.string.publish_presenter_publishpresenter_02) + compressFile);
}
if (!TextUtils.isEmpty(compressFile)) {
@@ -118,21 +132,23 @@ public class PublishPresenter extends BaseMvpPresenter<IPublishView> {
}
})
.compose(RxHelper.handleSchedulers())
.flatMap((Function<String, SingleSource<DynamicMedia>>)
path -> FileModel.get().uploadFileReturnImageInfo(path))
.flatMap((Function<String, SingleSource<String>>)
path -> FileModel.get().uploadFile(path))
.compose(bindUntilEvent(PresenterEvent.DESTROY))
.subscribe(new DontWarnObserver<DynamicMedia>() {
.subscribe(new DontWarnObserver<String>() {
@Override
public void acceptThrowable(DynamicMedia media, Throwable throwable) {
super.acceptThrowable(media, throwable);
public void acceptThrowable(String url, Throwable throwable) {
super.acceptThrowable(url, throwable);
if (throwable != null) {
throwable.printStackTrace();
if (mImageUploadSubscribe != null) {
mImageUploadSubscribe.dispose();
}
dealUploadFileError(throwable);
} else {
LogUtil.print(ResUtil.getString(R.string.publish_presenter_publishpresenter_04), media);
publishBody.addDynamicMedia(media);
item.setResUrl(url);
LogUtil.print(ResUtil.getString(R.string.publish_presenter_publishpresenter_04), item);
publishBody.addDynamicMedia(item);
imagePaths.remove(0);
upload(imagePaths);
}

View File

@@ -54,6 +54,7 @@ import com.yizhuan.xchat_android_library.common.photo.PhotoProvider;
import com.yizhuan.xchat_android_library.common.util.PhotoCompressUtil;
import com.yizhuan.xchat_android_library.common.util.PhotosCompressCallback;
import com.yizhuan.xchat_android_library.easypermisssion.EasyPermissions;
import com.yizhuan.xchat_android_library.easyphoto.models.album.entity.Photo;
import com.yizhuan.xchat_android_library.easyphoto.utils.settings.SettingsUtils;
import com.yizhuan.xchat_android_library.utils.ResUtil;
import com.yizhuan.xchat_android_library.utils.SingleToastUtil;
@@ -297,7 +298,7 @@ public class PublishActivity extends BaseMvpActivity<IPublishView, PublishPresen
tvPublish.setEnabled(false);
getDialogManager().showProgressDialog(context);
getMvpPresenter().publishDy(
ObjectTypeHelper.customToStringList(uploadList),
ObjectTypeHelper.customToMediaList(uploadList),
getMvpPresenter().getWorldId(), etContent.getText().toString(), isOriginalImage);
}
@@ -333,23 +334,34 @@ public class PublishActivity extends BaseMvpActivity<IPublishView, PublishPresen
if (data == null) {
return;
}
PhotoProvider.getResultPathListAsync(data, new Function1<List<String>, Unit>() {
PhotoProvider.getResultPathListAsync(data, new Function1<List<? extends Photo>, Unit>() {
@Override
public Unit invoke(List<String> list) {
public Unit invoke(List<? extends Photo> list) {
if (list.isEmpty()) {
return null;
} else {
if (mJob != null) {
mJob.cancel(null);
}
mJob = PhotoCompressUtil.compress(PublishActivity.this, list,
ArrayList<String> pathList = new ArrayList<>();
for (Photo photo : list) {
pathList.add(photo.path);
}
mJob = PhotoCompressUtil.compress(PublishActivity.this, pathList,
PhotoCompressUtil.getCompressCachePath("publish")
, new PhotosCompressCallback() {
@Override
public void onSuccess(@NonNull ArrayList<String> compressedImgList) {
List<CustomItem> pathResult = new ArrayList<>();
for (String path : compressedImgList) {
pathResult.add(new CustomItem(path, CustomItem.IMAGE_NORMAL, "jpeg"));
for (int i = 0; i < compressedImgList.size(); i++) {
if (i < list.size()) {
Photo photo = list.get(i);
String format = "image/jpeg";
if (photo.type != null) {
format = photo.type;
}
pathResult.add(new CustomItem(compressedImgList.get(i), CustomItem.IMAGE_NORMAL, format, photo.width, photo.height));
}
}
if (pathResult.size() == 0) {
return;
@@ -445,6 +457,7 @@ public class PublishActivity extends BaseMvpActivity<IPublishView, PublishPresen
@Override
public void onPublishFailed(Throwable throwable) {
tvPublish.setEnabled(true);
getDialogManager().dismissDialog();
toast(throwable.getMessage());
}
@@ -635,6 +648,7 @@ public class PublishActivity extends BaseMvpActivity<IPublishView, PublishPresen
maxSelect - uploadList.size(),
true,
REQUEST_CODE_OPEN_PHOTO_PROVIDER,
true,
true
);
}

View File

@@ -22,6 +22,22 @@ public class ObjectTypeHelper {
return resultList;
}
public static List<DynamicMedia> customToMediaList(List<CustomItem> paramsList) {
List<DynamicMedia> resultList = new ArrayList<>();
if (paramsList == null) {
return resultList;
}
for (CustomItem item : paramsList) {
DynamicMedia media = new DynamicMedia();
media.setLocalFilePath(item.getPath());
media.setWidth(item.getWidth());
media.setHeight(item.getHeight());
media.setFormat(item.getFormat());
resultList.add(media);
}
return resultList;
}
public static List<CustomItem> stringToCustomList(List<String> paramsList) {
List<CustomItem> resultList = new ArrayList<>();
if (paramsList == null) {

View File

@@ -107,23 +107,271 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="20dp"
android:background="@drawable/bg_vip_main_bottom"
android:background="@drawable/vip_bg_bottom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_min="601dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_not_open" />
<TextView
android:id="@+id/tv_tab_privilege"
android:layout_width="@dimen/dp_80"
android:layout_height="@dimen/dp_30"
android:layout_marginEnd="@dimen/dp_4"
android:background="@drawable/vip_bg_tab_selected"
android:gravity="center"
android:text="@string/vip_privilege"
android:textColor="#333333"
android:textSize="@dimen/dp_14"
android:layout_marginTop="@dimen/dp_28"
app:layout_constraintEnd_toStartOf="@id/tv_tab_rebate"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/view_bottom" />
<TextView
android:id="@+id/tv_tab_rebate"
android:layout_width="@dimen/dp_80"
android:layout_height="@dimen/dp_30"
android:background="@drawable/vip_bg_tab_unselected"
android:gravity="center"
android:text="@string/vip_rebate"
android:textColor="#333333"
android:textSize="@dimen/dp_14"
app:layout_constraintBottom_toBottomOf="@id/tv_tab_privilege"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_tab_privilege"
app:layout_constraintTop_toTopOf="@id/tv_tab_privilege" />
<ImageView
android:id="@+id/iv_tab_line_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dp_2"
android:src="@drawable/vip_ic_tab_line_left"
app:layout_constraintBottom_toBottomOf="@id/tv_tab_privilege"
app:layout_constraintEnd_toStartOf="@id/tv_tab_privilege"
app:layout_constraintTop_toTopOf="@id/tv_tab_privilege" />
<ImageView
android:id="@+id/iv_tab_line_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_2"
android:src="@drawable/vip_ic_tab_line_right"
app:layout_constraintBottom_toBottomOf="@id/tv_tab_rebate"
app:layout_constraintStart_toEndOf="@id/tv_tab_rebate"
app:layout_constraintTop_toTopOf="@id/tv_tab_rebate" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_rebate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/dp_12"
android:layout_marginTop="@dimen/dp_10"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_tab_rebate"
tools:visibility="visible">
<TextView
android:id="@+id/tv_rebate_disable_status"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_300"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:text="@string/vip_rebate_disable"
android:textColor="@color/white"
android:textSize="@dimen/dp_16"
android:visibility="gone"
tools:visibility="visible"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_rebate_tips_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/vip_buy_tips_format"
android:textColor="#FFE3AF"
android:textSize="@dimen/dp_12"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_rebate_tips_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_12"
android:text="@string/vip_rebate_tips"
android:textColor="#FFE3AF"
android:textSize="@dimen/dp_12"
app:layout_constraintTop_toBottomOf="@id/tv_rebate_tips_1" />
<TextView
android:id="@+id/tv_table_column_level_name"
android:layout_width="0dp"
android:layout_height="@dimen/dp_31"
android:layout_marginTop="@dimen/dp_12"
android:background="@drawable/vip_bg_cloumn_first"
android:gravity="center"
android:text="@string/vip_level_name"
android:textColor="#FFE3AF"
android:textSize="@dimen/dp_10"
app:layout_constraintEnd_toStartOf="@id/tv_table_column_rebate_date"
app:layout_constraintHorizontal_weight="70"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_rebate_tips_2" />
<TextView
android:id="@+id/tv_table_column_rebate_date"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#1AFFAA36"
android:gravity="center"
android:text="@string/vip_rebate_date"
android:textColor="#FFE3AF"
android:textSize="@dimen/dp_10"
app:layout_constraintBottom_toBottomOf="@id/tv_table_column_level_name"
app:layout_constraintEnd_toStartOf="@id/tv_table_column_rebate_num"
app:layout_constraintHorizontal_weight="78"
app:layout_constraintStart_toEndOf="@id/tv_table_column_level_name"
app:layout_constraintTop_toTopOf="@id/tv_table_column_level_name" />
<TextView
android:id="@+id/tv_table_column_rebate_num"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#1AFFAA36"
android:gravity="center"
android:text="@string/vip_rebate_number"
android:textColor="#FFE3AF"
android:textSize="@dimen/dp_10"
app:layout_constraintBottom_toBottomOf="@id/tv_table_column_level_name"
app:layout_constraintEnd_toStartOf="@id/tv_table_column_rebate_operation"
app:layout_constraintHorizontal_weight="97"
app:layout_constraintStart_toEndOf="@id/tv_table_column_rebate_date"
app:layout_constraintTop_toTopOf="@id/tv_table_column_level_name" />
<TextView
android:id="@+id/tv_table_column_rebate_operation"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/vip_bg_cloumn_last"
android:gravity="center"
android:text="@string/vip_rebate_operation"
android:textColor="#FFE3AF"
android:textSize="@dimen/dp_10"
app:layout_constraintBottom_toBottomOf="@id/tv_table_column_level_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="102"
app:layout_constraintStart_toEndOf="@id/tv_table_column_rebate_num"
app:layout_constraintTop_toTopOf="@id/tv_table_column_level_name" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_rebate"
android:layout_width="0dp"
android:minHeight="@dimen/dp_20"
android:layout_height="wrap_content"
android:orientation="vertical"
android:overScrollMode="never"
android:scrollbars="none"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="@id/tv_table_column_rebate_operation"
app:layout_constraintStart_toStartOf="@id/tv_table_column_rebate_date"
app:layout_constraintTop_toBottomOf="@id/tv_table_column_rebate_date"
tools:itemCount="4" />
<TextView
android:id="@+id/tv_table_level_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#BC9E66"
android:textSize="@dimen/dp_10"
app:layout_constraintBottom_toBottomOf="@id/rv_rebate"
app:layout_constraintEnd_toEndOf="@id/tv_table_column_level_name"
app:layout_constraintStart_toStartOf="@id/tv_table_column_level_name"
app:layout_constraintTop_toBottomOf="@id/tv_table_column_level_name"
tools:text="Name" />
<View
android:id="@+id/v_table_line_level"
android:layout_width="@dimen/dp_1"
android:layout_height="0dp"
android:background="#33FFAA36"
app:layout_constraintBottom_toBottomOf="@id/rv_rebate"
app:layout_constraintEnd_toStartOf="@id/tv_table_column_rebate_date"
app:layout_constraintStart_toEndOf="@id/tv_table_column_level_name"
app:layout_constraintTop_toTopOf="@id/tv_table_column_level_name" />
<View
android:id="@+id/v_table_line_date"
android:layout_width="@dimen/dp_1"
android:layout_height="0dp"
android:background="#33FFAA36"
app:layout_constraintBottom_toBottomOf="@id/rv_rebate"
app:layout_constraintEnd_toStartOf="@id/tv_table_column_rebate_num"
app:layout_constraintStart_toEndOf="@id/tv_table_column_rebate_date"
app:layout_constraintTop_toTopOf="@id/tv_table_column_level_name" />
<View
android:id="@+id/v_table_line_num"
android:layout_width="@dimen/dp_1"
android:layout_height="0dp"
android:background="#33FFAA36"
app:layout_constraintBottom_toBottomOf="@id/rv_rebate"
app:layout_constraintEnd_toStartOf="@id/tv_table_column_rebate_operation"
app:layout_constraintStart_toEndOf="@id/tv_table_column_rebate_num"
app:layout_constraintTop_toTopOf="@id/tv_table_column_level_name" />
<View
android:id="@+id/v_table_line_title"
android:layout_width="0dp"
android:layout_height="@dimen/dp_1"
android:background="#33FFAA36"
app:layout_constraintEnd_toEndOf="@id/tv_table_column_rebate_operation"
app:layout_constraintStart_toStartOf="@id/tv_table_column_level_name"
app:layout_constraintTop_toBottomOf="@id/tv_table_column_level_name" />
<View
android:id="@+id/v_table_border"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/vip_bg_rebate_table"
app:layout_constraintBottom_toBottomOf="@id/rv_rebate"
app:layout_constraintEnd_toEndOf="@id/rv_rebate"
app:layout_constraintStart_toStartOf="@id/tv_table_column_level_name"
app:layout_constraintTop_toTopOf="@id/tv_table_column_rebate_operation" />
<TextView
android:id="@+id/tv_rebate_tips_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_12"
android:text="@string/vip_rebate_tips2"
android:textColor="#FFE3AF"
android:textSize="@dimen/dp_12"
app:layout_constraintTop_toBottomOf="@id/rv_rebate" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.Group
android:id="@+id/group_privilege"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="tv_auth_num,recycler_view" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_auth_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="70dp"
android:layout_marginTop="@dimen/dp_10"
android:textColor="#ffffe7cf"
android:textSize="@dimen/sp_14"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/view_bottom"
app:layout_constraintTop_toBottomOf="@id/tv_tab_privilege"
tools:text="3/12" />
<androidx.recyclerview.widget.RecyclerView
@@ -131,7 +379,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:layout_marginBottom="125dp"
android:layout_marginBottom="165dp"
android:overScrollMode="never"
android:scrollbars="none"
app:layout_constraintBottom_toBottomOf="parent"
@@ -144,24 +392,6 @@
</androidx.core.widget.NestedScrollView>
<com.yizhuan.xchat_android_library.widget.DrawableCenterTextView
android:id="@+id/tv_open_vip"
android:layout_width="300dp"
android:layout_height="44dp"
android:layout_marginBottom="30dp"
android:background="@drawable/bg_vip_open_btn"
android:drawableStart="@drawable/ic_vip_open_btn"
android:drawablePadding="3dp"
android:gravity="center"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp_16"
android:textStyle="bold"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="@string/layout_activity_vip_main_03" />
<com.yizhuan.erban.base.TitleBar
android:id="@+id/title_bar"
android:layout_width="0dp"
@@ -174,16 +404,15 @@
<com.yizhuan.erban.ui.widget.magicindicator.MagicIndicator
android:id="@+id/magic_indicator"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_height="@dimen/dp_50"
android:layout_marginStart="6dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="6dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title_bar" />
<LinearLayout
android:id="@+id/ll_my_vip_info"
android:id="@+id/layout_bottom_panel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
@@ -194,16 +423,17 @@
tools:visibility="visible">
<FrameLayout
android:id="@+id/layout_level_info"
android:layout_width="match_parent"
android:layout_height="36dp"
android:background="#FF302B20">
android:background="#FF302B20"
android:layout_height="36dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center_vertical"
android:baselineAligned="true">
android:baselineAligned="true"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
@@ -300,8 +530,10 @@
</FrameLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_level_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/dp_20"
android:background="#FF252014">
<androidx.appcompat.widget.AppCompatImageView
@@ -309,10 +541,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="14dp"
android:layout_marginTop="24dp"
android:layout_marginBottom="50dp"
android:layout_marginTop="@dimen/dp_24"
android:src="@drawable/ic_vip_auth_text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -382,6 +612,23 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<com.yizhuan.xchat_android_library.widget.DrawableCenterTextView
android:id="@+id/tv_open_vip"
android:layout_width="300dp"
android:layout_height="44dp"
android:layout_marginBottom="@dimen/dp_20"
android:background="@drawable/bg_vip_open_btn"
android:drawableStart="@drawable/ic_vip_open_btn"
android:drawablePadding="3dp"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp_16"
android:textStyle="bold"
android:visibility="gone"
tools:visibility="visible"
tools:text="@string/layout_activity_vip_main_03" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,70 @@
<?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="@dimen/dp_24"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_date"
android:layout_width="0dp"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#BC9E66"
android:textSize="@dimen/dp_10"
app:layout_constraintEnd_toStartOf="@id/tv_num"
app:layout_constraintHorizontal_weight="78"
app:layout_constraintStart_toStartOf="parent"
tools:text="Name" />
<TextView
android:id="@+id/tv_num"
android:layout_width="0dp"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#BC9E66"
android:textSize="@dimen/dp_10"
app:layout_constraintEnd_toStartOf="@id/layout_operation"
app:layout_constraintHorizontal_weight="97"
app:layout_constraintStart_toEndOf="@id/tv_date"
tools:text="Name" />
<FrameLayout
android:id="@+id/layout_operation"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="102"
app:layout_constraintStart_toEndOf="@id/tv_num">
<FrameLayout
android:id="@+id/layout_status"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:paddingHorizontal="@dimen/dp_10">
<TextView
android:id="@+id/tv_status"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_13"
android:layout_gravity="center"
android:background="@drawable/shape_f6ad3f_9dp"
android:gravity="center"
android:paddingHorizontal="@dimen/dp_8"
android:textColor="@color/white"
android:textSize="@dimen/dp_8"
tools:text="Name" />
</FrameLayout>
</FrameLayout>
<View
android:id="@+id/v_line"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_1"
android:background="#33FFAA36"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -11,6 +11,8 @@ import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUS
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_LUCKY_SEA_GIFT_SERVER_ALL;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_BOX_ALL_ROOM_NOTIFY_BY_SVGA;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_DRAW_GIFT_L5;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY_ALL;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -32,6 +34,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.hjq.toast.ToastUtils;
import com.netease.nim.uikit.StatusBarUtil;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
@@ -61,6 +64,8 @@ import com.yizhuan.xchat_android_core.im.custom.bean.RoomBoxPrizeInfo;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomLuckySeaAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomLuckySeaMsgBean;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomReceivedLuckyGiftAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomTemplateNotifyAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomTemplateNotifyMsgBean;
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager;
import com.yizhuan.xchat_android_core.manager.IMNetEaseManager;
import com.yizhuan.xchat_android_core.manager.RoomEvent;
@@ -506,6 +511,14 @@ public class TreasureBoxActivity extends BaseBindingActivity<ActivityTreasureBox
IMNetEaseManager.get().noticeRoomEvent(message, RoomEvent.CRAZY_ZOO_ALL_ROOM_NOTIFY);
}
break;
case CUSTOM_MSG_TEMPLATE_NOTIFY://通用飘屏
if (baseProtocol.getSecond() == CUSTOM_MSG_TEMPLATE_NOTIFY_ALL) {
RoomTemplateNotifyAttachment attachment = new RoomTemplateNotifyAttachment(CUSTOM_MSG_TEMPLATE_NOTIFY, CUSTOM_MSG_TEMPLATE_NOTIFY_ALL);
attachment.setMsgBean(new Gson().fromJson(String.valueOf(baseProtocol.getData()), RoomTemplateNotifyMsgBean.class));
ChatRoomMessage message = ChatRoomMessageBuilder.createChatRoomCustomMessage(String.valueOf(AvRoomDataManager.get().getRoomId()), attachment);
IMNetEaseManager.get().noticeRoomEvent(message, RoomEvent.TEMPLATE_NOTIFY);
}
break;
case CUSTOM_MSG_LUCKY_GIFT://福袋
if (baseProtocol.getSecond() == CUSTOM_MSG_LUCKY_GIFT_SERVER_NOTIFY || baseProtocol.getSecond() == CUSTOM_MSG_LUCKY_GIFT_SERVER_ALL) {
RoomReceivedLuckyGiftAttachment attachment = new RoomReceivedLuckyGiftAttachment(CUSTOM_MSG_LUCKY_GIFT_SERVER_NOTIFY);

View File

@@ -107,6 +107,8 @@ dependencies {
implementation 'com.liulishuo.okdownload:okhttp:1.0.7'
implementation 'com.tencent.liteav:LiteAVSDK_TRTC:11.4.0.13189'
api 'com.qcloud.cos:cos-android:5.9.23'
}
repositories {
mavenCentral()

View File

@@ -23,7 +23,7 @@ public class XChatConstants {
/**
* 加密接口參數
*/
public static final String DES_ENCRYPT_KEY_SMS_PARAMS = "70d26f6a5c214d3b858f3f8daad7a161";
public static final String DES_ENCRYPT_KEY_SMS_PARAMS = "rpbs6us1m8r2j9g6u06ff2bo18orwaya";
/**
* 加密接口簽名
@@ -239,7 +239,7 @@ public class XChatConstants {
/**
* 聊天室文本消息易盾反垃圾業務id
*/
public static final String CHAT_ROOM_ANTI_SPAM_CONFIG_ID = BuildConfig.DEBUG ? "8151e1245163738e1fa84db7a02f8fb9" : "bddbbb617e9da4fcd08c6baf6686ad01";
public static final String CHAT_ROOM_ANTI_SPAM_CONFIG_ID = BuildConfig.DEBUG ? "8151e1245163738e1fa84db7a02f8fb9" : "f459972b432106844b89fd58c92b8061";
public static final int KICK_OUT_ROOM_LIMIT_ENTER_TIME = 5 * 60 * 1000;
public static final int CODE_IGNORE_TOAST = 5263;

View File

@@ -75,6 +75,7 @@ import com.yizhuan.xchat_android_core.family.event.FamilyMineEvent;
import com.yizhuan.xchat_android_core.gift.GiftModel;
import com.yizhuan.xchat_android_core.gift.bean.GiftInfo;
import com.yizhuan.xchat_android_core.gift.bean.GiftReceiveInfo;
import com.yizhuan.xchat_android_core.gift.bean.GiftType;
import com.yizhuan.xchat_android_core.gift.event.UpdateKnapFreeGiftDataEvent;
import com.yizhuan.xchat_android_core.helper.AtProxy;
import com.yizhuan.xchat_android_core.im.custom.bean.ActivityTimerAttachment;
@@ -722,7 +723,9 @@ public final class IMNetEaseManager {
|| customAttachment.getFirst() == CustomAttachment.CUSTOM_MESS_TAROT
|| customAttachment.getFirst() == CustomAttachment.CUSTOM_MSG_HEADER_TYPE_MONSTER_HUNTING
|| customAttachment.getFirst() == CustomAttachment.CUSTOM_MSG_MINI_WORLD) {
addMessages(msg);
if (!isIgnoreMessageOfSuperLuckGift(customAttachment)) {
addMessages(msg);
}
}
Logger.i(ResUtil.getString(R.string.xchat_android_core_manager_imneteasemanager_015) + customAttachment);
int second = customAttachment.getSecond();
@@ -821,7 +824,7 @@ public final class IMNetEaseManager {
GiftModel.get().addNewGift(giftInfo);
messages.add(msg);
gift = true;
if (!giftReceiveInfo.isRoomAlbum()) {
if (!giftReceiveInfo.isRoomAlbum() && giftInfo.getGiftType() != GiftType.GIFT_TYPE_SUPER_LUCKY) {
addMessages(msg);
}
} else if (customAttachment.getSecond() == CustomAttachment.CUSTOM_MSG_SUB_TYPE_SEND_LUCKY_GIFT) {
@@ -1017,6 +1020,11 @@ public final class IMNetEaseManager {
break;
}
break;
case CUSTOM_MSG_SUPER_LUCKY_GIFT_TEMPLATE:
if (second == CUSTOM_MSG_SUPER_LUCKY_GIFT_TEMPLATE_SUB) {
addMessages(msg);
}
break;
case CUSTOM_MSG_RADISH:
RoomBoxPrizeAttachment boxPrizeAttachment = ((RoomBoxPrizeAttachment) msg.getAttachment());
UserInfo userInfo = UserModel.get().getCacheLoginUserInfo();
@@ -1476,6 +1484,11 @@ public final class IMNetEaseManager {
noticeRoomEvent(msg, RoomEvent.CRAZY_ZOO_ROOM_NOTIFY);
}
break;
case CUSTOM_MSG_TEMPLATE_NOTIFY:
if (second == CUSTOM_MSG_TEMPLATE_NOTIFY_ROOM) {
noticeRoomEvent(msg, RoomEvent.TEMPLATE_NOTIFY);
}
break;
default:
break;
}
@@ -1491,6 +1504,36 @@ public final class IMNetEaseManager {
}
}
/**
* 是否不需要添加到公屏(超级幸运礼物特殊,会单独添加到公屏)
*/
private boolean isIgnoreMessageOfSuperLuckGift(CustomAttachment attachment) {
if (attachment.getFirst() == CUSTOM_MSG_HEADER_TYPE_MULTI_GIFT) {
if (attachment.getSecond() == CUSTOM_MSG_SUB_TYPE_SEND_MULTI_GIFT || attachment.getSecond() == CUSTOM_MSG_SUB_TYPE_BATCH_SEND_GIFT) {
if (attachment instanceof MultiGiftAttachment) {
MultiGiftAttachment multiGiftAttachment = (MultiGiftAttachment) attachment;
GiftInfo giftInfo = multiGiftAttachment.getMultiGiftReceiveInfo().getGift();
if (giftInfo != null && giftInfo.getGiftType() == GiftType.GIFT_TYPE_SUPER_LUCKY) {
return true;
}
}
}
}
if (attachment.getFirst() == CUSTOM_MSG_HEADER_TYPE_GIFT) {
if (attachment.getSecond() == CUSTOM_MSG_SUB_TYPE_SEND_GIFT) {
if (attachment instanceof GiftAttachment) {
GiftAttachment giftAttachment = (GiftAttachment) attachment;
GiftReceiveInfo giftReceiveInfo = giftAttachment.getGiftReceiveInfo();
GiftInfo giftInfo = giftReceiveInfo.getGift();
if (giftInfo != null && giftInfo.getGiftType() == GiftType.GIFT_TYPE_SUPER_LUCKY) {
return true;
}
}
}
}
return false;
}
private void pkCloseUpdateSelfMicInfo() {
if (AvRoomDataManager.get().isOnMic(AuthModel.get().getCurrentUid())) {
UserModel.get().getCacheLoginUserInfo().setGroupType(PKTeamInfo.TEAM_NONE);

View File

@@ -1009,7 +1009,7 @@ public class TRTCEngineAdapter extends BaseAdapterImpl {
}
if (enabled) {
trtcCloud.getDeviceManager().setSystemVolumeType(TXDeviceManager.TXSystemVolumeType.TXSystemVolumeTypeMedia);
trtcCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_DEFAULT);
trtcCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_MUSIC);
} else {
trtcCloud.stopLocalAudio();
}

View File

@@ -1,5 +1,6 @@
package com.yizhuan.xchat_android_core.manager.trtc;
import static io.agora.rtc2.Constants.AUDIO_PROFILE_MUSIC_HIGH_QUALITY;
import static io.agora.rtc2.Constants.AUDIO_PROFILE_MUSIC_STANDARD;
import static io.agora.rtc2.Constants.AUDIO_SCENARIO_GAME_STREAMING;
@@ -60,7 +61,7 @@ public class TRtcEngineManager extends BaseEngine {
//设置频道模式为直播
mRtcEngine.disableVideo();
mRtcEngine.setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING);
mRtcEngine.setAudioProfile(AUDIO_PROFILE_MUSIC_STANDARD, AUDIO_SCENARIO_GAME_STREAMING);
mRtcEngine.setAudioProfile(AUDIO_PROFILE_MUSIC_HIGH_QUALITY, AUDIO_SCENARIO_GAME_STREAMING);
mRtcEngine.enableAudioVolumeIndication(600, 3, false);
mRtcEngine.setDefaultAudioRoutetoSpeakerphone(true);
mRtcEngine.setExternalVideoSource(true, false, true);

View File

@@ -2,24 +2,23 @@ package com.yizhuan.xchat_android_core.file;
import android.text.TextUtils;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.qiniu.android.common.FixedZone;
import com.qiniu.android.storage.Configuration;
import com.qiniu.android.storage.UploadManager;
import com.chuhai.utils.AppUtils;
import com.chuhai.utils.PathUtils;
import com.yizhuan.xchat_android_core.R;
import com.yizhuan.xchat_android_core.base.BaseModel;
import com.yizhuan.xchat_android_core.bean.response.ServiceResult;
import com.yizhuan.xchat_android_core.community.bean.DynamicMedia;
import com.yizhuan.xchat_android_core.file.cos.CosToken;
import com.yizhuan.xchat_android_core.exception.ErrorThrowable;
import com.yizhuan.xchat_android_core.file.cos.CosClient;
import com.yizhuan.xchat_android_core.utils.net.RxHelper;
import com.yizhuan.xchat_android_library.net.rxnet.RxNet;
import com.yizhuan.xchat_android_library.utils.ResUtil;
import org.json.JSONObject;
import java.io.File;
import java.util.UUID;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import retrofit2.http.GET;
public class FileModel extends BaseModel implements IFileModel {
@@ -29,120 +28,51 @@ public class FileModel extends BaseModel implements IFileModel {
}
private FileModel() {
Configuration config = new Configuration.Builder()
.zone(FixedZone.zoneAs0) // 设置区域不指定会自动选择。指定不同区域的上传域名、备用域名、备用IP。
.build();
uploadManager = new UploadManager(config);
}
public static FileModel get() {
return Helper.INSTANCE;
}
private UploadManager uploadManager;
private final Api api = RxNet.create(Api.class);
private CosToken cosToken;
private Single<CosToken> getCosToken() {
if (cosToken != null && cosToken.isValid()) {
return Single.just(cosToken);
} else {
return api.getCosToken().compose(RxHelper.handleSchedulers())
.compose(RxHelper.handleBeanData()).map(cosToken -> {
FileModel.get().cosToken = cosToken;
return cosToken;
});
}
}
@Override
public Single<String> uploadFile(String path) {
File file;
if (TextUtils.isEmpty(path) || !((file = new File(path)).exists())) {
return Single.error(new ErrorThrowable(path + ResUtil.getString(R.string.xchat_android_core_file_filemodel_01)));
}
File finalFile = file;
return api.getUploadToken()
.compose(RxHelper.handleSchedulers())
.compose(RxHelper.handleBeanData())
.flatMap(uploadToken -> Single.create(singleEmitter ->
uploadManager.put(finalFile, uploadToken.getKey(), uploadToken.getToken() ,
(key, info, response) -> {
if (info.isOK()) {
try {
String imgUrl = response.getString("path");
singleEmitter.onSuccess(imgUrl);
} catch (Exception e) {
singleEmitter.onError(e);
}
} else {
singleEmitter.onError(new Throwable(info.error));
}
}, null)
));
String outName = UUID.randomUUID().toString() + PathUtils.INSTANCE.getSuffixType(finalFile.getName());
return getCosToken().flatMap(token -> CosClient.INSTANCE.upload(AppUtils.getApp(), finalFile, outName, token).map(cosXmlResult -> cosXmlResult.accessUrl))
.observeOn(AndroidSchedulers.mainThread());
}
@Override
public Single<DynamicMedia> uploadFileReturnImageInfo(String path) {
return uploadFileReturnImageInfo(path, null);
}
@Override
public Single<DynamicMedia> uploadFileReturnImageInfo(String path, String qiniuName) {
File file;
if (TextUtils.isEmpty(path) || !((file = new File(path)).exists())) {
return Single.error(new ErrorThrowable(path + ResUtil.getString(R.string.xchat_android_core_file_filemodel_02)));
}
File finalFile = file;
return api.getUploadToken()
.compose(RxHelper.handleSchedulers())
.compose(RxHelper.handleBeanData())
.flatMap(uploadToken -> Single.create(singleEmitter ->
uploadManager.put(finalFile, uploadToken.getKey(), uploadToken.getToken(),
(key, info, response) -> {
if (info.isOK()) {
try {
LogUtil.print(ResUtil.getString(R.string.xchat_android_core_file_filemodel_03));
LogUtil.print(response);
DynamicMedia media = responseToMeia(response);
if (media != null) {
singleEmitter.onSuccess(media);
return;
}
} catch (Exception e) {
e.printStackTrace();
}
singleEmitter.onError(new Throwable("qiniu json error"));
} else {
singleEmitter.onError(new Throwable(info.error));
}
}, null)));
}
@Override
public Single<String> downloadFile(String url) {
return null;
}
private DynamicMedia responseToMeia(JSONObject response) {
DynamicMedia media = new DynamicMedia();
try {
String imgNamePath = response.getString("path");
media.setResUrl(imgNamePath);
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
try {
media.setFormat(response.getString("format"));
media.setWidth(response.getInt("w"));
media.setHeight(response.getInt("h"));
} catch (Exception ex) {
ex.printStackTrace();
}
LogUtil.print(ResUtil.getString(R.string.xchat_android_core_file_filemodel_04), media);
return media;
}
interface Api {
/**
* 上传文件
*
* @return
*/
@GET("/qiniu/upload/getUploadToken")
Single<ServiceResult<UploadToken>> getUploadToken();
@GET("/tencent/cos/getToken")
Single<ServiceResult<CosToken>> getCosToken();
}
}

View File

@@ -22,9 +22,4 @@ public interface IFileModel extends IModel {
* @return
*/
Single<String> downloadFile(String url);
Single<DynamicMedia> uploadFileReturnImageInfo(String path);
Single<DynamicMedia> uploadFileReturnImageInfo(String path, String qiniuName);
}

View File

@@ -1,9 +0,0 @@
package com.yizhuan.xchat_android_core.file;
import lombok.Data;
@Data
public class UploadToken {
private String key;
private String token;
}

View File

@@ -0,0 +1,131 @@
package com.yizhuan.xchat_android_core.file.cos
import android.content.Context
import android.net.Uri
import android.util.Log
import com.tencent.cos.xml.CosXmlService
import com.tencent.cos.xml.CosXmlServiceConfig
import com.tencent.cos.xml.exception.CosXmlClientException
import com.tencent.cos.xml.exception.CosXmlServiceException
import com.tencent.cos.xml.listener.CosXmlResultListener
import com.tencent.cos.xml.model.CosXmlRequest
import com.tencent.cos.xml.model.CosXmlResult
import com.tencent.cos.xml.transfer.COSXMLUploadTask
import com.tencent.cos.xml.transfer.TransferConfig
import com.tencent.cos.xml.transfer.TransferManager
import com.yizhuan.xchat_android_library.common.application.Env
import io.reactivex.Single
import java.io.File
/**
* Created by Max on 2024/1/16 11:09
* Desc:
**/
object CosClient {
private var cosXmlClient: CosXmlService? = null
private var credentialProvider: CosCredentialProvider? = null
private fun getCosXmlClient(context: Context, token: CosToken): CosXmlService {
var client = this.cosXmlClient
if (client != null && credentialProvider != null) {
credentialProvider?.updateCredentials(token.toCredential())
return client
}
// 创建 CosXmlServiceConfig 对象,根据需要修改默认的配置参数
val serviceConfig: CosXmlServiceConfig = CosXmlServiceConfig.Builder()
.setRegion(token.region)
.isHttps(true) // 使用 HTTPS 请求, 默认为 HTTP 请求
.builder()
val credentials = token.toCredential()
credentialProvider = CosCredentialProvider(credentials)
// 初始化 COS Service获取实例
client = CosXmlService(
context,
serviceConfig, credentialProvider
)
cosXmlClient = client
return client
}
/**
* 上传文件
* @param outName 远端文件名
*/
fun upload(
context: Context,
file: File,
outName: String,
token: CosToken
): Single<CosXmlResult> {
if (Env.isDebug()) {
Log.e("CosClient", "upload file:${file.absolutePath} outName:${outName}")
}
return Single.create {
uploadFile(context, file, outName, token).apply {
setCosXmlResultListener(object : CosXmlResultListener {
override fun onSuccess(request: CosXmlRequest?, result: CosXmlResult) {
transformDomain(result, token)
if (Env.isDebug()) {
Log.e("CosClient", "upload onSuccess result:${result.accessUrl}")
}
it.onSuccess(result)
}
override fun onFail(
request: CosXmlRequest?,
clientException: CosXmlClientException?,
serviceException: CosXmlServiceException?
) {
if (Env.isDebug()) {
Log.e("CosClient", "upload onFail clientException:$clientException")
Log.e("CosClient", "upload onFail serviceException:$serviceException")
}
it.onError(CosException(clientException, serviceException))
}
})
}
}
}
private fun transformDomain(result: CosXmlResult, token: CosToken) {
try {
if (result.accessUrl.isNullOrEmpty()) {
return
}
if (token.customDomain.isNullOrEmpty()) {
return
}
val newUri = Uri.parse(token.customDomain)
result.accessUrl = Uri.parse(result.accessUrl).buildUpon().scheme(newUri.scheme)
.authority(newUri.authority).build().toString()
} catch (e: Exception) {
e.printStackTrace()
}
}
/**
* 上传文件
* @param outName 远端文件名
*/
private fun uploadFile(
context: Context,
file: File,
outName: String,
token: CosToken
): COSXMLUploadTask {
val cosXmlService = getCosXmlClient(context, token)
// 初始化 TransferConfig这里使用默认配置如果需要定制请参考 SDK 接口文档
val transferConfig = TransferConfig.Builder().build()
// 初始化 TransferManager
val transferManager = TransferManager(
cosXmlService,
transferConfig
)
return transferManager.upload(
token.bucket, outName,
file.absolutePath, null
)
}
}

View File

@@ -0,0 +1,20 @@
package com.yizhuan.xchat_android_core.file.cos
import com.tencent.qcloud.core.auth.BasicLifecycleCredentialProvider
import com.tencent.qcloud.core.auth.QCloudLifecycleCredentials
/**
* Created by Max on 2024/1/16 11:28
* Desc:
**/
class CosCredentialProvider(private var credentials: QCloudLifecycleCredentials) :
BasicLifecycleCredentialProvider() {
fun updateCredentials(credentials: QCloudLifecycleCredentials) {
this.credentials = credentials
}
override fun fetchNewCredentials(): QCloudLifecycleCredentials {
return credentials
}
}

View File

@@ -0,0 +1,21 @@
package com.yizhuan.xchat_android_core.file.cos
import com.tencent.cos.xml.exception.CosXmlClientException
import com.tencent.cos.xml.exception.CosXmlServiceException
/**
* Created by Max on 2024/1/16 15:49
* Desc:
**/
class CosException : Exception {
var clientException: CosXmlClientException? = null
var serviceException: CosXmlServiceException? = null
constructor(
clientException: CosXmlClientException?,
serviceException: CosXmlServiceException?
) : super(clientException ?: serviceException) {
this.clientException = clientException
this.serviceException = serviceException
}
}

View File

@@ -0,0 +1,44 @@
package com.yizhuan.xchat_android_core.file.cos
import com.tencent.qcloud.core.auth.QCloudLifecycleCredentials
import com.tencent.qcloud.core.auth.SessionQCloudCredentials
import com.yizhuan.xchat_android_core.utils.CurrentTimeUtils
/**
* Created by Max on 2024/1/16 11:44
* Desc:
**/
data class CosToken(
val secretId: String?,
val secretKey: String?,
val sessionToken: String?,
val bucket: String?,
val region: String?,
val startTime: Long?,
val expireTime: Long?,
val customDomain: String?
) {
/**
* 是否有效
*/
fun isValid(): Boolean {
if (expireTime == null) {
return false
}
val currentTime = CurrentTimeUtils.getCurrentTime() / 1000
// 预留一点安全时长
var safeTime = 30
if (safeTime >= (expireTime - (startTime ?: 0))) {
safeTime = 0
}
return currentTime <= (expireTime - safeTime)
}
fun toCredential(): QCloudLifecycleCredentials {
return SessionQCloudCredentials(
secretId ?: "", secretKey ?: "",
sessionToken ?: "", startTime ?: 0, expireTime ?: 0
)
}
}

View File

@@ -45,6 +45,7 @@ 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.pay.PayModel;
import com.yizhuan.xchat_android_core.pay.event.UpdateWalletInfoEvent;
import com.yizhuan.xchat_android_core.room.bean.RoomInfo;
import com.yizhuan.xchat_android_core.room.giftvalue.bean.GiftValueCommonUpdate;
import com.yizhuan.xchat_android_core.room.giftvalue.helper.GiftValueMrg;
@@ -96,7 +97,13 @@ public class GiftModel extends BaseModel implements IGiftModel {
api = RxNet.create(Api.class);
giftQueue = new ArrayList<>();
handler = new UiHandler(this);
loadGiftInfoList(null).subscribe();
}
@Override
public void tryLoadGiftList() {
if (AuthModel.get().isLogin()) {
loadGiftInfoList(null).subscribe();
}
}
public static IGiftModel get() {
@@ -196,7 +203,7 @@ public class GiftModel extends BaseModel implements IGiftModel {
giftInfos = allGiftListInfo.getNormalGift();
break;
case GiftType.GIFT_TYPE_LUCKY:
giftInfos = allGiftListInfo.getLuckyBagGift();
giftInfos = allGiftListInfo.getLuckyGift();
break;
case GiftType.GIFT_TYPE_VIP:
giftInfos = allGiftListInfo.getVipGift();
@@ -382,7 +389,12 @@ public class GiftModel extends BaseModel implements IGiftModel {
//应通过id去确定要需要更新的礼物背包
EventBus.getDefault().post(new UpdateKnapEvent(giftId, finalGiftNum * targetUids.size()));
} else {
PayModel.get().minusGold(giftInfo.getGoldPrice() * finalGiftNum * targetUids.size());
if (serviceResult.getData() != null && serviceResult.getData().getUserPurse() != null) {
PayModel.get().setWalletInfo(serviceResult.getData().getUserPurse());
EventBus.getDefault().post(new UpdateWalletInfoEvent());
} else {
PayModel.get().refreshWalletInfo(true);
}
}
GiftMultiReceiverInfo giftMultiReceiverInfo = serviceResult.getData();
if (giftId != giftMultiReceiverInfo.getGiftId()) {
@@ -573,7 +585,7 @@ public class GiftModel extends BaseModel implements IGiftModel {
giftInfo = findGiftInfoById(allGiftListInfo.getVipGift(), giftId);
}
if (giftInfo == null) {
giftInfo = findGiftInfoById(allGiftListInfo.getLuckyBagGift(), giftId);
giftInfo = findGiftInfoById(allGiftListInfo.getLuckyGift(), giftId);
}
if (giftInfo == null) {
giftInfo = findGiftInfoById(allGiftListInfo.getLuckyPoolGift(), giftId);
@@ -724,7 +736,7 @@ public class GiftModel extends BaseModel implements IGiftModel {
*
* @return -
*/
@GET("/gift/listV4")
@GET("/gift/listV5")
Single<ServiceResult<GiftListInfo>> requestGiftInfos(@Query("roomUid") String roomUid);
/**
@@ -745,7 +757,7 @@ public class GiftModel extends BaseModel implements IGiftModel {
* @param giftSource 礼物来源1:普通2:背包3:师徒
* @return
*/
@POST("/gift/sendV4")
@POST("/gift/sendV5")
@FormUrlEncoded
Single<ServiceResult<GiftMultiReceiverInfo>> sendGift(
@Field("uid") long uid,

View File

@@ -15,6 +15,7 @@ import java.util.List;
import io.reactivex.Single;
public interface IGiftModel {
void tryLoadGiftList();
/**
* 加载普通礼物,不带上房间专属的礼物

View File

@@ -96,6 +96,10 @@ public class GiftInfo implements Serializable {
private boolean drawGift;
private String bannerUrl;
private String skipUrl;
//免费礼物倒计时进度
private long mFreeGiftProgress = 0;

View File

@@ -11,7 +11,7 @@ import lombok.Data;
*/
@Data
public class GiftListInfo implements Serializable {
private List<GiftInfo> luckyBagGift;
private List<GiftInfo> luckyGift;
private List<GiftInfo> vipGift;
private List<GiftInfo> normalGift;
private List<GiftInfo> luckyPoolGift;

View File

@@ -1,5 +1,6 @@
package com.yizhuan.xchat_android_core.gift.bean;
import com.yizhuan.xchat_android_core.pay.bean.WalletInfo;
import com.yizhuan.xchat_android_core.room.giftvalue.bean.IndexGiftValue;
import java.io.Serializable;
@@ -26,4 +27,5 @@ public class GiftMultiReceiverInfo implements Serializable {
private List<LuckyBagGifts> luckyBagGifts;
private List<Long> targetUids;
private LuckyGiftList luckyGiftList;
private WalletInfo userPurse;
}

View File

@@ -41,4 +41,9 @@ public class GiftType {
public static final int GIFT_TYPE_SINGLE_ROOM = 11;
/**
* 超级幸运礼物
*/
public static final int GIFT_TYPE_SUPER_LUCKY = 16;
}

View File

@@ -17,6 +17,7 @@ import com.yizhuan.xchat_android_core.gift.bean.GiftInfo;
import com.yizhuan.xchat_android_core.gift.bean.GiftMultiReceiverInfo;
import com.yizhuan.xchat_android_core.gift.bean.GiftReceiveInfo;
import com.yizhuan.xchat_android_core.gift.bean.GiftReceiver;
import com.yizhuan.xchat_android_core.gift.bean.GiftType;
import com.yizhuan.xchat_android_core.gift.bean.LuckyBagGifts;
import com.yizhuan.xchat_android_core.gift.bean.MultiGiftReceiveInfo;
import com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment;
@@ -208,12 +209,15 @@ public class GiftToolbox {
LogUtil.print("single send gift");
int giftType = giftInfo.getGiftType();
ImRetryManager.sendRoomGiftMsg(message)
.doOnSuccess(retryChatRoomMessage -> {
// 发送礼物成功的回调,显示动画
GiftModel.get().onSendRoomMessageSuccess(message);
// 插入到公屏上
IMNetEaseManager.get().addMessagesImmediately(message);
if (giftType != GiftType.GIFT_TYPE_SUPER_LUCKY) {
// 插入到公屏上
IMNetEaseManager.get().addMessagesImmediately(message);
}
})
.subscribe();
@@ -277,13 +281,15 @@ public class GiftToolbox {
);
LogUtil.print("multi send gift");
int giftType = giftInfo.getGiftType();
ImRetryManager.sendRoomGiftMsg(message)
.doOnSuccess(retryChatRoomMessage -> {
// 发送礼物成功的回调,显示动画
GiftModel.get().onSendRoomMessageSuccess(message);
// 插入到公屏上
IMNetEaseManager.get().addMessagesImmediately(message);
if (giftType != GiftType.GIFT_TYPE_SUPER_LUCKY) {
// 插入到公屏上
IMNetEaseManager.get().addMessagesImmediately(message);
}
})
.subscribe();
@@ -314,13 +320,15 @@ public class GiftToolbox {
);
LogUtil.print("all mic send gift");
int giftType = giftInfo.getGiftType();
ImRetryManager.sendRoomGiftMsg(message)
.doOnSuccess(retryChatRoomMessage -> {
// 发送礼物成功的回调,显示动画
GiftModel.get().onSendRoomMessageSuccess(message);
// 插入到公屏上
IMNetEaseManager.get().addMessagesImmediately(message);
if (giftType != GiftType.GIFT_TYPE_SUPER_LUCKY) {
// 插入到公屏上
IMNetEaseManager.get().addMessagesImmediately(message);
}
})
.subscribe();
}

View File

@@ -77,6 +77,9 @@ import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUS
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_TYPE_SEND_LUCKY_MONEY;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_TYPE_SEND_MULTI_MAGIC;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_TYPE_SEND_SINGLE_MAGIC;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY_ALL;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_TEMPLATE_NOTIFY_ROOM;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_UPDATE_ROOM_INFO;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_UPDATE_ROOM_INFO_AUDIO;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_UPDATE_ROOM_INFO_CLEAN_SCREEN;
@@ -668,6 +671,11 @@ public class CustomAttachParser implements MsgAttachmentParser {
attachment = new TemplateMessageAttachment(first, second);
}
break;
case CustomAttachment.CUSTOM_MSG_SUPER_LUCKY_GIFT_TEMPLATE:
if (second == CustomAttachment.CUSTOM_MSG_SUPER_LUCKY_GIFT_TEMPLATE_SUB){
attachment = new TemplateMessageAttachment(first, second);
}
break;
case CUSTOM_MSG_CRAZY_ZOO:
switch (second) {
case CUSTOM_MSG_CRAZY_ZOO_SUB_ROOM:
@@ -676,6 +684,14 @@ public class CustomAttachParser implements MsgAttachmentParser {
break;
}
break;
case CUSTOM_MSG_TEMPLATE_NOTIFY:
switch (second) {
case CUSTOM_MSG_TEMPLATE_NOTIFY_ROOM:
case CUSTOM_MSG_TEMPLATE_NOTIFY_ALL:
attachment = new RoomTemplateNotifyAttachment(first, second);
break;
}
break;
default:
LogUtils.e(ResUtil.getString(R.string.custom_bean_customattachparser_01) + first + " second=" + second);
break;

View File

@@ -485,7 +485,7 @@ public class CustomAttachment implements MsgAttachment {
public static final int CUSTOM_MSG_ROOM_ALBUM = 101;
public static final int CUSTOM_MSG_ROOM_ALBUM_SUB = 1011;
// 模版消息
// 通用模版公屏
public static final int CUSTOM_MSG_ROOM_TEMPLATE = 103;
public static final int CUSTOM_MSG_ROOM_TEMPLATE_SUB_ROOM = 1031;
public static final int CUSTOM_MSG_ROOM_TEMPLATE_SUB_ALL_ROOM = 1032;
@@ -495,6 +495,15 @@ public class CustomAttachment implements MsgAttachment {
public static final int CUSTOM_MSG_CRAZY_ZOO_SUB_ROOM = 1041;// 动物园房间飘屏通知
public static final int CUSTOM_MSG_CRAZY_ZOO_SUB_ALL_ROOM = 1042;// 动物园全服飘屏通知
// 通用模版飘屏
public static final int CUSTOM_MSG_TEMPLATE_NOTIFY = 107;
public static final int CUSTOM_MSG_TEMPLATE_NOTIFY_ROOM = 1071;// 通用模版飘屏-房间
public static final int CUSTOM_MSG_TEMPLATE_NOTIFY_ALL = 1072;// 通用模版飘屏-全服
// 超级幸运礼物-通用模版公屏
public static final int CUSTOM_MSG_SUPER_LUCKY_GIFT_TEMPLATE = 106;
public static final int CUSTOM_MSG_SUPER_LUCKY_GIFT_TEMPLATE_SUB = 1061;
/**
* 自定义消息附件的类型,根据该字段区分不同的自定义消息
*/

View File

@@ -17,4 +17,5 @@ public class PlayEffectInfo {
private TarotMsgBean tarotMsgBean;
private NotifyH5Info notifyH5;
private RoomTemplateNotifyMsgBean templateNotifyMsgBean;
}

View File

@@ -0,0 +1,35 @@
package com.yizhuan.xchat_android_core.im.custom.bean
import com.alibaba.fastjson.JSONObject
import com.google.gson.Gson
/**
* Created by Max on 2024/3/18 10:14
* Desc:通用模版飘窗
**/
class RoomTemplateNotifyAttachment : CustomAttachment {
var msgBean: RoomTemplateNotifyMsgBean? = null
constructor() : super()
constructor(first: Int, second: Int) : super(first, second)
public override fun parseData(data: JSONObject?) {
super.parseData(data)
try {
msgBean = Gson().fromJson<RoomTemplateNotifyMsgBean>(
data!!.toJSONString(),
RoomTemplateNotifyMsgBean::class.java
)
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun packData(): JSONObject? {
val jsonStr = Gson().toJson(msgBean)
return JSONObject.parseObject(jsonStr)
}
fun getTemplateMsg() = msgBean
}

View File

@@ -0,0 +1,31 @@
package com.yizhuan.xchat_android_core.im.custom.bean
/**
* Created by Max on 2024/3/15 18:55
* Desc:通用模版飘窗
**/
class RoomTemplateNotifyMsgBean : TemplateMessage() {
var fontSize: Int? = null
// IMAGE、SVGA
var resourceType: String? = null
var resourceContent: String? = null
var skipType: Int? = null
var skipContent: String? = null
var resourceWidth: Int? = null
var resourceHeight: Int? = null
// SVGA-文本的坑位KEY
private var svgaTextKey: String? = null
fun getSvgaTextKey(): String {
return svgaTextKey ?: "noble_text_tx"
}
fun getDimensionRatio(): String? {
if (resourceWidth != null && resourceHeight != null) {
return "$resourceWidth:$resourceHeight"
}
return null
}
}

View File

@@ -10,11 +10,11 @@ import java.util.regex.Pattern
* Created by Max on 2024/2/22 18:51
* Desc:
**/
data class TemplateMessage(
var template: I18N? = null,
var textColor: String? = null,
val contents: List<Content>? = null
) : Serializable {
open class TemplateMessage : Serializable {
var template: I18N? = null
var textColor: String? = null
var contents: List<Content>? = null
private val nodeList: List<TemplateNode>? = null
@@ -73,29 +73,29 @@ data class TemplateMessage(
return list
}
data class Content(
/**
* 公共字段
*/
val key: String? = null,
// TEXT,IMAGE
val type: String? = null,
val skipType: Int? = null,
val skipContent: String? = null,
class Content : Serializable, IRouterData {
/**
* 公共字段
*/
val key: String? = null
/**
* 文本相关字段(type=TEXT)
*/
val text: I18N? = null,
var textColor: String? = null,
// TEXT,IMAGE
val type: String? = null
val skipType: Int? = null
val skipContent: String? = null
/**
* 图片相关字段(type=IMAGE)
*/
val image: String? = null,
val width: Int? = null,
val height: Int? = null
) : Serializable, IRouterData {
/**
* 文本相关字段(type=TEXT)
*/
val text: I18N? = null
var textColor: String? = null
/**
* 图片相关字段(type=IMAGE)
*/
val image: String? = null
val width: Int? = null
val height: Int? = null
override fun getSkipType(): Int {
return skipType ?: 0

View File

@@ -269,6 +269,9 @@ public class RoomEvent {
//疯狂动物园 - 全服房间飘窗通知
public static final int CRAZY_ZOO_ALL_ROOM_NOTIFY = 111;
//通用模版飘屏
public static final int TEMPLATE_NOTIFY = 112;
private int event = NONE;
private int micPosition = Integer.MIN_VALUE;
private int posState = -1;

View File

@@ -7,6 +7,7 @@ import com.yizhuan.xchat_android_core.base.IModel;
import com.yizhuan.xchat_android_core.bean.response.ServiceResult;
import com.yizhuan.xchat_android_core.bean.response.result.ChargeListResult;
import com.yizhuan.xchat_android_core.pay.bean.Banner;
import com.yizhuan.xchat_android_core.pay.bean.ChargeBean;
import com.yizhuan.xchat_android_core.pay.bean.ChargeChannelInfo;
import com.yizhuan.xchat_android_core.pay.bean.FirstChargeGoods;
import com.yizhuan.xchat_android_core.pay.bean.NewUserChargeInfo;
@@ -22,6 +23,8 @@ import io.reactivex.Single;
*/
public interface IPayModel extends IModel {
void refreshWalletInfo(boolean isNotice);
WalletInfo getCurrentWalletInfo();
void minusGold(float price);
@@ -45,6 +48,8 @@ public interface IPayModel extends IModel {
Single<ChargeListResult> getChargeList(int channelType, long uid);
Single<List<ChargeBean>> getVipList();
//发起充值u
Single<JsonObject> requestCharge(Context context, String chargeProdId, String payChannel);

View File

@@ -17,6 +17,7 @@ import com.yizhuan.xchat_android_core.manager.IMNetEaseManager;
import com.yizhuan.xchat_android_core.manager.RoomEvent;
import com.yizhuan.xchat_android_core.pay.bean.Banner;
import com.yizhuan.xchat_android_core.pay.bean.ChargeBannerInfo;
import com.yizhuan.xchat_android_core.pay.bean.ChargeBean;
import com.yizhuan.xchat_android_core.pay.bean.ChargeChannelInfo;
import com.yizhuan.xchat_android_core.pay.bean.FirstChargeGoods;
import com.yizhuan.xchat_android_core.pay.bean.NewUserChargeInfo;
@@ -89,6 +90,15 @@ public class PayModel extends BaseModel implements IPayModel {
EventBus.getDefault().register(this);
}
@Override
public void refreshWalletInfo(boolean isNotice) {
getMyRemoteWalletInfo().subscribe(info -> {
if (isNotice) {
EventBus.getDefault().post(new UpdateWalletInfoEvent());
}
});
}
@Override
public WalletInfo getCurrentWalletInfo() {
return walletInfo;
@@ -137,6 +147,9 @@ public class PayModel extends BaseModel implements IPayModel {
walletInfo.setCrystals(jsonObject.getDoubleValue("crystals"));
walletInfo.nobleGoldNum = jsonObject.getDoubleValue("nobleGoldNum");
walletInfo.chargeGoldNum = jsonObject.getDoubleValue("chargeGoldNum");
if (jsonObject.containsKey("canGoldSendGift")) {
walletInfo.canGoldSendGift = jsonObject.getBoolean("canGoldSendGift");
}
this.walletInfo = walletInfo;
// 兼容新版
setWalletInfo(walletInfo);
@@ -196,6 +209,12 @@ public class PayModel extends BaseModel implements IPayModel {
.compose(RxHelper.handleSchedulers());
}
@Override
public Single<List<ChargeBean>> getVipList() {
return api.getVipList("2")
.compose(RxHelper.handleBeanData())
.compose(RxHelper.handleSchedulers());
}
@Override
public Single<JsonObject> requestCharge(Context context, String chargeProdId, String payChannel) {
@@ -536,6 +555,15 @@ public class PayModel extends BaseModel implements IPayModel {
@Query("pub_uid") long pub_uid);
/**
* 获取VIP档位列表
*
* @param channelType
* @return
*/
@GET("/chargeprod/getVipList")
Single<ServiceResult<List<ChargeBean>>> getVipList(@Query("type") String channelType);
/**
* 发起充值
*

View File

@@ -39,6 +39,11 @@ public class WalletInfo implements Parcelable {
/** 1默认line2默认facebook */
private int defaultPay;
/**
* 是否可以在送礼时合并使用金币
*/
public boolean canGoldSendGift;
public WalletInfo() {
}
@@ -53,6 +58,7 @@ public class WalletInfo implements Parcelable {
nobleGoldNum = in.readDouble();
canGiveGoldNum = in.readDouble();
defaultPay = in.readInt();
canGoldSendGift = (in.readInt() == 1);
}
@Override
@@ -66,6 +72,7 @@ public class WalletInfo implements Parcelable {
dest.writeDouble(nobleGoldNum);
dest.writeDouble(canGiveGoldNum);
dest.writeInt(defaultPay);
dest.writeInt(canGoldSendGift ? 1 : 0);
}
@Override

View File

@@ -21,6 +21,7 @@ import com.yizhuan.xchat_android_core.gift.bean.GiftList;
import com.yizhuan.xchat_android_core.gift.bean.GiftMultiReceiverInfo;
import com.yizhuan.xchat_android_core.gift.bean.GiftReceiveInfo;
import com.yizhuan.xchat_android_core.gift.bean.GiftReceiver;
import com.yizhuan.xchat_android_core.gift.bean.GiftType;
import com.yizhuan.xchat_android_core.gift.bean.LuckyBagGifts;
import com.yizhuan.xchat_android_core.gift.bean.MultiGiftReceiveInfo;
import com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment;
@@ -129,6 +130,10 @@ public class PkModel extends BaseModel implements IPkModel {
//钻石礼物才算分数
return;
}
if (giftReceiveInfo.getGift() != null && giftReceiveInfo.getGift().getGiftType() == GiftType.GIFT_TYPE_SUPER_LUCKY) {
// 超级幸运礼物不算分数
return;
}
teamId = getTeamIdInPKMemberList(String.valueOf(giftReceiveInfo.getTargetUid()));
if (teamId != 0) {
if (curPkInfo.getVoteMode() == PK_VOTE_MODE_GIFT_VALUE) {
@@ -145,6 +150,10 @@ public class PkModel extends BaseModel implements IPkModel {
//钻石礼物才算分数
return;
}
if (giftMultiReceiverInfo.getGift() != null && giftMultiReceiverInfo.getGift().getGiftType() == GiftType.GIFT_TYPE_SUPER_LUCKY) {
// 超级幸运礼物不算分数
return;
}
for (GiftReceiver giftReceiver : giftMultiReceiverInfo.getTargetUsers()) {
teamId = getTeamIdInPKMemberList(String.valueOf(giftReceiver.getUid()));
if (teamId != 0) {
@@ -163,6 +172,10 @@ public class PkModel extends BaseModel implements IPkModel {
//钻石礼物才算分数
return;
}
if (multiReceiverInfo.getGift() != null && multiReceiverInfo.getGift().getGiftType() == GiftType.GIFT_TYPE_SUPER_LUCKY) {
// 超级幸运礼物不算分数
return;
}
for (Long targetUid : multiReceiverInfo.getTargetUids()) {
teamId = getTeamIdInPKMemberList(String.valueOf(targetUid));
if (teamId != 0) {

View File

@@ -20,8 +20,13 @@ data class VipInfo(
var remainSeconds: Int = 0,
var currLevel: Int = 0,
var currScore: Int = 0,
var nextVipName: String? = null
var nextVipName: String? = null,
val isReturnProfit: Int? = null,
val returnProfits: List<VipRebateInfo>? = null
) : Serializable {
fun isRebate() = isReturnProfit == 1
override fun equals(other: Any?): Boolean {
return other is VipInfo && other.vipLevel == vipLevel
}

View File

@@ -36,9 +36,16 @@ object VipModel : BaseModel() {
api.changeInvisibleInRoom(open)
}
suspend fun openVipWithDiamond(): Any? =
suspend fun openVipWithDiamond(vipLevel: Int): Any? =
launchRequest {
api.openVipWithDiamond(if (AvRoomDataManager.get().roomUid == 0L) null else AvRoomDataManager.get().roomUid)
api.openVipWithDiamond(if (AvRoomDataManager.get().roomUid == 0L) null else AvRoomDataManager.get().roomUid,
vipLevel
)
}
suspend fun getVipRebate(id: Long): Any? =
launchRequest {
api.getVipRebate(id)
}
private interface Api {
@@ -94,8 +101,18 @@ object VipModel : BaseModel() {
*/
@FormUrlEncoded
@POST("/vip/openWithDiamond")
suspend fun openVipWithDiamond(@Field("roomUid") roomUid: Long?): ServiceResult<Any>
suspend fun openVipWithDiamond(@Field("roomUid") roomUid: Long?,
@Field("vipLevel") vipLevel: Int
): ServiceResult<Any>
/**
* 领取返利
*
* @return
*/
@FormUrlEncoded
@POST("/vip/returnProfit/receive")
suspend fun getVipRebate(@Field("returnProfitRecordId") returnProfitRecordId: Long?): ServiceResult<Any>
}
}

Some files were not shown because too many files have changed in this diff Show More