夺宝精灵:主页接口对接

This commit is contained in:
huangjian
2023-02-17 18:10:09 +08:00
parent fb8f36929f
commit 9ddc66b4ae
12 changed files with 326 additions and 46 deletions

View File

@@ -0,0 +1,74 @@
package com.mango.moshen.treasurefairy
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.mango.moshen.base.BaseViewModel
import com.mango.core.bean.response.ListResult
import com.mango.core.home.bean.HomeRoomInfo
import com.mango.core.home.model.HomeModel
import com.mango.core.treasurefairy.DrawInfo
import com.mango.core.treasurefairy.PrizeInfo
import com.mango.core.treasurefairy.TreasureFairyModel
import com.mango.core.utils.net.ServerException
import com.mango.core.utils.toast
import com.mango.moshen.base.Event
class FairyViewModel : BaseViewModel() {
private val _drawInfoLiveData = MutableLiveData<DrawInfo>()
val drawInfoLiveData: LiveData<DrawInfo> = _drawInfoLiveData
private val _prizeInfoListLiveData = MutableLiveData<List<PrizeInfo>>()
val prizeInfoListLiveData: LiveData<List<PrizeInfo>> = _prizeInfoListLiveData
private val _resultLiveData = MutableLiveData<Event<List<PrizeInfo>>>()
val resultLiveData: LiveData<Event<List<PrizeInfo>>> = _resultLiveData
private val _showGetKeyLiveData = MutableLiveData<Event<Boolean>>()
val showGetKeyLiveData: LiveData<Event<Boolean>> = _showGetKeyLiveData
init {
initPrizeInfoList()
}
fun initDrawInfo() {
safeLaunch(
onError = {
_drawInfoLiveData.value = null
},
block = {
_drawInfoLiveData.value = TreasureFairyModel.getDrawInfo()
}
)
}
private fun initPrizeInfoList() {
safeLaunch(
onError = {
_prizeInfoListLiveData.value = null
},
block = {
_prizeInfoListLiveData.value = TreasureFairyModel.getPrizeInfoList()
}
)
}
fun drawFairy(drawNum: Int) {
safeLaunch(
onError = {
if (it is ServerException && it.code == 211188) {
_showGetKeyLiveData.value = Event(true)
} else {
it.message.toast()
}
_resultLiveData.value = null
},
block = {
val result = TreasureFairyModel.drawTreasureFairy(drawNum)
_resultLiveData.value = result?.let { Event(it) }
_drawInfoLiveData.value = TreasureFairyModel.getDrawInfo()
}
)
}
}

View File

@@ -6,63 +6,145 @@ import android.graphics.Path
import android.view.*
import android.widget.LinearLayout
import android.widget.TextView
import androidx.fragment.app.activityViewModels
import com.mango.core.UriProvider
import com.mango.core.treasurefairy.PrizeInfo
import com.mango.moshen.R
import com.mango.moshen.base.BaseDialog
import com.mango.moshen.common.widget.dialog.DialogManager
import com.mango.moshen.databinding.TreasureFairyDialogHomeBinding
import com.mango.treasure_box.bean.PrizeInfo
import com.mango.moshen.ui.webview.ElfDialogWebViewActivity
import com.netease.nim.uikit.common.util.sys.ScreenUtil
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import java.util.concurrent.TimeUnit
class HomeDialog : BaseDialog<TreasureFairyDialogHomeBinding>() {
private var selectIndex = 0
private var targetIndex: Int = -1
private val removeRunnable = Runnable { binding.llPrizeHint.removeAllViews() }
private val hintPrizeCacheList = ArrayList<PrizeInfo>()
override var width = WindowManager.LayoutParams.MATCH_PARENT
override var gravity = Gravity.BOTTOM
override fun init() {
val views = listOf<View>(
private var disposable: Disposable? = null
private val viewModel: FairyViewModel by activityViewModels()
private val fairyItems by lazy {
listOf(
binding.fairyItem0, binding.fairyItem1, binding.fairyItem2, binding.fairyItem3,
binding.fairyItem4, binding.fairyItem5, binding.fairyItem6, binding.fairyItem7,
binding.fairyItem8, binding.fairyItem9, binding.fairyItem10, binding.fairyItem11
)
}
Observable.interval(100, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.compose(bindToLifecycle())
.doOnNext {
views[selectIndex].isSelected = false
selectIndex++
if (selectIndex == views.size) selectIndex = 0
views[selectIndex].isSelected = true
}
.subscribe()
binding.ivLuckyStone.post {
val drawable = CustomDrawable(binding.ivLuckyStone.drawable)
val path = Path()
path.addRect(
0f,
0f,
binding.ivLuckyStone.width.toFloat(),
binding.ivLuckyStone.height.toFloat() / 2,
Path.Direction.CW
)
drawable.setSrcPath(path)
binding.ivLuckyStone.setImageDrawable(drawable)
@SuppressLint("SetTextI18n")
override fun init() {
looperHintPrize()
binding.tvKeyNum.setOnClickListener {
ElfDialogWebViewActivity.start(context, UriProvider.getFairyKey())
}
binding.ivOpen1.setOnClickListener {
HomePrizeDialog.newInstance().show(context)
}
binding.ivMyFairy.setOnClickListener {
MyFairyDialog.newInstance().show(context)
}
binding.ivOpen1.setOnClickListener {
rotatePrize()
viewModel.drawFairy(1)
}
binding.ivOpen10.setOnClickListener {
rotatePrize()
viewModel.drawFairy(10)
}
binding.ivOpen100.setOnClickListener {
rotatePrize()
viewModel.drawFairy(100)
}
binding.viewPrizeClick.setOnClickListener {
if (disposable?.isDisposed == false && targetIndex != -1) {
fairyItems[selectIndex].isSelected = false
fairyItems[targetIndex].isSelected = true
selectIndex = targetIndex
targetIndex = -1
HomePrizeDialog.newInstance().show(context)
disposable?.dispose()
}
}
viewModel.resultLiveData.observe(viewLifecycleOwner) { event ->
event?.getContentIfNotHandled()?.let {
targetIndex = viewModel.prizeInfoListLiveData.value?.indexOf(it[0]) ?: -1
hintPrizeCacheList.addAll(it.filter { prizeInfo -> prizeInfo.rewardLevel >= 3 })
} ?: run {
targetIndex = -1
disposable?.dispose()
}
}
viewModel.prizeInfoListLiveData.observe(viewLifecycleOwner) {
it?.forEachIndexed { index, prizeInfo ->
fairyItems[index].setPrizeInfo(prizeInfo)
}
}
viewModel.drawInfoLiveData.observe(viewLifecycleOwner) {
it?.let {
binding.tvKeyNum.text = it.drawTicketNum.toString()
binding.tvCurrentLuckyValue.text = it.luckyNum.toString()
binding.tvShortLuckyValue.text = "达到${it.needLuckyNum}后下次夺宝,额外获赠精灵球"
binding.ivLuckyStone.post {
val drawable = CustomDrawable(binding.ivLuckyStone.drawable)
val path = Path()
path.addRect(
0f,
0f,
binding.ivLuckyStone.width.toFloat(),
binding.ivLuckyStone.height *
(1 - it.luckyNum / it.needLuckyNum.toFloat().coerceAtLeast(1f)),
Path.Direction.CW
)
drawable.setSrcPath(path)
binding.ivLuckyStone.setImageDrawable(drawable)
}
}
}
viewModel.showGetKeyLiveData.observe(viewLifecycleOwner) {
it.getContentIfNotHandled()?.let {
DialogManager(context).showOkCancelDialog("购买限时装扮活动夺宝券", "去参与", "取消") {
ElfDialogWebViewActivity.start(context, UriProvider.getFairyKey())
}
}
}
}
override fun onResume() {
super.onResume()
viewModel.initDrawInfo()
}
private fun rotatePrize() {
targetIndex = -1
var minCount = 0
disposable?.dispose()
disposable = Observable.interval(70, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.compose(bindToLifecycle())
.doOnNext {
fairyItems[selectIndex].isSelected = false
selectIndex++
minCount++
if (selectIndex == fairyItems.size) selectIndex = 0
fairyItems[selectIndex].isSelected = true
if (selectIndex == targetIndex && minCount >= 24) {
HomePrizeDialog.newInstance().show(context)
disposable?.dispose()
}
}
.subscribe()
}
@SuppressLint("CheckResult")
@@ -104,9 +186,9 @@ class HomeDialog : BaseDialog<TreasureFairyDialogHomeBinding>() {
.start()
}
(linearLayout.findViewById<View>(R.id.tv_prize_name) as TextView).text =
prizeInfo.prizeName
prizeInfo.rewardName
(linearLayout.findViewById<View>(R.id.tv_prize_num) as TextView).text =
"x" + prizeInfo.prizeNum
"x" + prizeInfo.rewardNum
}
}

View File

@@ -4,8 +4,10 @@ import android.content.Context
import android.util.AttributeSet
import android.widget.LinearLayout
import androidx.annotation.Nullable
import com.mango.core.treasurefairy.PrizeInfo
import com.mango.moshen.R
import com.mango.moshen.databinding.TreasureFairyItemHomeBinding
import com.mango.moshen.ui.utils.load
/**
* 技能卡
@@ -18,10 +20,14 @@ class HomeItemView @JvmOverloads constructor(
private val binding: TreasureFairyItemHomeBinding
init {
inflate(context, R.layout.treasure_fairy_item_home, this)
binding = TreasureFairyItemHomeBinding.bind(this)
}
fun setPrizeInfo(prizeInfo: PrizeInfo) {
binding.ivPrizeIcon.load(prizeInfo.rewardPicUrl)
binding.tvPrizeName.text = prizeInfo.rewardName
}
}

View File

@@ -6,13 +6,15 @@ import com.chad.library.adapter.base.BaseViewHolder
import com.mango.moshen.R
import com.mango.moshen.ui.utils.load
import com.mango.core.room.game.GameInfo
import com.mango.core.treasurefairy.PrizeInfo
class HomePrizeAdapter :
BaseQuickAdapter<GameInfo, BaseViewHolder>(R.layout.treasure_fairy_item_home_prize) {
BaseQuickAdapter<PrizeInfo, BaseViewHolder>(R.layout.treasure_fairy_item_home_prize) {
override fun convert(helper: BaseViewHolder, item: GameInfo) {
helper.getView<ImageView>(R.id.iv_cover).load(item.pic,12f)
helper.itemView.isSelected = item.isSelect
override fun convert(helper: BaseViewHolder, item: PrizeInfo) {
helper.getView<ImageView>(R.id.iv_prize_icon).load(item.rewardPicUrl)
helper.setText(R.id.tv_prize_num, "x${item.rewardNum}")
helper.setText(R.id.tv_prize_name, item.rewardName)
}
}

View File

@@ -4,22 +4,26 @@ 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.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.mango.core.room.game.GameInfo
import com.mango.core.treasurefairy.PrizeInfo
import com.mango.moshen.base.BaseDialog
import com.mango.moshen.databinding.TreasureFairyDialogHomePrizeBinding
import com.mango.moshen.ui.utils.RVDelegate
class HomePrizeDialog : BaseDialog<TreasureFairyDialogHomePrizeBinding>() {
private lateinit var rvDelegate: RVDelegate<GameInfo>
private lateinit var rvDelegate: RVDelegate<PrizeInfo>
private val prizeAdapter = HomePrizeAdapter()
override var width = WindowManager.LayoutParams.MATCH_PARENT
override var gravity = Gravity.BOTTOM
private val viewModel: FairyViewModel by activityViewModels()
companion object{
fun newInstance(): HomePrizeDialog{
companion object {
fun newInstance(): HomePrizeDialog {
val args = Bundle()
val fragment = HomePrizeDialog()
fragment.arguments = args
@@ -33,11 +37,15 @@ class HomePrizeDialog : BaseDialog<TreasureFairyDialogHomePrizeBinding>() {
dismissAllowingStateLoss()
}
rvDelegate = RVDelegate.Builder<GameInfo>()
rvDelegate = RVDelegate.Builder<PrizeInfo>()
.setAdapter(prizeAdapter)
.setRecyclerView(binding.recyclerView)
.setLayoutManager(LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false))
.setLayoutManager(GridLayoutManager(context,4, LinearLayoutManager.VERTICAL, false))
.build()
viewModel.resultLiveData.observe(viewLifecycleOwner) { event ->
rvDelegate.setNewData(event.peekContent())
}
}
}

View File

@@ -34,6 +34,7 @@
android:background="@drawable/treasure_fairy_bg_key_number"
android:gravity="center"
android:paddingStart="8dp"
android:layout_marginStart="15dp"
android:paddingTop="2dp"
android:text="12.2W"
android:textColor="@color/white"
@@ -244,6 +245,15 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<View
android:id="@+id/view_prize_click"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="@id/fairy_item_6"
app:layout_constraintEnd_toEndOf="@id/fairy_item_3"
app:layout_constraintStart_toStartOf="@id/fairy_item_0"
app:layout_constraintTop_toTopOf="@id/fairy_item_0" />
<ImageView
android:id="@+id/iv_open_1"
android:layout_width="0dp"

View File

@@ -17,11 +17,14 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="20dp"
android:layout_marginTop="88dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="105dp"
app:layout_constraintBottom_toBottomOf="@id/view_bg"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View File

@@ -2,8 +2,11 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:gravity="center_horizontal"
android:orientation="vertical">
<FrameLayout

View File

@@ -504,4 +504,11 @@ public class UriProvider {
return JAVA_WEB_URL.concat("/yinyou/activity/act-sail/more.html");
}
/**
* 获取航海钥匙
*/
public static String getFairyKey() {
return JAVA_WEB_URL.concat("/yinyou/modules/act-treasureSnatching/index.html");
}
}

View File

@@ -0,0 +1,7 @@
package com.mango.core.treasurefairy
data class DrawInfo(
val drawTicketNum: Int = 0,
val luckyNum: Int = 0,
val needLuckyNum: Int = 0
)

View File

@@ -0,0 +1,28 @@
package com.mango.core.treasurefairy
data class PrizeInfo(
val rewardId: Int = 0,
val rewardName: String = "",
val rewardNum: Int = 0,
val rewardOrder: Int = 0,
val rewardLevel: Int = 0,
val rewardPicUrl: String = "",
val rewardType: String = "",
val rewardUnit: String = ""
)
{
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as PrizeInfo
if (rewardId != other.rewardId) return false
return true
}
override fun hashCode(): Int {
return rewardId
}
}

View File

@@ -0,0 +1,50 @@
package com.mango.core.treasurefairy
import com.mango.core.bean.response.ServiceResult
import com.mango.core.manager.AvRoomDataManager
import com.mango.core.utils.net.launchRequest
import com.mango.xchat_android_library.net.rxnet.RxNet
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET
import retrofit2.http.POST
object TreasureFairyModel {
private val api = RxNet.create(Api::class.java)
suspend fun drawTreasureFairy(drawNum: Int): List<PrizeInfo>? = launchRequest {
api.drawTreasureFairy(drawNum, AvRoomDataManager.get().roomUid)
}
suspend fun getDrawInfo(): DrawInfo? = launchRequest {
api.getDrawInfo()
}
suspend fun getPrizeInfoList(): List<PrizeInfo>? = launchRequest {
api.getPrizeInfoList()
}
private interface Api {
/**
*
*
* @param drawNum
* @return
*/
@FormUrlEncoded
@POST("act/seize-treasure/draw")
suspend fun drawTreasureFairy(
@Field("drawNum") drawNum: Int,
@Field("roomUid") roomUid: Long
): ServiceResult<List<PrizeInfo>>
@GET("act/seize-treasure/user/draw/info")
suspend fun getDrawInfo(): ServiceResult<DrawInfo>
@GET("act/seize-treasure/draw/pool/list")
suspend fun getPrizeInfoList(): ServiceResult<List<PrizeInfo>>
}
}