honghengqiang 3 年之前
父節點
當前提交
e495c57397
共有 42 個文件被更改,包括 1025 次插入78 次删除
  1. 9 0
      .idea/misc.xml
  2. 4 0
      baseswago/src/main/java/com/swago/baseswago/PayVm.kt
  3. 114 0
      baseswago/src/main/java/com/swago/baseswago/dialog/BenefitBagDialog.kt
  4. 28 1
      baseswago/src/main/java/com/swago/baseswago/dialog/PayDialog.kt
  5. 1 0
      baseswago/src/main/java/com/swago/baseswago/im/IRoomChat.kt
  6. 1 0
      baseswago/src/main/java/com/swago/baseswago/libpay/IPayCallback.kt
  7. 30 26
      baseswago/src/main/java/com/swago/baseswago/libpay/PayManager.kt
  8. 5 0
      baseswago/src/main/java/com/swago/baseswago/model/im/AnchorRoomClosedBean.java
  9. 5 0
      baseswago/src/main/java/com/swago/baseswago/model/im/RoomChatMsgBean.java
  10. 5 0
      baseswago/src/main/java/com/swago/baseswago/model/im/UserJoinRoomBean.java
  11. 13 0
      baseswago/src/main/java/com/swago/baseswago/model/live/game/GameInfoModel.kt
  12. 0 24
      baseswago/src/main/java/com/swago/baseswago/util/KeyboardUtil.kt
  13. 7 0
      baseswago/src/main/res/drawable/shape_fef0bf_30fef0bf_12.xml
  14. 7 0
      baseswago/src/main/res/drawable/shape_ff4747_ffe249_23.xml
  15. 6 0
      baseswago/src/main/res/drawable/shape_white_bottom_24.xml
  16. 184 0
      baseswago/src/main/res/layout/dialog_benefit_bag.xml
  17. 二進制
      baseswago/src/main/res/mipmap-id-xxhdpi/benefit_title.webp
  18. 二進制
      baseswago/src/main/res/mipmap-xxhdpi/benefit_close.png
  19. 二進制
      baseswago/src/main/res/mipmap-xxhdpi/benefit_coin.webp
  20. 二進制
      baseswago/src/main/res/mipmap-xxhdpi/benefit_effects.webp
  21. 二進制
      baseswago/src/main/res/mipmap-xxhdpi/benefit_medal.webp
  22. 二進制
      baseswago/src/main/res/mipmap-xxhdpi/benefit_title.webp
  23. 二進制
      baseswago/src/main/res/mipmap-xxhdpi/bg_benefit.webp
  24. 2 0
      home/src/main/AndroidManifest.xml
  25. 2 0
      home/src/main/java/com/swago/home/HomeActivity.kt
  26. 1 0
      home/src/main/java/com/swago/home/HomeFragment.kt
  27. 二進制
      room/src/main/assets/icon_chat_benefit.png
  28. 148 15
      room/src/main/java/com/swago/room/adapter/RoomChatAdapter.kt
  29. 34 0
      room/src/main/java/com/swago/room/adapter/bitmap/CenterAlignImageSpan.java
  30. 82 0
      room/src/main/java/com/swago/room/adapter/bitmap/CustomImageSpan.java
  31. 129 0
      room/src/main/java/com/swago/room/adapter/bitmap/HtmlImageGetter.java
  32. 42 0
      room/src/main/java/com/swago/room/adapter/bitmap/UrlDrawable.java
  33. 2 0
      room/src/main/java/com/swago/room/base/BaseComFragment.kt
  34. 0 2
      room/src/main/java/com/swago/room/dialog/SendMsgDialog.kt
  35. 129 0
      room/src/main/java/com/swago/room/game/GamePlayDialog.kt
  36. 1 1
      room/src/main/java/com/swago/room/gift/control/SvgPlayerManager.kt
  37. 10 6
      room/src/main/java/com/swago/room/gift/control/XSvgPlayer.kt
  38. 8 0
      room/src/main/res/layout/dialog_game_play.xml
  39. 1 0
      room/src/main/res/layout/fragment_base_com.xml
  40. 1 1
      room/src/main/res/layout/item_chat.xml
  41. 7 0
      room/src/main/res/layout/item_chat_level.xml
  42. 7 2
      user/src/main/java/com/swago/user/recharge/RechargeActivity.kt

+ 9 - 0
.idea/misc.xml

@@ -31,14 +31,20 @@
         <entry key="baseswago/src/main/res/drawable/shape_black_5.xml" value="0.35794871794871796" />
         <entry key="baseswago/src/main/res/drawable/shape_dadada_5.xml" value="0.35794871794871796" />
         <entry key="baseswago/src/main/res/drawable/shape_f7f8fa_5.xml" value="0.19895833333333332" />
+        <entry key="baseswago/src/main/res/drawable/shape_fef0bf_30fef0bf_12.xml" value="0.20572916666666666" />
+        <entry key="baseswago/src/main/res/drawable/shape_ff4747_ffe249_23.xml" value="0.20572916666666666" />
         <entry key="baseswago/src/main/res/drawable/shape_ff9300_20.xml" value="0.21927083333333333" />
         <entry key="baseswago/src/main/res/drawable/shape_touming.xml" value="0.37333333333333335" />
         <entry key="baseswago/src/main/res/drawable/shape_white_20.xml" value="0.35794871794871796" />
         <entry key="baseswago/src/main/res/drawable/shape_white_5.xml" value="0.39375" />
+        <entry key="baseswago/src/main/res/drawable/shape_white_bottom_24.xml" value="0.20572916666666666" />
         <entry key="baseswago/src/main/res/drawable/shape_white_top_20.xml" value="0.39375" />
         <entry key="baseswago/src/main/res/layout/activity_abs_room_user.xml" value="0.3776041666666667" />
         <entry key="baseswago/src/main/res/layout/activity_web.xml" value="0.19047619047619047" />
+        <entry key="baseswago/src/main/res/layout/dialog_benefit_bag.xml" value="0.36302083333333335" />
+        <entry key="baseswago/src/main/res/layout/dialog_game_play.xml" value="0.35" />
         <entry key="baseswago/src/main/res/layout/dialog_loading.xml" value="0.36302083333333335" />
+        <entry key="baseswago/src/main/res/layout/dialog_off_line.xml" value="0.17654508611955422" />
         <entry key="baseswago/src/main/res/layout/dialog_order_lost.xml" value="0.3015625" />
         <entry key="baseswago/src/main/res/layout/dialog_pay.xml" value="0.335" />
         <entry key="baseswago/src/main/res/layout/dialog_person_data.xml" value="0.36302083333333335" />
@@ -56,6 +62,7 @@
         <entry key="home/src/main/res/drawable/shape_50white_4.xml" value="0.4078125" />
         <entry key="home/src/main/res/drawable/shape_f74c31_10.xml" value="0.37916666666666665" />
         <entry key="home/src/main/res/layout/activity_chat_detail.xml" value="0.3776041666666667" />
+        <entry key="home/src/main/res/layout/activity_common_web.xml" value="0.35" />
         <entry key="home/src/main/res/layout/activity_home.xml" value="0.25" />
         <entry key="home/src/main/res/layout/activity_official_message.xml" value="0.36302083333333335" />
         <entry key="home/src/main/res/layout/activity_search.xml" value="0.39166666666666666" />
@@ -83,6 +90,7 @@
         <entry key="room/src/main/res/layout/activity_anchor_room.xml" value="0.21302083333333333" />
         <entry key="room/src/main/res/layout/activity_rank_list.xml" value="0.3776041666666667" />
         <entry key="room/src/main/res/layout/dialog_anchor_close.xml" value="0.25" />
+        <entry key="room/src/main/res/layout/dialog_game_play.xml" value="0.3776041666666667" />
         <entry key="room/src/main/res/layout/dialog_gift.xml" value="0.3015625" />
         <entry key="room/src/main/res/layout/dialog_message_list.xml" value="0.3776041666666667" />
         <entry key="room/src/main/res/layout/dialog_send_msg.xml" value="0.338768115942029" />
@@ -94,6 +102,7 @@
         <entry key="room/src/main/res/layout/fragment_rank_list.xml" value="0.39166666666666666" />
         <entry key="room/src/main/res/layout/item_chat.xml" value="0.3776041666666667" />
         <entry key="room/src/main/res/layout/item_gift.xml" value="0.75" />
+        <entry key="room/src/main/res/layout/item_level.xml" value="0.3776041666666667" />
         <entry key="room/src/main/res/layout/item_page_gift.xml" value="0.36302083333333335" />
         <entry key="room/src/main/res/layout/item_rank_list.xml" value="0.3770833333333333" />
         <entry key="room/src/main/res/layout/item_room_user.xml" value="0.3446557971014493" />

+ 4 - 0
baseswago/src/main/java/com/swago/baseswago/PayVm.kt

@@ -96,4 +96,8 @@ class PayVm(application: Application) : BaseViewModel(application) {
         }
     }
 
+    /**
+     * 获取特惠礼包
+     */
+
 }

+ 114 - 0
baseswago/src/main/java/com/swago/baseswago/dialog/BenefitBagDialog.kt

@@ -0,0 +1,114 @@
+package com.swago.baseswago.dialog
+
+import android.os.Bundle
+import android.view.Gravity
+import android.widget.Toast
+import androidx.fragment.app.viewModels
+import com.android.billingclient.api.Purchase
+import com.swago.baseswago.PayVm
+import com.swago.baseswago.R
+import com.swago.baseswago.databinding.DialogBenefitBagBinding
+import com.swago.baseswago.libpay.IPayCallback
+import com.swago.baseswago.libpay.PayManager
+import com.swago.baseswago.model.pay.PayModel
+import com.swago.baseswago.util.AppContext
+import com.swago.baseswago.util.NoDoubleClickListener
+import com.swago.baseswago.util.SwagoLoading
+
+/**
+ *@date 2022/1/18 20:29
+ *description:
+ */
+class BenefitBagDialog : BaseXDFragment<DialogBenefitBagBinding>(), IPayCallback {
+
+    private val payVm by viewModels<PayVm>()
+
+    companion object{
+        fun newInstance(): BenefitBagDialog {
+            val args = Bundle()
+            val dialog = BenefitBagDialog()
+            dialog.arguments = args
+            return dialog
+        }
+    }
+
+    override fun initOther() {
+        PayManager.listener.add(this)
+        binding.ivClose.setOnClickListener(object:NoDoubleClickListener(){
+            override fun onClick() {
+                dismissAllowingStateLoss()
+            }
+        })
+        binding.tvRecharge.setOnClickListener(object:NoDoubleClickListener(){
+            override fun onClick() {
+                activity?.let {
+                    SwagoLoading.showLoadingDialog(it)
+                }
+                //TODO 对接接口的时候在弄
+                //PayManager.queryUnConsumeOrder(adapter.data[selectedPosition].id)
+            }
+
+        })
+    }
+
+    override fun initLiveData() {
+
+    }
+
+    override fun onDestroyView() {
+        PayManager.listener.remove(this)
+        super.onDestroyView()
+    }
+
+    init {
+        setCanCancel(false)
+        setGravity(Gravity.CENTER)
+        setDimAmount(0.5f)
+    }
+
+    override fun onConnectedServer() {
+    }
+
+    override fun onPaySuccess(data: List<Purchase>?) {
+        data?.forEach {
+            payVm.payOrderToServer(it, 1)
+        }
+    }
+
+    override fun onQueryProductPrice(data: List<PayModel>) {
+        SwagoLoading.cancelLoadingDialog()
+        binding.tvRecharge.text = data[0].product_price
+        PayManager.queryUnConsumeOrder("")
+    }
+
+    override fun onPayError(code: Int) {
+        SwagoLoading.cancelLoadingDialog()
+        Toast.makeText(AppContext.getContext(), AppContext.getContext().resources.getString(R.string.pay_fail)+"-$code", Toast.LENGTH_SHORT).show()
+        payVm.payOrderToServer(null, 2)
+    }
+
+    override fun onPayCancel() {
+        Toast.makeText(AppContext.getContext(), AppContext.getContext().resources.getString(R.string.pay_cancel), Toast.LENGTH_SHORT).show()
+        payVm.payOrderToServer(null, 3)
+    }
+
+    override fun onUnConsumeOrder(data: List<Purchase>) {
+        data.forEach {
+            val orderLostDialog = OrderLostDialog.newInstance(it.orderId)
+            orderLostDialog.commitLostOrderFun = {
+                payVm.payOrderToServer(it,4)
+            }
+            orderLostDialog.show(childFragmentManager, "OrderLostDialog")
+        }
+    }
+
+    override fun consumeOrderSuccess() {
+    }
+
+    override fun consumeOrderFail(code: Int) {
+    }
+
+    override fun toCreateNewOrder(productId: String) {
+        payVm.createOrder(productId)
+    }
+}

+ 28 - 1
baseswago/src/main/java/com/swago/baseswago/dialog/PayDialog.kt

@@ -17,6 +17,7 @@ import com.swago.baseswago.libpay.PayManager
 import com.swago.baseswago.model.pay.PayModel
 import com.swago.baseswago.util.AppContext
 import com.swago.baseswago.util.DpPxUtil
+import com.swago.baseswago.util.NoDoubleClickListener
 import com.swago.baseswago.util.SwagoLoading
 
 /**
@@ -30,6 +31,7 @@ class PayDialog : BaseXDFragment<DialogPayBinding>(), IPayCallback {
         RechargeAdapter()
     }
 
+    private var selectedPosition = 0
 
     init {
         setGravity(Gravity.BOTTOM)
@@ -54,6 +56,27 @@ class PayDialog : BaseXDFragment<DialogPayBinding>(), IPayCallback {
 
         payVm.getCoins()
         payVm.getProductList()
+
+        adapter.setOnItemClickListener { _, _, position ->
+            if (selectedPosition != position) {
+                adapter.data[selectedPosition].isSelected = false
+                adapter.data[position].isSelected = true
+                adapter.notifyItemChanged(selectedPosition)
+                adapter.notifyItemChanged(position)
+                selectedPosition = position
+            }
+        }
+
+        binding.tvRecharge.setOnClickListener(object:NoDoubleClickListener(){
+            override fun onClick() {
+                activity?.let {
+                    SwagoLoading.showLoadingDialog(it)
+                }
+                PayManager.queryUnConsumeOrder(adapter.data[selectedPosition].id)
+            }
+
+        })
+
     }
 
     override fun initLiveData() {
@@ -79,7 +102,7 @@ class PayDialog : BaseXDFragment<DialogPayBinding>(), IPayCallback {
     override fun onQueryProductPrice(data: List<PayModel>) {
         SwagoLoading.cancelLoadingDialog()
         adapter.setNewData(data)
-        PayManager.queryUnConsumeOrder(null,"","")
+        PayManager.queryUnConsumeOrder("")
     }
 
     override fun onPayError(code: Int) {
@@ -111,6 +134,10 @@ class PayDialog : BaseXDFragment<DialogPayBinding>(), IPayCallback {
 
     }
 
+    override fun toCreateNewOrder(productId: String) {
+        payVm.createOrder(productId)
+    }
+
     inner class GridItemDecoration : RecyclerView.ItemDecoration() {
         override fun getItemOffsets(
             outRect: Rect,

+ 1 - 0
baseswago/src/main/java/com/swago/baseswago/im/IRoomChat.kt

@@ -10,5 +10,6 @@ interface IRoomChat {
     fun getMsgContent():String
     fun getMsgType():Int
     fun getUserLevel():Int
+    fun getIsBenefit():Int
 
 }

+ 1 - 0
baseswago/src/main/java/com/swago/baseswago/libpay/IPayCallback.kt

@@ -17,5 +17,6 @@ interface IPayCallback {
     fun onUnConsumeOrder(data:List<Purchase>)
     fun consumeOrderSuccess()
     fun consumeOrderFail(code:Int)
+    fun toCreateNewOrder(productId:String)
 
 }

+ 30 - 26
baseswago/src/main/java/com/swago/baseswago/libpay/PayManager.kt

@@ -14,7 +14,7 @@ import java.lang.Exception
 object PayManager {
 
     val listener = ArrayList<IPayCallback>()
-    private val publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA184P/HXDtDi+3NgrxRkwIRU6tI2tiodETDzIyA/uwqgKwl/9JgXw2fZEFlsbEv1rUCVvvFGLGo7Z1GrUoR7WUAPktIuMWF330BurThfiwkpkSamzHEe+Pk/98/1YjZ8ltF2xaunUHZhRuE2WonrTy/rFvv/9PZtYd0xNFN5yOQwzFmT5nJvtpfCDWe2OhHXxuswG1bBn+faCcE0Rg1ZkSi36+0gDVvGjX/zQDgsXhwGJqFdVaJu7E7iR4zEGZLHquA931M0gYgGuF/tO9h8ppcaP1N7yR/ibek6KLcs969P47ENlRaL1QnrB3MSbomhhrtAzDLlV8YEIlukzsLrR7wIDAQAB"
+    private const val publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA184P/HXDtDi+3NgrxRkwIRU6tI2tiodETDzIyA/uwqgKwl/9JgXw2fZEFlsbEv1rUCVvvFGLGo7Z1GrUoR7WUAPktIuMWF330BurThfiwkpkSamzHEe+Pk/98/1YjZ8ltF2xaunUHZhRuE2WonrTy/rFvv/9PZtYd0xNFN5yOQwzFmT5nJvtpfCDWe2OhHXxuswG1bBn+faCcE0Rg1ZkSi36+0gDVvGjX/zQDgsXhwGJqFdVaJu7E7iR4zEGZLHquA931M0gYgGuF/tO9h8ppcaP1N7yR/ibek6KLcs969P47ENlRaL1QnrB3MSbomhhrtAzDLlV8YEIlukzsLrR7wIDAQAB"
 
     private var isConnected = false
     private var billingClient: BillingClient? = null
@@ -63,7 +63,7 @@ object PayManager {
                         it.onConnectedServer()
                         LogUtil.d("链接到谷歌")
                     }
-                    queryUnConsumeOrder(null,"","")
+                    queryUnConsumeOrder("")
                 } else {
                     listener.forEach {
                         it.onPayError(p0.responseCode)
@@ -144,41 +144,42 @@ object PayManager {
     /**
      * productId  谷歌商品id
      */
-    fun queryUnConsumeOrder(productId: String?, userId: String, orderId: String) {
+    fun queryUnConsumeOrder(productId: String) {
         billingClient?.let {
             val result = it.queryPurchases(BillingClient.SkuType.INAPP)
             when (result.responseCode) {
                 BillingClient.BillingResponseCode.OK -> {
                     if (result.purchasesList != null && result.purchasesList!!.size != 0) {
                         val unConsumePurchase: MutableList<Purchase> = ArrayList()
-                        result.purchasesList?.onEach {
-                            if (Security.verify(
-                                    Security.generatePublicKey(publicKey),
-                                    it.originalJson,
-                                    it.signature
-                                )
-                            ) {
-                                unConsumePurchase.add(it)
+                        result.purchasesList?.onEach { purchase ->
+                            if (Security.verify(Security.generatePublicKey(publicKey), purchase.originalJson, purchase.signature)) {
+                                unConsumePurchase.add(purchase)
                             }
                         }
-                        listener.forEach {
-                            it.onUnConsumeOrder(unConsumePurchase)
+                        listener.forEach { callback ->
+                            callback.onUnConsumeOrder(unConsumePurchase)
                         }
                     } else {
-                        //不存在未消费
-                        productId?.let {
-                            val idList = ArrayList<String>()
-                            idList.add(productId)
-                            //先去查ID对应的商品是否存在存在才去支付
-                            queryProductIsExit(idList, userId, orderId)
+                        /**
+                         * 不存在未消费
+                         * 当productId空字符串的时候
+                         * 代表着只是查询未消费订单
+                         * 当productId不为空字符串,
+                         * 代表着此时没有未消费的订单
+                         * 然后去创建新的订单购买商品
+                         */
+                        if (productId.isNotEmpty()){
+                            listener.forEach { callback ->
+                                callback.toCreateNewOrder(productId)
+                            }
                         }
                     }
 
                 }
 
                 else -> {
-                    listener.forEach {
-                        it.onPayError(result.responseCode)
+                    listener.forEach { callback ->
+                        callback.onPayError(result.responseCode)
                     }
                 }
 
@@ -194,14 +195,14 @@ object PayManager {
                 when (billingResult.responseCode) {
                     BillingClient.BillingResponseCode.OK -> {
                         //查询到商品然后支付
-                        data?.onEach {
-                            startPay(it, userId, orderId)
+                        data?.onEach { skuDetails ->
+                            startPay(skuDetails, userId, orderId)
                         }
                     }
 
                     else -> {
-                        listener.forEach {
-                            it.onPayError(billingResult.responseCode)
+                        listener.forEach { callback ->
+                            callback.onPayError(billingResult.responseCode)
                         }
                     }
                 }
@@ -227,7 +228,10 @@ object PayManager {
 
     fun pay(productId: String, userId: String, orderId: String) {
         if (isConnected) {
-            queryUnConsumeOrder(productId, userId, orderId)
+            val idList = ArrayList<String>()
+            idList.add(productId)
+            //先去查ID对应的商品是否存在存在才去支付
+            queryProductIsExit(idList, userId, orderId)
         }
     }
 

+ 5 - 0
baseswago/src/main/java/com/swago/baseswago/model/im/AnchorRoomClosedBean.java

@@ -38,4 +38,9 @@ public class AnchorRoomClosedBean implements IRoomChat {
     public int getUserLevel() {
         return 0;
     }
+
+    @Override
+    public int getIsBenefit() {
+        return 0;
+    }
 }

+ 5 - 0
baseswago/src/main/java/com/swago/baseswago/model/im/RoomChatMsgBean.java

@@ -38,4 +38,9 @@ public class RoomChatMsgBean implements IRoomChat {
     public int getUserLevel() {
         return senderLevel;
     }
+
+    @Override
+    public int getIsBenefit() {
+        return 0;
+    }
 }

+ 5 - 0
baseswago/src/main/java/com/swago/baseswago/model/im/UserJoinRoomBean.java

@@ -43,4 +43,9 @@ public class UserJoinRoomBean implements IRoomChat {
     public int getUserLevel() {
         return senderLevel;
     }
+
+    @Override
+    public int getIsBenefit() {
+        return 0;
+    }
 }

+ 13 - 0
baseswago/src/main/java/com/swago/baseswago/model/live/game/GameInfoModel.kt

@@ -0,0 +1,13 @@
+package com.swago.baseswago.model.live.game
+
+/**
+ *@date 2022/1/19 21:09
+ *description:
+ */
+data class GameInfoModel (
+    val roomId:String,
+    val userId:String,
+    val anchorId:String,
+    val anchorType:Int,
+    val language:String
+    )

+ 0 - 24
baseswago/src/main/java/com/swago/baseswago/util/KeyboardUtil.kt

@@ -1,24 +0,0 @@
-package com.swago.baseswago.util
-
-import android.content.Context
-import android.view.inputmethod.InputMethodManager
-import android.widget.EditText
-
-/**
- *@date 2021/10/23 20:12
- *description:
- */
-object KeyboardUtil {
-
-    fun openKeyboard(editText: EditText,context: Context){
-        val im = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
-        im.showSoftInput(editText,InputMethodManager.RESULT_SHOWN)
-        im.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.HIDE_IMPLICIT_ONLY)
-    }
-
-    fun closeKeyboard(editText: EditText,context: Context){
-        val im = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
-        im.hideSoftInputFromWindow(editText.windowToken,0)
-    }
-
-}

+ 7 - 0
baseswago/src/main/res/drawable/shape_fef0bf_30fef0bf_12.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient android:angle="90"
+        android:startColor="#fef0bf"
+        android:endColor="#4DFEF0BF"/>
+    <corners android:radius="12dp"/>
+</shape>

+ 7 - 0
baseswago/src/main/res/drawable/shape_ff4747_ffe249_23.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient android:angle="0"
+        android:startColor="#ff4747"
+        android:endColor="#ffe249"/>
+    <corners android:radius="23dp"/>
+</shape>

+ 6 - 0
baseswago/src/main/res/drawable/shape_white_bottom_24.xml

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

+ 184 - 0
baseswago/src/main/res/layout/dialog_benefit_bag.xml

@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+
+        <ImageView
+            android:id="@+id/ivBg"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            android:src="@mipmap/bg_benefit"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+
+        <ImageView
+            android:src="@mipmap/benefit_title"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintBottom_toBottomOf="@+id/ivBg"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/clBottom"
+            android:background="@drawable/shape_white_bottom_24"
+            app:layout_constraintTop_toBottomOf="@+id/ivBg"
+            app:layout_constraintStart_toStartOf="@+id/ivBg"
+            app:layout_constraintEnd_toEndOf="@+id/ivBg"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content">
+
+            <LinearLayout
+                android:id="@+id/llOne"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toStartOf="@+id/llTwo"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintHorizontal_chainStyle="spread"
+                android:layout_marginTop="12dp"
+                android:layout_marginStart="16dp"
+                android:gravity="center"
+                android:background="@drawable/shape_fef0bf_30fef0bf_12"
+                android:orientation="vertical"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content">
+
+                <ImageView
+                    android:layout_marginTop="4dp"
+                    android:src="@mipmap/benefit_coin"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"/>
+
+                <TextView
+                    android:textSize="10dp"
+                    android:textColor="#FFAE34"
+                    android:text="@string/diamond"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"/>
+
+                <TextView
+                    android:textSize="16dp"
+                    android:textColor="#FFAE34"
+                    android:text="10000"
+                    android:layout_marginBottom="5dp"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"/>
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:id="@+id/llTwo"
+                app:layout_constraintStart_toEndOf="@+id/llOne"
+                app:layout_constraintEnd_toStartOf="@+id/llThree"
+                app:layout_constraintTop_toTopOf="parent"
+                android:layout_marginTop="12dp"
+                android:layout_marginStart="8dp"
+                android:gravity="center"
+                android:background="@drawable/shape_fef0bf_30fef0bf_12"
+                android:orientation="vertical"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content">
+
+                <ImageView
+                    android:layout_marginTop="4dp"
+                    android:src="@mipmap/benefit_effects"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"/>
+
+                <TextView
+                    android:textSize="10dp"
+                    android:textColor="#FFAE34"
+                    android:text="@string/diamond"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"/>
+
+                <TextView
+                    android:textSize="16dp"
+                    android:textColor="#FFAE34"
+                    android:text="10000"
+                    android:layout_marginBottom="5dp"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"/>
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:id="@+id/llThree"
+                app:layout_constraintStart_toEndOf="@+id/llTwo"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                android:layout_marginTop="12dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="16dp"
+                android:gravity="center"
+                android:background="@drawable/shape_fef0bf_30fef0bf_12"
+                android:orientation="vertical"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content">
+
+                <ImageView
+                    android:layout_marginTop="4dp"
+                    android:src="@mipmap/benefit_medal"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"/>
+
+                <TextView
+                    android:textSize="10dp"
+                    android:textColor="#FFAE34"
+                    android:text="@string/diamond"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"/>
+
+                <TextView
+                    android:textSize="16dp"
+                    android:textColor="#FFAE34"
+                    android:text="10000"
+                    android:layout_marginBottom="5dp"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"/>
+
+            </LinearLayout>
+
+
+            <TextView
+                android:id="@+id/tvRecharge"
+                android:textColor="#fff"
+                app:layout_constraintTop_toBottomOf="@+id/llOne"
+                android:layout_marginTop="20dp"
+                android:layout_marginStart="16dp"
+                android:layout_marginEnd="16dp"
+                android:layout_marginBottom="25dp"
+                android:text="$1"
+                android:gravity="center"
+                android:textSize="16dp"
+
+                android:background="@drawable/shape_ff4747_ffe249_23"
+                app:layout_constraintBottom_toBottomOf="parent"
+                android:layout_width="match_parent"
+                android:layout_height="44dp"/>
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+        <ImageView
+            android:id="@+id/ivClose"
+            android:layout_marginTop="32dp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/clBottom"
+            android:src="@mipmap/benefit_close"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>

二進制
baseswago/src/main/res/mipmap-id-xxhdpi/benefit_title.webp


二進制
baseswago/src/main/res/mipmap-xxhdpi/benefit_close.png


二進制
baseswago/src/main/res/mipmap-xxhdpi/benefit_coin.webp


二進制
baseswago/src/main/res/mipmap-xxhdpi/benefit_effects.webp


二進制
baseswago/src/main/res/mipmap-xxhdpi/benefit_medal.webp


二進制
baseswago/src/main/res/mipmap-xxhdpi/benefit_title.webp


二進制
baseswago/src/main/res/mipmap-xxhdpi/bg_benefit.webp


+ 2 - 0
home/src/main/AndroidManifest.xml

@@ -11,6 +11,8 @@
             android:screenOrientation="portrait"/>
         <activity android:name=".search.SearchActivity"
             android:screenOrientation="portrait"/>
+        <activity android:name=".web.CommonWebActivity"
+            android:screenOrientation="portrait"/>
     </application>
 
 </manifest>

+ 2 - 0
home/src/main/java/com/swago/home/HomeActivity.kt

@@ -161,6 +161,8 @@ class HomeActivity : BaseXActivity<ActivityHomeBinding>(), IPayCallback {
     override fun consumeOrderFail(code: Int) {
     }
 
+    override fun toCreateNewOrder(productId: String) {}
+
     override fun onBackPressed() {
         moveTaskToBack(true)
     }

+ 1 - 0
home/src/main/java/com/swago/home/HomeFragment.kt

@@ -10,6 +10,7 @@ import com.permissionx.guolindev.PermissionX
 import com.swago.baseswago.GradientIndicator
 import com.swago.baseswago.SwagoAdapter
 import com.swago.baseswago.constant.ARouteConstant
+import com.swago.baseswago.dialog.BenefitBagDialog
 import com.swago.baseswago.fragment.BaseXFragment
 import com.swago.baseswago.util.AppContext
 import com.swago.baseswago.util.DpPxUtil

二進制
room/src/main/assets/icon_chat_benefit.png


+ 148 - 15
room/src/main/java/com/swago/room/adapter/RoomChatAdapter.kt

@@ -1,47 +1,97 @@
 package com.swago.room.adapter
 
+import android.graphics.Bitmap
+import android.text.Html
 import android.text.SpannableString
-import androidx.core.content.ContextCompat
+import android.text.Spanned
+import android.text.style.ClickableSpan
+import android.text.style.ImageSpan
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
 import com.chad.library.adapter.base.BaseQuickAdapter
 import com.chad.library.adapter.base.BaseViewHolder
+import com.swago.baseswago.cusview.SwagoLevelView
 import com.swago.baseswago.im.IRoomChat
 import com.swago.baseswago.im.RoomMsgType
 import com.swago.room.R
+import com.swago.room.adapter.bitmap.CenterAlignImageSpan
+import com.swago.room.adapter.bitmap.CustomImageSpan
+import com.swago.room.adapter.bitmap.HtmlImageGetter
+import java.util.HashMap
 
 /**
  *@date 2021/10/23 19:17
  *description:
  */
-class RoomChatAdapter : BaseQuickAdapter<IRoomChat,BaseViewHolder>(R.layout.item_chat, arrayListOf()) {
+class RoomChatAdapter :
+    BaseQuickAdapter<IRoomChat, BaseViewHolder>(R.layout.item_chat, arrayListOf()) {
+
+    /**
+     * 图标bitmap缓存
+     */
+    private val iconBitmapCachePool: HashMap<String, Bitmap> = HashMap()
+    private val localImageKey = ArrayList<String>()
+
+    companion object {
+        const val LEVEL_KEY = "level"
+    }
+
+    init {
+        localImageKey.add(LEVEL_KEY)
+    }
+
 
     override fun convert(helper: BaseViewHolder, item: IRoomChat) {
+        var count = 0
         helper.apply {
-
-            when(item.getMsgType()){
+            val tvContent = itemView.findViewById<TextView>(R.id.tvContent)
+            val span: SpannableString?
+            when (item.getMsgType()) {
                 RoomMsgType.ROOM_CHAT_TEXT -> {
-                    setBackgroundRes(R.id.tv,R.drawable.shape_white_20)
-                    setTextColor(R.id.tv,ContextCompat.getColor(mContext,R.color._000000))
-                    setText(R.id.tv,"${item.getSenderName()}:${item.getMsgContent()}")
+                    val sb = StringBuffer()
+                    sb.append(item.getSenderName())
+                        .append("<img src='" + "file:///xx/")
+                        .append(LEVEL_KEY).append(".png")
+                        .append("'>")
+
+                    if (item.getIsBenefit() == 0) {
+                        count++
+                        sb.append("<img src='" + "file:///android_asset/icon_chat_benefit.png")
+                            .append("'>")
+                    }
+                    sb.append(":")
+
+
+                    sb.append(item.getMsgContent())
+
+                    val glideImageGetter = HtmlImageGetter(mContext, tvContent, 14, localImageKey)
+                    val fromHtml = Html.fromHtml(sb.toString(), glideImageGetter, null)
+                    span = SpannableString(fromHtml)
+                    setHtml(span, helper, item)
+
+                    setBackgroundRes(R.id.tvContent, R.drawable.shape_white_20)
+                    tvContent.text = span
                 }
 
                 RoomMsgType.USER_ENTER_ROOM -> {
-                    setTextColor(R.id.tv,ContextCompat.getColor(mContext,R.color._000000))
-                    setText(R.id.tv,"${item.getSenderName()} ${item.getMsgContent()}")
-                    when(item.getUserLevel()){
+                    setText(R.id.tvContent, "${item.getSenderName()} ${item.getMsgContent()}")
+                    when (item.getUserLevel()) {
                         in 0..37 -> {
-                            setBackgroundRes(R.id.tv,R.drawable.shape_4bce98_20)
+                            setBackgroundRes(R.id.tvContent, R.drawable.shape_4bce98_20)
                         }
                         in 38..54 -> {
-                            setBackgroundRes(R.id.tv,R.drawable.shape_6c55ff_20)
+                            setBackgroundRes(R.id.tvContent, R.drawable.shape_6c55ff_20)
                         }
                         in 55..75 -> {
-                            setBackgroundRes(R.id.tv,R.drawable.shape_6720d1_180c72_20)
+                            setBackgroundRes(R.id.tvContent, R.drawable.shape_6720d1_180c72_20)
                         }
                         in 76..97 -> {
-                            setBackgroundRes(R.id.tv,R.drawable.shape_f8614b_8c2922_20)
+                            setBackgroundRes(R.id.tvContent, R.drawable.shape_f8614b_8c2922_20)
                         }
                         in 98..1000 -> {
-                            setBackgroundRes(R.id.tv,R.drawable.shape_434343_000000_20)
+                            setBackgroundRes(R.id.tvContent, R.drawable.shape_434343_000000_20)
                         }
                     }
                 }
@@ -49,4 +99,87 @@ class RoomChatAdapter : BaseQuickAdapter<IRoomChat,BaseViewHolder>(R.layout.item
 
         }
     }
+
+
+    private fun setHtml(span: SpannableString, helper: BaseViewHolder, item: IRoomChat) {
+        try {
+            val imageSpans = span.getSpans(0, span.length, ImageSpan::class.java)
+            var i = 0
+            val size = imageSpans.size
+            while (i < size) {
+                val imageSpan = imageSpans[i]
+                val d = imageSpan.drawable
+                val newImageSpan =
+                    CenterAlignImageSpan(d, ImageSpan.ALIGN_BASELINE)
+                val start = span.getSpanStart(imageSpan)
+                val end = span.getSpanEnd(imageSpan)
+                val clickableSpans = span.getSpans(start, end, ClickableSpan::class.java)
+                if (clickableSpans != null && clickableSpans.isNotEmpty()) {
+                    for (cs in clickableSpans) {
+                        span.removeSpan(cs)
+                    }
+                }
+                if (imageSpan.source != null && imageSpan!!.source!!.contains(LEVEL_KEY)) {
+                    span.setSpan(
+                        setLevel(item.getUserLevel(), helper.itemView as ViewGroup),
+                        start,
+                        end,
+                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+                    )
+                } else {
+                    span.setSpan(newImageSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+                }
+                span.removeSpan(imageSpan)
+                i++
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+    }
+
+
+    private fun setLevel(iSenderLevel: Int, viewGroup: ViewGroup): CustomImageSpan? {
+        var level = iSenderLevel.toString()
+        if (level.isNullOrEmpty()) {
+            level = "1"
+        }
+        var bm = iconBitmapCachePool[level + "level"]
+        if (bm == null) {
+            val view = LayoutInflater.from(mContext).inflate(R.layout.item_chat_level, viewGroup, false) as SwagoLevelView
+            view.measure(
+                View.MeasureSpec.makeMeasureSpec(
+                    (1 shl 30) - 1,
+                    View.MeasureSpec.AT_MOST
+                ),
+                View.MeasureSpec.makeMeasureSpec(
+                    (1 shl 30) - 1,
+                    View.MeasureSpec.AT_MOST
+                )
+            )
+            view.setUserLevel(level.toInt())
+            bm = convertViewToBitmap(view)
+            if (bm != null) {
+                iconBitmapCachePool[level + "level"] = bm
+            }
+        }
+
+        return CustomImageSpan(mContext, bm, CustomImageSpan.ALIGN_FONTCENTER)
+    }
+
+
+    private fun convertViewToBitmap(view: View): Bitmap? {
+        view.measure(
+            View.MeasureSpec.makeMeasureSpec(
+                (1 shl 30) - 1,
+                View.MeasureSpec.AT_MOST
+            ),
+            View.MeasureSpec.makeMeasureSpec(
+                (1 shl 30) - 1,
+                View.MeasureSpec.AT_MOST
+            )
+        )
+        view.layout(0, 0, view.measuredWidth, view.measuredHeight)
+        view.buildDrawingCache()
+        return view.drawingCache
+    }
 }

+ 34 - 0
room/src/main/java/com/swago/room/adapter/bitmap/CenterAlignImageSpan.java

@@ -0,0 +1,34 @@
+package com.swago.room.adapter.bitmap;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.drawable.Drawable;
+import android.text.style.ImageSpan;
+
+/**
+ * @date 2022/1/18 21:13
+ * description:
+ */
+public class CenterAlignImageSpan extends ImageSpan {
+    public CenterAlignImageSpan(Drawable drawable, int verticalAlignment) {
+        super(drawable, verticalAlignment);
+    }
+
+    @Override
+    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
+        Drawable b = getDrawable();
+        if (paint != null) {
+            Paint.FontMetricsInt fm = paint.getFontMetricsInt();
+            //计算y方向的位移
+            int transY = (y + fm.descent + y + fm.ascent) / 2 - b.getBounds().bottom / 2;
+            if (canvas != null) {
+                canvas.save();
+                //绘制图片位移一段距离
+                canvas.translate(x, transY);
+                b.draw(canvas);
+                canvas.restore();
+            }
+        }
+
+    }
+}

+ 82 - 0
room/src/main/java/com/swago/room/adapter/bitmap/CustomImageSpan.java

@@ -0,0 +1,82 @@
+package com.swago.room.adapter.bitmap;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.text.style.ImageSpan;
+
+/**
+ * @date 2022/1/18 21:09
+ * description:
+ */
+public class CustomImageSpan extends ImageSpan {
+
+    //自定义对齐方式--与文字中间线对齐
+    public static int ALIGN_FONTCENTER = 2;
+
+    public CustomImageSpan(Context context, int resourceId) {
+        super(context, resourceId);
+    }
+
+    public CustomImageSpan(Context context, int resourceId, int verticalAlignment) {
+        super(context, resourceId, verticalAlignment);
+    }
+
+    public CustomImageSpan(Context context, Bitmap resourceId, int verticalAlignment) {
+        super(context, resourceId, verticalAlignment);
+    }
+
+    @Override
+    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom,
+                     Paint paint) {
+
+        //draw 方法是重写的ImageSpan父类 DynamicDrawableSpan中的方法,在DynamicDrawableSpan类中,虽有getCachedDrawable(),
+        // 但是私有的,不能被调用,所以调用ImageSpan中的getrawable()方法,该方法中 会根据传入的drawable ID ,获取该id对应的
+        // drawable的流对象,并最终获取drawable对象
+        Drawable drawable = getDrawable(); //调用imageSpan中的方法获取drawable对象
+        canvas.save();
+
+        //获取画笔的文字绘制时的具体测量数据
+        Paint.FontMetricsInt fm = paint.getFontMetricsInt();
+
+        //系统原有方法,默认是Bottom模式)
+        int transY = bottom - drawable.getBounds().bottom;
+        if (mVerticalAlignment == ALIGN_BASELINE) {
+            transY -= fm.descent;
+        } else if (mVerticalAlignment == ALIGN_FONTCENTER) {    //此处加入判断, 如果是自定义的居中对齐
+            //与文字的中间线对齐(这种方式不论是否设置行间距都能保障文字的中间线和图片的中间线是对齐的)
+            // y+ascent得到文字内容的顶部坐标,y+descent得到文字的底部坐标,(顶部坐标+底部坐标)/2=文字内容中间线坐标
+            transY = ((y + fm.descent) + (y + fm.ascent)) / 2 - drawable.getBounds().bottom / 2;
+        }
+
+        canvas.translate(x, transY);
+        drawable.draw(canvas);
+        canvas.restore();
+    }
+
+    /**
+     * 重写getSize方法,只有重写该方法后,才能保证不论是图片大于文字还是文字大于图片,都能实现中间对齐
+     */
+    @Override
+    public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
+        Drawable d = getDrawable();
+        Rect rect = d.getBounds();
+        if (fm != null) {
+            Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
+            int fontHeight = fmPaint.bottom - fmPaint.top;
+            int drHeight = rect.bottom - rect.top;
+
+            int top = drHeight / 2 - fontHeight / 4;
+            int bottom = drHeight / 2 + fontHeight / 4;
+
+            fm.ascent = -bottom;
+            fm.top = -bottom;
+            fm.bottom = top;
+            fm.descent = top;
+        }
+        return rect.right;
+    }
+}

+ 129 - 0
room/src/main/java/com/swago/room/adapter/bitmap/HtmlImageGetter.java

@@ -0,0 +1,129 @@
+package com.swago.room.adapter.bitmap;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.text.Html;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.RequestBuilder;
+import com.bumptech.glide.load.resource.gif.GifDrawable;
+import com.bumptech.glide.request.target.SimpleTarget;
+import com.bumptech.glide.request.target.Target;
+import com.bumptech.glide.request.transition.Transition;
+import com.swago.baseswago.util.DpPxUtil;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * @date 2022/1/18 21:07
+ * description:
+ */
+public class HtmlImageGetter implements Html.ImageGetter{
+
+    List<String> tempImgKeys = new ArrayList<>();
+    private final Context mContext;
+    private final TextView mTextView;
+    private int suitHeight = 15;
+    private HashSet<Target> targets;
+    private HashSet<GifDrawable> gifDrawables;
+
+    public HtmlImageGetter(Context context, TextView textView, int suitHight, List<String> tempImgKey) {
+        tempImgKeys = (tempImgKey);
+        this.mContext = context;
+        this.mTextView = textView;
+        this.suitHeight = suitHight;
+        targets = new HashSet<>();
+        gifDrawables = new HashSet<>();
+    }
+
+    @Override
+    public Drawable getDrawable(String source) {
+        final UrlDrawable urlDrawable = new UrlDrawable();
+        for (String s : tempImgKeys) {
+            if (source.contains(s)) {
+                return urlDrawable;
+            }
+        }
+        RequestBuilder load;
+        final Target target;
+        if (isGif(source)) {
+            load = Glide.with(mContext).asGif().load(source);
+            target = new GifTarget(urlDrawable);
+        } else {
+            load = Glide.with(mContext).asBitmap().load(source);
+            target = new BitmapTarget(urlDrawable, source);
+        }
+        targets.add(target);
+        load.into(target);
+        return urlDrawable;
+    }
+
+
+    private static boolean isGif(String path) {
+        int index = path.lastIndexOf('.');
+        return index > 0 && "gif".toUpperCase().equals(path.substring(index + 1).toUpperCase());
+    }
+
+    private class GifTarget extends SimpleTarget<GifDrawable> {
+        private final UrlDrawable urlDrawable;
+
+
+        private GifTarget(UrlDrawable urlDrawable) {
+            this.urlDrawable = urlDrawable;
+
+        }
+
+        @Override
+        public void onResourceReady(GifDrawable resource, Transition<? super GifDrawable> glideAnimation) {
+            int w = DpPxUtil.INSTANCE.getScreenWidth();
+            int hh = resource.getIntrinsicHeight();
+            int ww = resource.getIntrinsicWidth();
+            int high = hh * (w - 50) / ww;
+            Rect rect = new Rect(20, 20, w - 30, high);
+            resource.setBounds(rect);
+            urlDrawable.setBounds(rect);
+            urlDrawable.setDrawable(resource);
+            gifDrawables.add(resource);
+            resource.setCallback(mTextView);
+            resource.start();
+            resource.setLoopCount(GifDrawable.LOOP_FOREVER);
+            mTextView.setText(mTextView.getText());
+            mTextView.invalidate();
+        }
+    }
+
+    private class BitmapTarget extends SimpleTarget<Bitmap> {
+        private final UrlDrawable urlDrawable;
+        private String mUrl;
+
+        private BitmapTarget(UrlDrawable urlDrawable, String url) {
+            this.urlDrawable = urlDrawable;
+            this.mUrl = url;
+        }
+
+        @Override
+        public void onResourceReady(Bitmap resource, Transition<? super Bitmap> glideAnimation) {
+            Drawable drawable = new BitmapDrawable(resource);
+            int width = resource.getWidth();
+            int height = resource.getHeight();
+            float type = width * 1f / height;
+            setBounds(drawable, type);
+            mTextView.setText(mTextView.getText());
+            mTextView.invalidate();
+        }
+
+        private void setBounds(Drawable drawable, float type) {
+            int heights = DpPxUtil.INSTANCE.dip2px(suitHeight);
+            int widths = (int) (heights * type);
+            drawable.setBounds(0, 0, widths, heights);
+            urlDrawable.setBounds(0, 0, widths, heights);
+            urlDrawable.setDrawable(drawable);
+        }
+    }
+}

+ 42 - 0
room/src/main/java/com/swago/room/adapter/bitmap/UrlDrawable.java

@@ -0,0 +1,42 @@
+package com.swago.room.adapter.bitmap;
+
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+
+/**
+ * @date 2022/1/18 21:06
+ * description:
+ */
+public class UrlDrawable extends BitmapDrawable implements Drawable.Callback{
+    private Drawable drawable;
+
+    @Override
+    public void draw(Canvas canvas) {
+        if (drawable != null) {
+            drawable.draw(canvas);
+        }
+    }
+
+    public Drawable getDrawable() {
+        return drawable;
+    }
+
+    @Override
+    public void scheduleDrawable(Drawable who, Runnable what, long when) {
+        scheduleSelf(what, when);
+    }
+
+    @Override
+    public void unscheduleDrawable(Drawable who, Runnable what) {
+        unscheduleSelf(what);
+    }
+    @Override
+    public void invalidateDrawable(Drawable who) {
+        invalidateSelf();
+    }
+
+    public void setDrawable(Drawable drawable) {
+        this.drawable = drawable;
+    }
+}

+ 2 - 0
room/src/main/java/com/swago/room/base/BaseComFragment.kt

@@ -111,7 +111,9 @@ abstract class BaseComFragment<T:FragmentBaseComBinding> : BaseXFragment<T>(),IR
             addChatMsgToRv(it)
         }
         msgVm.playSvgUrl = {
+            //svg播放
             svgPlayerManager.addSvgUrl(it)
+            //飘条
             waftManager.addNewMessage(it)
         }
     }

+ 0 - 2
room/src/main/java/com/swago/room/dialog/SendMsgDialog.kt

@@ -13,13 +13,11 @@ import com.swago.baseswago.dialog.BaseXDFragment
 import com.swago.baseswago.im.ImConstant.room_chat_text
 import com.swago.baseswago.model.im.RoomChatMsgBean
 import com.swago.baseswago.util.*
-import com.swago.baseswago.util.KeyboardUtil.closeKeyboard
 import com.swago.room.R
 import com.swago.room.databinding.DialogSendMsgBinding
 import com.swago.room.util.IMSender
 import com.tencent.imsdk.v2.V2TIMMessage
 import com.tencent.imsdk.v2.V2TIMValueCallback
-import com.tencent.qcloud.tim.uikit.utils.SoftKeyBoardUtil
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
 import org.json.JSONObject

+ 129 - 0
room/src/main/java/com/swago/room/game/GamePlayDialog.kt

@@ -0,0 +1,129 @@
+package com.swago.room.game
+
+import android.os.Bundle
+import android.view.Gravity
+import android.view.ViewGroup
+import android.webkit.JavascriptInterface
+import android.webkit.WebResourceRequest
+import android.webkit.WebView
+import android.webkit.WebViewClient
+import android.widget.FrameLayout
+import com.google.gson.Gson
+import com.swago.baseswago.dialog.BaseXDFragment
+import com.swago.baseswago.model.live.game.GameInfoModel
+import com.swago.baseswago.util.DpPxUtil
+import com.swago.room.databinding.DialogGamePlayBinding
+
+/**
+ *@date 2022/1/19 20:41
+ *description:
+ */
+class GamePlayDialog : BaseXDFragment<DialogGamePlayBinding>() {
+
+    private var url = ""
+
+    private var webView:WebView? = null
+    private val jsLoad by lazy {
+        JSLoad()
+    }
+    private val gson by lazy {
+        Gson()
+    }
+
+    companion object{
+        private const val URL = "url"
+        fun newInstance(url:String): GamePlayDialog {
+            val dialog = GamePlayDialog()
+            val bundle = Bundle()
+            bundle.putString(URL,url)
+            dialog.arguments = bundle
+            return dialog
+        }
+    }
+
+    init {
+        setCanCancel(false)
+        setGravity(Gravity.BOTTOM)
+        setDimAmount(0f)
+    }
+
+
+    override fun initOther() {
+        arguments?.let {
+            url = it.getString(URL,"")
+            activity?.let { activity ->
+                webView = WebView(activity)
+                webView?.apply {
+                    settings.javaScriptEnabled = true
+                    addJavascriptInterface(jsLoad,"jsLoad")
+                    settings.allowUniversalAccessFromFileURLs = true
+                    settings.allowFileAccess = true
+                    settings.allowFileAccessFromFileURLs = true
+                    settings.useWideViewPort = true
+                    settings.loadWithOverviewMode = true
+                    settings.javaScriptCanOpenWindowsAutomatically = true//设置允许JS弹窗
+                    settings.domStorageEnabled = true
+                    isHorizontalScrollBarEnabled = true
+                    isVerticalScrollBarEnabled = true
+                    clearCache(true)
+                    webViewClient = object:WebViewClient(){
+                        override fun shouldOverrideUrlLoading(
+                            view: WebView?,
+                            request: WebResourceRequest?
+                        ): Boolean {
+                            return super.shouldOverrideUrlLoading(view, request)
+                        }
+                    }
+
+                    //设置大小
+                    val params = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
+                    params.width = DpPxUtil.getScreenWidth()
+                    params.height = (params.width*276/360f).toInt()
+                    this.layoutParams = params
+                    binding.cl.addView(this)
+                }
+
+                webView?.loadUrl(url)
+            }
+        }
+    }
+
+    override fun initLiveData() {
+
+
+    }
+
+
+    inner class JSLoad{
+
+        @JavascriptInterface
+        fun getGameNeedInfo():String{
+//            val gameInfoModel = GameInfoModel()
+//            return gson.toJson(gameInfoModel)
+            return ""
+        }
+
+    }
+
+    override fun onDestroyView() {
+        try {
+            webView?.apply {
+                webChromeClient = null
+                parent?.let {
+                    val parent = it as ViewGroup
+                    parent.removeView(this)
+                }
+                stopLoading()
+                clearHistory()
+                removeAllViews()
+                clearCache(true)
+                destroy()
+                webView = null
+                binding.cl.removeAllViews()
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        super.onDestroyView()
+    }
+}

+ 1 - 1
room/src/main/java/com/swago/room/gift/control/SvgPlayerManager.kt

@@ -75,7 +75,7 @@ class SvgPlayerManager : IRoomActiveListener {
                 this.xSvgPlayer?.playSvga(it)
             } else {
                 this.xSvgPlayer?.apply {
-                    if (this.isCanplay){
+                    if (this.isCanPlay){
                         svgListQueue.add(it)
                     }else{
                         svgListQueue.clear()

+ 10 - 6
room/src/main/java/com/swago/room/gift/control/XSvgPlayer.kt

@@ -25,7 +25,10 @@ class XSvgPlayer : ConstraintLayout {
 
     var nextSvgPlay:(()->Unit)? = null
 
-    var isCanplay = false
+    /**
+     * 是否正在播放svg
+     */
+    var isCanPlay = false
 
     constructor(context: Context) : super(context)
     constructor(context: Context, mAttributeSet: AttributeSet?) : super(context, mAttributeSet){
@@ -40,7 +43,7 @@ class XSvgPlayer : ConstraintLayout {
 
     fun playSvga(imGiftModel:IMGiftModel){
         svgaParser!!.let {
-            isCanplay = true
+            isCanPlay = true
             it.parse(URL(imGiftModel.svga),object:SVGAParser.ParseCompletion{
                 override fun onComplete(videoItem: SVGAVideoEntity) {
                     binding!!.apply {
@@ -49,8 +52,8 @@ class XSvgPlayer : ConstraintLayout {
                         svgaImageView.setImageDrawable(drawable)
                         svgaImageView.loops = 1
                         svgaImageView.callback = callback
-                        Log.d("svgPlayer","dddd--$isCanplay")
-                        if (isCanplay){
+                        Log.d("svgPlayer","dddd--$isCanPlay")
+                        if (isCanPlay){
                             svgaImageView.startAnimation()
                         }
 
@@ -60,6 +63,7 @@ class XSvgPlayer : ConstraintLayout {
 
                 override fun onError() {
                     binding?.apply {
+                        isCanPlay = false
                         svgaImageView.visibility = View.GONE
                         nextSvgPlay?.invoke()
                     }
@@ -71,7 +75,7 @@ class XSvgPlayer : ConstraintLayout {
 
     fun clear(){
         binding?.apply {
-            isCanplay = false
+            isCanPlay = false
             svgaImageView.pauseAnimation()
             svgaImageView.clear()
         }
@@ -82,7 +86,7 @@ class XSvgPlayer : ConstraintLayout {
 
         override fun onFinished() {
             Log.d("svgPlayer","dddd--结束")
-            isCanplay = false
+            isCanPlay = false
             binding?.svgaImageView?.visibility = View.GONE
             nextSvgPlay?.invoke()
         }

+ 8 - 0
room/src/main/res/layout/dialog_game_play.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/cl"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 0
room/src/main/res/layout/fragment_base_com.xml

@@ -24,6 +24,7 @@
         android:id="@+id/rv"
         android:layout_marginStart="10dp"
         android:layout_marginEnd="10dp"
+        android:requiresFadingEdge="vertical"
         app:layout_constraintBottom_toBottomOf="parent"
         android:layout_marginBottom="70dp"
         android:layout_width="match_parent"

+ 1 - 1
room/src/main/res/layout/item_chat.xml

@@ -6,7 +6,7 @@
     xmlns:tools="http://schemas.android.com/tools">
 
     <TextView
-        android:id="@+id/tv"
+        android:id="@+id/tvContent"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:paddingStart="12dp"

+ 7 - 0
room/src/main/res/layout/item_chat_level.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.swago.baseswago.cusview.SwagoLevelView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+
+</com.swago.baseswago.cusview.SwagoLevelView>

+ 7 - 2
user/src/main/java/com/swago/user/recharge/RechargeActivity.kt

@@ -67,8 +67,9 @@ class RechargeActivity : BaseXActivity<ActivityRechargeBinding>(), IPayCallback
 
         binding.btRecharge.setOnClickListener(object : NoDoubleClickListener() {
             override fun onClick() {
+                //先去查询是否有未消费的订单
                 SwagoLoading.showLoadingDialog(this@RechargeActivity)
-                payVm.createOrder(adapter.data[selectedPosition].id)
+                PayManager.queryUnConsumeOrder(adapter.data[selectedPosition].id)
             }
         })
 
@@ -127,7 +128,7 @@ class RechargeActivity : BaseXActivity<ActivityRechargeBinding>(), IPayCallback
     override fun onQueryProductPrice(data: List<PayModel>) {
         SwagoLoading.cancelLoadingDialog()
         adapter.setNewData(data)
-        PayManager.queryUnConsumeOrder(null,"","")
+        PayManager.queryUnConsumeOrder("")
     }
 
     override fun onPayError(code: Int) {
@@ -158,4 +159,8 @@ class RechargeActivity : BaseXActivity<ActivityRechargeBinding>(), IPayCallback
     override fun consumeOrderFail(code: Int) {
 
     }
+
+    override fun toCreateNewOrder(productId: String) {
+        payVm.createOrder(productId)
+    }
 }