Compare commits

..

139 Commits

Author SHA1 Message Date
wzq
ad5a769f25 清除 Google 内购代码 2023-10-19 18:02:03 +08:00
wzq
be291fa7e1 升级 Google 内购库 2023-10-19 17:22:58 +08:00
wzq
27713e5300 混淆 bean 2023-10-19 15:00:22 +08:00
wzq
80e180f2b8 debug 混淆配置; 升级eventbus 2023-10-19 14:46:11 +08:00
wzq
ba93c9c0fe eventbus 混淆规则更新 2023-10-19 14:26:44 +08:00
wzq
6f9d1d81ad 房间相册 UI问题 2023-10-19 12:02:18 +08:00
wzq
81d0cd819d 房间相册-公屏 修复崩溃及图片不显示 2023-10-19 10:19:51 +08:00
wzq
36897df28b 房间相册-上传 多张图片上传时去除参数中的空格 2023-10-19 10:05:02 +08:00
wzq
6bdfe0426e 房间相册-上传 删除已选照片后, 重新显示 添加按钮 2023-10-18 18:58:21 +08:00
wzq
997b7ee9a3 [Build] debug 打包配置混淆 打印信息 2023-10-18 18:08:37 +08:00
wzq
b885a24b8e [Build] debug 打包配置混淆 2023-10-18 17:40:25 +08:00
wzq
5d2551e04f 房间相册 修复 神奇的手机无法点击图标关闭解锁弹窗 2023-10-18 17:19:11 +08:00
wzq
309e696a07 房间相册 上传图片前 压缩图片 2023-10-18 16:43:56 +08:00
wzq
68c9c6a8cb 房间相册 照片列表分页问题 2023-10-18 16:30:01 +08:00
wzq
448e6800ab 房间相册 公屏消息 UI显示问题 2023-10-18 15:36:49 +08:00
wzq
068ffcbed4 房间相册 公屏消息 解锁区域放大至整个消息区域 2023-10-18 15:08:03 +08:00
wzq
cf7b49b69d 房间相册 UI问题 2023-10-18 14:37:14 +08:00
wzq
09fd7c586a 房间相册 数据展示及交互 2023-10-18 14:35:53 +08:00
wzq
03b77fae08 房间相册 查看大图 2023-10-18 14:23:06 +08:00
wzq
b75ba89d75 房间相册 公屏消息 解锁 2023-10-18 13:14:49 +08:00
wzq
2074039de2 房间相册 解锁 2023-10-17 20:57:02 +08:00
wzq
6b580ad2a6 房间相册 删除图片 2023-10-17 20:05:47 +08:00
wzq
6134962297 房间相册 发送图片至公屏 2023-10-17 19:12:42 +08:00
wzq
ce5cc20ac4 房间相册 列表,上传 数据对接 2023-10-17 18:16:41 +08:00
wzq
bc718f26c6 房间相册 入口 2023-10-17 16:32:42 +08:00
wzq
8f9a5bd565 房间相册 公屏消息UI 2023-10-17 14:08:23 +08:00
wzq
623a721e58 房间相册 选择解锁礼物UI 交互 2023-10-17 10:10:42 +08:00
wzq
a9be418fc3 房间相册 选择解锁礼物UI 2023-10-16 22:39:13 +08:00
wzq
5b781b890c 房间相册 上传照片UI 2023-10-16 20:04:09 +08:00
wzq
4a6892d0c6 房间相册UI 2023-10-13 19:37:38 +08:00
wzq
a6e6992b1a 修复 首页房间item 周榜框 显示重叠 2023-10-13 11:36:38 +08:00
wzq
248e306e85 修复 房间 "精灵夺宝" 抽奖 一直转圈的问题 2023-10-12 19:10:15 +08:00
wzq
bce08e82ca 引入 okdownload 下载库 下载表情. 避免网络请求卡死 2023-10-12 18:39:30 +08:00
wzq
32814780c2 房间 "夺宝精灵" 购买碎片 成功弹窗显示问题 2023-10-12 18:30:04 +08:00
wzq
d0dc4cab49 房间 "夺宝精灵" 精灵兑换 底部显示我拥有的精灵 2023-10-12 17:25:49 +08:00
wzq
80d571d1d1 房间 "夺宝精灵" 精灵分解. 根据不同等级的精灵, 显示不同的提示文案 2023-10-12 16:36:36 +08:00
wzq
b92c97dfb9 房间 "夺宝精灵" 自定义购买弹窗 支持输入数量 2023-10-12 16:01:23 +08:00
wzq
e585899c44 房间 "夺宝精灵" 兑换商店-碎片兑换 图标不正确 2023-10-12 15:15:56 +08:00
wzq
03f28b7be0 房间 "夺宝精灵" 兑换商店-精灵兑换 UI适配 2023-10-12 15:04:07 +08:00
wzq
c7225892f0 房间 公屏输入框 回车键 发送信息 2023-10-12 12:00:55 +08:00
wzq
f8d4601c38 适配 声网 音量回调 2023-10-12 11:51:49 +08:00
wzq
ce4fce319e 房间 "夺宝精灵" 精灵试炼 动画文件更换 2023-10-11 18:34:35 +08:00
wzq
ce4293ec35 房间 "夺宝精灵" 精灵分解 更新碎片 2023-10-11 17:59:09 +08:00
wzq
1c9de5f03a 房间 "夺宝精灵" 兑换记录 移除类型显示 2023-10-11 17:57:48 +08:00
wzq
2734ff1ff2 房间 "夺宝精灵" 精灵试炼记录 区分类型 2023-10-11 17:49:48 +08:00
wzq
c7a28c5ac9 房间 "夺宝精灵" 精灵分解 提示文案 2023-10-11 16:30:06 +08:00
wzq
ae4d327baf 房间 "夺宝精灵" 精灵试炼 传说试炼 底部精灵展示为普通精灵 2023-10-11 16:02:49 +08:00
wzq
9e9eb5d5b7 修复 房间 "夺宝精灵" 召唤精灵 价格不显示 2023-10-11 15:20:10 +08:00
wzq
96b1ad9e4c 修复 房间 "夺宝精灵" 幸运值进度条不正确 2023-10-11 11:56:46 +08:00
wzq
48c527e789 修复 房间 "夺宝精灵" 幸运值无法刷新 2023-10-11 11:38:58 +08:00
wzq
4e0a55ae46 修复 房间 "夺宝精灵" 购买弹窗bug 2023-10-11 10:53:58 +08:00
wzq
c85065d86c 房间 "夺宝精灵" 新增 自定义购买数量碎片弹窗 2023-10-10 17:54:47 +08:00
wzq
c1371fab10 房间寻爱活动 购买限制数量200调整至99999 2023-10-10 17:03:11 +08:00
wzq
6717f9aa69 房间 送礼接口 失败后 显示toast 2023-10-09 16:09:16 +08:00
wzq
61cafd8c8c okhttp 网络配置 2023-10-09 14:21:36 +08:00
wzq
e4f0853d3e 升级 Facebook SDK 2023-10-09 11:48:53 +08:00
wzq
46a2985a49 首页 滑动折叠效果 2023-10-08 18:15:17 +08:00
wzq
b2f9f07ded 首页 UI问题 2023-10-08 17:41:27 +08:00
wzq
5023d9a250 测试包 关于页面 点击logo 可切换 正式/测试环境 2023-10-08 17:40:55 +08:00
wzq
29957775e0 Fixed NPE. 2023-10-07 16:36:52 +08:00
wzq
5f73c46868 升级 realm 数据库 2023-10-07 16:09:55 +08:00
wzq
656eea5ebc fixed NPE. 2023-10-07 15:36:05 +08:00
wzq
f9b8c20d85 优化打包, 使用 splits abi 对每种CPU架构打独立的apk; 腾讯TRTC SDK优化集成方式, 并优化参数 2023-10-07 15:01:09 +08:00
wzq
2d7b55ad0d 修复 星座 计算不正确 2023-10-07 15:00:30 +08:00
wzq
91350218d6 首页UI 适配 2023-10-07 15:00:30 +08:00
wzq
ca56ee0877 修复 寻爱 票据数量问题 2023-09-27 23:32:16 +08:00
wzq
23214de384 修复 寻爱 票据数量问题 2023-09-27 22:46:57 +08:00
wzq
da45a64af9 fixed "default constructor not found." 2023-09-27 22:14:43 +08:00
wzq
e236ef2aff fixed "default constructor not found." 2023-09-27 22:08:41 +08:00
wzq
7de533bf3f 混淆问题 2023-09-27 21:33:21 +08:00
wzq
e23363c736 混淆问题 2023-09-27 21:30:55 +08:00
wzq
4395951973 首页 跟随进房; UI问题 2023-09-27 20:52:51 +08:00
wzq
e02020577d 首页 ViewPager2 滑动冲突 2023-09-27 20:31:55 +08:00
wzq
61306e833a 充值页 UI适配 2023-09-27 20:04:31 +08:00
wzq
49ba0a2701 房间 关闭PK模式 不主动关麦 2023-09-27 19:55:26 +08:00
wzq
2e32184248 房间 寻爱 动态飘屏 进退场动画 2023-09-27 18:57:16 +08:00
wzq
bab64db25c 房间 合并 寻爱 动态/静态 飘屏 队列 2023-09-27 18:43:28 +08:00
wzq
612502153c 房间 PK模式 默认不闭麦 2023-09-27 18:01:00 +08:00
wzq
9cdb0eef53 性别图标 更换成 性别+年龄 2023-09-27 16:00:32 +08:00
wzq
6528ac407a 个人资料页 UI调整 2023-09-27 14:17:58 +08:00
wzq
94d18e6035 礼物面板 item 礼物标签 右对齐 2023-09-27 12:07:27 +08:00
wzq
08abf47890 调整 房间小游戏安全区域 2023-09-27 12:02:24 +08:00
wzq
cb89eccf23 显示 消息页 "发现萌新" 入口, 房间PK入口 2023-09-27 11:26:08 +08:00
wzq
b57622ad42 显示 消息页 "发现萌新" 入口, 房间PK入口 2023-09-27 10:35:41 +08:00
wzq
fd71af897f 修复 塔罗高级 未添加公屏通知 2023-09-26 19:34:40 +08:00
wzq
1998258bda 塔罗活动静态飘屏 只在本房间触发 2023-09-26 19:03:07 +08:00
wzq
5cce2cb68c 首页tab item 新增声音卡 2023-09-26 18:20:00 +08:00
wzq
08230c55a3 首页 UI字体调节 2023-09-26 14:38:07 +08:00
wzq
f51dec1101 Merge branch '1.10.6' into develop
# Conflicts:
#	core/src/diff_src_erban/java/com/yizhuan/xchat_android_constants/XChatConstants.java
#	gradle.properties
2023-09-26 14:27:54 +08:00
wzq
1dd5d64a09 修复 寻爱bug 2023-09-26 11:34:05 +08:00
wzq
30d793d794 寻爱飘屏 UI优化 2023-09-25 19:54:42 +08:00
wzq
d2fb38f094 更换声网key 2023-09-25 19:38:09 +08:00
wzq
01958edd06 修复 "寻爱"活动 自定义购买爱心数量 未更新金额 2023-09-25 17:20:27 +08:00
wzq
5a2903d14d 礼物弹窗 标签优化 2023-09-25 17:12:45 +08:00
wzq
1bade9dd00 小时榜飘屏 更换背景图 2023-09-25 16:59:29 +08:00
wzq
8d7ab335e2 新增 H5 跳转 话题页 2023-09-25 16:37:48 +08:00
wzq
8bf25ad378 根据接口返回选择 跳转 原生/H5 充值页 2023-09-25 16:23:01 +08:00
wzq
6e11cfb30d 新增 充值页跳转私聊客服充值 2023-09-25 16:00:50 +08:00
wzq
0c2fd28f15 移除 网络代理 2023-09-22 19:07:04 +08:00
wzq
a2e0e9df53 升级 声网SDK 4.2.2 2023-09-22 18:03:05 +08:00
wzq
9e3ebfa541 升级 声网SDK 4.2.2 2023-09-22 17:27:04 +08:00
wzq
94a0575909 修复 "寻爱之旅"活动页面 UI 以及 余额不足未弹出充值弹窗 2023-09-22 10:20:35 +08:00
wzq
3d161b94e4 修复 "寻爱之旅"活动页面 购买数量问题 2023-09-21 17:50:21 +08:00
wzq
08d9534095 新增 首页房间item PK动画 2023-09-21 16:20:59 +08:00
wzq
ff1cd57d98 修复 首页"优质陪伴"tab UI 问题 2023-09-21 16:02:08 +08:00
wzq
2a57ad3145 增加首页顶部与状态栏之间的间距 2023-09-21 14:17:55 +08:00
wzq
92f2db36ae 修改 首页tab indicator 样式 2023-09-21 12:53:53 +08:00
wushaocheng
362c75f93c [Modify]小时榜和周榜逻辑修改 2023-09-20 18:34:30 +08:00
wzq
b9c3bbdbec 修复 首页tab切换导致SVGA停止播放 2023-09-20 17:56:55 +08:00
wushaocheng
0a24dc66e6 [Modify]更新版本号和寻爱逻辑修改 2023-09-20 17:17:50 +08:00
wushaocheng
ca62822bfb [Modify]首页和夺宝修改 2023-09-20 16:07:17 +08:00
wzq
5db5afa5ed 房间麦位魅力值UI适配 2023-09-20 16:03:45 +08:00
wzq
edad692309 修复 全服飘窗 2023-09-20 14:55:52 +08:00
wzq
23a34434a0 Merge remote-tracking branch 'origin/develop' into develop 2023-09-19 17:20:56 +08:00
wzq
8ad38583ff 新增 充值页 Banner, 个人信息页 "官方代充" 标识 2023-09-19 17:20:08 +08:00
wushaocheng
391fae9006 [Modify]安卓用户头像遮罩去掉 2023-09-19 16:02:23 +08:00
wzq
9854e91fe8 礼物弹窗 礼物标签图片 替换 2023-09-19 15:19:03 +08:00
wzq
d587f1b43d 寻爱飘屏 SVGA 文件替换 2023-09-19 15:01:18 +08:00
wzq
595d3a767a 登录页 默认勾选协议 2023-09-19 14:14:43 +08:00
wzq
4d13cf5e9c 星座 优化 2023-09-19 11:59:01 +08:00
wzq
62ce160dfa 性别图标 替换成 性别+年龄 2023-09-19 11:17:26 +08:00
wzq
c631c1d3a8 新增 H5活动通用飘屏 2023-09-18 15:32:59 +08:00
wushaocheng
27420aa51a [Modify]修改房间背景 2023-09-18 14:12:45 +08:00
wushaocheng
12c5344d72 [Modify]安卓用户头像遮罩去掉 2023-09-18 11:57:33 +08:00
wushaocheng
a716136090 [Modify]安卓13适配和谷歌充值页面加loading 2023-09-18 11:49:27 +08:00
wushaocheng
f860c96887 [Modify]安卓13适配和谷歌充值页面加loading 2023-09-18 11:49:23 +08:00
wushaocheng
873ecf1d2b [Modify]安卓13适配和谷歌充值页面加loading 2023-09-18 11:45:51 +08:00
wushaocheng
957b64476f [Modify]安卓13适配和谷歌充值页面加loading 2023-09-18 11:43:25 +08:00
wzq
306e0a99a0 [Modify]幸运塔罗新增公屏通知, 飘屏 2023-09-15 18:31:57 +08:00
wushaocheng
bfd619e8b5 [Modify]寻爱之旅完善 2023-09-15 17:44:07 +08:00
wushaocheng
4c0184c80b [Modify]寻爱之旅完善 2023-09-15 17:14:02 +08:00
wushaocheng
aeb47da0ee [Modify]首页逻辑调整 2023-09-14 15:56:38 +08:00
wushaocheng
d99ef80d2e [Modify]夺宝精灵和尋愛邏輯修改 2023-09-13 20:46:29 +08:00
wushaocheng
77dcc9d117 [Modify]夺宝精灵逻辑修改 2023-09-13 15:22:10 +08:00
wushaocheng
a7f17276c5 [Modify]夺宝精灵的精灵分解和精灵试炼功能完善 2023-09-12 18:59:35 +08:00
wushaocheng
63f1e02c6f [Modify]夺宝精灵修改 2023-09-12 10:03:24 +08:00
wushaocheng
5c6657c538 [Modify]增加fir渠道 2023-09-08 16:30:12 +08:00
wushaocheng
7548b4174a [Modify]夺宝精灵功能修改 2023-09-08 11:55:52 +08:00
wushaocheng
928857f97d [Modify]优质陪伴页面修改 2023-09-06 15:10:15 +08:00
179 changed files with 4530 additions and 852 deletions

View File

@@ -26,7 +26,7 @@ dependencies {
api 'androidx.annotation:annotation:1.4.0'
api 'androidx.legacy:legacy-support-v4:1.0.0'
implementation "androidx.core:core-ktx:1.7.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}
repositories {
mavenCentral()

View File

@@ -2,7 +2,6 @@ apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.tencent.vasdolly'
apply from: '../mob.gradle'
@@ -65,12 +64,12 @@ android {
}
}
lintOptions {
lint {
abortOnError false
disable 'MissingTranslation'
disable 'ExtraTranslation'
disable 'MissingTranslation', 'ExtraTranslation', 'ContentDescription', 'SmallSp'
}
dataBinding {
enabled = true
}
@@ -152,6 +151,8 @@ android {
def server_url_release = '"https://api.pekolive.com/"'
debug {
println("minifyEnabled = " + minify_enabled)
ext.enableCrashlytics = false
ext.alwaysUpdateBuildId = false // Firebase Crashlytics禁用更新构建ID
@@ -159,7 +160,8 @@ android {
buildConfigField "String", "BASE_URL_DEBUG", "BASE_URL"
buildConfigField "String", "BASE_URL_STAGING", "BASE_URL"
buildConfigField "String", "BASE_URL_RELEASE", server_url_release
minifyEnabled false // 是否混淆
minifyEnabled minify_enabled.toBoolean() // 是否混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
crunchPngs false // 停用 PNG 压缩
signingConfig signingConfigs.v2
gradle.taskGraph.whenReady {
@@ -213,6 +215,9 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

View File

@@ -99,16 +99,18 @@
-keep class android.support.v7.** { *;}
#----------------EventBus事件巴士-----------------
-keepclassmembers class ** {
-keepattributes *Annotation*
-keepclassmembers class * {
@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(Java.lang.Throwable);
# If using AsyncExecutord, keep required constructor of default event used.
# Adjust the class name if a custom failure event type is used.
-keepclassmembers class org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
# Accessed via reflection, avoid renaming or removal
-keep class org.greenrobot.eventbus.android.AndroidComponentsImpl
#-------------云信相关的混淆配置------------
-dontwarn com.netease.**
@@ -234,6 +236,7 @@
-dontwarn com.yizhuan.xchat_android_core.**
-keep class com.yizhuan.xchat_android_core.** {*;}
-keep class com.yizhuan.treasure_box.bean.** {*;}
-keep class com.yizhuan.erban.avroom.bean.** {*;}
#百度统计

View File

@@ -1086,6 +1086,8 @@
</intent-filter>
</activity>
<activity android:name=".avroom.room_album.RoomAlbumActivity" />
</application>
</manifest>

View File

@@ -39,7 +39,7 @@ class RoomPKBoardView @JvmOverloads constructor(
) : DragLayout(context, attrs, defStyleAttr) {
private val binding = LayoutRoomPkBoardViewBinding.inflate(LayoutInflater.from(context))
private val observer = Observer<RoomPkBean> { updateView(it) }
private val observer = Observer<RoomPkBean?> { updateView(it) }
private var disposable: Disposable? = null
private lateinit var helpPopupWindow: PopupWindow
private var roomPkBean: RoomPkBean? = null

View File

@@ -0,0 +1,14 @@
package com.yizhuan.erban.avroom.bean
data class RoomAlbumPhotoInfo(
val giftId: Int,
val giftNum: Int,
val giftUrl: String,
val id: Int,
val photoUrl: String,
val roomUid: Int,
val status: Int,
val totalGoldPrice: Int,
val type: Int,
val uid: Int
)

View File

@@ -24,6 +24,7 @@ import com.yizhuan.erban.avroom.activity.CreatePKActivity;
import com.yizhuan.erban.avroom.activity.RoomSettingActivity;
import com.yizhuan.erban.avroom.anotherroompk.RoomPKCreateActivity;
import com.yizhuan.erban.avroom.giftvalue.GiftValueDialogUiHelper;
import com.yizhuan.erban.avroom.room_album.RoomAlbumActivity;
import com.yizhuan.erban.avroom.singleroompk.SingleRoomPKCreateActivity;
import com.yizhuan.erban.common.util.Utils;
import com.yizhuan.erban.common.widget.dialog.DialogManager;
@@ -112,6 +113,7 @@ public class RoomOperationDialog extends BottomSheetDialog {
true));
rvOPtList.setLayoutManager(new FullyGridLayoutManager(getContext(), 5));
optAdapter = new OptAdapter(context, null);
addRoomAlbum(optAdapter);
addDatingAction(optAdapter);
addPKAction(optAdapter);
addRoomPKAction(optAdapter);
@@ -267,6 +269,14 @@ public class RoomOperationDialog extends BottomSheetDialog {
}
}
private void addRoomAlbum(OptAdapter optAdapter) {
if (AvRoomDataManager.get().isHasRoomAlbum()) {
optAdapter.addData(new OptAction(R.drawable.ic_room_operation_album, "房间相册", () -> {
RoomAlbumActivity.start(getContext());
}));
}
}
/**
* 相亲 模式
*
@@ -419,7 +429,7 @@ public class RoomOperationDialog extends BottomSheetDialog {
superAdminModel.roomOperate(SuperAdminModel.CLOSE_PUBLIC_SCREEN).subscribe();
}
AvRoomModel.get().closeScreen(roomInfo.getRoomId(),
!isCloseScreen)
!isCloseScreen)
.compose(RxHelper.bindContext(context))
.flatMap(data -> IMNetEaseManager.get().closeOpenScreen(
data.getRoomId(), data))
@@ -639,7 +649,7 @@ public class RoomOperationDialog extends BottomSheetDialog {
}
optAdapter.addData(new OptAction(R.drawable.icon_room_shield_report,
ResUtil.getString(R.string.me_shield_report),
() ->{
() -> {
DialogManager dialogManager = new DialogManager(context);
List<ButtonItem> buttonItems = new ArrayList<>();
ButtonItem buttonItem1 = new ButtonItem(ResUtil.getString(R.string.me_shield_room), () -> {

View File

@@ -18,8 +18,8 @@ import android.widget.TextView
import androidx.recyclerview.widget.GridLayoutManager
import com.android.billingclient.api.BillingClient
import com.android.billingclient.api.BillingResult
import com.android.billingclient.api.ProductDetails
import com.android.billingclient.api.Purchase
import com.android.billingclient.api.SkuDetails
import com.appsflyer.AFInAppEventParameterName
import com.appsflyer.AFInAppEventType
import com.appsflyer.AppsFlyerLib
@@ -123,7 +123,7 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
ResUtil.getString(R.string.avroom_firstcharge_firstchargedialog_01).toast()
} else if (channel.equals(Constants.GOOGLE)) {
goodsList?.get(position)?.let { charge ->
buyProduct(charge.skuDetails)
buyProduct(charge.productDetails)
}
} else {
CommonWebViewActivity.start(
@@ -142,18 +142,23 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
FirstChargeReward.ONE -> {
spanSize = 6
}
FirstChargeReward.TWO_LEFT -> {
spanSize = 3
}
FirstChargeReward.TWO_RIGHT -> {
spanSize = 3
}
FirstChargeReward.THREE -> {
spanSize = 2
}
FirstChargeReward.TWO_LEFT_SMALL -> {
spanSize = 3
}
FirstChargeReward.TWO_RIGHT_SMALL -> {
spanSize = 3
}
@@ -196,11 +201,13 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
binding.rbPlanC.visibility = View.GONE
binding.rbPlanA.text = "$${goodsList[0].chargeMoney}"
}
2 -> {
binding.rbPlanC.visibility = View.GONE
binding.rbPlanA.text = "$${goodsList[0].chargeMoney}"
binding.rbPlanB.text = "$${goodsList[1].chargeMoney}"
}
3 -> {
binding.rbPlanA.text = "$${goodsList[0].chargeMoney}"
binding.rbPlanB.text = "$${goodsList[1].chargeMoney}"
@@ -227,20 +234,19 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
for (bean in goodsList) {
productKeys.add(bean.chargeProdId)
}
billingManager?.querySkuDetailsAsync(
BillingClient.SkuType.INAPP, productKeys
) { billingResult: BillingResult, skuDetailsList: List<SkuDetails>? ->
billingManager?.querySkuDetailsAsync(productKeys) { billingResult: BillingResult, productDetails: MutableList<ProductDetails> ->
if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
Log.w(
TAG,
"Unsuccessful query for type: " + BillingClient.SkuType.INAPP
+ ". Error code: " + billingResult.responseCode
"Unsuccessful query for type: " + BillingClient.ProductType.INAPP + ". Error code: " + billingResult.responseCode
)
} else if (skuDetailsList != null && skuDetailsList.isNotEmpty()) {
return@querySkuDetailsAsync
}
if (productDetails.isNotEmpty()) {
for (chargeBean in goodsList) {
for (skuDetails in skuDetailsList) {
if (skuDetails.sku == chargeBean.chargeProdId) {
chargeBean.skuDetails = skuDetails
for (skuDetails in productDetails) {
if (skuDetails.productId == chargeBean.chargeProdId) {
chargeBean.productDetails = skuDetails
break
}
}
@@ -258,7 +264,7 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
) {
PayModel.get().verifyOrder(
purchase.accountIdentifiers!!.obfuscatedAccountId,
purchase.skus[0],
purchase.products[0],
purchase.packageName,
purchase.purchaseToken
)
@@ -267,12 +273,12 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
{ token: String? ->
//L.i("token=" + token);
billingManager?.consumeAsync(token)
var skuDetails: SkuDetails? = null
var skuDetails: ProductDetails? = null
val goodList = goodsList
if (goodList != null && goodList.isNotEmpty()) {
if (!goodList.isNullOrEmpty()) {
for (datum in goodList) {
if (datum.chargeProdId == purchase.skus[0]) {
skuDetails = datum.skuDetails
if (datum.chargeProdId == purchase.products[0]) {
skuDetails = datum.productDetails
break
}
}
@@ -282,12 +288,12 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
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.priceAmountMicros / 1000000f
eventValue["Price"] = skuDetails.price
skuDetails.oneTimePurchaseOfferDetails?.priceAmountMicros!! / 1000000f
eventValue["Price"] = skuDetails.oneTimePurchaseOfferDetails?.formattedPrice!!
eventValue[AFInAppEventParameterName.CURRENCY] =
skuDetails.priceCurrencyCode
skuDetails.oneTimePurchaseOfferDetails?.priceCurrencyCode!!
AppsFlyerLib.getInstance().logEvent(
applicationContext,
AFInAppEventType.PURCHASE,
@@ -315,10 +321,10 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
/*购买商品*/
@SuppressLint("CheckResult")
fun buyProduct(skuDetails: SkuDetails?) {
fun buyProduct(skuDetails: ProductDetails?) {
if (skuDetails != null) {
Log.d(TAG, "BuyProduct:" + skuDetails.sku)
PayModel.get().placeOrder(skuDetails.sku)
Log.d(TAG, "BuyProduct:" + skuDetails.productId)
PayModel.get().placeOrder(skuDetails.productId)
.compose(bindToLifecycle())
.subscribe(
{ recordId: PayRecordId ->
@@ -372,6 +378,7 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
bean.itemType = FirstChargeReward.ONE
}
}
2 -> {
for (i in firstChargeRewardList.indices) {
if (i == 0) {
@@ -381,11 +388,13 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
}
}
}
3 -> {
for (bean in firstChargeRewardList) {
bean.itemType = FirstChargeReward.THREE
}
}
4 -> {
for (i in firstChargeRewardList.indices) {
if ((i + 1) % 2 != 0) {
@@ -395,6 +404,7 @@ class FirstChargeDialog : BaseViewBindingActivity<DialogFirstChargeBinding>(),
}
}
}
else -> {
if (firstChargeRewardList.size % 3 == 0) {
for (bean in firstChargeRewardList) {

View File

@@ -11,12 +11,10 @@ import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.ViewStub
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import android.widget.ImageView
import android.widget.RelativeLayout
@@ -49,6 +47,7 @@ import com.yizhuan.erban.avroom.dialog.RoomOperationDialog
import com.yizhuan.erban.avroom.firstcharge.FirstChargeDialog
import com.yizhuan.erban.avroom.presenter.BaseRoomPresenter
import com.yizhuan.erban.avroom.redpackage.RedPackageSendDialog
import com.yizhuan.erban.avroom.room_album.RoomAlbumModel
import com.yizhuan.erban.avroom.view.IBaseRoomView
import com.yizhuan.erban.avroom.widget.BottomView
import com.yizhuan.erban.avroom.widget.MessageView
@@ -286,6 +285,16 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
//获取免费礼物详情
mvpPresenter?.queryFreeFlower()
initRoomAlbum()
}
@SuppressLint("CheckResult")
private fun initRoomAlbum() {
RoomAlbumModel.listUnlockRoomPhoto(AvRoomDataManager.get().roomUid)
.compose(bindToLifecycle())
.subscribe({
AvRoomDataManager.get().unlockedRoomAlbumPhotos = it
}, { toast(it.message) })
}
@CallSuper

View File

@@ -0,0 +1,84 @@
package com.yizhuan.erban.avroom.room_album
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.recyclerview.widget.GridLayoutManager
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.yizhuan.erban.R
import com.yizhuan.erban.databinding.DialogChooseGiftRoomAlbumBinding
import com.yizhuan.erban.ui.utils.ImageLoadUtilsV2
import com.yizhuan.erban.ui.widget.recyclerview.decoration.GridSpacingItemNewDecoration
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.GiftType
class ChooseGiftRoomAlbumDialogFragment : BottomSheetDialogFragment() {
private var _binding: DialogChooseGiftRoomAlbumBinding? = null
private val binding get() = _binding!!
var onPickedListener: OnPickedListener? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, R.style.ErbanBottomSheetDialog)
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState)
dialog.window?.attributes?.apply {
width = WindowManager.LayoutParams.MATCH_PARENT
height = WindowManager.LayoutParams.MATCH_PARENT
}
return dialog
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = DialogChooseGiftRoomAlbumBinding.inflate(layoutInflater, container, false)
binding.rvGifts.layoutManager = GridLayoutManager(context, 4)
binding.rvGifts.addItemDecoration(GridSpacingItemNewDecoration(resources.getDimensionPixelOffset(R.dimen.dp_20), true))
binding.rvGifts.adapter = object : BaseQuickAdapter<GiftInfo, BaseViewHolder>(R.layout.item_gift_room_album){
override fun convert(helper: BaseViewHolder, item: GiftInfo) {
ImageLoadUtilsV2.loadImage(helper.getView(R.id.iv_gift), item.giftUrl)
helper.setText(R.id.tv_gift, item.giftName)
helper.setText(R.id.tv_value, item.goldPrice.toString())
}
}.apply {
val gifts = GiftModel.get().getGiftInfoList(GiftType.GIFT_TYPE_NORMAL)
setNewData(gifts)
setOnItemClickListener { _, _, position ->
onPickedListener?.onPicked(data[position])
dismiss()
}
}
binding.ivClose.setOnClickListener { dismiss() }
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
fun interface OnPickedListener {
fun onPicked(giftInfo: GiftInfo)
}
}

View File

@@ -0,0 +1,14 @@
package com.yizhuan.erban.avroom.room_album
import com.chad.library.adapter.base.entity.MultiItemEntity
data class PhotoItem(val path: String, val type: Int) : MultiItemEntity {
override fun getItemType(): Int {
return type
}
companion object {
const val TYPE_PHOTO = 0
const val TYPE_ADD = 1
}
}

View File

@@ -0,0 +1,114 @@
package com.yizhuan.erban.avroom.room_album
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.graphics.Canvas
import android.graphics.LinearGradient
import android.graphics.Shader
import androidx.activity.viewModels
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseViewBindingActivity
import com.yizhuan.erban.databinding.ActivityRoomAlbumBinding
import com.yizhuan.erban.ui.widget.magicindicator.ViewPagerHelper
import com.yizhuan.erban.ui.widget.magicindicator.buildins.commonnavigator.CommonNavigator
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.GradientLinePagerIndicator
import com.yizhuan.erban.ui.widget.magicindicator.buildins.commonnavigator.indicators.LinePagerIndicator
import com.yizhuan.erban.ui.widget.magicindicator.buildins.commonnavigator.titles.ColorTransitionPagerTitleView
class RoomAlbumActivity : BaseViewBindingActivity<ActivityRoomAlbumBinding>() {
val viewModel: RoomAlbumViewModel by viewModels()
override fun init() {
initTitleBar(getString(R.string.room_album))
mTitleBar.setBackgroundResource(R.color.white)
val titles = listOf("我的照片", "普通照片", "解鎖照片")
binding.indicator.navigator = CommonNavigator(this).apply {
isAdjustMode = true
adapter = object : CommonNavigatorAdapter() {
var startColor = ContextCompat.getColor(context, R.color.color_5CF1FF)
var endColor = ContextCompat.getColor(context, R.color.color_CF70FF)
override fun getCount(): Int {
return 3
}
override fun getTitleView(context: Context, index: Int): IPagerTitleView {
return ColorTransitionPagerTitleView(context).apply {
normalColor = ContextCompat.getColor(context, R.color.color_767585)
selectedColor = ContextCompat.getColor(context, R.color.color_1F1B4F)
text = titles[index]
}.apply {
setOnClickListener { binding.vp.currentItem = index }
}
}
override fun getIndicator(context: Context?): IPagerIndicator {
return object : GradientLinePagerIndicator(context) {
@SuppressLint("DrawAllocation")
override fun onDraw(canvas: Canvas) {
val g = LinearGradient(
lineRect.left,
lineRect.top,
lineRect.right,
lineRect.bottom,
intArrayOf(startColor, endColor),
null,
Shader.TileMode.CLAMP
)
paint.shader = g
canvas.drawRoundRect(lineRect, roundRadius, roundRadius, paint)
}
}.apply {
lineHeight = resources.getDimensionPixelOffset(R.dimen.dp_4).toFloat()
lineWidth = resources.getDimensionPixelOffset(R.dimen.dp_15).toFloat()
roundRadius = resources.getDimensionPixelOffset(R.dimen.dp_2).toFloat()
mode = LinePagerIndicator.MODE_EXACTLY
}
}
}
}
ViewPagerHelper.bind(binding.indicator, binding.vp)
val fragments = listOf(
RoomAlbumFragment.newInstance(RoomAlbumFragment.TYPE_MINE),
RoomAlbumFragment.newInstance(RoomAlbumFragment.TYPE_COMMON),
RoomAlbumFragment.newInstance(RoomAlbumFragment.TYPE_LOCKED)
)
binding.vp.adapter = object : FragmentStateAdapter(this) {
override fun getItemCount(): Int {
return fragments.size
}
override fun createFragment(position: Int): Fragment {
return fragments[position]
}
}
binding.tvUpload.setOnClickListener {
UploadRoomAlbumDialogFragment().show(
supportFragmentManager,
UploadRoomAlbumDialogFragment::class.java.simpleName
)
}
}
companion object {
@JvmStatic
fun start(context: Context) {
val starter = Intent(context, RoomAlbumActivity::class.java)
context.startActivity(starter)
}
}
}

View File

@@ -0,0 +1,201 @@
package com.yizhuan.erban.avroom.room_album
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.GridLayoutManager
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.chad.library.adapter.base.diff.BaseQuickDiffCallback
import com.yizhuan.erban.R
import com.yizhuan.erban.avroom.bean.RoomAlbumPhotoInfo
import com.yizhuan.erban.base.BaseViewBindingFragment
import com.yizhuan.erban.community.photo.BigPhotoActivity
import com.yizhuan.erban.community.photo.PagerOption
import com.yizhuan.erban.community.utils.ObjectTypeHelper
import com.yizhuan.erban.databinding.FragmentRoomAlbumBinding
import com.yizhuan.erban.ui.utils.ImageLoadUtils
import com.yizhuan.erban.ui.utils.ImageLoadUtilsV2
import com.yizhuan.erban.ui.widget.ButtonItem
import com.yizhuan.erban.ui.widget.recyclerview.decoration.GridSpacingItemNewDecoration
import com.yizhuan.xchat_android_core.Constants
class RoomAlbumFragment : BaseViewBindingFragment<FragmentRoomAlbumBinding>() {
private val activityViewModel by activityViewModels<RoomAlbumViewModel>()
private val viewModel by viewModels<RoomAlbumFragmentViewModel>()
private val type: Int by lazy {
requireArguments().getInt("type")
}
private var page = 1
override fun init() {
binding.recyclerView.layoutManager = GridLayoutManager(context, 2)
val offsetH = resources.getDimensionPixelOffset(R.dimen.dp_7)
val offsetV = resources.getDimensionPixelOffset(R.dimen.dp_4)
binding.recyclerView.addItemDecoration(
GridSpacingItemNewDecoration(
offsetV,
offsetH,
false
)
)
val adapter = object :
BaseQuickAdapter<RoomAlbumPhotoInfo, BaseViewHolder>(R.layout.item_room_album) {
override fun convert(helper: BaseViewHolder, item: RoomAlbumPhotoInfo) {
val ivPhoto = helper.getView<ImageView>(R.id.iv_pic)
if (item.status == 1) {
ImageLoadUtilsV2.loadImage(ivPhoto, item.photoUrl)
helper.setVisible(R.id.iv_lock, false)
} else {
ImageLoadUtils.loadImageWithBlur(
context,
item.photoUrl,
ivPhoto,
25, 4
)
helper.setVisible(R.id.iv_lock, true)
}
helper.setVisible(R.id.v_action, type == TYPE_MINE)
helper.setVisible(R.id.v_bottom_mask, item.type == 2)
helper.setVisible(R.id.iv_gift, item.type == 2)
helper.setVisible(R.id.iv_diamond, item.type == 2)
helper.setVisible(R.id.tv_value, item.type == 2)
helper.itemView.setOnClickListener {
if (item.type != 1) {
return@setOnClickListener
}
BigPhotoActivity.start(
activity,
ObjectTypeHelper.pathToCustomItems(item.photoUrl),
0, PagerOption().setSave(true)
)
}
if (item.type == 2) {
val ivGift = helper.getView<ImageView>(R.id.iv_gift)
ImageLoadUtilsV2.loadImage(ivGift, item.giftUrl)
helper.setText(R.id.tv_value, item.totalGoldPrice.toString())
}
}
override fun onCreateDefViewHolder(
parent: ViewGroup?,
viewType: Int
): BaseViewHolder {
val holder = super.onCreateDefViewHolder(parent, viewType)
holder.addOnClickListener(R.id.v_action)
return holder
}
}.apply {
addFooterView(View(context).apply {
layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, resources.getDimensionPixelOffset(R.dimen.dp_80))
})
setEnableLoadMore(true)
setOnLoadMoreListener({
viewModel.loadPhotos(type, ++page)
}, binding.recyclerView)
setOnItemChildClickListener { _, view, position ->
if (view.id == R.id.v_action) {
val buttonItems = listOf(
ButtonItem("發送到公屏") {
dialogManager.showOkCancelDialog("確認將該照片發送至公屏") {
viewModel.sendPhoto(data[position].id)
}
},
ButtonItem("刪除照片") {
viewModel.deletePhoto(data[position].id)
},
ButtonItem("查看大圖") {
BigPhotoActivity.start(
activity,
ObjectTypeHelper.pathToCustomItems(data[position].photoUrl),
0, PagerOption().setSave(true)
)
}
)
dialogManager.showCommonPopupDialog(buttonItems)
}
}
}
binding.recyclerView.adapter = adapter
binding.refreshLayout.setOnRefreshListener {
page = Constants.PAGE_START
viewModel.loadPhotos(type)
}
viewModel.loadPhotos(type)
activityViewModel.uploadLiveData.observe(this) {
page = Constants.PAGE_START
viewModel.loadPhotos(type)
}
viewModel.myPhotosLiveData.observe(this@RoomAlbumFragment) {
adapter.loadMoreComplete()
adapter.setNewDiffData(object : BaseQuickDiffCallback<RoomAlbumPhotoInfo>(it) {
override fun areItemsTheSame(
oldItem: RoomAlbumPhotoInfo,
newItem: RoomAlbumPhotoInfo
): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(
oldItem: RoomAlbumPhotoInfo,
newItem: RoomAlbumPhotoInfo
): Boolean {
return oldItem.photoUrl === newItem.photoUrl
}
})
binding.refreshLayout.finishRefresh()
}
viewModel.deleteLiveData.observe(this) {
viewModel.loadPhotos(type)
}
viewModel.loadStateLiveData.observe(this) {
if (it == true) {
adapter.loadMoreComplete()
} else {
if (page > 1) {
page--
}
adapter.loadMoreFail()
}
binding.refreshLayout.finishRefresh()
}
viewModel.noMoreLiveData.observe(this) {
if (it == true) {
adapter.loadMoreEnd()
}
}
}
companion object {
const val TYPE_MINE = 0
const val TYPE_COMMON = 1
const val TYPE_LOCKED = 2
fun newInstance(type: Int) = RoomAlbumFragment().apply {
arguments = Bundle().apply {
putInt("type", type)
}
}
}
}

View File

@@ -0,0 +1,68 @@
package com.yizhuan.erban.avroom.room_album
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.hjq.toast.ToastUtils
import com.yizhuan.erban.avroom.bean.RoomAlbumPhotoInfo
import com.yizhuan.erban.base.BaseViewModel
import com.yizhuan.xchat_android_core.Constants
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager
import com.yizhuan.xchat_android_core.utils.toast
class RoomAlbumFragmentViewModel : BaseViewModel() {
private val _myPhotosLiveData = MutableLiveData<MutableList<RoomAlbumPhotoInfo>?>()
val myPhotosLiveData: LiveData<MutableList<RoomAlbumPhotoInfo>?> = _myPhotosLiveData
private val _deleteLiveData = MutableLiveData<Boolean?>()
val deleteLiveData: LiveData<Boolean?> = _deleteLiveData
private val _loadStateLiveData = MutableLiveData<Boolean?>()
val loadStateLiveData: LiveData<Boolean?> = _loadStateLiveData
private val _noMoreLiveData = MutableLiveData<Boolean?>()
val noMoreLiveData: LiveData<Boolean?> = _noMoreLiveData
fun loadPhotos(type: Int, page: Int = 1) {
safeLaunch(block = {
val data = RoomAlbumModel.loadPhotos(AvRoomDataManager.get().roomUid, type, page)
data?.let {
val value = _myPhotosLiveData.value
if (page == 1) {
_myPhotosLiveData.value = it.toMutableList()
} else {
value?.addAll(it)
_myPhotosLiveData.value = value
}
_loadStateLiveData.value = true
_noMoreLiveData.value = it.size < Constants.PAGE_SIZE
}
}, onError = {
it.message.toast()
_loadStateLiveData.value = false
})
}
fun sendPhoto(photoId: Int) {
safeLaunch(block = {
RoomAlbumModel.sendPhoto(AvRoomDataManager.get().roomUid, photoId)
}, onComplete = {
ToastUtils.show("發送成功")
})
}
fun deletePhoto(photoId: Int) {
safeLaunch(block = {
RoomAlbumModel.deletePhoto(photoId)
_deleteLiveData.value = true
}, onComplete = {
ToastUtils.show("成功")
})
}
}

View File

@@ -0,0 +1,100 @@
package com.yizhuan.erban.avroom.room_album
import com.yizhuan.erban.avroom.bean.RoomAlbumPhotoInfo
import com.yizhuan.xchat_android_core.Constants
import com.yizhuan.xchat_android_core.bean.response.ServiceResult
import com.yizhuan.xchat_android_core.gift.bean.GiftReceiveInfo
import com.yizhuan.xchat_android_core.utils.net.RxHelper
import com.yizhuan.xchat_android_core.utils.net.launchRequest
import com.yizhuan.xchat_android_library.net.rxnet.RxNet
import io.reactivex.Single
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Query
object RoomAlbumModel {
private val api = RxNet.create(Api::class.java)
suspend fun loadPhotos(roomUid: Long, type: Int, page: Int): List<RoomAlbumPhotoInfo>? {
return launchRequest {
api.loadPhotos(roomUid, type, page, Constants.PAGE_SIZE)
}
}
suspend fun uploadPhotos(roomUid: Long, type: Int, photoUrls: String, giftId: Int?): String? {
return launchRequest {
api.uploadPhotos(roomUid, type, photoUrls, giftId)
}
}
suspend fun sendPhoto(roomUid: Long, photoId: Int): String? {
return launchRequest {
api.sendPhoto(roomUid, photoId)
}
}
suspend fun deletePhoto(photoId: Int): String? {
return launchRequest {
api.deletePhoto(photoId)
}
}
fun unlockRoomPhoto(roomUid: Long, photoId: Int): Single<GiftReceiveInfo> {
return api.unlockRoomPhoto(roomUid, photoId)
.compose(RxHelper.handleCommon())
.compose(RxHelper.handleSchAndExce())
}
fun listUnlockRoomPhoto(roomUid: Long): Single<List<Int>> {
return api.listUnlockRoomPhoto(roomUid)
.compose(RxHelper.handleCommon())
.compose(RxHelper.handleSchAndExce())
}
private interface Api {
@GET("roomAlbum/pagePhoto")
suspend fun loadPhotos(
@Query("roomUid") roomUid: Long,
@Query("type") type: Int,
@Query("page") page: Int,
@Query("pageSize") pageSize: Int,
): ServiceResult<List<RoomAlbumPhotoInfo>>
@FormUrlEncoded
@POST("roomAlbum/upload")
suspend fun uploadPhotos(
@Field("roomUid") roomUid: Long,
@Field("type") type: Int,
@Field("photoUrls") photoUrls: String,
@Field("giftId") giftId: Int?,
): ServiceResult<String>
@FormUrlEncoded
@POST("roomAlbum/sendPhoto")
suspend fun sendPhoto(
@Field("roomUid") roomUid: Long,
@Field("id") photoId: Int,
): ServiceResult<String>
@FormUrlEncoded
@POST("roomAlbum/delete")
suspend fun deletePhoto(
@Field("id") photoId: Int,
): ServiceResult<String>
@FormUrlEncoded
@POST("roomAlbum/unlockPhoto")
fun unlockRoomPhoto(
@Field("roomUid") roomUid: Long,
@Field("id") photoId: Int
): Single<ServiceResult<GiftReceiveInfo>>
@GET("roomAlbum/listUnlockPhoto")
fun listUnlockRoomPhoto(
@Query("roomUid") roomUid: Long,
): Single<ServiceResult<List<Int>>>
}
}

View File

@@ -0,0 +1,48 @@
package com.yizhuan.erban.avroom.room_album
import android.annotation.SuppressLint
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.yizhuan.erban.base.BaseViewModel
import com.yizhuan.erban.base.Event
import com.yizhuan.xchat_android_core.file.FileModel
import com.yizhuan.xchat_android_core.gift.bean.GiftInfo
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager
import com.yizhuan.xchat_android_core.utils.toast
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
class RoomAlbumViewModel : BaseViewModel() {
private val _uploadLiveData = MutableLiveData<Event<Boolean>>()
val uploadLiveData: LiveData<Event<Boolean>?> = _uploadLiveData
@SuppressLint("CheckResult")
fun upload(list: MutableList<String>, type: Int, unlockedGift: GiftInfo?) {
Observable.fromIterable(list)
.flatMap {
FileModel.get().uploadFile(it).toObservable()
}
.toList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
safeLaunch(onError = {
_uploadLiveData.value = Event(false)
}, block = {
RoomAlbumModel.uploadPhotos(
AvRoomDataManager.get().roomUid,
type,
it.joinToString(","),
unlockedGift?.giftId
)
_uploadLiveData.value = Event(true)
})
}, {
it.message.toast()
_uploadLiveData.value = Event(false)
})
}
}

View File

@@ -0,0 +1,59 @@
package com.yizhuan.erban.avroom.room_album
import android.annotation.SuppressLint
import android.os.Bundle
import com.hjq.toast.ToastUtils
import com.yizhuan.erban.base.BaseDialog
import com.yizhuan.erban.databinding.DialogLockRoomAlbumPhotoBinding
import com.yizhuan.erban.ui.utils.ImageLoadUtilsV2
import com.yizhuan.xchat_android_core.gift.bean.GiftReceiveInfo
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager
class UnlockRoomAlbumPhotoDialog : BaseDialog<DialogLockRoomAlbumPhotoBinding>(){
var onUnlockRoomPhotoListener: OnUnlockRoomPhotoListener? = null
@SuppressLint("CheckResult")
override fun init() {
val arguments = requireArguments()
val giftUrl = arguments.getString("giftUrl")
val giftName = arguments.getString("giftName")
val price = arguments.getInt("price")
val photoId = arguments.getInt("photoId")
ImageLoadUtilsV2.loadImage(binding.ivGift, giftUrl)
binding.tvGiftName.text = giftName
binding.tvValue.text = price.toString()
binding.tvAction.setOnClickListener {
RoomAlbumModel.unlockRoomPhoto(AvRoomDataManager.get().roomUid, photoId)
.subscribe({
onUnlockRoomPhotoListener?.onUnlockRoomPhoto(it)
dismiss()
}, {
ToastUtils.show(it.message)
})
}
binding.ivClose.setOnClickListener {
dismiss()
}
}
companion object{
fun newInstance(photoId:Int, giftUrl: String?, giftName:String, price:Int): UnlockRoomAlbumPhotoDialog {
val args = Bundle()
args.putInt("photoId", photoId)
args.putString("giftUrl", giftUrl)
args.putString("giftName", giftName)
args.putInt("price", price)
val fragment = UnlockRoomAlbumPhotoDialog()
fragment.arguments = args
return fragment
}
}
fun interface OnUnlockRoomPhotoListener{
fun onUnlockRoomPhoto(unlockRoomAlbumPhotoInfo: GiftReceiveInfo)
}
}

View File

@@ -0,0 +1,294 @@
package com.yizhuan.erban.avroom.room_album
import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.core.content.ContextCompat
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.hjq.toast.ToastUtils
import com.yizhuan.erban.R
import com.yizhuan.erban.common.widget.dialog.DialogManager
import com.yizhuan.erban.databinding.DialogRoomAlbumUploadBinding
import com.yizhuan.erban.ui.utils.ImageLoadUtilsV2
import com.yizhuan.erban.ui.widget.recyclerview.decoration.GridSpacingItemNewDecoration
import com.yizhuan.xchat_android_core.Constants
import com.yizhuan.xchat_android_core.gift.bean.GiftInfo
import com.yizhuan.xchat_android_library.common.photo.PhotoProvider
import com.yizhuan.xchat_android_library.common.photo.PhotoProvider.photoProvider
import com.yizhuan.xchat_android_library.common.util.PhotoCompressUtil.compress
import com.yizhuan.xchat_android_library.common.util.PhotoCompressUtil.getCompressCachePath
import com.yizhuan.xchat_android_library.common.util.PhotosCompressCallback
import com.yizhuan.xchat_android_library.easypermisssion.EasyPermissions
import kotlinx.coroutines.Job
class UploadRoomAlbumDialogFragment : BottomSheetDialogFragment() {
private var _binding: DialogRoomAlbumUploadBinding? = null
private val binding get() = _binding!!
private val viewModel by activityViewModels<RoomAlbumViewModel>()
private lateinit var photoAdapter: BaseMultiItemQuickAdapter<PhotoItem, BaseViewHolder>
private var unlockedGift: GiftInfo? = null
private var compressJob: Job? = null
val dialogManager by lazy {
DialogManager(context)
}
private val addItem = PhotoItem("", PhotoItem.TYPE_ADD)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, R.style.ErbanBottomSheetDialog)
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState)
dialog.window?.attributes?.apply {
width = WindowManager.LayoutParams.MATCH_PARENT
height = WindowManager.LayoutParams.MATCH_PARENT
}
return dialog
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = DialogRoomAlbumUploadBinding.inflate(layoutInflater, container, false)
binding.rvPhoto.layoutManager = GridLayoutManager(context, 3)
binding.rvPhoto.addItemDecoration(
GridSpacingItemNewDecoration(
resources.getDimensionPixelOffset(
R.dimen.dp_18
), true
)
)
photoAdapter =
object : BaseMultiItemQuickAdapter<PhotoItem, BaseViewHolder>(mutableListOf(addItem)) {
init {
addItemType(PhotoItem.TYPE_PHOTO, R.layout.item_publish_image)
addItemType(PhotoItem.TYPE_ADD, R.layout.item_add_picture)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val holder = super.onCreateViewHolder(parent, viewType)
if (viewType == PhotoItem.TYPE_PHOTO) {
holder.setGone(R.id.iv_gif_tag, false)
holder.setImageResource(R.id.iv_delete, R.drawable.ic_delete_room_album)
holder.addOnClickListener(R.id.iv_delete)
}
return holder
}
override fun convert(helper: BaseViewHolder, item: PhotoItem) {
if (item.type == PhotoItem.TYPE_ADD) {
return
}
ImageLoadUtilsV2.loadImage(helper.getView(R.id.iv_photo), item.path, false, 8)
}
}.apply {
setOnItemChildClickListener { _, view, position ->
if (view.id == R.id.iv_delete) {
remove(position)
if (data.last().type != PhotoItem.TYPE_ADD) {
addData(addItem)
}
}
}
setOnItemClickListener { _, _, position ->
if (position == data.size - 1) {
checkStoragePermission()
}
}
}
binding.rvPhoto.adapter = photoAdapter
binding.vGift.isEnabled = false
binding.rgType.setOnCheckedChangeListener { group, checkedId ->
if (checkedId == binding.rbCommon.id) {
binding.tvNoGift.visibility = View.VISIBLE
binding.tvNoGift.text =
getString(R.string.room_album_type_no_need_unlocked_gift_tips)
binding.groupGift.visibility = View.INVISIBLE
unlockedGift = null
binding.vGift.isEnabled = false
binding.tvGiftLabel.setTextColor(
ContextCompat.getColor(
requireContext(),
R.color.color_B3B3C3
)
)
} else {
binding.tvNoGift.visibility = View.VISIBLE
binding.tvNoGift.text =
getString(R.string.room_album_type_choose_unlocked_gift_tips)
binding.groupGift.visibility = View.INVISIBLE
binding.vGift.isEnabled = true
binding.tvGiftLabel.setTextColor(
ContextCompat.getColor(
requireContext(),
R.color.color_1F1B4F
)
)
}
}
binding.vGift.setOnClickListener {
val chooseGiftRoomAlbumDialogFragment = ChooseGiftRoomAlbumDialogFragment()
chooseGiftRoomAlbumDialogFragment.onPickedListener =
ChooseGiftRoomAlbumDialogFragment.OnPickedListener {
unlockedGift = it
binding.tvNoGift.visibility = View.INVISIBLE
binding.groupGift.visibility = View.VISIBLE
ImageLoadUtilsV2.loadImage(binding.ivGift, it.giftUrl)
binding.tvGiftName.text = it.giftName
binding.tvGiftValue.text = it.goldPrice.toString()
}
chooseGiftRoomAlbumDialogFragment.show(
childFragmentManager,
UploadRoomAlbumDialogFragment::class.java.simpleName
)
}
binding.slConfirm.setOnClickListener {
val list = mutableListOf<String>()
photoAdapter.data.forEach {
if (it.type == PhotoItem.TYPE_PHOTO) {
list.add(it.path)
}
}
if (list.size < 1) {
ToastUtils.show("未選擇圖片")
return@setOnClickListener
}
val type = if (binding.rgType.checkedRadioButtonId == binding.rbCommon.id) 1 else 2
if (type == 2 && unlockedGift == null) {
ToastUtils.show("未選擇解鎖禮物")
return@setOnClickListener
}
dialogManager.showProgressDialog(context)
viewModel.upload(
list,
type,
unlockedGift
)
}
viewModel.uploadLiveData.observe(this) {
it?.getContentIfNotHandled()?.let { success ->
dialogManager.hideProgressDialog()
if (success) {
dismiss()
}
}
}
binding.ivClose.setOnClickListener { dismiss() }
return binding.root
}
private fun checkStoragePermission() {
if (!EasyPermissions.hasPermissions(
requireContext(),
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES
else Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
100,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES
else Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
photoProvider(
this,
7 - photoAdapter.data.size,
true,
200,
true
)
}
}
@Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode != Activity.RESULT_OK) {
return
}
if (requestCode == 200) {
PhotoProvider.getResultPathListAsync(data) {
it?.let { paths ->
compressPhotos(paths.toMutableList())
}
}
}
}
@SuppressLint("NotifyDataSetChanged")
private fun compressPhotos(paths: MutableList<String>) {
compressJob?.cancel(null)
compressJob = compress(
requireContext(), paths,
getCompressCachePath(),
object : PhotosCompressCallback {
override fun onSuccess(compressedImgList: ArrayList<String>) {
val list = photoAdapter.data
val removeLast = list.removeLast()
compressedImgList.forEach { item ->
list.add(PhotoItem(item, PhotoItem.TYPE_PHOTO))
}
if (list.size < 6) {
list.add(removeLast)
}
photoAdapter.notifyDataSetChanged()
}
override fun onFail(e: Throwable) {
ToastUtils.show(getString(R.string.picker_image_error))
}
}, 200, false, Constants.UPLOAD_IMAGE_MAX_SIZE, Constants.UPLOAD_IMAGE_MAX_FILE_LENGTH
)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -3,6 +3,7 @@ package com.yizhuan.erban.avroom.widget;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_FAIRY;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_GIFT_COMPOUND;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_RED_PACKAGE;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_ROOM_ALBUM;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_BOX_ME;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_CONVERT_L1;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_CONVERT_L2;
@@ -23,6 +24,7 @@ import static com.yizhuan.xchat_android_core.redpackage.RedPackageTypeKt.ROOM_DI
import static com.yizhuan.xchat_android_core.redpackage.RedPackageTypeKt.ROOM_GIFT;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
@@ -42,6 +44,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
@@ -59,6 +62,7 @@ import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessageExtension;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomNotificationAttachment;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
import com.netease.nimlib.sdk.msg.constant.NotificationType;
import com.netease.nimlib.sdk.msg.model.IMMessage;
@@ -67,13 +71,18 @@ import com.yizhuan.erban.R;
import com.yizhuan.erban.UIHelper;
import com.yizhuan.erban.avroom.activity.AVRoomActivity;
import com.yizhuan.erban.avroom.dialog.PKResultDialog;
import com.yizhuan.erban.avroom.room_album.UnlockRoomAlbumPhotoDialog;
import com.yizhuan.erban.common.util.Utils;
import com.yizhuan.erban.common.widget.CustomAutoWidthImageSpan;
import com.yizhuan.erban.common.widget.CustomImageSpan;
import com.yizhuan.erban.common.widget.OriginalDrawStatusClickSpan;
import com.yizhuan.erban.community.photo.BigPhotoActivity;
import com.yizhuan.erban.community.photo.PagerOption;
import com.yizhuan.erban.community.utils.ObjectTypeHelper;
import com.yizhuan.erban.treasure_box.widget.GoldBoxHelper;
import com.yizhuan.erban.treasurefairy.HomeFairyActivity;
import com.yizhuan.erban.ui.utils.ImageLoadUtils;
import com.yizhuan.erban.ui.utils.ImageLoadUtilsV2;
import com.yizhuan.erban.ui.widget.DividerItemDecoration;
import com.yizhuan.erban.ui.widget.MyItemAnimator;
import com.yizhuan.erban.ui.widget.RecyclerViewNoViewpagerScroll;
@@ -93,6 +102,7 @@ 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.LuckyBagGifts;
import com.yizhuan.xchat_android_core.gift.bean.LuckyBagNoticeInfo;
import com.yizhuan.xchat_android_core.gift.toolbox.GiftToolbox;
import com.yizhuan.xchat_android_core.helper.ImHelperUtils;
import com.yizhuan.xchat_android_core.home.event.FollowRoomEvent;
import com.yizhuan.xchat_android_core.home.model.CollectionRoomModel;
@@ -119,16 +129,20 @@ import com.yizhuan.xchat_android_core.im.custom.bean.MultiGiftAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.MultiLuckyGiftAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.NobleAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RedPackageRoomMsgAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomAlbumAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomAlbumMsgInfo;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomBoxPrizeAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomFollowOwnerAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomFollowOwnerAttachment2;
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.RoomNoticeAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomPhoto;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomReceivedLuckyGiftAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RoomTipAttachment;
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.im.custom.bean.User;
import com.yizhuan.xchat_android_core.im.custom.bean.VipMessageAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.WelcomeAttachment;
import com.yizhuan.xchat_android_core.level.UserLevelResourceType;
@@ -735,8 +749,28 @@ public class MessageView extends FrameLayout {
this.data = data;
}
@Override
public int getItemViewType(int position) {
ChatRoomMessage chatRoomMessage = data.get(position);
if (chatRoomMessage.getMsgType() == MsgTypeEnum.custom) {
MsgAttachment attachment = chatRoomMessage.getAttachment();
if (attachment instanceof CustomAttachment) {
if (((CustomAttachment) attachment).getFirst() == CustomAttachment.CUSTOM_MSG_ROOM_ALBUM) {
return CustomAttachment.CUSTOM_MSG_ROOM_ALBUM;
}
}
}
return super.getItemViewType(position);
}
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == CustomAttachment.CUSTOM_MSG_ROOM_ALBUM) {
return new MessageViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_msg_view_holder_room_album, parent, false));
}
return new MessageViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_chatrrom_msg, parent, false));
}
@@ -995,6 +1029,8 @@ public class MessageView extends FrameLayout {
setGiftCompoundMsg(chatRoomMessage, tvContent);
} else if (first == CUSTOM_MSG_FAIRY) {
setFairyMsg(chatRoomMessage, tvContent);
} else if (first == CUSTOM_MSG_ROOM_ALBUM) {
setRoomAlbumMsg(chatRoomMessage, baseViewHolder);
} else {
tvContent.setTextColor(Color.WHITE);
tvContent.setText(tvContent.getResources().getText(R.string.not_support_message_tip));
@@ -1008,6 +1044,103 @@ public class MessageView extends FrameLayout {
}
}
private void setRoomAlbumMsg(ChatRoomMessage chatRoomMessage, MessageViewHolder baseViewHolder) {
RoomAlbumAttachment attachment = (RoomAlbumAttachment) chatRoomMessage.getAttachment();
RoomAlbumMsgInfo mRoomAlbumMsgInfo = attachment.getMRoomAlbumMsgInfo();
if (mRoomAlbumMsgInfo == null) {
return;
}
RoomPhoto roomPhoto = mRoomAlbumMsgInfo.getRoomPhoto();
User user = mRoomAlbumMsgInfo.getUser();
boolean isMyself = UserModel.get().isMyseft(user.getUid());
ImageView ivUserLevel = baseViewHolder.itemView.findViewById(R.id.iv_user_level);
ImageView ivUserCharm = baseViewHolder.itemView.findViewById(R.id.iv_user_charm);
ImageView ivPhoto = baseViewHolder.itemView.findViewById(R.id.iv_photo);
ImageView ivGift = baseViewHolder.itemView.findViewById(R.id.iv_gift);
ImageView ivDiamond = baseViewHolder.itemView.findViewById(R.id.iv_diamond);
TextView tvNick = baseViewHolder.itemView.findViewById(R.id.tv_nick);
TextView tvValue = baseViewHolder.itemView.findViewById(R.id.tv_value);
TextView tvUnlock = baseViewHolder.itemView.findViewById(R.id.tv_unlock);
View vBottomMask = baseViewHolder.itemView.findViewById(R.id.v_bottom_mask);
ImageLoadUtilsV2.loadImage(ivUserLevel, mRoomAlbumMsgInfo.getUserLevel().getExperUrl());
ImageLoadUtilsV2.loadImage(ivUserCharm, mRoomAlbumMsgInfo.getUserLevel().getCharmUrl());
tvNick.setText(user.getNick());
tvUnlock.setText("解鎖");
tvUnlock.setBackgroundResource(R.drawable.bg_9168fa_6);
if (roomPhoto.getType() == 1) {
vBottomMask.setVisibility(View.INVISIBLE);
ivGift.setVisibility(View.INVISIBLE);
ivDiamond.setVisibility(View.INVISIBLE);
tvValue.setVisibility(View.INVISIBLE);
tvUnlock.setVisibility(View.INVISIBLE);
ImageLoadUtilsV2.loadImage(ivPhoto, roomPhoto.getPhotoUrl());
} else {
vBottomMask.setVisibility(View.VISIBLE);
ivGift.setVisibility(View.VISIBLE);
ivDiamond.setVisibility(View.VISIBLE);
tvValue.setVisibility(View.VISIBLE);
tvUnlock.setVisibility(View.VISIBLE);
if (isMyself) {
tvUnlock.setVisibility(View.INVISIBLE);
}
if (isMyself || hadUnlock(roomPhoto.getId())) {
ImageLoadUtilsV2.loadImage(ivPhoto, roomPhoto.getPhotoUrl());
tvUnlock.setText("已解鎖");
tvUnlock.setBackgroundResource(R.drawable.bg_9e9ea8_6);
} else {
ImageLoadUtils.loadImageWithBlur(mContext, roomPhoto.getPhotoUrl(), ivPhoto, 25, 4);
}
ImageLoadUtilsV2.loadImage(ivGift, roomPhoto.getGiftUrl());
tvValue.setText(String.valueOf(roomPhoto.getTotalGoldPrice()));
}
ivPhoto.setOnClickListener(v -> {
if (roomPhoto.getType() == 2 && !isMyself && !hadUnlock(roomPhoto.getId())) {
unlockRoomPhoto(baseViewHolder.getAbsoluteAdapterPosition(), roomPhoto);
return;
}
BigPhotoActivity.start((Activity) mContext, ObjectTypeHelper.pathToCustomItems(roomPhoto.getPhotoUrl()),
0, new PagerOption());
});
baseViewHolder.itemView.setOnClickListener(v -> {
if (roomPhoto.getType() == 2 && !isMyself && !hadUnlock(roomPhoto.getId())) {
unlockRoomPhoto(baseViewHolder.getAbsoluteAdapterPosition(), roomPhoto);
}
});
tvUnlock.setOnClickListener(v -> unlockRoomPhoto(baseViewHolder.getAbsoluteAdapterPosition(), roomPhoto));
}
private void unlockRoomPhoto(int position, RoomPhoto roomPhoto) {
UnlockRoomAlbumPhotoDialog unlockRoomAlbumPhotoDialog = UnlockRoomAlbumPhotoDialog.Companion
.newInstance(roomPhoto.getId(), roomPhoto.getGiftUrl(), roomPhoto.getGiftName(), roomPhoto.getTotalGoldPrice());
unlockRoomAlbumPhotoDialog.setOnUnlockRoomPhotoListener(giftReceiveInfo -> {
giftReceiveInfo.setRoomAlbum(true);
GiftToolbox.sendGiftRoomMessage(giftReceiveInfo);
AvRoomDataManager.get().addUnlockedRoomAlbumPhoto(roomPhoto.getId());
notifyItemChanged(position);
});
unlockRoomAlbumPhotoDialog.show(mContext);
}
private boolean hadUnlock(int photoId) {
List<Integer> unlockedIds= AvRoomDataManager.get().getUnlockedRoomAlbumPhotos();
return unlockedIds.contains(photoId);
}
private void setFairyMsg(ChatRoomMessage chatRoomMessage, TextView tvContent) {
if (chatRoomMessage.getAttachment() instanceof FairyMsgAttachment) {
FairyMsgAttachment attachment = (FairyMsgAttachment) chatRoomMessage.getAttachment();
@@ -1326,7 +1459,7 @@ public class MessageView extends FrameLayout {
case CustomAttachment.CUSTOM_MESS_TAROT_SENIOR_PRIZE_WINNING:
text.append(ResUtil.getString(R.string.avroom_widget_messageview_026), new ForegroundColorSpan(textColor))
.append(nickName, new ForegroundColorSpan(roomTipNickColor))
.append(ResUtil.getString(R.string.avroom_widget_messageview_0160), new ForegroundColorSpan(textColor))
.append(ResUtil.getString(R.string.avroom_widget_messageview_0160), new ForegroundColorSpan(textColor))
.append(tarotMsgBean.getDrawGoldNum() + ResUtil.getString(R.string.avroom_widget_messageview_027), new ForegroundColorSpan(roomTipColor));
tvContent.setText(text.build());
break;

View File

@@ -16,7 +16,7 @@ abstract class BaseDialog<T : ViewBinding> : RxDialogFragment() {
private var _binding: T? = null
private var onDismissListener: (() -> Unit)? = null
val binding get() = _binding
val binding get() = _binding!!
open var width = ScreenUtil.getDialogWidth()
open var height = WindowManager.LayoutParams.WRAP_CONTENT
open var gravity = Gravity.CENTER

View File

@@ -8,6 +8,8 @@ import android.os.Bundle
import android.os.Parcelable
import android.text.Editable
import android.text.TextWatcher
import android.widget.EditText
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseActivity
@@ -18,7 +20,6 @@ import com.yizhuan.xchat_android_core.room.bean.SearchRoomInfo
import com.yizhuan.xchat_android_core.room.model.AvRoomModel
import com.yizhuan.xchat_android_core.utils.net.RxHelper
import com.yizhuan.xchat_android_library.utils.ResUtil
import kotlinx.android.synthetic.main.activity_give_gold_search.*
class GiveGoldSearchActivity : BaseActivity(), TextWatcher {
@@ -42,7 +43,7 @@ class GiveGoldSearchActivity : BaseActivity(), TextWatcher {
.setPageSize(Int.MAX_VALUE)
.setEmptyView(EmptyViewHelper.createEmptyTextView(this, ResUtil.getString(R.string.pay_activity_givegoldsearchactivity_01)))
.setLayoutManager(LinearLayoutManager(this))
.setRecyclerView(recyclerView)
.setRecyclerView(findViewById(R.id.recyclerView))
.setAdapter(adapter)
.build()
adapter.setOnItemClickListener { _, _, position ->
@@ -53,8 +54,8 @@ class GiveGoldSearchActivity : BaseActivity(), TextWatcher {
})
finish()
}
editSearch.addTextChangedListener(this)
tvCancel.setOnClickListener { finish() }
findViewById<EditText>(R.id.editSearch).addTextChangedListener(this)
findViewById<TextView>(R.id.tvCancel).setOnClickListener { finish() }
}
override fun afterTextChanged(s: Editable?) {

View File

@@ -3,10 +3,10 @@ package com.yizhuan.erban.pay.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.widget.TextView
import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseActivity
import com.yizhuan.xchat_android_library.utils.ResUtil
import kotlinx.android.synthetic.main.activity_give_gold_success.*
class GiveGoldSuccessActivity : BaseActivity() {
@@ -24,9 +24,9 @@ class GiveGoldSuccessActivity : BaseActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_give_gold_success)
initTitleBar(ResUtil.getString(R.string.pay_activity_givegoldsuccessactivity_01))
tvNickname.text = "轉贈給:${intent.getStringExtra("nickname")}"
tvGold.text = "${intent.getStringExtra("gold")?.toInt()}鉆石"
tvSure.setOnClickListener { finish() }
findViewById<TextView>(R.id.tvNickname).text = "轉贈給:${intent.getStringExtra("nickname")}"
findViewById<TextView>(R.id.tvGold).text = "${intent.getStringExtra("gold")?.toInt()}鉆石"
findViewById<TextView>(R.id.tvSure).setOnClickListener { finish() }
}

View File

@@ -10,6 +10,7 @@ import android.text.TextWatcher
import android.util.SparseArray
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.activity.viewModels
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
@@ -39,7 +40,6 @@ import com.yizhuan.xchat_android_core.pay.PayModel
import com.yizhuan.xchat_android_core.user.UserModel
import com.yizhuan.xchat_android_core.user.bean.SearchUserInfo
import com.yizhuan.xchat_android_library.utils.ResUtil
import kotlinx.android.synthetic.main.activity_give_gold_to_user.*
class GiveGoldToUserActivity : BaseViewBindingActivity<ActivityGiveGoldToUserBinding>(),
GridPasswordNoFocusView.OnPasswordChangedListener,
@@ -371,7 +371,7 @@ class GiveGoldToUserActivity : BaseViewBindingActivity<ActivityGiveGoldToUserBin
if (password.length == 6) {
searchUserInfo?.apply {
dialogManager.showProgressDialog(context)
PayModel.get().giveGold(uid, mEditGold.text.toString(), DESAndBase64(password))
PayModel.get().giveGold(uid, findViewById<EditText>(R.id.mEditGold).text.toString(), DESAndBase64(password))
.compose(bindToLifecycle())
.doOnError {
toast(it.message)

View File

@@ -10,7 +10,19 @@ import com.yizhuan.erban.treasurefairy.event.UpdateDataEvent
import com.yizhuan.erban.treasurefairy.view.MyFairyItemView
import com.yizhuan.xchat_android_core.bean.response.ListResult
import com.yizhuan.xchat_android_core.gift.bean.SimpleUserInfo
import com.yizhuan.xchat_android_core.treasurefairy.*
import com.yizhuan.xchat_android_core.treasurefairy.Compound
import com.yizhuan.xchat_android_core.treasurefairy.DrawInfo
import com.yizhuan.xchat_android_core.treasurefairy.ExchangeGiftInfo
import com.yizhuan.xchat_android_core.treasurefairy.FairyInfo
import com.yizhuan.xchat_android_core.treasurefairy.FairyResolveParam
import com.yizhuan.xchat_android_core.treasurefairy.FairyTestParam
import com.yizhuan.xchat_android_core.treasurefairy.ForestInfo
import com.yizhuan.xchat_android_core.treasurefairy.MyFairyInfo
import com.yizhuan.xchat_android_core.treasurefairy.PrizeInfo
import com.yizhuan.xchat_android_core.treasurefairy.ResolveInfo
import com.yizhuan.xchat_android_core.treasurefairy.SendFairyInfo
import com.yizhuan.xchat_android_core.treasurefairy.TestFairyRecordInfo
import com.yizhuan.xchat_android_core.treasurefairy.TreasureFairyModel
import com.yizhuan.xchat_android_core.utils.net.ServerException
import com.yizhuan.xchat_android_core.utils.toast
import org.greenrobot.eventbus.EventBus
@@ -54,7 +66,8 @@ class FairyViewModel : BaseViewModel() {
val sendFairyRecordLiveData: LiveData<ListResult<SendFairyInfo>> = _sendFairyRecordLiveData
private val _compoundFairyInfosLiveData = MutableLiveData<SparseArray<FairyInfo>?>()
val compoundFairyInfosLiveData: MutableLiveData<SparseArray<FairyInfo>?> = _compoundFairyInfosLiveData
val compoundFairyInfosLiveData: MutableLiveData<SparseArray<FairyInfo>?> =
_compoundFairyInfosLiveData
private val _testResultLiveData = MutableLiveData<Event<FairyInfo>?>()
val testResultLiveData: MutableLiveData<Event<FairyInfo>?> = _testResultLiveData
@@ -62,17 +75,26 @@ class FairyViewModel : BaseViewModel() {
private val _testLegendResultLiveData = MutableLiveData<Event<FairyInfo>?>()
val testLegendResultLiveData: MutableLiveData<Event<FairyInfo>?> = _testLegendResultLiveData
private val _resolveResultLiveData = MutableLiveData<Event<ResolveInfo>?>()
val resolveResultLiveData: MutableLiveData<Event<ResolveInfo>?> = _resolveResultLiveData
private val _testRecordLiveData = MutableLiveData<ListResult<TestFairyRecordInfo>>()
val testRecordLiveData: LiveData<ListResult<TestFairyRecordInfo>> = _testRecordLiveData
private val _exchangeGiftListLiveData = MutableLiveData<List<ExchangeGiftInfo>?>()
val exchangeGiftListLiveData: MutableLiveData<List<ExchangeGiftInfo>?> = _exchangeGiftListLiveData
val exchangeGiftListLiveData: MutableLiveData<List<ExchangeGiftInfo>?> =
_exchangeGiftListLiveData
private val _exchangeGiftLiveData = MutableLiveData<Event<ExchangeGiftInfo>>()
val exchangeGiftLiveData: LiveData<Event<ExchangeGiftInfo>> = _exchangeGiftLiveData
//精灵召唤列表
private val _fairyCallInfoLiveData = MutableLiveData<List<ExchangeGiftInfo>?>()
val fairyCallInfoLiveData: MutableLiveData<List<ExchangeGiftInfo>?> = _fairyCallInfoLiveData
private val _debrisExchangeListLiveData = MutableLiveData<List<ExchangeGiftInfo>?>()
val debrisExchangeListLiveData: MutableLiveData<List<ExchangeGiftInfo>?> = _debrisExchangeListLiveData
val debrisExchangeListLiveData: MutableLiveData<List<ExchangeGiftInfo>?> =
_debrisExchangeListLiveData
private val _debrisExchangeLiveData = MutableLiveData<Event<ExchangeGiftInfo>>()
val debrisExchangeLiveData: LiveData<Event<ExchangeGiftInfo>> = _debrisExchangeLiveData
@@ -85,6 +107,9 @@ class FairyViewModel : BaseViewModel() {
val exchangeDebrisRecordLiveData: LiveData<ListResult<ExchangeGiftInfo>> =
_exchangeDebrisRecordLiveData
private val _buyDebrisLiveData = MutableLiveData<Event<Int>>()
val buyDebrisLiveData: LiveData<Event<Int>> = _buyDebrisLiveData
init {
initPrizeInfoList()
}
@@ -197,6 +222,21 @@ class FairyViewModel : BaseViewModel() {
)
}
/**
* 精灵召唤列表
*/
fun getFairyCallInfo() {
safeLaunch(
onError = {
_myFairyInfoLiveData.value = null
it.message.toast()
},
block = {
_myFairyInfoLiveData.value = TreasureFairyModel.getMyFairyInfo()
}
)
}
fun getFriendsList(nick: String? = null) {
safeLaunch(
onError = {
@@ -258,20 +298,21 @@ class FairyViewModel : BaseViewModel() {
_compoundFairyInfosLiveData.value = null
_testLegendResultLiveData.value = null
_testResultLiveData.value = null
_resolveResultLiveData.value = null
val myFairyInfo = _myFairyInfoLiveData.value
myFairyInfo?.lowElves?.forEach {
it.selectedNum = 0
}
myFairyInfo?.middleElves?.forEach {
myFairyInfo?.highElves?.forEach {
it.selectedNum = 0
}
_myFairyInfoLiveData.value = myFairyInfo
}
fun addTestFairy(fairyInfo: FairyInfo) {
fun addTestFairy(fairyInfo: FairyInfo, size: Int) {
val array = _compoundFairyInfosLiveData.value ?: SparseArray()
if (array.size() >= 3) {
if (array.size() >= size) {
"試煉爐已滿!".toast()
} else {
if (fairyInfo.elfNum == 0) {
@@ -313,9 +354,9 @@ class FairyViewModel : BaseViewModel() {
}
}
fun oneKeyAdd(fairyInfos: List<FairyInfo>) {
fun oneKeyAdd(fairyInfos: List<FairyInfo>, size: Int) {
val compoundFairyInfos = _compoundFairyInfosLiveData.value ?: SparseArray()
var needNum = 3 - compoundFairyInfos.size()
var needNum = size - compoundFairyInfos.size()
if (needNum == 0) {
"試煉爐已滿!".toast()
return
@@ -327,7 +368,7 @@ class FairyViewModel : BaseViewModel() {
compoundFairyInfos.put(nextIndex(compoundFairyInfos), it)
}
}
if (needNum <= 3 && needNum != 0) {
if (needNum <= size && needNum != 0) {
"精靈數量不足".toast()
return
}
@@ -342,21 +383,27 @@ class FairyViewModel : BaseViewModel() {
fairyInfos.get(1) == null -> {
1
}
else -> {
fairyInfos.get(2) == null -> {
2
}
fairyInfos.get(3) == null -> {
3
}
else -> {
4
}
}
}
fun testFairy(level: Int): Boolean {
val fairyInfos = _compoundFairyInfosLiveData.value ?: SparseArray()
if (fairyInfos.size() != 3) {
if (fairyInfos.size() != 5) {
"精靈數量不足".toast()
return false
}
safeLaunch(
onError = {
if (level == MyFairyItemView.EPIC) {
if (level == MyFairyItemView.LEGEND) {
_testLegendResultLiveData.value = null
} else {
_testResultLiveData.value = null
@@ -371,7 +418,7 @@ class FairyViewModel : BaseViewModel() {
}
fairyTestParam.level = level
val result = TreasureFairyModel.testFairy(fairyTestParam)
(if (level == MyFairyItemView.EPIC) {
(if (level == MyFairyItemView.LEGEND) {
_testLegendResultLiveData
} else {
_testResultLiveData
@@ -382,6 +429,30 @@ class FairyViewModel : BaseViewModel() {
return true
}
fun resolveFairy(): Boolean {
val fairyInfos = _compoundFairyInfosLiveData.value ?: SparseArray()
if (fairyInfos.size() != 1) {
"精靈數量不足".toast()
return false
}
safeLaunch(
onError = {
_resolveResultLiveData.value = null
it.message.toast()
},
block = {
val fairyTestParam = FairyResolveParam()
fairyInfos.forEach { _, value ->
fairyTestParam.expendList.add(Compound(value.elfId, 1))
}
val result = TreasureFairyModel.resolveFairy(fairyTestParam)
_resolveResultLiveData.value = result?.let { Event(it[0]) }
getMyFairyInfo()
}
)
return true
}
fun getTestFairyRecordList(
page: Int,
pageSize: Int
@@ -409,6 +480,18 @@ class FairyViewModel : BaseViewModel() {
)
}
//精灵召唤列表
fun getFairyCallList() {
safeLaunch(
onError = {
_fairyCallInfoLiveData.value = null
},
block = {
val result = TreasureFairyModel.getFairyCallList()
_fairyCallInfoLiveData.value = result
}
)
}
fun getDebrisExchangeList() {
safeLaunch(
@@ -435,6 +518,7 @@ class FairyViewModel : BaseViewModel() {
val result = TreasureFairyModel.exchangeGift(itemId)
_debrisExchangeLiveData.value = result?.let { Event(it) }
_myFairyInfoLiveData.value = TreasureFairyModel.getMyFairyInfo()
initDrawInfo()
}
}
@@ -468,4 +552,21 @@ class FairyViewModel : BaseViewModel() {
)
}
fun buyDebris(num: Int, uid: String) {
safeLaunch(
block = {
TreasureFairyModel.buyDebris(num, uid)
_drawInfoLiveData.value?.apply {
this.drawTicketNum = this.drawTicketNum + num
_drawInfoLiveData.value = this
}
initDrawInfo()
_buyDebrisLiveData.value = Event(num)
}
)
}
}

View File

@@ -10,24 +10,26 @@ import android.os.Build
import android.os.Bundle
import android.text.style.ForegroundColorSpan
import android.view.*
import android.view.animation.AnimationUtils
import android.widget.LinearLayout
import android.widget.TextView
import androidx.activity.viewModels
import androidx.core.content.ContextCompat
import androidx.core.graphics.toColorInt
import androidx.core.widget.doAfterTextChanged
import com.alibaba.fastjson.JSON
import com.hjq.toast.ToastUtils
import com.netease.nim.uikit.common.util.sys.ScreenUtil
import com.netease.nimlib.sdk.chatroom.ChatRoomMessageBuilder
import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseViewBindingActivity
import com.yizhuan.erban.common.widget.dialog.DialogManager
import com.yizhuan.erban.databinding.TreasureFairyDialogHomeBinding
import com.yizhuan.erban.treasurefairy.dialog.ForestFairyDialog
import com.yizhuan.erban.treasurefairy.dialog.HomeMorePopupWindow
import com.yizhuan.erban.treasurefairy.dialog.HomePrizeDialog
import com.yizhuan.erban.treasurefairy.dialog.MyFairyDialog
import com.yizhuan.erban.treasure_box.activity.TreasureBoxActivity
import com.yizhuan.erban.treasurefairy.dialog.*
import com.yizhuan.erban.treasurefairy.view.CustomDrawable
import com.yizhuan.erban.ui.webview.FairyDialogWebViewActivity
import com.yizhuan.erban.utils.KeyBoardUtils
import com.yizhuan.erban.utils.SpannableBuilder
import com.yizhuan.xchat_android_core.UriProvider
import com.yizhuan.xchat_android_core.auth.AuthModel
@@ -40,7 +42,11 @@ import com.yizhuan.xchat_android_core.manager.RoomEvent
import com.yizhuan.xchat_android_core.treasurefairy.DrawInfo
import com.yizhuan.xchat_android_core.treasurefairy.FairyMsgInfoBean
import com.yizhuan.xchat_android_core.treasurefairy.PrizeInfo
import com.yizhuan.xchat_android_library.common.SpConstants
import com.yizhuan.xchat_android_library.common.util.SPUtils
import com.yizhuan.xchat_android_library.utils.FormatUtils
import com.yizhuan.xchat_android_library.utils.SingleToastUtil
import com.yizhuan.xchat_android_library.utils.TimeUtils
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
@@ -64,6 +70,8 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
private var isCheck = false
private var mPrice = -1
companion object {
@JvmStatic
fun start(context: Context) {
@@ -96,16 +104,75 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
ScreenUtil.screenHeight - ScreenUtil.getStatusBarHeight(this)
)
window.setGravity(Gravity.BOTTOM)
binding.fairyItem0.isSelected = true
looperHintPrize()
binding.tvKeyNum.setOnClickListener {
FairyDialogWebViewActivity.start(this, UriProvider.getFairyKey())
binding.viewPrice1.setOnClickListener {
setFairyPriceSelect(1)
}
binding.viewPrice2.setOnClickListener {
setFairyPriceSelect(2)
}
binding.viewPrice3.setOnClickListener {
setFairyPriceSelect(3)
}
binding.etQuantity.doAfterTextChanged {
try {
mPrice = it.toString().toInt()
if (mPrice > TreasureBoxActivity.MAX_BUY_QUANTITY_LIMIT) {
mPrice = TreasureBoxActivity.MAX_BUY_QUANTITY_LIMIT
binding.etQuantity.setText(mPrice.toString())
binding.etQuantity.setSelection(binding.etQuantity.text.length)
SingleToastUtil.showToast(
getString(
R.string.treasure_box_activity_treasureboxactivity_01,
TreasureBoxActivity.MAX_BUY_QUANTITY_LIMIT
)
)
}
setFairyPriceSelect(0)
} catch (e: NumberFormatException) {
e.printStackTrace()
mPrice = -1
}
}
binding.tvBuy.setOnClickListener {
if (mPrice < 1) {
toast("請選擇購買的碎片數量")
return@setOnClickListener
}
val date = SPUtils.getLong(SpConstants.FAIRY_BUY_DEBRIS, 0L)
if (TimeUtils.isToday(date)) {
viewModel.buyDebris(
mPrice,
AuthModel.get().currentUid.toString()
)
return@setOnClickListener
}
FairyBuyDebrisDialog.newInstance(mPrice).show(context)
}
viewModel.buyDebrisLiveData.observe(this) {
val date = SPUtils.getLong(SpConstants.FAIRY_BUY_SUCCESS, 0L)
if (TimeUtils.isToday(date)) {
ToastUtils.show("購買碎片成功")
return@observe
}
FairyBuySuccessDialog.newInstance(it.peekContent()).show(this)
}
binding.ivMyFairy.setOnClickListener {
MyFairyDialog.newInstance().show(this)
}
binding.ivFairyTreasure.setOnClickListener {
ForestFairyDialog.newInstance().show(this)
binding.ivFairyStore.setOnClickListener {
ExchangeFairyDialog.newInstance().show(context)
}
binding.ivOpen1.setOnClickListener {
if (checkKeyNum(1)) {
@@ -152,6 +219,16 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
isCheck = isChecked
}
binding.viewBgLuckyValue.setOnClickListener {
binding.ivRefresh.startAnimation(
AnimationUtils.loadAnimation(
this,
R.anim.comm_loading
)
)
viewModel.initDrawInfo()
}
viewModel.prizeInfoListLiveData.observe(this) {
it?.forEachIndexed { index, prizeInfo ->
if (index < fairyItems.size) {
@@ -166,6 +243,9 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
?.indexOfFirst { prize ->
it[0].itemIndex == prize.itemIndex
} ?: -2
if (targetIndex >= fairyItems.size) {
targetIndex = 0
}
if (targetIndex == -2) {
viewModel.initPrizeInfoList()
}
@@ -177,6 +257,8 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
}
viewModel.drawInfoLiveData.observe(this) {
binding.ivRefresh.clearAnimation()
it?.let {
drawInfo = it
binding.tvKeyNum.text = FormatUtils.formatBigNum(it.drawTicketNum.toString())
@@ -184,9 +266,12 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
binding.tvShortLuckyValue.text =
SpannableBuilder()
.append("幸運值達到", ForegroundColorSpan("#59FDFF".toColorInt()))
.append("還差", ForegroundColorSpan("#59FDFF".toColorInt()))
.append("${it.needLuckyNum}", ForegroundColorSpan("#FFE8AA".toColorInt()))
.append("后,下次奪寶獲贈精靈球", ForegroundColorSpan("#59FDFF".toColorInt()))
.append(
"幸運值,額外獲贈傳説精靈",
ForegroundColorSpan("#59FDFF".toColorInt())
)
.build()
binding.ivLuckyStone.post {
val drawable =
@@ -202,7 +287,8 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
0f,
binding.ivLuckyStone.width.toFloat(),
binding.ivLuckyStone.height *
(1 - it.luckyNum / it.needLuckyNum.toFloat().coerceAtLeast(1f)),
(1 - it.luckyNum / (it.luckyNum + it.needLuckyNum).toFloat()
.coerceAtLeast(1f)),
Path.Direction.CW
)
drawable.setSrcPath(path)
@@ -213,21 +299,83 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
viewModel.showGetKeyLiveData.observe(this) {
it.getContentIfNotHandled()?.let {
DialogManager(context).showOkCancelDialog("購買限時裝扮活動奪寶券", "去參与", "取消") {
DialogManager(context).showOkCancelDialog(
"購買限時裝扮活動奪寶券",
"去參与",
"取消"
) {
FairyDialogWebViewActivity.start(context, UriProvider.getFairyKey())
}
}
}
}
private fun setFairyPriceSelect(pos: Int) {
if (pos == 0) {
binding.viewPrice1.isSelected = false
binding.viewPrice2.isSelected = false
binding.viewPrice3.isSelected = false
binding.ivDebris1.alpha = 0.4f
binding.ivDebris2.alpha = 0.4f
binding.ivDebris3.alpha = 0.4f
binding.tvOne.alpha = 0.4f
binding.tvTwo.alpha = 0.4f
binding.tvThree.alpha = 0.4f
return
}
binding.etQuantity.text = null
KeyBoardUtils.hideKeyBoard(this, binding.etQuantity)
binding.etQuantity.clearFocus()
when (pos) {
1 -> {
mPrice = 1
binding.viewPrice1.isSelected = true
binding.viewPrice2.isSelected = false
binding.viewPrice3.isSelected = false
binding.ivDebris1.alpha = 1f
binding.ivDebris2.alpha = 0.4f
binding.ivDebris3.alpha = 0.4f
binding.tvOne.alpha = 1f
binding.tvTwo.alpha = 0.4f
binding.tvThree.alpha = 0.4f
}
2 -> {
mPrice = 10
binding.viewPrice1.isSelected = false
binding.viewPrice2.isSelected = true
binding.viewPrice3.isSelected = false
binding.ivDebris1.alpha = 0.4f
binding.ivDebris2.alpha = 1f
binding.ivDebris3.alpha = 0.4f
binding.tvOne.alpha = 0.4f
binding.tvTwo.alpha = 1f
binding.tvThree.alpha = 0.4f
}
3 -> {
mPrice = 100
binding.viewPrice1.isSelected = false
binding.viewPrice2.isSelected = false
binding.viewPrice3.isSelected = true
binding.ivDebris1.alpha = 0.4f
binding.ivDebris2.alpha = 0.4f
binding.ivDebris3.alpha = 1f
binding.tvOne.alpha = 0.4f
binding.tvTwo.alpha = 0.4f
binding.tvThree.alpha = 1f
}
}
}
private fun checkKeyNum(num: Int): Boolean {
val keyNum = drawInfo?.drawTicketNum ?: 0
if (keyNum >= num) {
return true
}
DialogManager(context).showOkCancelDialog("購買限時裝扮活動奪寶券", "去參与", "取消") {
FairyDialogWebViewActivity.start(context, UriProvider.getFairyKey())
}
FairyBuyDebrisModifyQuantityDialog.newInstance(num).show(this)
return false
}
@@ -253,7 +401,7 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
fairyItems[selectIndex].isSelected = true
}
if ((selectIndex == targetIndex || targetIndex == -2) && minCount >= 24) {
if(!isCheck) {
if (!isCheck) {
HomePrizeDialog.newInstance().show(context)
}
disposable?.dispose()
@@ -320,10 +468,10 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
*/
override fun onReceivedNimBroadcastMessage(body: String?) {
val baseProtocol: BaseProtocol<*> = try {
JSON.parseObject(body, BaseProtocol::class.java)
} catch (e: Exception) {
null
} ?: return
JSON.parseObject(body, BaseProtocol::class.java)
} catch (e: Exception) {
null
} ?: return
when (baseProtocol.first) {
CustomAttachment.CUSTOM_MSG_BOX -> if (baseProtocol.second == CustomAttachment.CUSTOM_MSG_SUB_BOX_ALL_ROOM_NOTIFY_BY_SVGA) {
val roomBoxPrizeAttachment = RoomBoxPrizeAttachment(
@@ -364,6 +512,7 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
)
}
}
CustomAttachment.CUSTOM_MSG_LUCKY_SEA -> if (baseProtocol.second == CustomAttachment.CUSTOM_MSG_LUCKY_SEA_GIFT_SERVER_ALL) {
val attachment = RoomLuckySeaAttachment(
CustomAttachment.CUSTOM_MSG_LUCKY_SEA,
@@ -383,6 +532,7 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
IMNetEaseManager.get()
.noticeRoomEvent(message, RoomEvent.LUCKY_SEA_GIFT_SERVER_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)
@@ -397,6 +547,7 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
IMNetEaseManager.get().noticeServiceLuckyBagNotice(message)
IMNetEaseManager.get().addMessages(message)
}
CustomAttachment.CUSTOM_MSG_FAIRY -> if (baseProtocol.second == CustomAttachment.CUSTOM_MSG_SUB_DRAW_GIFT_L5) {
val attachment = FairyMsgAttachment(
CustomAttachment.CUSTOM_MSG_FAIRY,
@@ -412,6 +563,7 @@ class HomeFairyActivity : BaseViewBindingActivity<TreasureFairyDialogHomeBinding
)
IMNetEaseManager.get().noticeRoomEvent(message, RoomEvent.FAIRY_DRAW_GIFT_L5)
}
else -> {}
}
}

View File

@@ -12,7 +12,8 @@ class ExchangeDebrisAdapter :
override fun convert(helper: BaseViewHolder, item: ExchangeGiftInfo) {
ImageLoadUtilsV2.loadImage(helper.getView(R.id.iv_prize_icon), item.rewardPicUrl)
helper.setText(R.id.tv_prize_name, item.getPrizeName())
helper.setText(R.id.tv_need_num, "${item.expendNum}")
helper.setText(R.id.tv_value, item.expendNum.toString())
helper.addOnClickListener(R.id.tv_exchange)
}

View File

@@ -18,13 +18,6 @@ class ExchangeFairyRecordAdapter :
helper.setText(R.id.tv_time_year, formatYear.format(item.createTime))
helper.setText(R.id.tv_time_hour, formatHour.format(item.createTime))
helper.setText(R.id.tv_prize_name, "${item.rewardName}x${item.rewardNum}")
helper.setText(
R.id.tv_prize_type, when (item.convertLevel) {
1 -> mContext.getString(R.string.fairy_primary_call)
2 -> mContext.getString(R.string.fairy_epic_call)
else -> mContext.getString(R.string.fairy_legend_call)
}
)
}
}

View File

@@ -0,0 +1,33 @@
package com.yizhuan.erban.treasurefairy.adapter
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yizhuan.erban.R
import com.yizhuan.erban.ui.utils.ImageLoadUtilsV2
import com.yizhuan.xchat_android_core.treasurefairy.ExchangeGiftInfo
import com.yizhuan.xchat_android_core.treasurefairy.PropItemInfo
class ExchangeSummonAdapter :
BaseQuickAdapter<ExchangeGiftInfo, BaseViewHolder>(R.layout.treasure_fairy_item_exchange_summon) {
override fun convert(helper: BaseViewHolder, item: ExchangeGiftInfo) {
ImageLoadUtilsV2.loadImage(helper.getView(R.id.iv_prize_icon), item.rewardPicUrl)
helper.setText(R.id.tv_prize_name, item.getPrizeName())
val adapter: BaseQuickAdapter<PropItemInfo, BaseViewHolder> =
object : BaseQuickAdapter<PropItemInfo, BaseViewHolder>(R.layout.item_exchange_debris) {
override fun convert(helper: BaseViewHolder, item: PropItemInfo) {
ImageLoadUtilsV2.loadImage(helper.getView(R.id.iv_icon), item.picUrl)
helper.setText(R.id.tv_num, "${item.propName}x${item.propNum}")
}
}
helper.getView<RecyclerView>(R.id.mRecyclerView).adapter = adapter
item.propItems?.let {
adapter.setNewData(it)
}
helper.addOnClickListener(R.id.tv_exchange)
}
}

View File

@@ -0,0 +1,25 @@
package com.yizhuan.erban.treasurefairy.adapter
import android.widget.ImageView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yizhuan.erban.R
import com.yizhuan.erban.ui.utils.load
import com.yizhuan.xchat_android_core.treasurefairy.FairyInfo
import java.util.*
class ResolveFairyAdapter :
BaseQuickAdapter<FairyInfo, BaseViewHolder>(R.layout.treasure_fairy_item_resolve_fairy) {
override fun convert(helper: BaseViewHolder, item: FairyInfo) {
helper.getView<ImageView>(R.id.iv_fairy_icon).load(item.elfPicUrl)
helper.setText(R.id.tv_fairy_num, "${item.selectedNum}/${item.elfNum}")
helper.setText(R.id.tv_fairy_name, item.elfName)
helper.setBackgroundRes(
R.id.ll_root,
if (item.selectedNum > 0) R.drawable.treasure_fairy_bg_test_fairy_item_select else 0
)
}
}

View File

@@ -0,0 +1,15 @@
package com.yizhuan.erban.treasurefairy.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yizhuan.erban.R
import com.yizhuan.xchat_android_core.treasurefairy.ResolveInfo
class ResolveFairyResultAdapter :
BaseQuickAdapter<ResolveInfo, BaseViewHolder>(R.layout.treasure_fairy_item_forest_prize_single_resolve) {
override fun convert(helper: BaseViewHolder, item: ResolveInfo) {
helper.setText(R.id.tv_prize_name, "x${item.pieceNum}")
}
}

View File

@@ -19,8 +19,9 @@ class TestFairyRecordAdapter :
helper.setText(R.id.tv_time_hour, formatHour.format(item.createTime))
helper.setText(R.id.tv_prize_name, item.elfName)
helper.setText(
R.id.tv_prize_type, when (item.elfLevel) {
2 -> "史詩試煉"
R.id.tv_prize_type, when (item.type) {
4 -> "傳說試煉"
7 -> "精靈分解"
else -> "傳說試煉"
}
)

View File

@@ -13,6 +13,7 @@ import com.yizhuan.erban.databinding.TreasureFairyDialogExchangeBinding
import com.yizhuan.erban.treasurefairy.FairyViewModel
import com.yizhuan.erban.treasurefairy.fragment.ExchangeDebrisFragment
import com.yizhuan.erban.treasurefairy.fragment.ExchangeFairyFragment
import com.yizhuan.erban.treasurefairy.fragment.ExchangeSummonFragment
class ExchangeFairyDialog : BaseDialog<TreasureFairyDialogExchangeBinding>() {
@@ -32,31 +33,31 @@ class ExchangeFairyDialog : BaseDialog<TreasureFairyDialogExchangeBinding>() {
@SuppressLint("CheckResult")
override fun init() {
binding?.ivBack?.setOnClickListener {
binding.ivBack.setOnClickListener {
dismissAllowingStateLoss()
}
binding?.tvRecord?.setOnClickListener {
binding.tvRecord.setOnClickListener {
ExchangeRecordDialog.newInstance().show(context)
}
binding?.rg?.setOnCheckedChangeListener { _, checkedId ->
binding.rg.setOnCheckedChangeListener { _, checkedId ->
when (checkedId) {
R.id.rb_epic -> binding?.viewPager?.currentItem = 0
R.id.rb_legend -> binding?.viewPager?.currentItem = 1
R.id.rb_epic -> binding.viewPager.currentItem = 0
R.id.rb_legend -> binding.viewPager.currentItem = 1
}
}
binding?.viewPager?.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
binding.viewPager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
override fun onPageSelected(position: Int) {
when (position) {
0 -> binding?.rg?.check(R.id.rb_epic)
1 -> binding?.rg?.check(R.id.rb_legend)
0 -> binding.rg.check(R.id.rb_epic)
1 -> binding.rg.check(R.id.rb_legend)
}
}
})
binding?.viewPager?.adapter = RoomVPAdapter(
binding.viewPager.adapter = RoomVPAdapter(
childFragmentManager,
listOf(
ExchangeFairyFragment.newInstance(),
ExchangeSummonFragment.newInstance(),
ExchangeDebrisFragment.newInstance()
)
)

View File

@@ -0,0 +1,65 @@
package com.yizhuan.erban.treasurefairy.dialog
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.Gravity
import android.view.WindowManager
import androidx.fragment.app.activityViewModels
import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseDialog
import com.yizhuan.erban.databinding.TreasureFairyDialogBuyDebrisBinding
import com.yizhuan.erban.treasurefairy.FairyViewModel
import com.yizhuan.xchat_android_core.auth.AuthModel
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager
import com.yizhuan.xchat_android_library.common.SpConstants
import com.yizhuan.xchat_android_library.common.util.SPUtils
/**
* 购买碎片
*/
class FairyBuyDebrisDialog : BaseDialog<TreasureFairyDialogBuyDebrisBinding>() {
override var width = WindowManager.LayoutParams.MATCH_PARENT
override var height = WindowManager.LayoutParams.WRAP_CONTENT
override var gravity = Gravity.CENTER
private val viewModel: FairyViewModel by activityViewModels()
companion object {
fun newInstance(num: Int): FairyBuyDebrisDialog {
val args = Bundle()
args.putInt("num", num)
val fragment = FairyBuyDebrisDialog()
fragment.arguments = args
return fragment
}
}
private val num by lazy { requireArguments().getInt("num") }
private val price by lazy { AvRoomDataManager.get().mSeizeTreasureSwitchVo?.price ?: 0 }
@SuppressLint("CheckResult")
override fun init() {
binding.tvDebrisNum.text = getString(R.string.buy_debris, num)
binding.tvPrizeName.text = (num * price).toString()
binding.cbPay.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
SPUtils.putLong(SpConstants.FAIRY_BUY_DEBRIS, System.currentTimeMillis())
} else {
SPUtils.putLong(SpConstants.FAIRY_BUY_DEBRIS, 0L)
}
}
binding.tvBuy.setOnClickListener {
viewModel.buyDebris(num, AuthModel.get().currentUid.toString())
}
viewModel.buyDebrisLiveData.observe(this) {
it.getContentIfNotHandled()?.let {
dismissAllowingStateLoss()
}
}
}
}

View File

@@ -0,0 +1,102 @@
package com.yizhuan.erban.treasurefairy.dialog
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.Gravity
import android.view.WindowManager
import androidx.core.widget.doAfterTextChanged
import androidx.fragment.app.activityViewModels
import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseDialog
import com.yizhuan.erban.databinding.TreasureFairyDialogBuyDebrisModifyQuantityBinding
import com.yizhuan.erban.treasure_box.activity.TreasureBoxActivity
import com.yizhuan.erban.treasurefairy.FairyViewModel
import com.yizhuan.xchat_android_core.auth.AuthModel
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager
import com.yizhuan.xchat_android_core.utils.StringUtils
import com.yizhuan.xchat_android_library.utils.SingleToastUtil
/**
* 购买碎片
*/
class FairyBuyDebrisModifyQuantityDialog :
BaseDialog<TreasureFairyDialogBuyDebrisModifyQuantityBinding>() {
override var width = WindowManager.LayoutParams.MATCH_PARENT
override var height = WindowManager.LayoutParams.WRAP_CONTENT
override var gravity = Gravity.CENTER
private val viewModel: FairyViewModel by activityViewModels()
companion object {
fun newInstance(num: Int): FairyBuyDebrisModifyQuantityDialog {
val args = Bundle()
args.putInt("num", num)
val fragment = FairyBuyDebrisModifyQuantityDialog()
fragment.arguments = args
return fragment
}
}
private var num = 0
private val price by lazy { AvRoomDataManager.get().mSeizeTreasureSwitchVo?.price ?: 0 }
@SuppressLint("CheckResult")
override fun init() {
num = requireArguments().getInt("num")
binding.etNum.setText(num.toString())
binding.tvPrizeName.text = (num * price).toString()
binding.ivDecrease.setOnClickListener {
num = (num - 10).coerceAtLeast(1)
binding.etNum.setText(num.toString())
binding.etNum.setSelection(num.toString().length)
binding.tvPrizeName.text = (num * price).toString()
}
binding.ivIncrease.setOnClickListener {
num = (num + 10).coerceAtMost(200)
binding.etNum.setText(num.toString())
binding.etNum.setSelection(num.toString().length)
binding.tvPrizeName.text = (num * price).toString()
}
binding.etNum.doAfterTextChanged {
var n = StringUtils.toInt(binding.etNum.text.toString(), 0)
if (n < 1) {
binding.etNum.setText("1")
binding.etNum.setSelection(1)
num = 1
return@doAfterTextChanged
}
if (n > TreasureBoxActivity.MAX_BUY_QUANTITY_LIMIT) {
n = TreasureBoxActivity.MAX_BUY_QUANTITY_LIMIT
binding.etNum.setText(n.toString())
binding.etNum.setSelection(n.toString().length)
SingleToastUtil.showToast(
getString(
R.string.treasure_box_activity_treasureboxactivity_01,
TreasureBoxActivity.MAX_BUY_QUANTITY_LIMIT
)
)
}
binding.tvPrizeName.text = (n * price).toString()
num = n
}
binding.tvBuy.setOnClickListener {
viewModel.buyDebris(num, AuthModel.get().currentUid.toString())
}
viewModel.buyDebrisLiveData.observe(this) {
it.getContentIfNotHandled()?.let {
dismissAllowingStateLoss()
}
}
}
}

View File

@@ -0,0 +1,48 @@
package com.yizhuan.erban.treasurefairy.dialog
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.Gravity
import android.view.WindowManager
import androidx.fragment.app.activityViewModels
import com.yizhuan.erban.base.BaseDialog
import com.yizhuan.erban.databinding.TreasureFairyDialogBuySuccessBinding
import com.yizhuan.erban.treasurefairy.FairyViewModel
import com.yizhuan.xchat_android_library.common.SpConstants
import com.yizhuan.xchat_android_library.common.util.SPUtils
/**
* 购买碎片成功
*/
class FairyBuySuccessDialog : BaseDialog<TreasureFairyDialogBuySuccessBinding>() {
override var width = WindowManager.LayoutParams.MATCH_PARENT
override var height = WindowManager.LayoutParams.WRAP_CONTENT
override var gravity = Gravity.CENTER
companion object {
fun newInstance(num: Int): FairyBuySuccessDialog {
val args = Bundle()
args.putSerializable("num", num)
val fragment = FairyBuySuccessDialog()
fragment.arguments = args
return fragment
}
}
private val num by lazy { requireArguments().getInt("num") }
@SuppressLint("CheckResult", "SetTextI18n")
override fun init() {
binding.tvDebrisNum.text = "x${num}"
binding.cbPay.setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
SPUtils.putLong(SpConstants.FAIRY_BUY_SUCCESS, System.currentTimeMillis())
} else {
SPUtils.putLong(SpConstants.FAIRY_BUY_SUCCESS, 0L)
}
}
}
}

View File

@@ -34,7 +34,7 @@ class HomePrizeDialog : BaseDialog<TreasureFairyDialogHomePrizeBinding>() {
@SuppressLint("CheckResult")
override fun init() {
binding?.rootView?.setOnClickListener {
binding.rootView.setOnClickListener {
dismissAllowingStateLoss()
}
val prizeInfoList = viewModel.resultLiveData.value?.peekContent()
@@ -43,7 +43,7 @@ class HomePrizeDialog : BaseDialog<TreasureFairyDialogHomePrizeBinding>() {
prizeAdapter = HomePrizeAdapter(isSingle)
rvDelegate = RVDelegate.Builder<PrizeInfo>()
.setAdapter(prizeAdapter)
.setRecyclerView(binding?.recyclerView)
.setRecyclerView(binding.recyclerView)
.setLayoutManager(
if (isSingle) {
LinearLayoutManager(context)

View File

@@ -39,39 +39,39 @@ class MyFairyDialog : BaseDialog<TreasureFairyDialogMyFairyBinding>() {
override fun init() {
EventBus.getDefault().register(this)
binding?.ivBack?.setOnClickListener {
binding.ivBack.setOnClickListener {
dismissAllowingStateLoss()
}
binding?.ivRecord?.setOnClickListener {
binding.ivFairyTest.setOnClickListener {
TestFairyDialog.newInstance().show(context)
}
binding.ivRecord.setOnClickListener {
MyFairyRecordDialog.newInstance().show(context)
}
binding?.rg?.setOnCheckedChangeListener { _, checkedId ->
binding.rg.setOnCheckedChangeListener { _, checkedId ->
when (checkedId) {
R.id.rb_base -> binding?.viewPager?.currentItem = 0
R.id.rb_epic -> binding?.viewPager?.currentItem = 1
R.id.rb_legend -> binding?.viewPager?.currentItem = 2
R.id.rb_base -> binding.viewPager.currentItem = 0
R.id.rb_legend -> binding.viewPager.currentItem = 1
}
}
binding?.viewPager?.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
binding.viewPager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
override fun onPageSelected(position: Int) {
when (position) {
0 -> binding?.rg?.check(R.id.rb_base)
1 -> binding?.rg?.check(R.id.rb_epic)
2 -> binding?.rg?.check(R.id.rb_legend)
0 -> binding.rg.check(R.id.rb_base)
1 -> binding.rg.check(R.id.rb_legend)
}
DemoCache.saveMyFairyIndex(position)
}
})
binding?.viewPager?.adapter = RoomVPAdapter(
binding.viewPager.adapter = RoomVPAdapter(
childFragmentManager,
listOf(
MyFairyFragment.newInstance(MyFairyItemView.BASE),
MyFairyFragment.newInstance(MyFairyItemView.EPIC),
MyFairyFragment.newInstance(MyFairyItemView.LEGEND)
)
)
binding?.viewPager?.setCurrentItem(DemoCache.readMyFairyIndex(), false)
binding.viewPager.setCurrentItem(DemoCache.readMyFairyIndex(), false)
viewModel.getMyFairyInfo()
}

View File

@@ -0,0 +1,56 @@
package com.yizhuan.erban.treasurefairy.dialog
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.Gravity
import android.view.WindowManager
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.LinearLayoutManager
import com.yizhuan.erban.base.BaseDialog
import com.yizhuan.erban.databinding.TreasureFairyDialogResolveFairyResultBinding
import com.yizhuan.erban.treasurefairy.FairyViewModel
import com.yizhuan.erban.treasurefairy.adapter.ResolveFairyResultAdapter
import com.yizhuan.erban.ui.utils.RVDelegate
import com.yizhuan.xchat_android_core.treasurefairy.ResolveInfo
class ResolveFairyResultDialog : BaseDialog<TreasureFairyDialogResolveFairyResultBinding>() {
private lateinit var rvDelegate: RVDelegate<ResolveInfo>
private lateinit var prizeAdapter: ResolveFairyResultAdapter
override var width = WindowManager.LayoutParams.MATCH_PARENT
override var height = WindowManager.LayoutParams.WRAP_CONTENT
override var gravity = Gravity.CENTER
private val viewModel: FairyViewModel by activityViewModels()
companion object {
fun newInstance(resolveInfo: ResolveInfo): ResolveFairyResultDialog {
val args = Bundle()
args.putSerializable("resolveInfo",resolveInfo)
val fragment = ResolveFairyResultDialog()
fragment.arguments = args
return fragment
}
}
private val resolveInfo by lazy { requireArguments().getSerializable("resolveInfo") as ResolveInfo }
@SuppressLint("CheckResult")
override fun init() {
binding.tvClose.setOnClickListener {
dismissAllowingStateLoss()
}
prizeAdapter = ResolveFairyResultAdapter()
rvDelegate = RVDelegate.Builder<ResolveInfo>()
.setAdapter(prizeAdapter)
.setRecyclerView(binding.recyclerView)
.setLayoutManager(
LinearLayoutManager(context)
)
.build()
rvDelegate.setNewData(arrayListOf(resolveInfo))
viewModel.cleanTestParam()
viewModel.initDrawInfo()
}
}

View File

@@ -32,33 +32,33 @@ class TestFairyDialog : BaseDialog<TreasureFairyDialogTestFairyBinding>() {
@SuppressLint("CheckResult")
override fun init() {
binding?.ivBack?.setOnClickListener {
binding.ivBack.setOnClickListener {
dismissAllowingStateLoss()
}
binding?.tvRecord?.setOnClickListener {
binding.tvRecord.setOnClickListener {
TestFairyRecordDialog.newInstance().show(context)
}
binding?.rg?.setOnCheckedChangeListener { _, checkedId ->
binding.rg.setOnCheckedChangeListener { _, checkedId ->
when (checkedId) {
R.id.rb_epic -> binding?.viewPager?.currentItem = 0
R.id.rb_legend -> binding?.viewPager?.currentItem = 1
R.id.rb_epic -> binding.viewPager.currentItem = 0
R.id.rb_legend -> binding.viewPager.currentItem = 1
}
}
binding?.viewPager?.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
binding.viewPager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
override fun onPageSelected(position: Int) {
when (position) {
0 -> binding?.rg?.check(R.id.rb_epic)
1 -> binding?.rg?.check(R.id.rb_legend)
0 -> binding.rg.check(R.id.rb_epic)
1 -> binding.rg.check(R.id.rb_legend)
}
viewModel.cleanTestParam()
}
})
binding?.viewPager?.adapter = RoomVPAdapter(
binding.viewPager.adapter = RoomVPAdapter(
childFragmentManager,
listOf(
TestFairyFragment.newInstance(MyFairyItemView.BASE),
TestFairyFragment.newInstance(MyFairyItemView.EPIC)
TestFairyFragment.newInstance(MyFairyItemView.LEGEND)
)
)
viewModel.getMyFairyInfo()

View File

@@ -36,13 +36,13 @@ class TestFairyResultDialog : BaseDialog<TreasureFairyDialogTestFairyResultBindi
private val fairyInfo by lazy { requireArguments().getSerializable("fairyInfo") as FairyInfo }
@SuppressLint("CheckResult")
override fun init() {
binding?.tvClose?.setOnClickListener {
binding.tvClose.setOnClickListener {
dismissAllowingStateLoss()
}
prizeAdapter = TestFairyResultAdapter()
rvDelegate = RVDelegate.Builder<FairyInfo>()
.setAdapter(prizeAdapter)
.setRecyclerView(binding?.recyclerView)
.setRecyclerView(binding.recyclerView)
.setLayoutManager(
LinearLayoutManager(context)
)

View File

@@ -2,6 +2,7 @@ package com.yizhuan.erban.treasurefairy.fragment
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.View
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
@@ -21,7 +22,6 @@ import com.yizhuan.xchat_android_core.utils.toast
class ExchangeDebrisFragment :
BaseViewBindingFragment<TreasureFairyFragmentExchangeDebrisBinding>() {
companion object {
fun newInstance(): ExchangeDebrisFragment {
val args = Bundle()
@@ -49,7 +49,6 @@ class ExchangeDebrisFragment :
)
.setLayoutManager(GridLayoutManager(context, 2, LinearLayoutManager.VERTICAL, false))
.build()
viewModel.getDebrisExchangeList()
viewModel.debrisExchangeListLiveData.observe(viewLifecycleOwner) {
rvDelegate.setNewData(it)
}
@@ -61,8 +60,11 @@ class ExchangeDebrisFragment :
}
}
viewModel.getDebrisExchangeList()
viewModel.getMyFairyInfo()
binding.llMyDebris.visibility = View.VISIBLE
binding.rvMyFairy.visibility = View.GONE
viewModel.myFairyInfoLiveData.observe(viewLifecycleOwner) {
it?.let {
binding.tvDebrisNum.text = it.chipNum.toString()

View File

@@ -0,0 +1,102 @@
package com.yizhuan.erban.treasurefairy.fragment
import android.annotation.SuppressLint
import android.os.Bundle
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseViewBindingFragment
import com.yizhuan.erban.common.EmptyViewHelper
import com.yizhuan.erban.databinding.TreasureFairyFragmentExchangeDebrisBinding
import com.yizhuan.erban.treasurefairy.FairyViewModel
import com.yizhuan.erban.treasurefairy.adapter.ExchangeSummonAdapter
import com.yizhuan.erban.ui.utils.ImageLoadUtilsV2
import com.yizhuan.erban.ui.utils.RVDelegate
import com.yizhuan.erban.ui.utils.loadAvatar
import com.yizhuan.xchat_android_core.treasurefairy.ExchangeGiftInfo
import com.yizhuan.xchat_android_core.treasurefairy.FairyInfo
import com.yizhuan.xchat_android_core.user.UserModel
import com.yizhuan.xchat_android_core.utils.subAndReplaceDot
import com.yizhuan.xchat_android_core.utils.toast
class ExchangeSummonFragment :
BaseViewBindingFragment<TreasureFairyFragmentExchangeDebrisBinding>() {
companion object {
fun newInstance(): ExchangeSummonFragment {
val args = Bundle()
val fragment = ExchangeSummonFragment()
fragment.arguments = args
return fragment
}
}
private val viewModel: FairyViewModel by activityViewModels()
private lateinit var rvDelegate: RVDelegate<ExchangeGiftInfo>
private lateinit var exchangeSummonAdapter: ExchangeSummonAdapter
@SuppressLint("CheckResult")
override fun init() {
exchangeSummonAdapter = ExchangeSummonAdapter()
rvDelegate = RVDelegate.Builder<ExchangeGiftInfo>()
.setAdapter(exchangeSummonAdapter)
.setRecyclerView(binding.recyclerView)
.setEmptyView(
EmptyViewHelper.createEmptyTextViewNoImage(
context,
getString(R.string.fairy_no_further_data_is_available)
)
)
.setLayoutManager(GridLayoutManager(context, 2, LinearLayoutManager.VERTICAL, false))
.build()
viewModel.fairyCallInfoLiveData.observe(viewLifecycleOwner) {
rvDelegate.setNewData(it)
}
exchangeSummonAdapter.setOnItemChildClickListener { _, _, position ->
exchangeSummonAdapter.getItem(position)?.let {
dialogManager.showTipsDialog("您將要兌換“${it.getPrizeName()}", "兌換") {
viewModel.debrisExchange(it.itemId)
}
}
}
viewModel.getFairyCallList()
viewModel.getMyFairyInfo()
viewModel.myFairyInfoLiveData.observe(viewLifecycleOwner) {
it?.let {
binding.tvDebrisNum.text = it.chipNum.toString()
}
}
UserModel.get().cacheLoginUserInfo?.let {
binding.ivAvatar.loadAvatar(it.avatar)
binding.tvNickname.text = it.nick.subAndReplaceDot(7)
}
viewModel.debrisExchangeLiveData.observe(viewLifecycleOwner) {
it?.getContentIfNotHandled()?.let {
"兌換成功~".toast()
}
}
val myFairyAdapter =
object : BaseQuickAdapter<FairyInfo, BaseViewHolder>(R.layout.item_my_fairy) {
override fun convert(helper: BaseViewHolder, item: FairyInfo) {
ImageLoadUtilsV2.loadImage(helper.getView(R.id.iv_fairy), item.elfPicUrl)
helper.setText(R.id.tv_count, item.elfNum.toString())
}
}
binding.rvMyFairy.adapter = myFairyAdapter
viewModel.myFairyInfoLiveData.observe(this) {
it?.let {
myFairyAdapter.setNewData(it.highElves?.take(3))
}
}
}
}

View File

@@ -33,8 +33,6 @@ class MyFairyFragment : BaseViewBindingFragment<TreasureFairyFragmentMyFairyBind
binding.fairyItem0,
binding.fairyItem1,
binding.fairyItem2,
binding.fairyItem3,
binding.fairyItem4
)
fairyItems.forEach {
it.setFairyType(fairyType)

View File

@@ -2,6 +2,8 @@ package com.yizhuan.erban.treasurefairy.fragment
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
@@ -10,7 +12,9 @@ import com.yizhuan.erban.base.BaseViewBindingFragment
import com.yizhuan.erban.common.EmptyViewHelper
import com.yizhuan.erban.databinding.TreasureFairyFragmentTestFairyBinding
import com.yizhuan.erban.treasurefairy.FairyViewModel
import com.yizhuan.erban.treasurefairy.adapter.ResolveFairyAdapter
import com.yizhuan.erban.treasurefairy.adapter.TestFairyAdapter
import com.yizhuan.erban.treasurefairy.dialog.ResolveFairyResultDialog
import com.yizhuan.erban.treasurefairy.dialog.TestFairyResultDialog
import com.yizhuan.erban.treasurefairy.view.MyFairyItemView
import com.yizhuan.erban.ui.utils.RVDelegate
@@ -19,7 +23,6 @@ import com.yizhuan.xchat_android_core.treasurefairy.FairyInfo
class TestFairyFragment : BaseViewBindingFragment<TreasureFairyFragmentTestFairyBinding>() {
companion object {
fun newInstance(fairyType: Int): TestFairyFragment {
val args = Bundle()
@@ -34,6 +37,7 @@ class TestFairyFragment : BaseViewBindingFragment<TreasureFairyFragmentTestFairy
private val viewModel: FairyViewModel by activityViewModels()
private lateinit var rvDelegate: RVDelegate<FairyInfo>
private lateinit var testFairyAdapter: TestFairyAdapter
private lateinit var resolveFairyAdapter: ResolveFairyAdapter
private val showResultRunnable = Runnable {
if (canShowResult) {
@@ -51,44 +55,69 @@ class TestFairyFragment : BaseViewBindingFragment<TreasureFairyFragmentTestFairy
resultNotShowed = true
}
}
/**
* 获得精灵碎片
*/
private val showResolveResultRunnable = Runnable {
if (canShowResult) {
canShowResult = false
binding.ivBegin.isEnabled = true
viewModel.resolveResultLiveData.value?.peekContent()?.let {
ResolveFairyResultDialog.newInstance(it).show(context)
}
} else {
resultNotShowed = true
}
}
private var canShowResult = false
private var resultNotShowed = false
@SuppressLint("CheckResult")
override fun init() {
val fairyViews = listOf(binding.ivFairy0, binding.ivFairy1, binding.ivFairy2)
val fairyViews = listOf(
binding.ivFairy0,
binding.ivFairy1,
binding.ivFairy2,
binding.ivFairy3,
binding.ivFairy4
)
val fairyResolveViews = listOf(binding.ivFairy3)
testFairyAdapter = TestFairyAdapter()
resolveFairyAdapter = ResolveFairyAdapter()
rvDelegate = RVDelegate.Builder<FairyInfo>()
.setAdapter(testFairyAdapter)
.setEmptyView(EmptyViewHelper.createEmptyTextViewNoImage(
context,
getString(R.string.fairy_no_further_data_is_available)
))
.setAdapter(if(fairyType == MyFairyItemView.BASE) resolveFairyAdapter else testFairyAdapter)
.setEmptyView(
EmptyViewHelper.createEmptyTextViewNoImage(
context,
getString(R.string.fairy_no_further_data_is_available)
)
)
.setRecyclerView(binding.recyclerView)
.setLayoutManager(GridLayoutManager(context, 5, LinearLayoutManager.VERTICAL, false))
.setLayoutManager(GridLayoutManager(context, if(fairyType == MyFairyItemView.BASE) 6 else 3 , LinearLayoutManager.VERTICAL, false))
.build()
viewModel.myFairyInfoLiveData.observe(viewLifecycleOwner) {
val fairyInfos = it?.let {
when (fairyType) {
MyFairyItemView.EPIC -> {
it.middleElves
}
else -> {
it.lowElves
}
}
val fairyInfos = it?.lowElves
if(fairyType == MyFairyItemView.BASE) {
val list = mutableListOf<FairyInfo>()
it?.lowElves?.take(3)?.let { it1 -> list.addAll(it1) }
it?.highElves?.take(3)?.let { it2 -> list.addAll(it2) }
rvDelegate.setNewData(list)
} else {
rvDelegate.setNewData(fairyInfos?.take(3))
}
rvDelegate.setNewData(fairyInfos)
}
if (fairyType == MyFairyItemView.EPIC) {
binding.tvTips.text = "點擊投入試煉傳說精靈"
resolveFairyAdapter.setOnItemClickListener { _, _, position ->
resolveFairyAdapter.getItem(position)?.let {
viewModel.addTestFairy(it, 1)
}
}
testFairyAdapter.setOnItemClickListener { _, _, position ->
testFairyAdapter.getItem(position)?.let {
viewModel.addTestFairy(it)
viewModel.addTestFairy(it, 5)
}
}
@@ -97,20 +126,53 @@ class TestFairyFragment : BaseViewBindingFragment<TreasureFairyFragmentTestFairy
viewModel.minusTestFairy(index)
}
}
fairyResolveViews.forEachIndexed { index, imageView ->
imageView.setOnClickListener {
viewModel.minusTestFairy(index)
}
}
binding.tvReset.setOnClickListener {
viewModel.cleanTestParam()
}
binding.tvOneKeyAdd.setOnClickListener {
viewModel.oneKeyAdd(testFairyAdapter.data)
if (fairyType == MyFairyItemView.BASE) {
viewModel.oneKeyAdd(resolveFairyAdapter.data, 1)
} else {
viewModel.oneKeyAdd(testFairyAdapter.data, 5)
}
}
if (fairyType == MyFairyItemView.EPIC) {
if (fairyType == MyFairyItemView.BASE) {
binding.viewBgAnim.setBackgroundResource(R.drawable.treasure_fairy_bg_test_fairy_anim_legend)
val p = binding.ivFairy3.layoutParams as ConstraintLayout.LayoutParams
p.verticalBias = 0.9f
binding.tvResolveTips.visibility = View.VISIBLE
binding.tvResolveTips.text = getString(R.string.tips_fairy_resolve_low)
binding.viewBgTop.setBackgroundResource(R.drawable.treasure_fairy_bg_test_fairy_legend)
binding.ivBegin.setBackgroundResource(R.drawable.treasure_fairy_bg_resolve_fairy_begin)
binding.tvTips.text = "點擊投入需要分解的精靈"
} else {
binding.viewBgAnim.setBackgroundResource(R.drawable.treasure_fairy_bg_test_fairy_anim_epic)
val p = binding.ivFairy3.layoutParams as ConstraintLayout.LayoutParams
p.verticalBias = 0.94f
binding.tvResolveTips.visibility = View.GONE
binding.viewBgTop.setBackgroundResource(R.drawable.treasure_fairy_bg_test_fairy)
binding.ivBegin.setBackgroundResource(R.drawable.treasure_fairy_bg_test_fairy_begin)
binding.tvTips.text = "點擊投入試煉傳說精靈"
}
binding.ivBegin.setOnClickListener {
if (viewModel.testFairy(fairyType)) {
if (fairyType == MyFairyItemView.BASE) {
if (viewModel.resolveFairy()) {
binding.animView.startPlay(
requireContext().assets,
"vap/test_fairy_anim_epic.mp4"
)
binding.ivBegin.isEnabled = false
canShowResult = false
binding.ivBegin.postDelayed(showResolveResultRunnable, 1800)
}
} else if (viewModel.testFairy(fairyType)) {
binding.animView.startPlay(
requireContext().assets,
if (fairyType == MyFairyItemView.BASE) {
@@ -146,15 +208,47 @@ class TestFairyFragment : BaseViewBindingFragment<TreasureFairyFragmentTestFairy
binding.ivBegin.isEnabled = true
}
}
viewModel.compoundFairyInfosLiveData.observe(viewLifecycleOwner) {
fairyViews.forEachIndexed { index, imageView ->
it?.get(index)?.elfPicUrl?.let { elfPicUrl ->
imageView.load(elfPicUrl)
} ?: run {
imageView.setImageDrawable(null)
//分解碎片
viewModel.resolveResultLiveData.observe(viewLifecycleOwner) {
it?.getContentIfNotHandled()?.let {
canShowResult = true
if (resultNotShowed) {
showResultRunnable.run()
}
} ?: run {
binding.ivBegin.isEnabled = true
}
}
viewModel.compoundFairyInfosLiveData.observe(viewLifecycleOwner) {
if (fairyType == MyFairyItemView.BASE) {
fairyResolveViews.forEachIndexed { index, imageView ->
it?.get(index)?.elfPicUrl?.let { elfPicUrl ->
binding.tvResolveTips.text = getString(
if (it[index].level == FairyInfo.LEVEL_HIGH) {
R.string.tips_fairy_resolve_high
} else {
R.string.tips_fairy_resolve_low
}
)
imageView.load(elfPicUrl)
} ?: run {
binding.tvResolveTips.text = getString(R.string.tips_fairy_resolve_low)
imageView.setImageDrawable(null)
}
}
resolveFairyAdapter.notifyDataSetChanged()
} else {
fairyViews.forEachIndexed { index, imageView ->
it?.get(index)?.elfPicUrl?.let { elfPicUrl ->
imageView.load(elfPicUrl)
} ?: run {
imageView.setImageDrawable(null)
}
}
testFairyAdapter.notifyDataSetChanged()
}
testFairyAdapter.notifyDataSetChanged()
}
}

View File

@@ -22,13 +22,13 @@ import com.yizhuan.erban.ui.im.avtivity.NimP2PMessageActivity;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderAudioParty;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderChatHint;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderContent;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderP2PContactRecharge;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderFairy;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderGift;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderHello;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderLevel;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderLottery;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderOnline;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderP2PContactRecharge;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderRedPackage;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderRedPacket;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderSkill;
@@ -44,7 +44,6 @@ import com.yizhuan.xchat_android_core.im.custom.bean.CarAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.CarveUpGoldThirdLevelAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.ChatHintAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.CpInviteAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.P2PContactRechargeAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.FairySendAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.GiftAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.InAppSharingFamilyAttachment;
@@ -60,6 +59,7 @@ import com.yizhuan.xchat_android_core.im.custom.bean.NobleAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.NoticeAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.OpenRoomNotiAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.OpenSignInAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.P2PContactRechargeAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RedPackageAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RedPacketAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.SkillMsgAttachment;

View File

@@ -3,35 +3,25 @@ package com.yizhuan.erban.ui.pay;
import android.app.Activity;
import android.util.Log;
import androidx.annotation.NonNull;
import com.alibaba.fastjson.JSONObject;
import com.android.billingclient.api.AcknowledgePurchaseParams;
import com.android.billingclient.api.AcknowledgePurchaseResponseListener;
import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingClient.BillingResponseCode;
import com.android.billingclient.api.BillingClient.SkuType;
import com.android.billingclient.api.BillingClientStateListener;
import com.android.billingclient.api.BillingFlowParams;
import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.ConsumeParams;
import com.android.billingclient.api.ConsumeResponseListener;
import com.android.billingclient.api.ProductDetails;
import com.android.billingclient.api.ProductDetailsResponseListener;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.Purchase.PurchasesResult;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.SkuDetails;
import com.android.billingclient.api.SkuDetailsParams;
import com.android.billingclient.api.SkuDetailsResponseListener;
import com.yizhuan.erban.event.ChargeEvent;
import com.android.billingclient.api.QueryProductDetailsParams;
import com.android.billingclient.api.QueryPurchasesParams;
import org.greenrobot.eventbus.EventBus;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class BillingManager implements PurchasesUpdatedListener {
@@ -55,9 +45,6 @@ public class BillingManager implements PurchasesUpdatedListener {
/*商品列表*/
private final List<Purchase> purchaseList = new ArrayList<>();
/*消耗令牌*/
private Set<String> mTokensToBeConsumed;
/*监听接口*/
public interface BillingUpdatesListener {
void onBillingClientSetupFinished();
@@ -109,32 +96,19 @@ public class BillingManager implements PurchasesUpdatedListener {
/*请求商品库存*/
public void onQueryPurchases() {
Runnable queryToExecute = () -> {
//系统当前时间
long time = System.currentTimeMillis();
//请求内购商品
PurchasesResult purchasesResult = billingClient.queryPurchases(SkuType.INAPP);
onQueryPurchasesFinished(purchasesResult);
};
Runnable queryToExecute = () ->
billingClient.queryPurchasesAsync(
QueryPurchasesParams.newBuilder()
.setProductType(BillingClient.ProductType.INAPP)
.build(), this::onPurchasesUpdated);
executeServiceRequest(queryToExecute);
}
/*请求商品信息完成*/
private void onQueryPurchasesFinished(PurchasesResult result) {
if (billingClient == null || result.getResponseCode() != BillingResponseCode.OK) {
Log.w(TAG, "billingClient is null or result code (" + result.getResponseCode()
+ ") was bad - quitting");
return;
}
purchaseList.clear();
onPurchasesUpdated(result.getBillingResult(), result.getPurchasesList());
}
/*更新商品*/
@Override
public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
//Log.i(TAG, "billingResult.getResponseCode()==" + billingResult.getResponseCode() + ",purchases.size()==" + purchases.size());
Log.i(TAG, "billingResult.getResponseCode()==" + billingResult.getResponseCode() + ",purchases.size()==" + purchases.size());
purchaseList.clear();
if (billingResult.getResponseCode() == BillingResponseCode.OK) {
for (Purchase purchase : purchases) {
handlePurchase(purchase);
@@ -178,28 +152,46 @@ public class BillingManager implements PurchasesUpdatedListener {
}
/*查询内购商品详情*/
public void querySkuDetailsAsync(@SkuType final String itemType, final List<String> skuList,
final SkuDetailsResponseListener listener) {
public void querySkuDetailsAsync(final List<String> productIdList,
final ProductDetailsResponseListener listener) {
Runnable queryRequest = () -> {
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList)
.setType(itemType);
billingClient.querySkuDetailsAsync(params.build(), listener);
ArrayList<QueryProductDetailsParams.Product> products = new ArrayList<>();
for (String productId : productIdList) {
products.add(QueryProductDetailsParams.Product.newBuilder()
.setProductId(productId)
.setProductType(BillingClient.ProductType.INAPP)
.build());
}
QueryProductDetailsParams queryProductDetailsParams =
QueryProductDetailsParams.newBuilder()
.setProductList(products)
.build();
billingClient.queryProductDetailsAsync(
queryProductDetailsParams,
listener
);
};
executeServiceRequest(queryRequest);
}
/*启动购买,订购流程*/
public void initiatePurchaseFlow(final SkuDetails skuDetails, String recordId) {
public void initiatePurchaseFlow(final ProductDetails productDetails, String recordId) {
Runnable purchaseFlowRequest = () -> {
BillingFlowParams.ProductDetailsParams p = BillingFlowParams.ProductDetailsParams.newBuilder()
.setProductDetails(productDetails)
.build();
JSONObject jsonObject = new JSONObject();
jsonObject.put("p", skuDetails.getPrice());
jsonObject.put("a", skuDetails.getPriceAmountMicros() / 10000);
jsonObject.put("c", skuDetails.getPriceCurrencyCode());
ProductDetails.OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails = productDetails.getOneTimePurchaseOfferDetails();
if (oneTimePurchaseOfferDetails != null) {
jsonObject.put("p", oneTimePurchaseOfferDetails.getFormattedPrice());
jsonObject.put("a", oneTimePurchaseOfferDetails.getPriceAmountMicros() / 10000);
jsonObject.put("c", oneTimePurchaseOfferDetails.getPriceCurrencyCode());
}
BillingFlowParams purchaseParams = BillingFlowParams.newBuilder()
.setObfuscatedAccountId(recordId)
.setObfuscatedProfileId(jsonObject.toJSONString())
.setSkuDetails(skuDetails)
.setProductDetailsParamsList(List.of(p))
.build();
BillingResult billingResult = billingClient.launchBillingFlow(mActivity, purchaseParams);
Log.i(TAG, " initiatePurchaseFlow billingResult=" + billingResult.getResponseCode() + " " + billingResult.getDebugMessage());
@@ -208,28 +200,10 @@ public class BillingManager implements PurchasesUpdatedListener {
}
public void consumeAsync(final String purchaseToken) {
if (mTokensToBeConsumed == null) {
mTokensToBeConsumed = new HashSet<>();
} else if (mTokensToBeConsumed.contains(purchaseToken)) {
Log.i(TAG, "Token was already scheduled to be consumed - skipping...");
return;
}
mTokensToBeConsumed.add(purchaseToken);
final ConsumeParams consumeParams = ConsumeParams.newBuilder().setPurchaseToken(purchaseToken).build();
final ConsumeResponseListener consumeResponseListener = new ConsumeResponseListener() {
@Override
public void onConsumeResponse(@NonNull @NotNull BillingResult billingResult, @NonNull @NotNull String s) {
mBillingUpdatesListener.onConsumeFinished(purchaseToken, billingResult.getResponseCode());
}
};
executeServiceRequest(() -> billingClient.consumeAsync(consumeParams, consumeResponseListener));
}
public void acknowledgePurchase(AcknowledgePurchaseParams acknowledgePurchaseParams, AcknowledgePurchaseResponseListener Listener) {
billingClient.acknowledgePurchase(acknowledgePurchaseParams, Listener);
executeServiceRequest(() -> billingClient.consumeAsync(consumeParams, (billingResult, s) ->
mBillingUpdatesListener.onConsumeFinished(purchaseToken, billingResult.getResponseCode())));
}
/**

View File

@@ -24,8 +24,8 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.ProductDetails;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.SkuDetails;
import com.appsflyer.AFInAppEventParameterName;
import com.appsflyer.AFInAppEventType;
import com.appsflyer.AppsFlyerLib;
@@ -186,19 +186,19 @@ public class ChargeActivity extends BaseMvpActivity<IChargeView, ChargePresenter
productKeys.add(chargeBean.getChargeProdId());
}
mChargeAdapter.setNewData(chargeBeanList);
billingManager.querySkuDetailsAsync(BillingClient.SkuType.INAPP, productKeys, (billingResult, skuDetailsList) -> {
billingManager.querySkuDetailsAsync(productKeys, (billingResult, productDetails) -> {
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
Log.w(TAG, "Unsuccessful query for type: " + BillingClient.SkuType.INAPP
Log.w(TAG, "Unsuccessful query for type: " + BillingClient.ProductType.INAPP
+ ". Error code: " + billingResult.getResponseCode());
getDialogManager().dismissDialog();
toast(getString(R.string.Recharge_failure));
} else if (skuDetailsList != null && skuDetailsList.size() > 0) {
} else if (productDetails.size() > 0) {
getDialogManager().dismissDialog();
List<ChargeBean> showChargeList = new ArrayList<>();
for (ChargeBean chargeBean : chargeBeanList) {
for (SkuDetails skuDetails : skuDetailsList) {
if (skuDetails.getSku().equals(chargeBean.getChargeProdId())) {
chargeBean.setSkuDetails(skuDetails);
for (ProductDetails product : productDetails) {
if (product.getProductId().equals(chargeBean.getChargeProdId())) {
chargeBean.setProductDetails(product);
showChargeList.add(chargeBean);
break;
}
@@ -221,30 +221,28 @@ public class ChargeActivity extends BaseMvpActivity<IChargeView, ChargePresenter
purchase.getAccountIdentifiers() != null) {
PayModel.get().verifyOrder(
purchase.getAccountIdentifiers().getObfuscatedAccountId(),
purchase.getSkus().get(0),
purchase.getProducts().get(0),
purchase.getPackageName(),
purchase.getPurchaseToken())
.compose(bindToLifecycle())
.subscribe(
token -> {
//L.i("token=" + token);
.subscribe(token -> {
billingManager.consumeAsync(token);
SkuDetails skuDetails = null;
ProductDetails productDetails = null;
for (ChargeBean datum : mChargeAdapter.getData()) {
if (datum.getChargeProdId().equals(purchase.getSkus().get(0))) {
skuDetails = datum.getSkuDetails();
if (datum.getChargeProdId().equals(purchase.getProducts().get(0))) {
productDetails = datum.getProductDetails();
break;
}
}
if (skuDetails != null) {
if (productDetails != null) {
Map<String, Object> eventValue = new HashMap<>();
eventValue.put(AFInAppEventParameterName.CONTENT_TYPE, "Gold");
eventValue.put(AFInAppEventParameterName.QUANTITY, 1);
eventValue.put(AFInAppEventParameterName.CONTENT_ID, purchase.getOrderId());
eventValue.put(AFInAppEventParameterName.REVENUE, skuDetails.getPriceAmountMicros() / 1000000f);
eventValue.put("Price", skuDetails.getPrice());
eventValue.put(AFInAppEventParameterName.CURRENCY, skuDetails.getPriceCurrencyCode());
eventValue.put(AFInAppEventParameterName.REVENUE, productDetails.getOneTimePurchaseOfferDetails().getPriceAmountMicros() / 1000000f);
eventValue.put("Price", productDetails.getOneTimePurchaseOfferDetails().getFormattedPrice());
eventValue.put(AFInAppEventParameterName.CURRENCY, productDetails.getOneTimePurchaseOfferDetails().getPriceCurrencyCode());
AppsFlyerLib.getInstance().logEvent(getApplicationContext(), AFInAppEventType.PURCHASE, eventValue);
}
},
@@ -269,12 +267,12 @@ public class ChargeActivity extends BaseMvpActivity<IChargeView, ChargePresenter
/*购买商品*/
@SuppressLint("CheckResult")
public void buyProduct(SkuDetails skuDetails) {
if (skuDetails != null) {
Log.d(TAG, "BuyProduct:" + skuDetails.getSku());
PayModel.get().placeOrder(skuDetails.getSku())
public void buyProduct(ProductDetails productDetails) {
if (productDetails != null) {
Log.d(TAG, "BuyProduct:" + productDetails.getProductId());
PayModel.get().placeOrder(productDetails.getProductId())
.compose(bindToLifecycle())
.subscribe(recordId -> billingManager.initiatePurchaseFlow(skuDetails, recordId.getRecordId()),
.subscribe(recordId -> billingManager.initiatePurchaseFlow(productDetails, recordId.getRecordId()),
throwable -> {
if (throwable instanceof FailReasonException) {
FailReasonException failReasonException = (FailReasonException) throwable;
@@ -342,8 +340,8 @@ public class ChargeActivity extends BaseMvpActivity<IChargeView, ChargePresenter
}
if (mChargePosition != -1) {
ChargeBean bean = mChargeAdapter.getItem(mChargePosition);
if (bean != null && bean.getSkuDetails() != null) {
buyProduct(bean.getSkuDetails());
if (bean != null && bean.getProductDetails() != null) {
buyProduct(bean.getProductDetails());
//点击充值
HashMap<String, Object> map = new HashMap<>(3);
map.put(IReportConstants.MONEY, bean.money);

View File

@@ -21,8 +21,8 @@ public class ChargeAdapter extends BaseQuickAdapter<ChargeBean, BaseViewHolder>
if (chargeBean == null) return;
baseViewHolder.getView(R.id.ll_bg).setSelected(chargeBean.isSelected);
baseViewHolder.setText(R.id.tv_title, chargeBean.getProdName());
if (chargeBean.getSkuDetails() != null) {
baseViewHolder.setText(R.id.item_charge_money, chargeBean.getSkuDetails().getPrice());
if (chargeBean.getProductDetails() != null) {
baseViewHolder.setText(R.id.item_charge_money, chargeBean.getProductDetails().getOneTimePurchaseOfferDetails().getFormattedPrice());
} else {
baseViewHolder.setText(R.id.item_charge_money, "USD$" + chargeBean.getMoney());
}

View File

@@ -316,7 +316,7 @@ public class ImageLoadUtils {
GlideApp.with(context)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(R.drawable.default_avatar)
.placeholder(R.drawable.default_cover)
.transform(new BlurTransformation(context, blur, scale))
.into(imageView);
}

View File

@@ -40,7 +40,7 @@ public class FairyDialogWebViewActivity extends CommonWebViewActivity {
getWindow().setGravity(Gravity.BOTTOM);
View layoutRoot = findViewById(R.id.ll_root);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) layoutRoot.getLayoutParams();
layoutParams.height = ScreenUtil.screenWidth * 1100 / 750;
layoutParams.height = ScreenUtil.screenWidth * 1245 / 750;
layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT;
layoutRoot.setLayoutParams(layoutParams);
layoutTitleBar.setVisibility(View.GONE);

View File

@@ -0,0 +1,92 @@
package com.yizhuan.erban.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.yizhuan.erban.R;
/**
* @author wzq
*/
public class ShadowFrameLayout extends FrameLayout {
private Paint mShadowPaint;
private float mCornerRadius;
/**
* 只有上面有阴影
*/
private boolean mShadowTop;
private float mShadowRadius;
private RectF mRectF;
public ShadowFrameLayout(@NonNull Context context) {
this(context, null);
}
public ShadowFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public ShadowFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShadowFrameLayout);
int shadowColor = typedArray.getColor(R.styleable.ShadowFrameLayout_shadowColor,
ContextCompat.getColor(context, R.color.color_1E686868));
int backgroundColor = typedArray.getColor(R.styleable.ShadowFrameLayout_backgroundColor, Color.WHITE);
mShadowRadius = typedArray.getDimension(R.styleable.ShadowFrameLayout_shadowRadius, 0);
mCornerRadius = typedArray.getDimension(R.styleable.ShadowFrameLayout_cornerRadius, 0);
mShadowTop = typedArray.getBoolean(R.styleable.ShadowFrameLayout_shadowTop, false);
typedArray.recycle();
mShadowPaint = new Paint();
mShadowPaint.setShadowLayer(mShadowRadius, 0, 0, shadowColor);
mShadowPaint.setAntiAlias(true);
mShadowPaint.setColor(backgroundColor);
setLayerType(LAYER_TYPE_SOFTWARE, null);
mRectF = new RectF();
}
@Override
public void setBackgroundColor(@ColorInt int color) {
mShadowPaint.setColor(color);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int measuredWidth = getMeasuredWidth();
int measuredHeight = getMeasuredHeight();
if (mShadowTop) {
// 矩形只有上方有阴影
mRectF.set(0, mShadowRadius, measuredWidth, measuredHeight + mCornerRadius);
} else {
// 环绕阴影
mRectF.set(mShadowRadius, mShadowRadius, measuredWidth - mShadowRadius, measuredHeight - mShadowRadius);
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.drawRoundRect(mRectF, mCornerRadius, mCornerRadius, mShadowPaint);
super.dispatchDraw(canvas);
}
}

View File

@@ -14,8 +14,8 @@ import androidx.core.view.isVisible
import androidx.recyclerview.widget.GridLayoutManager
import com.android.billingclient.api.BillingClient
import com.android.billingclient.api.BillingResult
import com.android.billingclient.api.ProductDetails
import com.android.billingclient.api.Purchase
import com.android.billingclient.api.SkuDetails
import com.appsflyer.AFInAppEventParameterName
import com.appsflyer.AFInAppEventType
import com.appsflyer.AppsFlyerLib
@@ -233,12 +233,12 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
binding.tvOpenVip.setOnClickListener {
if (AppMetaDataUtil.getChannelID().equals(Constants.GOOGLE)) {
if ((googleChargeBean?.skuDetails?.price ?: "0") == "0") {
if ((googleChargeBean?.productDetails?.oneTimePurchaseOfferDetails?.priceAmountMicros ?: "0") == "0") {
toast(getString(R.string.Recharge_failure))
return@setOnClickListener
}
SelectPayTypeDialog.newInstance(
googleChargeBean?.skuDetails?.price ?: "0",
googleChargeBean?.productDetails?.oneTimePurchaseOfferDetails?.formattedPrice ?: "0",
true,
googleChargeBean?.getMoney() ?: 0.0
)
@@ -248,7 +248,7 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
}
setOnGoogleChargeClick {
googleChargeBean?.let { charge ->
buyProduct(charge.skuDetails)
buyProduct(charge.productDetails)
}
}
setOnChargeClick {
@@ -396,20 +396,18 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
chargeInfo?.let { chargeBean ->
val productKeys: MutableList<String> = ArrayList()
productKeys.add(chargeBean.getChargeProdId())
billingManager?.querySkuDetailsAsync(
BillingClient.SkuType.INAPP, productKeys
) { billingResult: BillingResult, skuDetailsList: List<SkuDetails>? ->
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 (skuDetailsList != null && skuDetailsList.isNotEmpty()) {
} else if (productDetails.isNotEmpty()) {
val showChargeList: MutableList<ChargeBean> = ArrayList()
for (skuDetails in skuDetailsList) {
if (skuDetails.sku == chargeBean.getChargeProdId()) {
chargeBean.skuDetails = skuDetails
for (skuDetails in productDetails) {
if (skuDetails.productId == chargeBean.getChargeProdId()) {
chargeBean.productDetails = skuDetails
showChargeList.add(chargeBean)
break
}
@@ -439,7 +437,7 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
) {
PayModel.get().verifyOrder(
purchase.accountIdentifiers!!.obfuscatedAccountId,
purchase.skus[0],
purchase.products[0],
purchase.packageName,
purchase.purchaseToken
)
@@ -448,21 +446,21 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
{ token: String? ->
//L.i("token=" + token);
billingManager?.consumeAsync(token)
var skuDetails: SkuDetails? = null
if (googleChargeBean?.getChargeProdId() == purchase.skus[0]) {
skuDetails = googleChargeBean?.skuDetails
var skuDetails: ProductDetails? = null
if (googleChargeBean?.getChargeProdId() == purchase.products[0]) {
skuDetails = googleChargeBean?.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.priceAmountMicros / 1000000f
eventValue["Price"] = skuDetails.price
skuDetails.oneTimePurchaseOfferDetails?.priceAmountMicros!! / 1000000f
eventValue["Price"] = skuDetails.oneTimePurchaseOfferDetails?.formattedPrice!!
eventValue[AFInAppEventParameterName.CURRENCY] =
skuDetails.priceCurrencyCode
skuDetails.oneTimePurchaseOfferDetails?.priceCurrencyCode!!
AppsFlyerLib.getInstance().logEvent(
applicationContext,
AFInAppEventType.PURCHASE,
@@ -490,15 +488,15 @@ class VipMainActivity : BaseViewBindingActivity<ActivityVipMainBinding>(),
/*购买商品*/
@SuppressLint("CheckResult")
fun buyProduct(skuDetails: SkuDetails?) {
if (skuDetails != null) {
Log.d(TAG, "BuyProduct:" + skuDetails.sku)
PayModel.get().placeOrder(skuDetails.sku)
fun buyProduct(productDetails: ProductDetails?) {
if (productDetails != null) {
Log.d(TAG, "BuyProduct:" + productDetails.productId)
PayModel.get().placeOrder(productDetails.productId)
.compose(bindToLifecycle())
.subscribe(
{ recordId: PayRecordId ->
billingManager?.initiatePurchaseFlow(
skuDetails,
productDetails,
recordId.recordId
)
}

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/white" android:state_checked="true" />
<item android:color="@color/color_9168FA" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 367 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -0,0 +1,15 @@
<?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="#ff284d5a"
android:startColor="#ff17303c"
android:type="linear"
android:useLevel="true" />
<stroke
android:width="0.5dp"
android:color="@color/color_white_60" />
<corners
android:radius="@dimen/dp_15" />
</shape>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#19ffffff" />
<corners android:radius="@dimen/dp_10" />
</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">
<solid android:color="#19ffffff" />
<corners android:radius="@dimen/dp_10" />
<stroke
android:width="0.5dp"
android:color="@color/color_F2DE84" />
</shape>

View File

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

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_24" />
<gradient
android:endColor="@color/color_CF70FF"
android:startColor="#5AECFA" />
</shape>

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_8" />
<solid android:color="@color/color_001338" />
</shape>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="@dimen/dp_4" />
<solid android:color="@color/color_001338" />
<stroke
android:width="@dimen/dp_1"
android:color="@color/color_D6D6D6" />
</shape>

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