33 Revize fb64531e2b ... 847460782e

Autor SHA1 Zpráva Datum
  tongmengxiao 847460782e feat: update game před 2 měsíci
  tongmengxiao 382ad50ede fix: remove music empty před 2 měsíci
  tongmengxiao 19944b85c8 fix: join animal peek před 2 měsíci
  tongmengxiao f18db4aded feat: person leak před 2 měsíci
  tongmengxiao 6eede5dd19 fix: message info před 2 měsíci
  tongmengxiao 6d26d55b38 fix: buyProduct success před 2 měsíci
  tongmengxiao df01288aa9 fix: bug před 2 měsíci
  tongmengxiao c2cb1e6c79 fix: music local před 2 měsíci
  tongmengxiao f487d7284e fix: using před 2 měsíci
  tongmengxiao f1ce65af40 fix: game send před 2 měsíci
  tongmengxiao fcf09737c7 fix: chat text před 2 měsíci
  tongmengxiao efd29c678b fix: 商品状态 před 2 měsíci
  tongmengxiao d7da59782d fix: 主播底部弹窗 game背景图 před 2 měsíci
  tongmengxiao 87f8430518 fix: bug před 2 měsíci
  tongmengxiao 367a91f9e1 feat: daodb proguard před 2 měsíci
  tongmengxiao 6c4f0c29d7 feat: import před 2 měsíci
  tongmengxiao 2b30c79159 feat:chat 默认背景图 před 2 měsíci
  tongmengxiao bf5035f686 feat: android ios chat před 3 měsíci
  tongmengxiao f4bffb2244 feat:私聊背景图 před 3 měsíci
  tongmengxiao 4afa87a6a0 feat: delete toastutils před 3 měsíci
  tongmengxiao 86c65988c6 feat: 聊天气泡 před 3 měsíci
  tongmengxiao b1fd42c25d feat: home refresh před 3 měsíci
  tongmengxiao bbe326c575 feat: game bg před 3 měsíci
  tongmengxiao 6bcaf120c4 feat:点九 před 3 měsíci
  tongmengxiao 1a976c4dd2 feat: 头像框 před 3 měsíci
  tongmengxiao 32e4c3e2e1 feat: home refresh před 3 měsíci
  tongmengxiao b3420a30ea feat: 分辨率 před 3 měsíci
  tongmengxiao a662baad2c feat : 头像 před 3 měsíci
  tongmengxiao e37d0aaa53 feat: 头像框 před 3 měsíci
  tongmengxiao 53379a6500 feat: 聊天气泡 před 3 měsíci
  tongmengxiao 6e31f5c479 feat: glide před 3 měsíci
  tongmengxiao 558bbbc803 feat: 选中装扮 před 3 měsíci
  tongmengxiao 0d1a82f5f8 feat: asset game před 3 měsíci
100 změnil soubory, kde provedl 1933 přidání a 275 odebrání
  1. 14 1
      app/proguard-rules.pro
  2. 13 0
      app/src/main/java/com/swago/app/SplashActivity.kt
  3. binární
      baseswago/src/main/assets/avatar.svga
  4. binární
      baseswago/src/main/assets/com-swago-magical-piggy.zip
  5. 39 3
      baseswago/src/main/java/com/swago/baseswago/PersonDataDFragment.kt
  6. 2 1
      baseswago/src/main/java/com/swago/baseswago/agora/AgoraManager.kt
  7. 2 0
      baseswago/src/main/java/com/swago/baseswago/agora/ISwagoIRtcEngineEventHandler.kt
  8. 5 0
      baseswago/src/main/java/com/swago/baseswago/baseroom/IRoomInfo.kt
  9. 2 0
      baseswago/src/main/java/com/swago/baseswago/constant/UrlConstant.kt
  10. 1 1
      baseswago/src/main/java/com/swago/baseswago/dialog/ChoiceDialogFragment.kt
  11. 13 0
      baseswago/src/main/java/com/swago/baseswago/inter/UserApi.kt
  12. 44 0
      baseswago/src/main/java/com/swago/baseswago/model/MomentModel.java
  13. 45 0
      baseswago/src/main/java/com/swago/baseswago/model/UserInfoModel.java
  14. 3 0
      baseswago/src/main/java/com/swago/baseswago/model/im/RoomChatMsgBean.java
  15. 5 0
      baseswago/src/main/java/com/swago/baseswago/model/im/UserJoinRoomBean.java
  16. 37 0
      baseswago/src/main/java/com/swago/baseswago/model/live/RoomModel.java
  17. 27 1
      baseswago/src/main/java/com/swago/baseswago/model/live/RoomUserModel.java
  18. 5 2
      baseswago/src/main/java/com/swago/baseswago/model/live/audio/AudioSeatModel.kt
  19. 2 1
      baseswago/src/main/java/com/swago/baseswago/model/live/audio/AudioSendGiftModel.kt
  20. 1 0
      baseswago/src/main/java/com/swago/baseswago/model/live/audio/IMAudioModel.kt
  21. 2 1
      baseswago/src/main/java/com/swago/baseswago/model/live/audio/IMAudioSeatUpdateModel.kt
  22. 1 0
      baseswago/src/main/java/com/swago/baseswago/model/live/audio/MaiUserModel.kt
  23. 9 0
      baseswago/src/main/java/com/swago/baseswago/model/live/gift/IMGiftModel.java
  24. 7 1
      baseswago/src/main/java/com/swago/baseswago/model/mine/StoreProductModel.kt
  25. 85 0
      baseswago/src/main/java/com/swago/baseswago/util/BitmapUtils.kt
  26. 50 0
      baseswago/src/main/java/com/swago/baseswago/util/DianJiuUtil.kt
  27. 29 0
      baseswago/src/main/java/com/swago/baseswago/util/FileUtil.kt
  28. 61 0
      baseswago/src/main/java/com/swago/baseswago/util/NinePatchChunk.kt
  29. 24 0
      baseswago/src/main/java/com/swago/baseswago/util/StringUtils.kt
  30. 57 0
      baseswago/src/main/java/com/swago/glide.kt
  31. 42 14
      baseswago/src/main/res/layout/dialog_person_data.xml
  32. 13 1
      baseswago/src/main/res/values-ar/strings.xml
  33. 12 0
      baseswago/src/main/res/values-in/strings.xml
  34. 12 0
      baseswago/src/main/res/values-ms/strings.xml
  35. 13 1
      baseswago/src/main/res/values-zh/strings.xml
  36. 13 1
      baseswago/src/main/res/values/strings.xml
  37. 59 5
      home/src/main/java/com/swago/home/ChatDetailActivity.kt
  38. 27 5
      home/src/main/java/com/swago/home/MessageFragment.kt
  39. 21 2
      home/src/main/java/com/swago/home/MineFragment.kt
  40. 7 2
      home/src/main/java/com/swago/home/innerhome/FollowFragment.kt
  41. 7 2
      home/src/main/java/com/swago/home/innerhome/HotFragment.kt
  42. 7 2
      home/src/main/java/com/swago/home/innerhome/NewFragment.kt
  43. 14 2
      home/src/main/res/layout/fragment_mine.xml
  44. binární
      home/src/main/res/mipmap-xxhdpi/icon_my_store.png
  45. 25 0
      room/src/main/java/com/swago/room/adapter/AudienceAdapter.kt
  46. 78 6
      room/src/main/java/com/swago/room/adapter/RoomChatAdapter.kt
  47. 29 1
      room/src/main/java/com/swago/room/adapter/RoomUserAdapter.kt
  48. 4 0
      room/src/main/java/com/swago/room/anchor/AnchorRoomActivity.kt
  49. 45 7
      room/src/main/java/com/swago/room/anchor/AnchorRoomFragment.kt
  50. 28 1
      room/src/main/java/com/swago/room/audio/AudioSeatAdapter.kt
  51. 68 34
      room/src/main/java/com/swago/room/base/BaseComFragment.kt
  52. 28 0
      room/src/main/java/com/swago/room/bean/UserRoomModel.kt
  53. 1 1
      room/src/main/java/com/swago/room/database/DBManager.kt
  54. 13 1
      room/src/main/java/com/swago/room/dialog/FooterMoreDialog.kt
  55. 24 4
      room/src/main/java/com/swago/room/dialog/MessageListDialog.kt
  56. 12 2
      room/src/main/java/com/swago/room/dialog/SendMsgDialog.kt
  57. 58 17
      room/src/main/java/com/swago/room/game/GamePlayDialog.kt
  58. 9 0
      room/src/main/java/com/swago/room/gift/GiftDialog.kt
  59. 25 0
      room/src/main/java/com/swago/room/gift/audio/MaiUserAdapter.kt
  60. 38 0
      room/src/main/java/com/swago/room/gift/control/XSvgPlayer.kt
  61. 16 0
      room/src/main/java/com/swago/room/giftdandao/GiftDanDaoView.kt
  62. 6 0
      room/src/main/java/com/swago/room/hongbao/RedEnvelopResultDialog.kt
  63. 82 0
      room/src/main/java/com/swago/room/manager/JoinAnimalManager.kt
  64. 49 0
      room/src/main/java/com/swago/room/manager/JoinRoomManager.kt
  65. 1 1
      room/src/main/java/com/swago/room/music/LocalMusicActivity.kt
  66. 1 1
      room/src/main/java/com/swago/room/music/MusicVm.kt
  67. 4 0
      room/src/main/java/com/swago/room/music/MyMusicAdapter.kt
  68. 28 13
      room/src/main/java/com/swago/room/music/MyMusicDialog.kt
  69. 4 0
      room/src/main/java/com/swago/room/user/UserRoomActivity.kt
  70. 13 2
      room/src/main/java/com/swago/room/vm/MsgVm.kt
  71. 3 0
      room/src/main/java/com/swago/room/vm/RoomVm.kt
  72. 22 4
      room/src/main/java/com/swago/room/widget/AnchorFooterView.kt
  73. 21 0
      room/src/main/java/com/swago/room/widget/ComHeaderView.kt
  74. 6 0
      room/src/main/java/com/swago/room/widget/UserShowAnchorCloseView.kt
  75. 17 1
      room/src/main/res/layout/dialog_footer_more.xml
  76. 10 2
      room/src/main/res/layout/dialog_game_play.xml
  77. 0 62
      room/src/main/res/layout/dialog_my_music.xml
  78. 30 8
      room/src/main/res/layout/item_audio_seat.xml
  79. 33 9
      room/src/main/res/layout/item_dialog_audience.xml
  80. 11 1
      room/src/main/res/layout/item_mai_user.xml
  81. 26 15
      room/src/main/res/layout/item_my_music.xml
  82. 18 2
      room/src/main/res/layout/item_room_user.xml
  83. 3 3
      room/src/main/res/layout/layout_anchor_footer_view.xml
  84. 30 8
      room/src/main/res/layout/layout_user_header_view.xml
  85. 31 10
      room/src/main/res/layout/view_item_gift.xml
  86. 11 1
      room/src/main/res/layout/view_user_join_room.xml
  87. binární
      room/src/main/res/mipmap-xxhdpi/bg_food_wheel.png
  88. binární
      room/src/main/res/mipmap-xxhdpi/bg_frenzy_vagas.png
  89. binární
      room/src/main/res/mipmap-xxhdpi/bg_fruit_party.png
  90. binární
      room/src/main/res/mipmap-xxhdpi/bg_lucky_piggy.png
  91. binární
      room/src/main/res/mipmap-xxhdpi/bg_magical_piggy.png
  92. binární
      room/src/main/res/mipmap-xxhdpi/bg_three_card.png
  93. binární
      room/src/main/res/mipmap-xxhdpi/bg_three_card_duel.png
  94. binární
      room/src/main/res/mipmap-xxhdpi/bg_tigers.jpg
  95. binární
      room/src/main/res/mipmap-xxhdpi/ic_music_play.png
  96. binární
      room/src/main/res/mipmap-xxhdpi/ic_music_stop.png
  97. 17 0
      tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/chat/base/ChatManagerKit.java
  98. 30 0
      tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/chat/interfaces/IMessageProperties.java
  99. 42 0
      tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/chat/layout/message/MessageLayoutUI.java
  100. 51 9
      tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/chat/layout/message/holder/MessageContentHolder.java

+ 14 - 1
app/proguard-rules.pro

@@ -247,4 +247,17 @@
 -keepclassmembers class com.facebook.applinks.** { *; }
 -keep class com.facebook.FacebookSdk { *; }
 -keep class com.huawei.hms.ads.** { *; }
--keep class com.facebook.login.** { *; }
+-keep class com.facebook.login.** { *; }
+
+-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {
+public static java.lang.String TABLENAME;
+}
+-keep class **$Properties { *; }
+
+# If you DO use SQLCipher:
+-keep class org.greenrobot.greendao.database.SqlCipherEncryptedHelper { *; }
+
+# If you do NOT use SQLCipher:
+-dontwarn net.sqlcipher.database.**
+# If you do NOT use RxJava:
+-dontwarn rx.**

+ 13 - 0
app/src/main/java/com/swago/app/SplashActivity.kt

@@ -10,7 +10,12 @@ import androidx.appcompat.app.AppCompatActivity
 import com.alibaba.android.arouter.launcher.ARouter
 import com.swago.baseswago.constant.ARouteConstant
 import com.permissionx.guolindev.PermissionX
+import com.swago.baseswago.constant.UrlConstant
+import com.swago.baseswago.util.AppContext
+import com.swago.baseswago.util.FileUtil
 import com.swago.baseswago.util.MD5Util
+import com.swago.baseswago.util.SpUtil
+import java.io.File
 
 class SplashActivity : AppCompatActivity() {
 
@@ -69,5 +74,13 @@ class SplashActivity : AppCompatActivity() {
                     }
                 }
         }
+
+        if(!File(UrlConstant.appGameRootPath + File.separator + 8 + File.separator + "index.html").exists()){
+            FileUtil.copyAssetFile(AppContext.getContext() , "com-swago-magical-piggy.zip" , File(UrlConstant.appGameRootPath + File.separator + 8 + File.separator + "com-swago-magical-piggy.zip"))
+            SpUtil.putInt("8", 33)
+            val t = UrlConstant.appGameRootPath + File.separator + 8
+            FileUtil.upZipFile(UrlConstant.appGameRootPath + File.separator + 8 + File.separator + "com-swago-magical-piggy.zip" , t + File.separator)
+        }
+
     }
 }

binární
baseswago/src/main/assets/avatar.svga


binární
baseswago/src/main/assets/com-swago-magical-piggy.zip


+ 39 - 3
baseswago/src/main/java/com/swago/baseswago/PersonDataDFragment.kt

@@ -9,6 +9,9 @@ import android.widget.Toast
 import androidx.fragment.app.viewModels
 import com.alibaba.android.arouter.launcher.ARouter
 import com.bumptech.glide.Glide
+import com.opensource.svgaplayer.SVGADrawable
+import com.opensource.svgaplayer.SVGAParser
+import com.opensource.svgaplayer.SVGAVideoEntity
 import com.permissionx.guolindev.PermissionX
 import com.swago.baseswago.baseroom.SwagoRoomManager
 import com.swago.baseswago.constant.ARouteConstant
@@ -17,9 +20,13 @@ import com.swago.baseswago.dialog.BaseXDFragment
 import com.swago.baseswago.dialog.HandleDialogFragment
 import com.swago.baseswago.dialog.ReportDialog
 import com.swago.baseswago.util.AppContext
+import com.swago.baseswago.util.BitmapUtils
 import com.swago.baseswago.util.IMUtil
 import com.swago.baseswago.util.NoDoubleClickListener
 import com.swago.baseswago.util.UserInfo
+import com.swago.loadUrl
+import com.swago.loadUrlNoPlaceHolder
+import java.net.URL
 
 /**
  *@date 2021/8/27 17:14
@@ -36,6 +43,7 @@ class PersonDataDFragment : BaseXDFragment<DialogPersonDataBinding>() {
     var nickIcon = ""
     var account = ""
     var roomId:String = ""
+    var headSpecial:String = ""
     var isAnchor = false //是否是主播点击了资料卡
     var isAdmin = false
     var isMessage = false
@@ -44,6 +52,9 @@ class PersonDataDFragment : BaseXDFragment<DialogPersonDataBinding>() {
     var openGiftDialog:((nickName:String,userId:String)->Unit)? = null
     var openGiftIconDialog:((nickName:String,userId:String,nickIcon:String)->Unit)? = null
     var sendMsgInRoom:((nickName:String)->Unit)? = null
+    val svgaParser by lazy {
+        SVGAParser(activity)
+    }
 
     companion object{
         fun newInstance(uid:String,isAnchor:Boolean=false,inRoom:Boolean=false,roomId:String="",isMessage:Boolean=false): PersonDataDFragment {
@@ -117,7 +128,8 @@ class PersonDataDFragment : BaseXDFragment<DialogPersonDataBinding>() {
                                 if (allGranted) {
                                     ARouter.getInstance().build(ARouteConstant.Home.chatDetail)
                                         .withString("account",account)
-                                        .withString("chatName",binding.tvName.text.toString()).navigation()
+                                        .withString("chatName",binding.tvName.text.toString())
+                                        .withString("headSpecial" , headSpecial).navigation()
                                     dismissAllowingStateLoss()
                                 } else {
                                     Toast.makeText(
@@ -151,7 +163,7 @@ class PersonDataDFragment : BaseXDFragment<DialogPersonDataBinding>() {
                         if (!TextUtils.isEmpty(uid)){
                             userVm.getOtherUserInfo(uid,roomId)
                         }
-                    }.show(parentFragmentManager,"HandleDialogFragment")
+                    }.show(childFragmentManager,"HandleDialogFragment")
                 }
             })
 
@@ -165,6 +177,7 @@ class PersonDataDFragment : BaseXDFragment<DialogPersonDataBinding>() {
             nickName = it.user_name
             nickIcon = it.user_head_img_url
             account = it.user_account
+            headSpecial = it.android_head_special
             binding.ivVip.visibility = if (it.is_benefit==1) View.VISIBLE else View.GONE
             Glide.with(this).load(it.user_head_img_url)
                 .placeholder(R.mipmap.default_avatar)
@@ -235,9 +248,32 @@ class PersonDataDFragment : BaseXDFragment<DialogPersonDataBinding>() {
             }
 
             isAdmin = it.is_room_admin == 1
-        }
 
+            if (!TextUtils.isEmpty(it.android_head_special)){
+                svgaParser.decodeFromURL(URL(it.android_head_special), object :SVGAParser.ParseCompletion{
+                    override fun onComplete(videoItem: SVGAVideoEntity) {
+                        val drawable = SVGADrawable(videoItem)
+                        binding.svgAvatar.setImageDrawable(drawable)
+                        binding.svgAvatar.startAnimation()
+                    }
+
+                    override fun onError() {
+                    }
+                })
+            }
+            if (TextUtils.isEmpty(it.android_badge_special)){
+                binding.ivBadge.visibility = View.GONE
+            } else {
+                activity?.let { activity ->
+                    Glide.with(activity)
+                        .load(it.android_badge_special)
+                        .override(200)
+                        .into(binding.ivBadge)
+                    binding.ivBadge.visibility = View.VISIBLE
+                }
 
+            }
+        }
         userVm.followStateLiveData.observe(this) {
             if (isFollow == 0) {
                 isFollow = 1

+ 2 - 1
baseswago/src/main/java/com/swago/baseswago/agora/AgoraManager.kt

@@ -124,6 +124,7 @@ object AgoraManager {
                     override fun onAudioMixingStateChanged(state: Int, reason: Int) {
                         super.onAudioMixingStateChanged(state, reason)
                         LogUtil.d("onAudioMixingStateChanged" , "结果--$state  $reason")
+                        iSwagoIRtcEngineEventHandler?.onAudioMixingStateChanged(state,reason)
                     }
                 })
             setChannelProfile()
@@ -264,7 +265,7 @@ object AgoraManager {
 
 
     fun setVideoConfiguration(
-        vd: VideoEncoderConfiguration.VideoDimensions = VideoEncoderConfiguration.VD_480x360,
+        vd: VideoEncoderConfiguration.VideoDimensions = VideoEncoderConfiguration.VD_640x480,
         fps: VideoEncoderConfiguration.FRAME_RATE = VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15
     ) {
         mRtcEngine?.setVideoEncoderConfiguration(

+ 2 - 0
baseswago/src/main/java/com/swago/baseswago/agora/ISwagoIRtcEngineEventHandler.kt

@@ -33,4 +33,6 @@ interface ISwagoIRtcEngineEventHandler {
         imageHeight: Int,
         faces: Array<out IRtcEngineEventHandler.AgoraFacePositionInfo>?
     )
+
+    fun onAudioMixingStateChanged(state:Int, reason:Int)
 }

+ 5 - 0
baseswago/src/main/java/com/swago/baseswago/baseroom/IRoomInfo.kt

@@ -46,4 +46,9 @@ interface IRoomInfo {
     fun getRoomBg():String //获取房间背景图
 
     fun getPassStatus():Int //是否密码房(1是0否)
+
+    fun getJoinSpecial():String //加入直播间特效
+    fun getHeadSpecial():String //头像框
+    fun getBadgeSpecial():String //徽章
+    fun getChatSpecial():String //聊天气泡
 }

+ 2 - 0
baseswago/src/main/java/com/swago/baseswago/constant/UrlConstant.kt

@@ -93,4 +93,6 @@ object UrlConstant {
     var lottieResourcePath =
         AppContext.getContext().getExternalFilesDir("")?.absolutePath + File.separator + "lottie"
     var lottieDownloadUrl = ""
+    var specialResourcePath =
+        AppContext.getContext().getExternalFilesDir("")?.absolutePath + File.separator + "swagoFile"
 }

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

@@ -49,7 +49,7 @@ class ChoiceDialogFragment : BaseXDFragment<DialogChoiceBinding>() {
                 binding.tvCancel.text = lefChoiceText
             }
             if (!rightChoiceText.isNullOrEmpty()){
-                binding.tvCancel.text = rightChoiceText
+                binding.tvSure.text = rightChoiceText
             }
 
             binding.tvCancel.setOnClickListener(object:NoDoubleClickListener(){

+ 13 - 0
baseswago/src/main/java/com/swago/baseswago/inter/UserApi.kt

@@ -160,10 +160,23 @@ interface UserApi {
     @POST("/v1/user/coin/product/list")
     suspend fun getProductList(): StoreProductModel
 
+    /**
+     * 购买
+     * */
     @FormUrlEncoded
     @POST("/v1/user/buy/product")
     suspend fun buyProduct(@Field("product_id") product_id: Long):Any
 
+    /**
+     * 装扮列表
+     * */
     @POST("/v1/user/exist/product/list")
     suspend fun exitProductList():StoreProductModel
+
+    /**
+     * 选中装扮
+     * */
+    @FormUrlEncoded
+    @POST("/v1/user/exist/product/chose")
+    suspend fun choseProduct(@Field("product_id") product_id: Long):Any
 }

+ 44 - 0
baseswago/src/main/java/com/swago/baseswago/model/MomentModel.java

@@ -33,6 +33,10 @@ public class MomentModel implements Parcelable {
     private int is_cup;
     private int user_broadcast_type; //直播间类型(1视频2语音)
     private int broadcast_password_status;//是否密码房(1是0否)
+    private String head_special;
+    private String badge_special;
+    private String join_special;
+    private String chat_special;
 
     public MomentModel(){
 
@@ -55,6 +59,10 @@ public class MomentModel implements Parcelable {
         is_cup = in.readInt();
         user_broadcast_type = in.readInt();
         broadcast_password_status = in.readInt();
+        head_special = in.readString();
+        badge_special = in.readString();
+        join_special = in.readString();
+        chat_special = in.readString();
     }
 
     @Override
@@ -75,6 +83,10 @@ public class MomentModel implements Parcelable {
         dest.writeInt(is_cup);
         dest.writeInt(user_broadcast_type);
         dest.writeInt(broadcast_password_status);
+        dest.writeString(head_special);
+        dest.writeString(badge_special);
+        dest.writeString(join_special);
+        dest.writeString(chat_special);
     }
 
     @Override
@@ -237,4 +249,36 @@ public class MomentModel implements Parcelable {
     public void setBroadcast_password_status(int broadcast_password_status) {
         this.broadcast_password_status = broadcast_password_status;
     }
+
+    public String getHead_special() {
+        return head_special;
+    }
+
+    public void setHead_special(String head_special) {
+        this.head_special = head_special;
+    }
+
+    public String getBadge_special() {
+        return badge_special;
+    }
+
+    public void setBadge_special(String badge_special) {
+        this.badge_special = badge_special;
+    }
+
+    public String getJoin_special() {
+        return join_special;
+    }
+
+    public void setJoin_special(String join_special) {
+        this.join_special = join_special;
+    }
+
+    public String getChat_special() {
+        return chat_special;
+    }
+
+    public void setChat_special(String chat_special) {
+        this.chat_special = chat_special;
+    }
 }

+ 45 - 0
baseswago/src/main/java/com/swago/baseswago/model/UserInfoModel.java

@@ -103,6 +103,11 @@ public class UserInfoModel {
      * 是否充值用户
      */
     private int is_recharge;
+    private String android_join_special;
+    private String android_head_special;
+    private String android_badge_special;
+    private String android_chat_special;
+    private String ios_chat_special;
 
     public String getUser_constellation() {
         return user_constellation;
@@ -407,4 +412,44 @@ public class UserInfoModel {
     public void setIs_recharge(int is_recharge) {
         this.is_recharge = is_recharge;
     }
+
+    public String getAndroid_join_special() {
+        return android_join_special;
+    }
+
+    public void setAndroid_join_special(String android_join_special) {
+        this.android_join_special = android_join_special;
+    }
+
+    public String getAndroid_head_special() {
+        return android_head_special;
+    }
+
+    public void setAndroid_head_special(String android_head_special) {
+        this.android_head_special = android_head_special;
+    }
+
+    public String getAndroid_badge_special() {
+        return android_badge_special;
+    }
+
+    public void setAndroid_badge_special(String android_badge_special) {
+        this.android_badge_special = android_badge_special;
+    }
+
+    public String getAndroid_chat_special() {
+        return android_chat_special;
+    }
+
+    public void setAndroid_chat_special(String android_chat_special) {
+        this.android_chat_special = android_chat_special;
+    }
+
+    public String getIos_chat_special() {
+        return ios_chat_special;
+    }
+
+    public void setIos_chat_special(String ios_chat_special) {
+        this.ios_chat_special = ios_chat_special;
+    }
 }

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

@@ -15,6 +15,9 @@ public class RoomChatMsgBean implements IRoomChat {
     public String sendName="";
     public String content="";
     public String roomId="";
+    public String ios_chat_special="";
+    public String android_chat_special="";
+    public String badge_special="";
     public int senderLevel;
     public int isBenefit;
     public int isPrettyAccount;

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

@@ -29,6 +29,11 @@ public class UserJoinRoomBean implements IRoomChat {
     public int isCrown;
     public int isCup;
     public int isFans;
+    public String androidJoinSpecial="";
+    public String androidHeadSpecial="";
+    public String androidBadgeSpecial="";
+    public String androidChatSpecial="";
+    public String iosChatSpecial="";
 
     @NonNull
     @Override

+ 37 - 0
baseswago/src/main/java/com/swago/baseswago/model/live/RoomModel.java

@@ -53,6 +53,11 @@ public class RoomModel {
 
     private String broadcast_bg_url;
 
+    private String join_special;
+    private String head_special;
+    private String badge_special;
+    private String chat_special;
+
     private CusNewMsgBean<RoomUserChangeModel> join_im_data;
 
     public String getRtc_token() {
@@ -278,4 +283,36 @@ public class RoomModel {
     public void setJoin_im_data(CusNewMsgBean<RoomUserChangeModel> join_im_data) {
         this.join_im_data = join_im_data;
     }
+
+    public String getJoin_special() {
+        return join_special;
+    }
+
+    public void setJoin_special(String join_special) {
+        this.join_special = join_special;
+    }
+
+    public String getHead_special() {
+        return head_special;
+    }
+
+    public void setHead_special(String head_special) {
+        this.head_special = head_special;
+    }
+
+    public String getBadge_special() {
+        return badge_special;
+    }
+
+    public void setBadge_special(String badge_special) {
+        this.badge_special = badge_special;
+    }
+
+    public String getChat_special() {
+        return chat_special;
+    }
+
+    public void setChat_special(String chat_special) {
+        this.chat_special = chat_special;
+    }
 }

+ 27 - 1
baseswago/src/main/java/com/swago/baseswago/model/live/RoomUserModel.java

@@ -54,8 +54,10 @@ public class RoomUserModel {
         private int is_official;
         private int is_crown;
         private int is_cup;
-
         private String contribute_val;
+        private String android_head_special;
+        private String head_special;
+        private String ios_head_special;
 
         public String getUser_id() {
             return user_id;
@@ -169,5 +171,29 @@ public class RoomUserModel {
         public void setContribute_val(String contribute_val) {
             this.contribute_val = contribute_val;
         }
+
+        public String getAndroid_head_special() {
+            return android_head_special;
+        }
+
+        public void setAndroid_head_special(String android_head_special) {
+            this.android_head_special = android_head_special;
+        }
+
+        public String getIos_head_special() {
+            return ios_head_special;
+        }
+
+        public void setIos_head_special(String ios_head_special) {
+            this.ios_head_special = ios_head_special;
+        }
+
+        public String getHead_special() {
+            return head_special;
+        }
+
+        public void setHead_special(String head_special) {
+            this.head_special = head_special;
+        }
     }
 }

+ 5 - 2
baseswago/src/main/java/com/swago/baseswago/model/live/audio/AudioSeatModel.kt

@@ -12,7 +12,8 @@ data class AudioSeatModel(
     var voice_jifen:String?,//积分
     var voice_user_id:String?,//被谁给闭麦
     val maiIndex:Int,//积分
-    var showVoice:Int //说话闪烁 1显示 0隐藏
+    var showVoice:Int, //说话闪烁 1显示 0隐藏
+    var head_special:String? //头像框
 ) : Parcelable {
     constructor(parcel: Parcel) : this(
         parcel.readString(),
@@ -23,7 +24,8 @@ data class AudioSeatModel(
         parcel.readString(),
         parcel.readString(),
         parcel.readInt(),
-        parcel.readInt()
+        parcel.readInt(),
+        parcel.readString()
     ) {
     }
 
@@ -37,6 +39,7 @@ data class AudioSeatModel(
         parcel.writeString(voice_user_id)
         parcel.writeInt(maiIndex)
         parcel.writeInt(showVoice)
+        parcel.writeString(head_special)
     }
 
     override fun describeContents(): Int {

+ 2 - 1
baseswago/src/main/java/com/swago/baseswago/model/live/audio/AudioSendGiftModel.kt

@@ -30,7 +30,8 @@ data class AudioSendGiftModel(
     val senderAvatar:String,
     val im_data: ImData,
     val isCombo: Int,
-    val senderCode: String
+    val senderCode: String,
+    val androidHeadSpecial: String
 )
 
 data class Receiver(

+ 1 - 0
baseswago/src/main/java/com/swago/baseswago/model/live/audio/IMAudioModel.kt

@@ -14,4 +14,5 @@ data class IMAudioModel(
     val applyId:String,
     val voice_jifen:String,
     val notice: String,
+    val head_special: String
 )

+ 2 - 1
baseswago/src/main/java/com/swago/baseswago/model/live/audio/IMAudioSeatUpdateModel.kt

@@ -14,5 +14,6 @@ data class IMAudioSeat(
     val userAvatar:String,
     val userId:String,
     val userName:String,
-    val voiceUserId:String
+    val voiceUserId:String,
+    val head_special :String
 )

+ 1 - 0
baseswago/src/main/java/com/swago/baseswago/model/live/audio/MaiUserModel.kt

@@ -9,4 +9,5 @@ data class MaiUserInfo(
     val user_id: String,
     val user_name: String,
     var selected:Boolean,
+    var head_special: String?=""
 )

+ 9 - 0
baseswago/src/main/java/com/swago/baseswago/model/live/gift/IMGiftModel.java

@@ -57,6 +57,7 @@ public class IMGiftModel implements IPiaoTiao {
     private String userWealthJingyanValue;
 
     private String nextWealthNeedJingyan;
+    private String androidHeadSpecial;
 
     public String getRoomId() {
         return roomId;
@@ -250,4 +251,12 @@ public class IMGiftModel implements IPiaoTiao {
     public void setNextWealthNeedJingyan(String nextWealthNeedJingyan) {
         this.nextWealthNeedJingyan = nextWealthNeedJingyan;
     }
+
+    public String getAndroidHeadSpecial() {
+        return androidHeadSpecial;
+    }
+
+    public void setAndroidHeadSpecial(String androidHeadSpecial) {
+        this.androidHeadSpecial = androidHeadSpecial;
+    }
 }

+ 7 - 1
baseswago/src/main/java/com/swago/baseswago/model/mine/StoreProductModel.kt

@@ -10,25 +10,31 @@ data class StoreProductModel(
 data class StoreItemBean (
     val product_name: String?,
     val product_url: String?,
+    val product_svg_url: String?,
     val product_category: Int,
     val product_coin: Long,
+    val expire_at: Long,
     val id: Long,
-    val product_status: Int
+    var product_status: Int
 ) :Parcelable{
     constructor(parcel: Parcel) : this(
+        parcel.readString(),
         parcel.readString(),
         parcel.readString(),
         parcel.readInt(),
         parcel.readLong(),
         parcel.readLong(),
+        parcel.readLong(),
         parcel.readInt()
     )
 
     override fun writeToParcel(parcel: Parcel, flags: Int) {
         parcel.writeString(product_name)
         parcel.writeString(product_url)
+        parcel.writeString(product_svg_url)
         parcel.writeInt(product_category)
         parcel.writeLong(product_coin)
+        parcel.writeLong(expire_at)
         parcel.writeLong(id)
         parcel.writeInt(product_status)
     }

+ 85 - 0
baseswago/src/main/java/com/swago/baseswago/util/BitmapUtils.kt

@@ -0,0 +1,85 @@
+package com.swago.baseswago.util
+
+import android.app.Activity
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.graphics.drawable.Drawable
+import android.text.TextUtils
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.DataSource
+import com.bumptech.glide.load.engine.GlideException
+import com.bumptech.glide.request.RequestListener
+import com.bumptech.glide.request.target.CustomTarget
+import com.bumptech.glide.request.target.Target
+import com.bumptech.glide.request.transition.Transition
+import com.swago.baseswago.constant.UrlConstant
+import java.io.File
+import java.io.FileOutputStream
+import java.io.IOException
+
+object BitmapUtils {
+    fun loadFile(context: Context, url:String?, response: ((resource: Bitmap?) -> Unit)?=null){
+        if (TextUtils.isEmpty(url)){
+            response?.invoke(null)
+            return
+        }
+        val arrayData = url?.split("/")
+        val stringBuffer = StringBuffer()
+        arrayData?.forEach {
+            stringBuffer.append(it)
+        }
+        val path = "${UrlConstant.specialResourcePath}/${stringBuffer}"
+        val pathFile =
+            File(path)
+        if (pathFile.exists()){
+
+            response?.invoke(BitmapFactory.decodeFile(path).apply { density = 480 })
+            return
+        }
+        Glide.with(context)
+            .asBitmap()
+            .load(url)
+            .listener(object : RequestListener<Bitmap>{
+                override fun onLoadFailed(
+                    p0: GlideException?,
+                    p1: Any?,
+                    p2: Target<Bitmap>?,
+                    p3: Boolean
+                ): Boolean {
+                    response?.invoke(null)
+                    return false
+                }
+
+                override fun onResourceReady(
+                    bitmap: Bitmap?,
+                    p1: Any?,
+                    p2: Target<Bitmap>?,
+                    p3: DataSource?,
+                    p4: Boolean
+                ): Boolean {
+                    return false
+                }
+            } )
+            .into(object : CustomTarget<Bitmap>() {
+                override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
+                    resource.density = 480
+                    var outputStream: FileOutputStream? = null
+                    try {
+                        outputStream = FileOutputStream(pathFile)
+                        resource.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
+                        outputStream.flush()
+                    } catch (e: IOException) {
+                        e.printStackTrace()
+                    } finally {
+                        outputStream?.close()
+                    }
+                    response?.invoke(resource.apply { density = 480 })
+                }
+
+                override fun onLoadCleared(placeholder: Drawable?) {
+
+                }
+            })
+    }
+}

+ 50 - 0
baseswago/src/main/java/com/swago/baseswago/util/DianJiuUtil.kt

@@ -0,0 +1,50 @@
+package com.swago.baseswago.util
+
+import android.app.Activity
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.graphics.NinePatch
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.NinePatchDrawable
+import android.text.TextUtils
+import com.bumptech.glide.Glide
+import com.bumptech.glide.request.target.CustomTarget
+import com.bumptech.glide.request.transition.Transition
+import java.io.File
+import java.io.FileInputStream
+
+object DianJiuUtil {
+    fun loadDian9Tu(context: Context, url: String, drawable: (e: NinePatchDrawable?) -> Unit){
+        if (context is Activity){
+            if (context.isDestroyed)
+                return
+        }
+        if (TextUtils.isEmpty(url)){
+            drawable.invoke(null)
+            return
+        }
+        Glide.with(context)
+            .asFile()
+            .load(url)
+            .into(object : CustomTarget<File>() {
+                override fun onResourceReady(resource: File, transition: Transition<in File>?) {
+                    val fileInputStream = FileInputStream(resource)
+                    ninePatchImageDrawable(context , BitmapFactory.decodeStream(fileInputStream) , drawable)
+                }
+
+                override fun onLoadCleared(placeholder: Drawable?) {
+
+                }
+            })
+    }
+
+    fun ninePatchImageDrawable(context: Context, bitmap: Bitmap, drawable: (e: NinePatchDrawable?) -> Unit) {
+        bitmap.density = 480
+        val chunk = bitmap.ninePatchChunk
+        if (NinePatch.isNinePatchChunk(chunk)){
+            drawable.invoke(NinePatchDrawable(context.resources,bitmap,chunk,NinePatchChunk.deserialize(chunk)?.mPaddings,null))
+        }
+        drawable.invoke(null)
+    }
+}

+ 29 - 0
baseswago/src/main/java/com/swago/baseswago/util/FileUtil.kt

@@ -1,6 +1,7 @@
 package com.swago.baseswago.util
 
 import android.app.Application
+import android.content.Context
 import java.io.*
 import java.lang.Exception
 import java.util.*
@@ -144,7 +145,35 @@ object FileUtil {
             File(baseDir, absFileName)
         }
     }
+    fun copyAssetFile(context: Context, assetFileName: String, destFile: File) {
+        if (!destFile.parentFile.exists()){
+            destFile.parentFile.mkdirs()
+        }
+        val assetManager = context.assets
+        var inputStream: InputStream? = null
+        var outputStream: FileOutputStream? = null
+
+        try {
+            inputStream = assetManager.open(assetFileName)
+            outputStream = FileOutputStream(destFile)
 
+            val buffer = ByteArray(1024)
+            var length: Int
+
+            while (inputStream.read(buffer).also { length = it } > 0) {
+                outputStream.write(buffer, 0, length)
+            }
+        } catch (e: IOException) {
+            e.printStackTrace()
+        } finally {
+            try {
+                inputStream?.close()
+                outputStream?.close()
+            } catch (e: IOException) {
+                e.printStackTrace()
+            }
+        }
+    }
     fun clearCache(context : Application){
         deleteFile(File(AppContext.getContext().cacheDir.absolutePath))
         deleteFile(File(AppContext.getContext().filesDir.absolutePath))

+ 61 - 0
baseswago/src/main/java/com/swago/baseswago/util/NinePatchChunk.kt

@@ -0,0 +1,61 @@
+package com.swago.baseswago.util
+
+import android.graphics.Rect
+import java.nio.ByteBuffer
+import java.nio.ByteOrder
+
+class NinePatchChunk {
+    companion object {
+        const val NO_COLOR = 0x00000001
+        const val TRANSPARENT_COLOR = 0x00000000
+
+        private fun readIntArray(data: IntArray, buffer: ByteBuffer) {
+            for (i in data.indices) {
+                data[i] = buffer.int
+            }
+        }
+
+        private fun checkDivCount(length: Int) {
+            if (length == 0 || length and 0x01 != 0) {
+                throw RuntimeException("invalid nine-patch: $length")
+            }
+        }
+
+        fun deserialize(data: ByteArray): NinePatchChunk? {
+            val byteBuffer = ByteBuffer.wrap(data).order(ByteOrder.nativeOrder())
+
+            if (byteBuffer.get() == 0.toByte()) return null // is not serialized
+
+            val chunk = NinePatchChunk()
+            chunk.mDivX = IntArray(byteBuffer.get().toInt())
+            chunk.mDivY = IntArray(byteBuffer.get().toInt())
+            chunk.mColor = IntArray(byteBuffer.get().toInt())
+
+            checkDivCount(chunk.mDivX.size)
+            checkDivCount(chunk.mDivY.size)
+
+            // skip 8 bytes
+            byteBuffer.int
+            byteBuffer.int
+
+            chunk.mPaddings.left = byteBuffer.int
+            chunk.mPaddings.right = byteBuffer.int
+            chunk.mPaddings.top = byteBuffer.int
+            chunk.mPaddings.bottom = byteBuffer.int
+
+            // skip 4 bytes
+            byteBuffer.int
+
+            readIntArray(chunk.mDivX, byteBuffer)
+            readIntArray(chunk.mDivY, byteBuffer)
+            readIntArray(chunk.mColor, byteBuffer)
+
+            return chunk
+        }
+    }
+
+    val mPaddings = Rect()
+    lateinit var mDivX: IntArray
+    lateinit var mDivY: IntArray
+    lateinit var mColor: IntArray
+}

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

@@ -0,0 +1,24 @@
+package com.swago.baseswago.util
+
+import org.json.JSONObject
+import java.util.regex.Pattern
+
+object StringUtils {
+    fun extractJsonObjects(text: String): List<JSONObject> {
+        val jsonObjects = mutableListOf<JSONObject>()
+        val pattern = Pattern.compile("\\{.*?\\}")
+        val matcher = pattern.matcher(text)
+
+        while (matcher.find()) {
+            val jsonString = matcher.group()
+            try {
+                val jsonObject = JSONObject(jsonString)
+                jsonObjects.add(jsonObject)
+            } catch (e: Exception) {
+                e.printStackTrace()
+            }
+        }
+
+        return jsonObjects
+    }
+}

+ 57 - 0
baseswago/src/main/java/com/swago/glide.kt

@@ -1,6 +1,12 @@
 package com.swago
 
+import android.app.Activity
 import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.graphics.NinePatch
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.NinePatchDrawable
 import android.os.Build
 import android.text.BidiFormatter
 import android.text.TextDirectionHeuristics
@@ -8,9 +14,16 @@ import android.widget.ImageView
 import androidx.annotation.DrawableRes
 import androidx.annotation.RequiresApi
 import com.bumptech.glide.Glide
+import com.bumptech.glide.load.engine.DiskCacheStrategy
 import com.bumptech.glide.request.RequestOptions
+import com.bumptech.glide.request.target.CustomTarget
+import com.bumptech.glide.request.transition.Transition
 import com.swago.baseswago.R
 import jp.wasabeef.glide.transformations.BlurTransformation
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileNotFoundException
+import java.io.IOException
 import java.util.*
 
 /**
@@ -35,6 +48,15 @@ fun ImageView.loadUrl(context: Context,url:String){
         .into(this)
 }
 
+fun ImageView.loadUrlCache(context: Context,url:String){
+    Glide.with(context)
+        .load(url)
+        .centerCrop()
+        .diskCacheStrategy(DiskCacheStrategy.ALL)
+        .placeholder(R.mipmap.default_avatar)
+        .error(R.mipmap.default_avatar)
+        .into(this)
+}
 fun ImageView.loadUrlNoPlaceHolder(context: Context,url:String){
     Glide.with(context)
         .load(url)
@@ -72,4 +94,39 @@ fun CharSequence.formatAr(): CharSequence {
         this,
         TextDirectionHeuristics.LOCALE
     )
+}
+
+fun loadDian9Tu(context: Context, imageView: ImageView, url: String){
+    if (context is Activity){
+        if (context.isDestroyed)
+            return
+    }
+    Glide.with(context)
+        .asFile()
+        .load(url)
+        .into(object : CustomTarget<File>() {
+            override fun onResourceReady(resource: File, transition: Transition<in File>?) {
+                try {
+                    FileInputStream(resource).use { inputStream ->
+                        val bitmap = BitmapFactory.decodeStream(inputStream)
+                        imageView.setNinePatchImage(context , bitmap)
+                    }
+                } catch (e: FileNotFoundException) {
+                    e.printStackTrace()
+                } catch (e: IOException) {
+                    e.printStackTrace()
+                }
+            }
+
+            override fun onLoadCleared(placeholder: Drawable?) {
+
+            }
+        })
+}
+
+fun ImageView.setNinePatchImage(context: Context, bitmap: Bitmap) {
+    val chunk = bitmap.ninePatchChunk
+    val ninePatch = NinePatch(bitmap, chunk, null)
+    val ninePatchDrawable = NinePatchDrawable(context.resources, ninePatch)
+    this.setImageDrawable(ninePatchDrawable)
 }

+ 42 - 14
baseswago/src/main/res/layout/dialog_person_data.xml

@@ -176,11 +176,22 @@
                 app:layout_constraintBottom_toBottomOf="@+id/tvLevelView"
                 app:layout_constraintTop_toTopOf="@+id/tvLevelView"
                 app:layout_constraintStart_toEndOf="@+id/tvAgent"
-               app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintEnd_toStartOf="@+id/ivBadge"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"/>
 
-
+            <ImageView
+                android:id="@+id/ivBadge"
+                android:textColor="#fff"
+                android:layout_marginStart="5dp"
+                android:visibility="gone"
+                tools:visibility="visible"
+                app:layout_constraintBottom_toBottomOf="@+id/tvLevelView"
+                app:layout_constraintTop_toTopOf="@+id/tvLevelView"
+                app:layout_constraintStart_toEndOf="@+id/tvOfficial"
+                app:layout_constraintEnd_toEndOf="parent"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"/>
             <LinearLayout
                 android:id="@+id/llFollow"
                 android:layout_width="wrap_content"
@@ -329,15 +340,35 @@
 
         </androidx.constraintlayout.widget.ConstraintLayout>
 
-
-        <de.hdodenhof.circleimageview.CircleImageView
-            android:id="@+id/ivAvatar"
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/clAvatar"
             android:layout_width="80dp"
             android:layout_height="80dp"
-            android:src="@mipmap/default_avatar"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="parent" />
+            app:layout_constraintTop_toTopOf="parent" >
+            <de.hdodenhof.circleimageview.CircleImageView
+                android:id="@+id/ivAvatar"
+                android:layout_width="60dp"
+                android:layout_height="60dp"
+                android:src="@mipmap/default_avatar"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"/>
+
+            <com.opensource.svgaplayer.SVGAImageView
+                android:id="@+id/svgAvatar"
+                android:layout_width="80dp"
+                android:layout_height="80dp"
+                android:visibility="visible"
+                app:autoPlay="true"
+                app:loopCount="0"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"/>
+        </androidx.constraintlayout.widget.ConstraintLayout>
 
         <ImageView
             android:id="@+id/ivSex"
@@ -346,8 +377,8 @@
             android:layout_marginStart="10dp"
             android:layout_marginTop="5dp"
             tools:src="@mipmap/info_female"
-            app:layout_constraintBottom_toBottomOf="@+id/ivAvatar"
-            app:layout_constraintEnd_toEndOf="@+id/ivAvatar" />
+            app:layout_constraintBottom_toBottomOf="@+id/clAvatar"
+            app:layout_constraintEnd_toEndOf="@+id/clAvatar" />
 
 
         <ImageView
@@ -356,13 +387,10 @@
             android:layout_height="wrap_content"
             android:src="@mipmap/onlive"
             android:visibility="gone"
-            app:layout_constraintBottom_toBottomOf="@+id/ivAvatar"
-            app:layout_constraintStart_toStartOf="@+id/ivAvatar"
+            app:layout_constraintBottom_toBottomOf="@+id/clAvatar"
+            app:layout_constraintStart_toStartOf="@+id/clAvatar"
             tools:visibility="visible" />
 
-
-
-
     </androidx.constraintlayout.widget.ConstraintLayout>
 
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 13 - 1
baseswago/src/main/res/values-ar/strings.xml

@@ -336,8 +336,20 @@
     <string name="select_all">اختر الكل</string>
     <string name="add_to_my_music">أضف إلى موسيقاي</string>
     <string name="sure_delete_this_music">هل أنت متأكد أنك تريد حذف هذه الموسيقى؟</string>
-    <string name="dress_up">إرتد ملابس</string>
+    <string name="dress_up">زخارف بلدي</string>
     <string name="mall">مجمع تجاري</string>
     <string name="buy_it_now">اشتر الآن</string>
     <string name="beauty_filter">الجمال والمرشحات</string>
+    <string name="entrance_effects">تأثيرات المدخل</string>
+    <string name="avatar_frame">إطار الصورة الرمزية</string>
+    <string name="badge">شارة</string>
+    <string name="chat_bubble">فقاعة الدردشة</string>
+    <string name="more">أكثر</string>
+    <string name="take_back">استرجع</string>
+    <string name="this_product_has_been_purchased">لقد تم شراء هذا المنتج</string>
+    <string name="purchase_successful">تم الشراء بنجاح</string>
+    <string name="no_time_limit">لا يوجد حد زمني</string>
+    <string name="already_owned">مملوكة</string>
+    <string name="using">استخدام</string>
+    <string name="local_music">Local Music</string>
 </resources>

+ 12 - 0
baseswago/src/main/res/values-in/strings.xml

@@ -352,4 +352,16 @@
     <string name="mall">Toko</string>
     <string name="buy_it_now">Beli sekarang</string>
     <string name="beauty_filter">kecantikan&amp;filter</string>
+    <string name="entrance_effects">Efek masuk</string>
+    <string name="avatar_frame">Bingkai avatar</string>
+    <string name="badge">Badge</string>
+    <string name="chat_bubble">chat bubble</string>
+    <string name="more">lebih banyak</string>
+    <string name="take_back">ambil kembali</string>
+    <string name="this_product_has_been_purchased">Produk ini telah dibeli</string>
+    <string name="purchase_successful">Pembelian berhasil</string>
+    <string name="no_time_limit">Tidak ada batas waktu</string>
+    <string name="already_owned">dimiliki</string>
+    <string name="using">digunakan</string>
+    <string name="local_music">Local Music</string>
 </resources>

+ 12 - 0
baseswago/src/main/res/values-ms/strings.xml

@@ -352,4 +352,16 @@
     <string name="mall">Toko</string>
     <string name="buy_it_now">Beli sekarang</string>
     <string name="beauty_filter">kecantikan&amp;filter</string>
+    <string name="entrance_effects">Efek masuk</string>
+    <string name="avatar_frame">Bingkai avatar</string>
+    <string name="badge">Badge</string>
+    <string name="chat_bubble">chat bubble</string>
+    <string name="more">lebih banyak</string>
+    <string name="take_back">ambil kembali</string>
+    <string name="this_product_has_been_purchased">Produk ini telah dibeli</string>
+    <string name="purchase_successful">Pembelian berhasil</string>
+    <string name="no_time_limit">Tidak ada batas waktu</string>
+    <string name="already_owned">dimiliki</string>
+    <string name="using">digunakan</string>
+    <string name="local_music">Local Music</string>
 </resources>

+ 13 - 1
baseswago/src/main/res/values-zh/strings.xml

@@ -336,8 +336,20 @@
     <string name="select_all">全选</string>
     <string name="add_to_my_music">添加到我的音乐</string>
     <string name="sure_delete_this_music">您确定要删除这段音乐吗?</string>
-    <string name="dress_up">装扮</string>
+    <string name="dress_up">我的装扮</string>
     <string name="mall">商城</string>
     <string name="buy_it_now">立即购买</string>
     <string name="beauty_filter">美颜&amp;滤镜</string>
+    <string name="entrance_effects">入场特效</string>
+    <string name="avatar_frame">头像框</string>
+    <string name="badge">徽章</string>
+    <string name="chat_bubble">聊天气泡</string>
+    <string name="more">更多</string>
+    <string name="take_back">收回</string>
+    <string name="this_product_has_been_purchased">该商品已经购买</string>
+    <string name="purchase_successful">购买成功</string>
+    <string name="no_time_limit">不限时间</string>
+    <string name="already_owned">已拥有</string>
+    <string name="using">使用中</string>
+    <string name="local_music">本地音乐</string>
 </resources>

+ 13 - 1
baseswago/src/main/res/values/strings.xml

@@ -368,8 +368,20 @@
     <string name="select_all">Select all</string>
     <string name="add_to_my_music">Add to my music</string>
     <string name="sure_delete_this_music">Are you sure you want to delete this music?</string>
-    <string name="dress_up">Dress up</string>
+    <string name="dress_up">my decorations</string>
     <string name="mall">Mall</string>
     <string name="buy_it_now">Buy it now</string>
     <string name="beauty_filter">beauty&amp;filter</string>
+    <string name="entrance_effects">Entrance effects</string>
+    <string name="avatar_frame">Avatar frame</string>
+    <string name="badge">Badge</string>
+    <string name="chat_bubble">Chat Bubble</string>
+    <string name="more">more</string>
+    <string name="take_back">take back</string>
+    <string name="this_product_has_been_purchased">This product has been purchased</string>
+    <string name="purchase_successful">Purchase successful</string>
+    <string name="no_time_limit">No time limit</string>
+    <string name="already_owned">owned</string>
+    <string name="using">using</string>
+    <string name="local_music">Local Music</string>
 </resources>

+ 59 - 5
home/src/main/java/com/swago/home/ChatDetailActivity.kt

@@ -1,20 +1,24 @@
 package com.swago.home
 
 import android.os.Bundle
+import android.text.TextUtils
 import android.view.View
 import androidx.activity.viewModels
 import androidx.core.content.ContextCompat
-import androidx.fragment.app.viewModels
 import com.alibaba.android.arouter.facade.annotation.Autowired
 import com.alibaba.android.arouter.facade.annotation.Route
 import com.alibaba.android.arouter.launcher.ARouter
 import com.google.gson.Gson
 import com.gyf.immersionbar.ImmersionBar
+import com.opensource.svgaplayer.SVGADrawable
+import com.opensource.svgaplayer.SVGAParser
+import com.opensource.svgaplayer.SVGAVideoEntity
 import com.swago.baseswago.PersonDataDFragment
 import com.swago.baseswago.UserVm
-import com.swago.baseswago.dialog.ReportBlockDialogFragment
 import com.swago.baseswago.activity.BaseXActivity
 import com.swago.baseswago.constant.ARouteConstant
+import com.swago.baseswago.dialog.ReportBlockDialogFragment
+import com.swago.baseswago.util.DianJiuUtil
 import com.swago.baseswago.util.NoDoubleClickListener
 import com.swago.baseswago.util.SpUtil
 import com.swago.baseswago.util.UserInfo
@@ -24,6 +28,8 @@ import com.tencent.qcloud.tim.uikit.modules.chat.base.ChatInfo
 import com.tencent.qcloud.tim.uikit.modules.chat.layout.message.MessageLayout
 import com.tencent.qcloud.tim.uikit.modules.message.MessageInfo
 import com.tencent.qcloud.tim.uikit.utils.ToastUtil
+import java.net.URL
+
 
 /**
  *@date 2021/8/24 15:01
@@ -41,6 +47,13 @@ class ChatDetailActivity  : BaseXActivity<ActivityChatDetailBinding>() {
     @JvmField
     var chatName: String = ""
 
+    @Autowired(required = true)
+    @JvmField
+    var headSpecial: String = ""
+
+    private var svgaParser:SVGAParser? = null
+
+    private var messageRecyclerView:MessageLayout?=null
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -52,12 +65,12 @@ class ChatDetailActivity  : BaseXActivity<ActivityChatDetailBinding>() {
     }
 
     override fun loadData() {
-
     }
 
     override fun initOther() {
         ARouter.getInstance().inject(this)
 
+        svgaParser = SVGAParser(this)
         val chatInfo = ChatInfo()
         chatInfo.type = V2TIMConversation.V2TIM_C2C
         chatInfo.chatName = chatName
@@ -81,8 +94,8 @@ class ChatDetailActivity  : BaseXActivity<ActivityChatDetailBinding>() {
             SpUtil.putString("user_info", Gson().toJson(it))
         }
 
-        val messageRecyclerView = binding.chatLayout.messageLayout
-        messageRecyclerView.setOnItemClickListener(object : MessageLayout.OnItemLongClickListener{
+        messageRecyclerView = binding.chatLayout.messageLayout
+        messageRecyclerView?.setOnItemClickListener(object : MessageLayout.OnItemLongClickListener{
             override fun onMessageLongClick(view: View?, position: Int, messageInfo: MessageInfo?) {
 
             }
@@ -110,6 +123,41 @@ class ChatDetailActivity  : BaseXActivity<ActivityChatDetailBinding>() {
                 }
             }
         })
+
+        if (UserInfo.getUserInfo() != null && !TextUtils.isEmpty(UserInfo.getUserInfo()?.android_chat_special)){
+            UserInfo.getUserInfo()?.android_chat_special?.let {chatUrl ->
+                DianJiuUtil.loadDian9Tu(this ,chatUrl ){ drawable ->
+                    drawable?.let {
+                        messageRecyclerView?.rightBubble = it
+                    }
+                }
+            }
+        }
+        if (!TextUtils.isEmpty(headSpecial)){
+            svgaParser?.decodeFromURL(URL(headSpecial), object :SVGAParser.ParseCompletion{
+                override fun onComplete(videoItem: SVGAVideoEntity) {
+                    messageRecyclerView?.leftSvgaAvatar = videoItem
+                }
+
+                override fun onError() {
+
+                }
+            })
+
+        }
+
+        if (UserInfo.getUserInfo() != null && !TextUtils.isEmpty(UserInfo.getUserInfo()?.android_head_special)){
+            UserInfo.getUserInfo()?.android_head_special?.let {
+                svgaParser?.decodeFromURL(URL(it), object :SVGAParser.ParseCompletion{
+                    override fun onComplete(videoItem: SVGAVideoEntity) {
+                        messageRecyclerView?.rightSvgaAvatar = videoItem
+                    }
+
+                    override fun onError() {
+                    }
+                })
+            }
+        }
     }
 
     override fun initLiveData() {
@@ -121,5 +169,11 @@ class ChatDetailActivity  : BaseXActivity<ActivityChatDetailBinding>() {
         userVm.getUserInfo()
     }
 
+    override fun onDestroy() {
+        super.onDestroy()
+        messageRecyclerView?.leftSvgaAvatar = null
+        messageRecyclerView?.rightSvgaAvatar = null
+        messageRecyclerView = null
+    }
 
 }

+ 27 - 5
home/src/main/java/com/swago/home/MessageFragment.kt

@@ -5,26 +5,33 @@ import android.content.Intent
 import android.view.View
 import android.widget.Toast
 import androidx.fragment.app.activityViewModels
+import androidx.fragment.app.viewModels
 import com.alibaba.android.arouter.launcher.ARouter
 import com.permissionx.guolindev.PermissionX
+import com.swago.baseswago.UserVm
 import com.swago.baseswago.constant.ARouteConstant
 import com.swago.baseswago.dialog.ChoiceDialogFragment
 import com.swago.baseswago.fragment.BaseXFragment
 import com.swago.baseswago.util.AppContext
+import com.swago.baseswago.util.DianJiuUtil
+import com.swago.baseswago.util.LogUtil
 import com.swago.baseswago.util.NoDoubleClickListener
 import com.swago.home.databinding.FragmentMessageBinding
 import com.swago.home.official.OfficialMessageActivity
 import com.swago.home.official.OfficialVm
 import com.tencent.imsdk.v2.V2TIMConversation
 import com.tencent.qcloud.tim.uikit.modules.conversation.ConversationManagerKit
+import com.tencent.qcloud.tim.uikit.modules.conversation.base.ConversationInfo
 
 /**
  *@date 2021/8/21 12:43
  *description:
  */
 class MessageFragment : BaseXFragment<FragmentMessageBinding>() {
-
+    private val userVm by viewModels<UserVm>()
     private val officialVm by activityViewModels<OfficialVm>()
+    private var conversationInfo: ConversationInfo ?= null
+    private var jumpDetail = true
 
     override fun loadData() {
         officialVm.getMsgSum()
@@ -37,10 +44,8 @@ class MessageFragment : BaseXFragment<FragmentMessageBinding>() {
                 .permissions(Manifest.permission.RECORD_AUDIO,Manifest.permission.CAMERA)
                 .request { allGranted, grantedList, deniedList ->
                     if (allGranted) {
-                        ARouter.getInstance().build(ARouteConstant.Home.chatDetail)
-                            .withInt("type", V2TIMConversation.V2TIM_C2C)
-                            .withString("account", messageInfo.id)
-                            .withString("chatName", messageInfo.title).navigation()
+                        conversationInfo = messageInfo
+                        userVm.getOtherUserInfo(messageInfo.id,"")
                     } else {
                         Toast.makeText(
                             AppContext.getContext(),
@@ -86,5 +91,22 @@ class MessageFragment : BaseXFragment<FragmentMessageBinding>() {
                 binding.tvCount.visibility = View.VISIBLE
             }
         }
+        userVm.otherUserInfoLiveData.observe(this){
+            if (jumpDetail){
+                ARouter.getInstance().build(ARouteConstant.Home.chatDetail)
+                    .withInt("type", V2TIMConversation.V2TIM_C2C)
+                    .withString("account", conversationInfo?.id)
+                    .withString("chatName", conversationInfo?.title)
+                    .withString("headSpecial" , it.android_head_special)
+                    .navigation()
+            }
+            jumpDetail = false
+
+        }
+    }
+
+    override fun onResume() {
+        super.onResume()
+        jumpDetail = true
     }
 }

+ 21 - 2
home/src/main/java/com/swago/home/MineFragment.kt

@@ -6,6 +6,9 @@ import androidx.fragment.app.viewModels
 import com.alibaba.android.arouter.launcher.ARouter
 import com.bumptech.glide.Glide
 import com.google.gson.Gson
+import com.opensource.svgaplayer.SVGADrawable
+import com.opensource.svgaplayer.SVGAParser
+import com.opensource.svgaplayer.SVGAVideoEntity
 import com.swago.baseswago.PayVm
 import com.swago.baseswago.R
 import com.swago.baseswago.UserVm
@@ -15,6 +18,7 @@ import com.swago.baseswago.dialog.BenefitBagDialog
 import com.swago.baseswago.fragment.BaseXFragment
 import com.swago.baseswago.util.*
 import com.swago.home.databinding.FragmentMineBinding
+import java.net.URL
 
 /**
  *@date 2021/11/20 10:32
@@ -24,10 +28,12 @@ class MineFragment : BaseXFragment<FragmentMineBinding>() {
 
     private val userVm by activityViewModels<UserVm>()
     private val payVm by viewModels<PayVm>()
-
-    override fun loadData() {}
+    private var svgaParser:SVGAParser? = null
+    override fun loadData() {
+    }
 
     override fun initOther() {
+        svgaParser = SVGAParser(activity)
         if (SwagoInfo.isGooglePackage()){
             binding.tvXWithdrawal.visibility = View.GONE
         }else{
@@ -230,6 +236,19 @@ class MineFragment : BaseXFragment<FragmentMineBinding>() {
             }else{
                 binding.tvModifyPassword.visibility = View.GONE
             }
+
+            if (!it.android_head_special.isNullOrEmpty()){
+                svgaParser?.decodeFromURL(URL(it.android_head_special), object :SVGAParser.ParseCompletion{
+                    override fun onComplete(videoItem: SVGAVideoEntity) {
+                        val drawable = SVGADrawable(videoItem)
+                        binding.svgAvatar.setImageDrawable(drawable)
+                        binding.svgAvatar.startAnimation()
+                    }
+
+                    override fun onError() {
+                    }
+                })
+            }
         }
 
         payVm.benefitLiveData.observe(this){

+ 7 - 2
home/src/main/java/com/swago/home/innerhome/FollowFragment.kt

@@ -14,6 +14,7 @@ import com.swago.baseswago.fragment.BaseListFragment
 import com.swago.baseswago.fragment.BaseXFragment
 import com.swago.baseswago.model.MomentModel
 import com.swago.baseswago.model.home.HomeModel
+import com.swago.baseswago.util.SpUtil
 import com.swago.home.databinding.FragmentFollowBinding
 import com.swago.home.databinding.FragmentHotBinding
 
@@ -39,6 +40,7 @@ class FollowFragment : BaseListFragment<FragmentHotBinding, MomentModel>(){
     }
 
     override fun initViewData() {
+        SpUtil.putString("followCloseRoomed" , "0")
         binding.rvLabel.visibility = View.GONE
         smartRecyclerView.recyclerView?.addItemDecoration(ComGridItemDecoration())
         adapter.setOnItemClickListener { _, _, position ->
@@ -75,8 +77,11 @@ class FollowFragment : BaseListFragment<FragmentHotBinding, MomentModel>(){
 
     override fun onResume() {
         super.onResume()
-        if (!isFirstLoadData){
-            smartRecyclerView.startRefresh()
+        val followCloseRoomed = SpUtil.readString("followCloseRoomed")
+        if (followCloseRoomed != "0"){
+            adapter.data.removeAll { it.id == followCloseRoomed }
+            adapter.notifyDataSetChanged()
+            SpUtil.putString("followCloseRoomed" , "0")
         }
         isFirstLoadData = false
     }

+ 7 - 2
home/src/main/java/com/swago/home/innerhome/HotFragment.kt

@@ -13,6 +13,7 @@ import com.swago.baseswago.cusview.SwagoRecyclerView
 import com.swago.baseswago.fragment.BaseListFragment
 import com.swago.baseswago.model.MomentModel
 import com.swago.baseswago.model.home.BannerModel
+import com.swago.baseswago.util.SpUtil
 import com.swago.baseswago.util.SwagoInfo
 import com.swago.home.databinding.FragmentHotBinding
 import com.swago.home.databinding.LayoutViewHeaderBinding
@@ -60,6 +61,7 @@ class HotFragment : BaseListFragment<FragmentHotBinding, MomentModel>() {
 
 
     override fun initViewData() {
+        SpUtil.putString("hotCloseRoomed" , "0")
         UrlConstant.getConfigModel()?.let {
             if (!it.language_lables.isNullOrEmpty()){
                 matchLanguageId = when(SwagoInfo.languageId){
@@ -159,8 +161,11 @@ class HotFragment : BaseListFragment<FragmentHotBinding, MomentModel>() {
 
     override fun onResume() {
         super.onResume()
-        if (!isFirstLoadData){
-            smartRecyclerView.startRefresh()
+        val hotCloseRoomed = SpUtil.readString("hotCloseRoomed")
+        if (hotCloseRoomed != "0"){
+            adapter.data.removeAll { it.id == hotCloseRoomed }
+            adapter.notifyDataSetChanged()
+            SpUtil.putString("hotCloseRoomed" , "0")
         }
         isFirstLoadData = false
     }

+ 7 - 2
home/src/main/java/com/swago/home/innerhome/NewFragment.kt

@@ -13,6 +13,7 @@ import com.swago.baseswago.fragment.BaseListFragment
 import com.swago.baseswago.fragment.BaseXFragment
 import com.swago.baseswago.model.MomentModel
 import com.swago.baseswago.model.home.HomeModel
+import com.swago.baseswago.util.SpUtil
 import com.swago.baseswago.util.SwagoInfo
 import com.swago.home.databinding.FragmentHotBinding
 import com.swago.home.databinding.FragmentNewBinding
@@ -48,6 +49,7 @@ class NewFragment  : BaseListFragment<FragmentHotBinding, MomentModel>(){
     }
 
     override fun initViewData() {
+        SpUtil.putString("newCloseRoomed" , "0")
         UrlConstant.getConfigModel()?.let {
             if (!it.language_lables.isNullOrEmpty()){
                 matchLanguageId = when(SwagoInfo.languageId){
@@ -117,8 +119,11 @@ class NewFragment  : BaseListFragment<FragmentHotBinding, MomentModel>(){
 
     override fun onResume() {
         super.onResume()
-        if (!isFirstLoadData){
-            smartRecyclerView.startRefresh()
+        val newCloseRoomed = SpUtil.readString("newCloseRoomed")
+        if (newCloseRoomed != "0"){
+            adapter.data.removeAll { it.id == newCloseRoomed }
+            adapter.notifyDataSetChanged()
+            SpUtil.putString("newCloseRoomed" , "0")
         }
         isFirstLoadData = false
     }

+ 14 - 2
home/src/main/res/layout/fragment_mine.xml

@@ -48,6 +48,18 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
 
+    <com.opensource.svgaplayer.SVGAImageView
+        android:id="@+id/svgAvatar"
+        android:layout_width="60dp"
+        android:layout_height="60dp"
+        android:visibility="visible"
+        app:autoPlay="true"
+        app:loopCount="0"
+        android:layout_marginStart="10dp"
+        android:layout_marginTop="60dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
     <com.swago.baseswago.cusview.BoldTextView
         android:id="@+id/tvName"
         android:layout_width="wrap_content"
@@ -342,7 +354,7 @@
             android:id="@+id/tvXStore"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:drawableTop="@mipmap/icon_my_store"
+            android:drawableTop="@mipmap/icon_my_outfit"
             android:drawablePadding="2dp"
             android:text="@string/mall"
             android:textColor="#131B23"
@@ -357,7 +369,7 @@
             android:id="@+id/tvXoutfit"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:drawableTop="@mipmap/icon_my_outfit"
+            android:drawableTop="@mipmap/icon_my_store"
             android:drawablePadding="2dp"
             android:text="@string/dress_up"
             android:textColor="#131B23"

binární
home/src/main/res/mipmap-xxhdpi/icon_my_store.png


+ 25 - 0
room/src/main/java/com/swago/room/adapter/AudienceAdapter.kt

@@ -3,20 +3,29 @@ package com.swago.room.adapter
 import android.view.View
 import com.chad.library.adapter.base.BaseQuickAdapter
 import com.chad.library.adapter.base.BaseViewHolder
+import com.opensource.svgaplayer.SVGADrawable
+import com.opensource.svgaplayer.SVGAImageView
+import com.opensource.svgaplayer.SVGAParser
+import com.opensource.svgaplayer.SVGAVideoEntity
 import com.swago.baseswago.cusview.SwagoLevelView
 import com.swago.baseswago.model.live.RoomUserModel
 import com.swago.loadUrl
 import com.swago.room.R
 import de.hdodenhof.circleimageview.CircleImageView
+import java.net.URL
 
 /**
  *@date 2022/3/29 20:33
  *description:
  */
 class AudienceAdapter : BaseQuickAdapter<RoomUserModel.ListBean, BaseViewHolder>(R.layout.item_dialog_audience, arrayListOf()) {
+    private val svgaParser by lazy {
+        SVGAParser(mContext)
+    }
     override fun convert(helper: BaseViewHolder, item: RoomUserModel.ListBean) {
         helper.apply {
             itemView.findViewById<CircleImageView>(R.id.ivAvatar).loadUrl(mContext,item.user_head_img_url)
+            val svgAvatar = itemView.findViewById<SVGAImageView>(R.id.svgAvatar)
             setText(R.id.tvContribution,item.contribute_val)
             setText(R.id.tvName,item.user_name)
             setGone(R.id.ivBenefit,item.is_benefit == 1)
@@ -25,6 +34,22 @@ class AudienceAdapter : BaseQuickAdapter<RoomUserModel.ListBean, BaseViewHolder>
             setGone(R.id.ivCrown,item.is_crown == 1)
             setGone(R.id.ivCup,item.is_cup == 1)
             itemView.findViewById<SwagoLevelView>(R.id.tvLevel).setUserLevel(item.user_wealth_level)
+
+            if (!item.head_special.isNullOrEmpty()){
+                svgAvatar.visibility = View.VISIBLE
+                svgaParser.decodeFromURL(URL(item.head_special), object :SVGAParser.ParseCompletion{
+                    override fun onComplete(videoItem: SVGAVideoEntity) {
+                        val drawable = SVGADrawable(videoItem)
+                        svgAvatar.setImageDrawable(drawable)
+                        svgAvatar.startAnimation()
+                    }
+
+                    override fun onError() {
+                    }
+                })
+            } else {
+                svgAvatar.visibility = View.INVISIBLE
+            }
         }
     }
 }

+ 78 - 6
room/src/main/java/com/swago/room/adapter/RoomChatAdapter.kt

@@ -2,6 +2,7 @@ package com.swago.room.adapter
 
 import android.graphics.Bitmap
 import android.graphics.Color
+import android.graphics.drawable.NinePatchDrawable
 import android.os.Build
 import android.text.*
 import android.text.method.LinkMovementMethod
@@ -11,12 +12,12 @@ import android.text.style.ImageSpan
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import android.widget.ImageView
 import android.widget.TextView
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.content.ContextCompat
 import com.chad.library.adapter.base.BaseQuickAdapter
 import com.chad.library.adapter.base.BaseViewHolder
-import com.swago.baseswago.baseroom.SwagoRoomManager
 import com.swago.baseswago.cusview.LiangView
 import com.swago.baseswago.cusview.SwagoLevelView
 import com.swago.baseswago.im.IRoomChat
@@ -25,6 +26,9 @@ import com.swago.baseswago.model.im.FollowSuccessMsgBean
 import com.swago.baseswago.model.im.IMLevelUpMsgBean
 import com.swago.baseswago.model.im.RoomChatMsgBean
 import com.swago.baseswago.model.im.UserJoinRoomBean
+import com.swago.baseswago.util.AppContext
+import com.swago.baseswago.util.BitmapUtils
+import com.swago.baseswago.util.DianJiuUtil
 import com.swago.formatAr
 import com.swago.room.R
 import com.swago.room.adapter.bitmap.CenterAlignImageSpan
@@ -48,6 +52,7 @@ class RoomChatAdapter :
 
     companion object {
         const val LEVEL_KEY = "level"
+        const val BADGE_KEY = "badge"
         const val PRETTY_KEY = "pretty"//靓号
         const val VIP_KEY = "vip"//每日首冲
         const val IS_OFFICIAL = "official"
@@ -60,6 +65,7 @@ class RoomChatAdapter :
 
     init {
         localImageKey.add(LEVEL_KEY)
+        localImageKey.add(BADGE_KEY)
         localImageKey.add(PRETTY_KEY)
         localImageKey.add(VIP_KEY)
         localImageKey.add(IS_OFFICIAL)
@@ -72,6 +78,9 @@ class RoomChatAdapter :
 
     var showUserInfoDialog: ((iChatMsg: IRoomChat) -> Unit)? = null
 
+    fun setChatAndBadge(chatDrawable: NinePatchDrawable , badgeBitmap: Bitmap){
+
+    }
 
     override fun convert(helper: BaseViewHolder, item: IRoomChat) {
         var count = 0
@@ -137,6 +146,12 @@ class RoomChatAdapter :
                             .append("'> ")
                     }
 
+                    if (item is RoomChatMsgBean && !item.badge_special.isNullOrEmpty()) {
+                        count++
+                        sb.append("<img src='" + "file:///xx/")
+                            .append(BADGE_KEY).append(".png")
+                            .append("'> ")
+                    }
                     count++
                     sb.append("<img src='" + "file:///xx/")
                         .append(LEVEL_KEY).append(".png")
@@ -149,7 +164,7 @@ class RoomChatAdapter :
                     val glideImageGetter = HtmlImageGetter(mContext, tvContent, 14, localImageKey)
                     val fromHtml = Html.fromHtml(sb.toString(), glideImageGetter, null)
                     span = SpannableString(fromHtml)
-                    setHtml(span, helper, item)
+                    setHtml(span, helper, item,tvContent)
 
 
                     if (span.length < item.getSenderName().length + count) {
@@ -190,6 +205,15 @@ class RoomChatAdapter :
                     }else{
                         setBackgroundRes(R.id.tvContent, R.drawable.shape_20000000_14)
                     }
+                    mContext?.let {
+                        if (item is RoomChatMsgBean&&!item.android_chat_special.isNullOrEmpty()){
+                            DianJiuUtil.loadDian9Tu(it ,item.android_chat_special ){ drawable ->
+                                drawable?.let { drawable ->
+                                    tvContent.background = drawable
+                                }
+                            }
+                        }
+                    }
                 }
 
                 RoomMsgType.SYSTEM_MESSAGE -> {
@@ -274,7 +298,7 @@ class RoomChatAdapter :
                     val glideImageGetter = HtmlImageGetter(mContext, tvContent, 14, localImageKey)
                     val fromHtml = Html.fromHtml(sb.toString(), glideImageGetter, null)
                     span = SpannableString(fromHtml)
-                    setHtml(span, helper, item)
+                    setHtml(span, helper, item,tvContent)
 
                     if (span.length < item.getSenderName().length + count) {
                         span.setSpan(
@@ -366,6 +390,13 @@ class RoomChatAdapter :
                             .append("'> ")
                     }
 
+                    if (item is UserJoinRoomBean && !item.androidBadgeSpecial.isNullOrEmpty()) {
+                        count++
+                        sb.append("<img src='" + "file:///xx/")
+                            .append(BADGE_KEY).append(".png")
+                            .append("'> ")
+                    }
+
                     count++
                     sb.append("<img src='" + "file:///xx/")
                         .append(LEVEL_KEY).append(".png")
@@ -378,7 +409,7 @@ class RoomChatAdapter :
                     val glideImageGetter = HtmlImageGetter(mContext, tvContent, 14, localImageKey)
                     val fromHtml = Html.fromHtml(sb.toString(), glideImageGetter, null)
                     span = SpannableString(fromHtml)
-                    setHtml(span, helper, item)
+                    setHtml(span, helper, item,tvContent)
 
                     if (span.length < item.getSenderName().length + count) {
                         span.setSpan(
@@ -432,8 +463,19 @@ class RoomChatAdapter :
                         }
                     }
 
+                    mContext?.let {
+                        if (item is UserJoinRoomBean&&!item.androidChatSpecial.isNullOrEmpty()){
+                            DianJiuUtil.loadDian9Tu(it ,item.androidChatSpecial ){ drawable ->
+                                drawable?.let { drawable ->
+                                    tvContent.background = drawable
+                                }
+                            }
+                        }
+                    }
+
                 }
             }
+
             tvContent.movementMethod = LinkMovementMethod.getInstance()
             tvContent.highlightColor = Color.TRANSPARENT
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -445,7 +487,7 @@ class RoomChatAdapter :
     }
 
 
-    private fun setHtml(span: SpannableString, helper: BaseViewHolder, item: IRoomChat) {
+    private fun setHtml(span: SpannableString, helper: BaseViewHolder, item: IRoomChat, tvContent:TextView) {
         try {
             val imageSpans = span.getSpans(0, span.length, ImageSpan::class.java)
             var i = 0
@@ -526,7 +568,32 @@ class RoomChatAdapter :
                         end,
                         Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                     )
-                }else {
+                }else if (imageSpan.source != null && imageSpan!!.source!!.contains(BADGE_KEY)) {
+                    if(item is UserJoinRoomBean && !TextUtils.isEmpty(item.androidBadgeSpecial)){
+                        BitmapUtils.loadFile(AppContext.getContext(),item.androidBadgeSpecial){
+                            it?.let {
+                                span.setSpan(
+                                    setBadge(it, helper.itemView as ViewGroup),
+                                    start,
+                                    end,
+                                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+                            }
+
+                        }
+                    } else if (item is RoomChatMsgBean && !TextUtils.isEmpty(item.badge_special)){
+                        BitmapUtils.loadFile(AppContext.getContext(),item.badge_special){
+                            it?.let {
+                                span.setSpan(
+                                    setBadge(it, helper.itemView as ViewGroup),
+                                    start,
+                                    end,
+                                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+                            }
+
+                        }
+                    }
+
+            }else {
                     span.setSpan(newImageSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
                 }
                 span.removeSpan(imageSpan)
@@ -723,6 +790,11 @@ class RoomChatAdapter :
         return CustomImageSpan(mContext, bm, CustomImageSpan.ALIGN_FONTCENTER)
     }
 
+    private fun setBadge(bitmap: Bitmap,viewGroup: ViewGroup): CustomImageSpan {
+        val imageView = ImageView(mContext)
+        viewGroup.addView(imageView)
+        return CustomImageSpan(mContext, bitmap, CustomImageSpan.ALIGN_FONTCENTER)
+    }
 
     private fun setLevel(iSenderLevel: Int, viewGroup: ViewGroup): CustomImageSpan {
         var level = iSenderLevel.toString()

+ 29 - 1
room/src/main/java/com/swago/room/adapter/RoomUserAdapter.kt

@@ -1,24 +1,52 @@
 package com.swago.room.adapter
 
+import android.text.TextUtils
+import android.view.View
 import com.bumptech.glide.Glide
 import com.chad.library.adapter.base.BaseQuickAdapter
 import com.chad.library.adapter.base.BaseViewHolder
+import com.opensource.svgaplayer.SVGADrawable
+import com.opensource.svgaplayer.SVGAImageView
+import com.opensource.svgaplayer.SVGAParser
+import com.opensource.svgaplayer.SVGAVideoEntity
 import com.swago.baseswago.model.live.RoomUserModel
+import com.swago.baseswago.util.UserInfo
 import com.swago.room.R
 import de.hdodenhof.circleimageview.CircleImageView
+import java.net.URL
 
 /**
  *@date 2021/10/23 09:56
  *description:
  */
 class RoomUserAdapter : BaseQuickAdapter<RoomUserModel.ListBean,BaseViewHolder>(R.layout.item_room_user, arrayListOf()) {
-
+    private val svgaParser by lazy {
+        SVGAParser(mContext)
+    }
     override fun convert(helper: BaseViewHolder, item: RoomUserModel.ListBean) {
         helper.apply {
             val ivAvatar = itemView.findViewById<CircleImageView>(R.id.ivAvatar)
+            val svgAvatar = itemView.findViewById<SVGAImageView>(R.id.svgAvatar)
             Glide.with(itemView.context).load(item.user_head_img_url)
                 .placeholder(R.mipmap.default_avatar)
                 .error(R.mipmap.default_avatar).into(ivAvatar)
+
+            if (!item.android_head_special.isNullOrEmpty()){
+                svgAvatar.visibility = View.VISIBLE
+                svgaParser.decodeFromURL(URL(item.android_head_special), object :SVGAParser.ParseCompletion{
+                    override fun onComplete(videoItem: SVGAVideoEntity) {
+                        val drawable = SVGADrawable(videoItem)
+                        svgAvatar.setImageDrawable(drawable)
+                        svgAvatar.startAnimation()
+                    }
+
+                    override fun onError() {
+                    }
+                })
+            } else{
+                svgAvatar.visibility = View.INVISIBLE
+            }
+
         }
     }
 }

+ 4 - 0
room/src/main/java/com/swago/room/anchor/AnchorRoomActivity.kt

@@ -521,6 +521,10 @@ class AnchorRoomActivity : AbsAnchorActivity<ActivityAnchorRoomBinding, IRoomInf
         LogUtil.d("onFacePositionChanged${faces?.size}")
     }
 
+    override fun onAudioMixingStateChanged(state: Int, reason: Int) {
+        anchorRoomFragment?.onAudioMixingStateChanged(state,reason)
+    }
+
     /**************************PK******************************/
     private val marginTopValue by lazy {
         ImmersionBar.getStatusBarHeight(this) + DpPxUtil.dip2px(78f)

+ 45 - 7
room/src/main/java/com/swago/room/anchor/AnchorRoomFragment.kt

@@ -17,12 +17,15 @@ import com.swago.room.R
 import com.swago.room.base.BaseComFragment
 import com.swago.room.databinding.FragmentBaseComBinding
 import com.swago.room.dialog.AudioNoticeDialog
+import com.swago.room.dialog.FooterMoreDialog
 import com.swago.room.game.GameListDialog
 import com.swago.room.gift.GiftDialog
 import com.swago.room.hongbao.RedEnvelopeDialog
 import com.swago.room.inter.IFooter
 import com.swago.room.inter.IHeader
 import com.swago.room.lianmai.AnchorLianMaiDialog
+import com.swago.room.music.MusicModel
+import com.swago.room.music.MyMusicDialog
 import com.swago.room.pk.PKAcceptDialog
 import com.swago.room.pk.PKInviteDialog
 import com.swago.room.pk.PKSearchLisDialog
@@ -38,6 +41,7 @@ class AnchorRoomFragment : BaseComFragment<FragmentBaseComBinding>() {
     private var footerView : AnchorFooterView? = null
     private var pkAcceptDialog:PKAcceptDialog? = null
     private var pkInviteDialog:PKInviteDialog? = null
+    private var chooseMusic:MusicModel? = null
 
     override fun initOther() {
         super.initOther()
@@ -93,17 +97,14 @@ class AnchorRoomFragment : BaseComFragment<FragmentBaseComBinding>() {
             openLianMaiListDialog()
         }
 
-        footerView?.clearJiFen = {
-            ChoiceDialogFragment.newInstance(AppContext.getContext().resources.getString(R.string.ji_fen_to_zero)).apply {
-                this.sureFun = {
-                    roomVm.clearJiFen()
-                }
-            }.show(childFragmentManager,"ChoiceDialogFragment")
-        }
         footerView?.openAudioNoticeDialogFun = {
             AudioNoticeDialog.newInstance().show(childFragmentManager,"AudioNoticeDialog")
         }
 
+        footerView?.openLocalMusicFun = {
+            openMusicDialog()
+        }
+
         footerView?.openGiftPanelFun = {
             //打开礼物列表
             SwagoRoomManager.iRoomInfo?.let {
@@ -162,6 +163,14 @@ class AnchorRoomFragment : BaseComFragment<FragmentBaseComBinding>() {
         }
     }
 
+    private fun openMusicDialog() {
+        MyMusicDialog.newInstance(chooseMusic).apply {
+            openChooseMusicFun = {
+                chooseMusic = it
+            }
+        }.show(childFragmentManager,"MyMusicDialog")
+    }
+
     private fun openLianMaiListDialog() {
         AnchorLianMaiDialog.newInstance().show(childFragmentManager,"AnchorLianMaiDialog")
     }
@@ -176,6 +185,27 @@ class AnchorRoomFragment : BaseComFragment<FragmentBaseComBinding>() {
     }
 
 
+    private fun openMoreDialog(){
+        FooterMoreDialog.newInstance(unReadNum).apply {
+            openMessageFun = {
+                openMessageListDialog()
+            }
+            openShareFun = {
+                openShareDialog()
+            }
+            openMusicFun = {
+                openMusicDialog()
+            }
+            clearJifenFun = {
+                ChoiceDialogFragment.newInstance(AppContext.getContext().resources.getString(R.string.ji_fen_to_zero)).apply {
+                    this.sureFun = {
+                        roomVm.clearJiFen()
+                    }
+                }.show(this@AnchorRoomFragment.childFragmentManager,"ChoiceDialogFragment")
+            }
+        }.show(childFragmentManager , "FooterMoreDialog")
+    }
+
     override fun changeRoom(iRoomInfo: IRoomInfo) {
         super.changeRoom(iRoomInfo)
     }
@@ -226,6 +256,14 @@ class AnchorRoomFragment : BaseComFragment<FragmentBaseComBinding>() {
         super.closeRoomed()
     }
 
+    fun onAudioMixingStateChanged(state: Int, reason: Int) {
+        if (state == 710){
+            footerView?.playMusicAnimator(true)
+        } else if (state == 713 || state == 711 || state == 714){
+            footerView?.playMusicAnimator(false)
+        }
+    }
+
     override val iHeader: IHeader by lazy {
         ComHeaderView(requireContext())
     }

+ 28 - 1
room/src/main/java/com/swago/room/audio/AudioSeatAdapter.kt

@@ -1,17 +1,26 @@
 package com.swago.room.audio
 
+import android.view.View
 import com.chad.library.adapter.base.BaseQuickAdapter
 import com.chad.library.adapter.base.BaseViewHolder
+import com.opensource.svgaplayer.SVGADrawable
+import com.opensource.svgaplayer.SVGAImageView
+import com.opensource.svgaplayer.SVGAParser
+import com.opensource.svgaplayer.SVGAVideoEntity
 import com.swago.baseswago.cusview.SwagoImageView
 import com.swago.baseswago.model.live.audio.AudioSeatModel
 import com.swago.room.R
+import java.net.URL
 
 class AudioSeatAdapter :
     BaseQuickAdapter<AudioSeatModel, BaseViewHolder>(R.layout.item_audio_seat, arrayListOf()) {
-
+    private val svgaParser by lazy {
+        SVGAParser(mContext)
+    }
     override fun convert(helper: BaseViewHolder?, item: AudioSeatModel?) {
         helper?.apply {
             item?.let {
+                val svgAvatar = itemView.findViewById<SVGAImageView>(R.id.svgAvatar)
                 if (it.user_id == "0") {
                     setVisible(R.id.tvIntegration, false)
                     setVisible(R.id.ivAudioState, false)
@@ -23,6 +32,7 @@ class AudioSeatAdapter :
                         itemView.findViewById<SwagoImageView>(R.id.ivImageView)
                             .loadImage(R.mipmap.ic_audio_seat)
                     }
+                    svgAvatar.visibility = View.INVISIBLE
                 } else {
                     itemView.findViewById<SwagoImageView>(R.id.ivImageView)
                         .loadImage(it.user_head_img_url ?: "")
@@ -48,6 +58,23 @@ class AudioSeatAdapter :
                         }
 
                     }
+
+                    if (!it.head_special.isNullOrEmpty()){
+                        svgAvatar.visibility = View.VISIBLE
+                        svgaParser.decodeFromURL(URL(it.head_special), object :SVGAParser.ParseCompletion{
+                            override fun onComplete(videoItem: SVGAVideoEntity) {
+                                val drawable = SVGADrawable(videoItem)
+                                svgAvatar.setImageDrawable(drawable)
+                                svgAvatar.startAnimation()
+                            }
+
+                            override fun onError() {
+                            }
+                        })
+                    } else {
+                        svgAvatar.visibility = View.INVISIBLE
+                    }
+
                 }
             }
         }

+ 68 - 34
room/src/main/java/com/swago/room/base/BaseComFragment.kt

@@ -79,6 +79,7 @@ import com.swago.room.hongbao.RedEnvelopeDialog
 import com.swago.room.inter.IFooter
 import com.swago.room.inter.IHeader
 import com.swago.room.lianmai.LianMaiVm
+import com.swago.room.manager.JoinAnimalManager
 import com.swago.room.music.MyMusicDialog
 import com.swago.room.piaotiao.WaftManager
 import com.swago.room.pk.IPKListener
@@ -92,9 +93,13 @@ import com.swago.room.widget.ComHeaderView
 import com.swago.room.wishgift.SetWishGiftsDialog
 import com.swago.room.wishgift.WishGiftOnUserDialog
 import io.agora.rtc.IRtcEngineEventHandler
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.cancel
 import kotlinx.coroutines.delay
+import kotlinx.coroutines.isActive
 import kotlinx.coroutines.launch
 import java.io.File
 import java.lang.Exception
@@ -141,6 +146,8 @@ abstract class BaseComFragment<T : FragmentBaseComBinding> : BaseXFragment<T>(),
     abstract val iFooter: IFooter
 
     var roomConfig: RoomConfig? = null
+    val job = Job()
+    val coroutineScope = CoroutineScope(Dispatchers.Main + job)
 
     var dialog: SendMsgDialog? = null
     var gameDialog: GamePlayDialog? = null
@@ -157,6 +164,9 @@ abstract class BaseComFragment<T : FragmentBaseComBinding> : BaseXFragment<T>(),
     private val svgPlayerManager by lazy {
         SvgPlayerManager()
     }
+    private val joinAnimalManager by lazy {
+        JoinAnimalManager()
+    }
 
     private val waftManager by lazy {
         WaftManager()
@@ -222,6 +232,7 @@ abstract class BaseComFragment<T : FragmentBaseComBinding> : BaseXFragment<T>(),
         chatAdapter.setNewData(dataChatList)
         context?.let {
             svgPlayerManager.init(it, binding.xSvgaPlayer, binding.svgDanDaoView)
+            joinAnimalManager.init(it, binding.xSvgaPlayer)
         }
 
         activity?.let {
@@ -238,6 +249,21 @@ abstract class BaseComFragment<T : FragmentBaseComBinding> : BaseXFragment<T>(),
                 roomOtherVm.userDianZan()
             }
         }
+
+        coroutineScope.launch {
+            while (isActive){
+                SwagoRoomManager.iRoomInfo?.let {
+                    if (it.getRoomType() == RoomType.AUDIO.type){
+                        roomVm.getAudioList(it.getAnchorId(), 2)
+                    }
+                }
+                if (SwagoRoomManager.roleType == RoleType.anchor){
+                    roomVm.loadRoomData()
+                }
+                delay(10000)
+            }
+        }
+
     }
 
     private fun initAudioRvList() {
@@ -453,9 +479,26 @@ abstract class BaseComFragment<T : FragmentBaseComBinding> : BaseXFragment<T>(),
         (iHeader as ComHeaderView).openAudienceListDialog = {
             AudienceListDialog.newInstance().apply {
                 this.showUserInfo = {userid ->
-                   PersonDataDFragment.newInstance(userid,
-                       isAnchor = false,
-                       inRoom = true).show(this@BaseComFragment.childFragmentManager,"PersonDataDFragment")
+                    PersonDataDFragment.newInstance(userid,
+                        isAnchor = false,
+                        inRoom = true).apply {
+                        this.openGiftIconDialog = { nickName, userId ,nickIcon->
+                            openGiftDialog(nickName, userId)
+                        }
+                        this.sendMsgInRoom = {
+                            if (isForbid) {
+                                Toast.makeText(
+                                    AppContext.getContext(),
+                                    AppContext.getContext().resources.getString(
+                                        R.string.you_are_been_forbid
+                                    ),
+                                    Toast.LENGTH_SHORT
+                                ).show()
+                            } else {
+                                openSendMessageDialog("@${it} ")
+                            }
+                        }
+                    }.show(this@BaseComFragment.childFragmentManager,"PersonDataDFragment")
                 }
             }.show(childFragmentManager, "AudienceListDialog")
         }
@@ -485,16 +528,16 @@ abstract class BaseComFragment<T : FragmentBaseComBinding> : BaseXFragment<T>(),
         }
         //推荐游戏列表
         roomVm.recommendGameListModelLiveData.observe(this){
-                binding.playBannerView.setData(it.list)
-                binding.playBannerView.jumpToWebFun = { game ->
-                    setRecommendGame(game)
+            binding.playBannerView.setData(it.list)
+            binding.playBannerView.jumpToWebFun = { game ->
+                setRecommendGame(game)
 
-                }
-                binding.videoPlayBannerView.setData(it.list)
-                binding.videoPlayBannerView.jumpToWebFun = { game ->
-                    setRecommendGame(game)
+            }
+            binding.videoPlayBannerView.setData(it.list)
+            binding.videoPlayBannerView.jumpToWebFun = { game ->
+                setRecommendGame(game)
 
-                }
+            }
         }
 
         //直播间配置
@@ -528,8 +571,11 @@ abstract class BaseComFragment<T : FragmentBaseComBinding> : BaseXFragment<T>(),
         //语音房麦位列表数据
         roomVm.audioSeatListLiveData.observe(this) {
             if (it != null) {
-                audioSeatAdapter.setNewData(it)
-                initMaiPosition()
+                if (audioSeatAdapter.data !=  it){
+                    audioSeatAdapter.setNewData(it)
+                    initMaiPosition()
+                }
+
             }
         }
 
@@ -601,6 +647,11 @@ abstract class BaseComFragment<T : FragmentBaseComBinding> : BaseXFragment<T>(),
             userVm.getUserInfo()
         }
 
+        msgVm.joinRoomFun = {
+            //svg播放
+            joinAnimalManager.addSvgUrl(it)
+        }
+
         userVm.userInfoLiveData.observe(this) {
             UserInfo.setUserInfo(it)
             SpUtil.putString("user_info", Gson().toJson(it))
@@ -628,10 +679,6 @@ abstract class BaseComFragment<T : FragmentBaseComBinding> : BaseXFragment<T>(),
         ShareDialog.newInstance().show(childFragmentManager,"ShareDialog")
     }
 
-    fun openMusicDialog() {
-        MyMusicDialog.newInstance().show(childFragmentManager,"MyMusicDialog")
-    }
-
     private fun initMaiPosition() {
         allPositionXYList.clear()
         val centerX = DpPxUtil.getScreenWidth() / 2
@@ -725,6 +772,7 @@ abstract class BaseComFragment<T : FragmentBaseComBinding> : BaseXFragment<T>(),
         dialog = null
         gameDialog = null
         msgListDialog = null
+        job.cancel()
         PKStateManager.removePKListener(this)
         activity?.let {
             KeyboardUtils.unregisterSoftInputChangedListener(it.window)
@@ -741,20 +789,6 @@ abstract class BaseComFragment<T : FragmentBaseComBinding> : BaseXFragment<T>(),
         dialog?.show(childFragmentManager, "SendMsgDialog")
     }
 
-    fun openMoreDialog(){
-        FooterMoreDialog.newInstance(unReadNum).apply {
-            openMessageFun = {
-                openMessageListDialog()
-            }
-            openShareFun = {
-                openShareDialog()
-            }
-            openMusicFun = {
-                openMusicDialog()
-            }
-        }.show(childFragmentManager , "FooterMoreDialog")
-    }
-
     fun openMessageListDialog() {
         msgListDialog = MessageListDialog.newInstance()
         msgListDialog?.show(childFragmentManager, "MessageListDialog")
@@ -771,9 +805,9 @@ abstract class BaseComFragment<T : FragmentBaseComBinding> : BaseXFragment<T>(),
             )
             if (download) {
                 gameDialog =
-                    GamePlayDialog.newInstance("file://" + UrlConstant.appGameRootPath + File.separator + it.getGameType() + File.separator + "index.html",it.getIsFullGame())
+                    GamePlayDialog.newInstance("file://" + UrlConstant.appGameRootPath + File.separator + it.getGameType() + File.separator + "index.html",it.getIsFullGame(), it.getGameType().toString())
             } else {
-                gameDialog = GamePlayDialog.newInstance(it.getGameUrl(),it.getIsFullGame())
+                gameDialog = GamePlayDialog.newInstance(it.getGameUrl(),it.getIsFullGame(), it.getGameType().toString())
             }
             gameDialog?.dialogDisFun = {
                 gameIsOpen = false
@@ -883,7 +917,7 @@ abstract class BaseComFragment<T : FragmentBaseComBinding> : BaseXFragment<T>(),
 
     override fun changeRoom(iRoomInfo: IRoomInfo) {
         binding.likeLayout.clear()
-       binding.rvAudio.visibility = View.GONE
+        binding.rvAudio.visibility = View.GONE
     }
 
     override fun leaveRoom(iRoomInfo: IRoomInfo) {

+ 28 - 0
room/src/main/java/com/swago/room/bean/UserRoomModel.kt

@@ -193,4 +193,32 @@ class UserRoomModel : IRoomInfo {
     override fun getPassStatus(): Int {
         return momentModel?.broadcast_password_status ?: 0
     }
+
+    override fun getJoinSpecial(): String {
+        return roomModel?.join_special ?: ""
+    }
+
+    override fun getHeadSpecial(): String {
+        return if (RoleType.user == SwagoRoomManager.roleType) {
+            momentModel?.head_special ?: ""
+        } else {
+            roomModel?.head_special ?: ""
+        }
+    }
+
+    override fun getBadgeSpecial(): String {
+        return if (RoleType.user == SwagoRoomManager.roleType) {
+            momentModel?.badge_special ?: ""
+        } else {
+            roomModel?.badge_special ?: ""
+        }
+    }
+
+    override fun getChatSpecial(): String {
+        return if (RoleType.user == SwagoRoomManager.roleType) {
+            momentModel?.chat_special ?: ""
+        } else {
+            roomModel?.chat_special ?: ""
+        }
+    }
 }

+ 1 - 1
room/src/main/java/com/swago/room/database/DBManager.kt

@@ -6,7 +6,7 @@ object DBManager {
     private var daoSession: DaoSession? = null
 
     fun init(context: Context) {
-        val helper = DaoMaster.DevOpenHelper(context, "meliv_db")
+        val helper = DaoMaster.DevOpenHelper(context, "meliv.db")
         val db = helper.writableDb
         val daoMaster = DaoMaster(db)
         daoSession = daoMaster.newSession()

+ 13 - 1
room/src/main/java/com/swago/room/dialog/FooterMoreDialog.kt

@@ -19,6 +19,7 @@ class FooterMoreDialog : BaseXDFragment<DialogFooterMoreBinding>() {
     var openMessageFun:(()->Unit)? = null
     var openShareFun:(()->Unit)? = null
     var openMusicFun:(()->Unit)? = null
+    var clearJifenFun:(()->Unit)? = null
 
     init {
         setGravity(Gravity.BOTTOM)
@@ -50,6 +51,13 @@ class FooterMoreDialog : BaseXDFragment<DialogFooterMoreBinding>() {
                 binding.tvNum.visibility = View.GONE
             }
         }
+        SwagoRoomManager.iRoomInfo?.let{
+            if (it.getRoomType() == 2){
+                binding.ivClearJifen.visibility = View.VISIBLE
+            } else if (it.getRoomType() == 1){
+                binding.ivVideoMusic.visibility = View.VISIBLE
+            }
+        }
         binding.ivMessage.setOnClickListener {
             openMessageFun?.invoke()
             dismissAllowingStateLoss()
@@ -58,9 +66,13 @@ class FooterMoreDialog : BaseXDFragment<DialogFooterMoreBinding>() {
             openShareFun?.invoke()
             dismissAllowingStateLoss()
         }
-        binding.ivMusic.setOnClickListener{
+        binding.ivVideoMusic.setOnClickListener{
             openMusicFun?.invoke()
             dismissAllowingStateLoss()
         }
+        binding.ivClearJifen.setOnClickListener {
+            clearJifenFun?.invoke()
+            dismissAllowingStateLoss()
+        }
     }
 }

+ 24 - 4
room/src/main/java/com/swago/room/dialog/MessageListDialog.kt

@@ -3,8 +3,10 @@ package com.swago.room.dialog
 import android.os.Bundle
 import android.view.Gravity
 import android.view.View
+import androidx.fragment.app.viewModels
 import com.alibaba.android.arouter.launcher.ARouter
 import com.gyf.immersionbar.ImmersionBar
+import com.swago.baseswago.UserVm
 import com.swago.baseswago.constant.ARouteConstant
 import com.swago.baseswago.dialog.BaseXDFragment
 import com.swago.baseswago.util.NoDoubleClickListener
@@ -12,12 +14,16 @@ import com.swago.room.databinding.DialogMessageListBinding
 import com.tencent.imsdk.v2.V2TIMConversation
 import com.tencent.qcloud.tim.uikit.modules.conversation.ConversationLayout
 import com.tencent.qcloud.tim.uikit.modules.conversation.ConversationManagerKit
+import com.tencent.qcloud.tim.uikit.modules.conversation.base.ConversationInfo
 
 /**
  *@date 2021/11/11 21:03
  *description:
  */
 class MessageListDialog : BaseXDFragment<DialogMessageListBinding>() {
+    private val userVm by viewModels<UserVm>()
+    private var conversationInfo: ConversationInfo?= null
+    private var jumpDetail = true
 
     init {
         setDimAmount(0f)
@@ -38,16 +44,25 @@ class MessageListDialog : BaseXDFragment<DialogMessageListBinding>() {
         activity?.let {
             binding.conversation.initDefault()
             binding.conversation.conversationList.setOnItemClickListener { view, position, messageInfo ->
-                ARouter.getInstance().build(ARouteConstant.Home.chatDetail)
-                    .withInt("type", V2TIMConversation.V2TIM_C2C)
-                    .withString("account",messageInfo.id)
-                    .withString("chatName",messageInfo.title).navigation()
+                conversationInfo = messageInfo
+                userVm.getOtherUserInfo(messageInfo.id,"")
             }
 
             binding.conversation.conversationList.setOnItemLongClickListener { view, position, messageInfo ->
 
             }
 
+            userVm.otherUserInfoLiveData.observe(it){model ->
+                if (jumpDetail){
+                    ARouter.getInstance().build(ARouteConstant.Home.chatDetail)
+                        .withInt("type", V2TIMConversation.V2TIM_C2C)
+                        .withString("account", conversationInfo?.id)
+                        .withString("chatName", conversationInfo?.title)
+                        .withString("headSpecial" , model.android_head_special)
+                        .navigation()
+                }
+              jumpDetail = false
+            }
         }
     }
 
@@ -56,4 +71,9 @@ class MessageListDialog : BaseXDFragment<DialogMessageListBinding>() {
         ConversationManagerKit.getInstance().detachAdapter()
         super.onDestroyView()
     }
+
+    override fun onResume() {
+        super.onResume()
+        jumpDetail = true
+    }
 }

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

@@ -5,6 +5,7 @@ import android.text.Editable
 import android.text.TextWatcher
 import android.view.Gravity
 import android.view.View
+import android.widget.Toast
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.content.ContextCompat
 import androidx.fragment.app.viewModels
@@ -22,7 +23,6 @@ import com.swago.room.util.IMSender
 import com.swago.room.vm.RoomOtherVm
 import com.tencent.imsdk.v2.V2TIMMessage
 import com.tencent.imsdk.v2.V2TIMValueCallback
-import com.tencent.qcloud.tim.uikit.utils.ToastUtil
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
 import org.json.JSONObject
@@ -157,6 +157,9 @@ class SendMsgDialog : BaseXDFragment<DialogSendMsgBinding>() {
                             roomChatMsgBean.isCup = it.is_cup
                             roomChatMsgBean.isAdmin = SwagoRoomManager.iRoomInfo?.getRoomAdmin()?:0
                             roomChatMsgBean.isFans = SwagoRoomManager.iRoomInfo?.getIsFans()?:0
+                            roomChatMsgBean.android_chat_special = it.android_chat_special
+                            roomChatMsgBean.ios_chat_special = it.ios_chat_special
+                            roomChatMsgBean.badge_special = it.android_badge_special
 
                             val jsonObject = JSONObject()
                             jsonObject.put("senderId", it.id)
@@ -172,6 +175,9 @@ class SendMsgDialog : BaseXDFragment<DialogSendMsgBinding>() {
                             jsonObject.put("isCup", it.is_cup)
                             jsonObject.put("isAdmin", SwagoRoomManager.iRoomInfo?.getRoomAdmin()?:0)
                             jsonObject.put("isFans", SwagoRoomManager.iRoomInfo?.getIsFans()?:0)
+                            jsonObject.put("android_chat_special", it.android_chat_special)
+                            jsonObject.put("ios_chat_special", it.ios_chat_special)
+                            jsonObject.put("badge_special", it.android_badge_special)
 
                             val jsonObjectType = JSONObject()
                             jsonObjectType.put("type", room_chat_text)
@@ -189,7 +195,11 @@ class SendMsgDialog : BaseXDFragment<DialogSendMsgBinding>() {
 
                                         override fun onError(code: Int, desc: String?) {
                                             if (code == 10016){
-                                                ToastUtil.toastShortMessage(AppContext.getContext().getString(R.string.you_been_banned))
+                                                Toast.makeText(
+                                                    AppContext.getContext(),
+                                                    AppContext.getContext().resources.getString(R.string.you_been_banned),
+                                                    Toast.LENGTH_SHORT
+                                                ).show()
                                             }
 
                                         }

+ 58 - 17
room/src/main/java/com/swago/room/game/GamePlayDialog.kt

@@ -4,13 +4,16 @@ import android.graphics.Color
 import android.os.Bundle
 import android.view.Gravity
 import android.view.ViewGroup
-import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
-import android.webkit.*
-import android.widget.FrameLayout
-import com.alibaba.android.arouter.launcher.ARouter
+import android.webkit.JavascriptInterface
+import android.webkit.WebResourceError
+import android.webkit.WebResourceRequest
+import android.webkit.WebView
+import android.webkit.WebViewClient
 import android.widget.ImageView
 import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.constraintlayout.widget.ConstraintSet
 import androidx.lifecycle.lifecycleScope
+import com.alibaba.android.arouter.launcher.ARouter
 import com.google.gson.Gson
 import com.swago.baseswago.baseroom.IRoomActiveListener
 import com.swago.baseswago.baseroom.IRoomInfo
@@ -18,20 +21,24 @@ import com.swago.baseswago.baseroom.SwagoRoomManager
 import com.swago.baseswago.constant.ARouteConstant
 import com.swago.baseswago.constant.UrlConstant
 import com.swago.baseswago.dialog.BaseXDFragment
-import com.swago.baseswago.dialog.PayDialog
 import com.swago.baseswago.im.IMGroupNewMsgListener
 import com.swago.baseswago.im.ImConstant
 import com.swago.baseswago.im.ImConstant.beauty_game_grab_host
 import com.swago.baseswago.im.ImConstant.beauty_game_grab_host_two
 import com.swago.baseswago.model.im.BeautyHostGameData
 import com.swago.baseswago.model.im.CusNewMsgBean
-import com.swago.baseswago.model.im.FollowSuccessMsgBean
 import com.swago.baseswago.model.im.GameData
 import com.swago.baseswago.model.live.game.GameInfoModel
-import com.swago.baseswago.util.*
+import com.swago.baseswago.util.DpPxUtil
+import com.swago.baseswago.util.FileUtil
+import com.swago.baseswago.util.MD5Util
+import com.swago.baseswago.util.NoDoubleClickListener
+import com.swago.baseswago.util.SwagoInfo
+import com.swago.baseswago.util.UserInfo
 import com.swago.room.R
 import com.swago.room.bean.UserRoomModel
 import com.swago.room.databinding.DialogGamePlayBinding
+import com.tencent.qcloud.tim.uikit.utils.ScreenUtil
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
@@ -45,6 +52,7 @@ import java.io.File
 class GamePlayDialog : BaseXDFragment<DialogGamePlayBinding>(), IRoomActiveListener {
 
     private var url = ""
+    private var gameType = ""
 
     private var webView: WebView? = null
     private var localGameUrl = ""
@@ -57,18 +65,18 @@ class GamePlayDialog : BaseXDFragment<DialogGamePlayBinding>(), IRoomActiveListe
 
     private val imGroupNewMsgListener = IMGroupNewMsgListener()
 
-    private var isFullScreen = false
-
     var dialogDisFun: (() -> Unit)? = null
     var openMessageFun:(()->Unit)? = null
     companion object {
         private const val URL = "url"
         private const val FULL_GAME = "fullGame"
-        fun newInstance(url: String,isFullGame:Boolean): GamePlayDialog {
+        private const val GAME_TYPE = "gameType"
+        fun newInstance(url: String,isFullGame:Boolean,gameType:String): GamePlayDialog {
             val dialog = GamePlayDialog()
             val bundle = Bundle()
             bundle.putString(URL, url)
             bundle.putBoolean(FULL_GAME, isFullGame)
+            bundle.putString(GAME_TYPE,gameType)
             dialog.arguments = bundle
             return dialog
         }
@@ -84,11 +92,31 @@ class GamePlayDialog : BaseXDFragment<DialogGamePlayBinding>(), IRoomActiveListe
     override fun initOther() {
         SwagoRoomManager.addListener(this)
         arguments?.let {
+            gameType = it.getString(GAME_TYPE,"")
+            when(gameType){
+                "1" ->
+                    binding.ivBg.setBackgroundResource(R.mipmap.bg_three_card)
+                "2" ->
+                    binding.ivBg.setBackgroundResource(R.mipmap.bg_fruit_party)
+                "3" ->
+                    binding.ivBg.setBackgroundResource(R.mipmap.bg_frenzy_vagas)
+                "4" ->
+                    binding.ivBg.setBackgroundResource(R.mipmap.bg_three_card_duel)
+                "6" ->
+                    binding.ivBg.setBackgroundResource(R.mipmap.bg_food_wheel)
+                "7" ->
+                    binding.ivBg.setBackgroundResource(R.mipmap.bg_lucky_piggy)
+                "8" ->
+                    binding.ivBg.setBackgroundResource(R.mipmap.bg_magical_piggy)
+                "9" ->{
+                    setDimensionRatio("H,75:74")
+                    binding.ivBg.setBackgroundResource(R.mipmap.bg_tigers)
+                }
+            }
             url = it.getString(URL, "")
             if (url.startsWith("file://")){
                 localGameUrl = url
             }
-            isFullScreen = it.getBoolean(FULL_GAME,false)
             activity?.let { activity ->
 
                 webView = WebView(activity)
@@ -97,7 +125,13 @@ class GamePlayDialog : BaseXDFragment<DialogGamePlayBinding>(), IRoomActiveListe
                 imageViewLayoutParams.bottomToBottom = R.id.cl
                 imageViewLayoutParams.leftToLeft = R.id.cl
                 imageViewLayoutParams.leftMargin = DpPxUtil.dip2px(10f)
-                imageViewLayoutParams.bottomMargin = DpPxUtil.dip2px(320f)
+                if (gameType == "9"){
+                    imageViewLayoutParams.bottomMargin =
+                        ScreenUtil.getScreenWidth(getActivity())
+                } else {
+                    imageViewLayoutParams.bottomMargin =
+                        ScreenUtil.getScreenWidth(getActivity()) - ScreenUtil.getPxByDp(40f)
+                }
                 val imageView = ImageView(activity)
                 imageView.setBackgroundResource(R.drawable.shape_80000000_20)
                 imageView.setImageResource(R.mipmap.live_chat)
@@ -161,11 +195,11 @@ class GamePlayDialog : BaseXDFragment<DialogGamePlayBinding>(), IRoomActiveListe
                     params.width = DpPxUtil.getScreenWidth()
                     params.bottomToBottom = R.id.cl
 
-                    if (isFullScreen){
-                        params.height = DpPxUtil.getScreenHeight()
-                    }else{
-                        params.height = (params.width * 276 / 360f).toInt()
-                    }
+//                    if (isFullScreen){
+                    params.height = DpPxUtil.getScreenHeight()
+//                    }else{
+//                        params.height = (params.width * 276 / 360f).toInt()
+//                    }
                     this.layoutParams = params
                     binding.cl.addView(this)
                     binding.cl.addView(imageView)
@@ -231,6 +265,13 @@ class GamePlayDialog : BaseXDFragment<DialogGamePlayBinding>(), IRoomActiveListe
 
     override fun initLiveData() {}
 
+    private fun setDimensionRatio(ratio: String) {
+        val constraintLayout = binding.cl
+        val constraintSet = ConstraintSet()
+        constraintSet.clone(constraintLayout)
+        constraintSet.setDimensionRatio(binding.ivBg.id, ratio)
+        constraintSet.applyTo(constraintLayout)
+    }
 
     inner class JSLoad {
 

+ 9 - 0
room/src/main/java/com/swago/room/gift/GiftDialog.kt

@@ -864,4 +864,13 @@ class GiftDialog : BaseXDFragment<DialogGiftBinding>() {
             }
         }
     }
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        luckyFragment = null
+        hotFragment = null
+        luxuryFragment = null
+        specialFragment = null
+        mingRenTangFragment = null
+    }
 }

+ 25 - 0
room/src/main/java/com/swago/room/gift/audio/MaiUserAdapter.kt

@@ -1,25 +1,50 @@
 package com.swago.room.gift.audio
 
+import android.text.TextUtils
 import android.view.View
 import com.chad.library.adapter.base.BaseQuickAdapter
 import com.chad.library.adapter.base.BaseViewHolder
+import com.opensource.svgaplayer.SVGADrawable
+import com.opensource.svgaplayer.SVGAImageView
+import com.opensource.svgaplayer.SVGAParser
+import com.opensource.svgaplayer.SVGAVideoEntity
 import com.swago.baseswago.model.live.audio.MaiUserInfo
 import com.swago.loadUrl
 import com.swago.room.R
 import de.hdodenhof.circleimageview.CircleImageView
+import java.net.URL
 
 class MaiUserAdapter : BaseQuickAdapter<MaiUserInfo, BaseViewHolder>(R.layout.item_mai_user, arrayListOf()) {
+    private val svgaParser by lazy {
+        SVGAParser(mContext)
+    }
 
     override fun convert(helper: BaseViewHolder?, item: MaiUserInfo?) {
         helper?.apply {
             item?.let {
                 itemView.findViewById<CircleImageView>(R.id.ivAvatar).loadUrl(mContext,it.user_head_img_url)
+                val svgaImageView = itemView.findViewById<SVGAImageView>(R.id.svgAvatar)
                 val view = itemView.findViewById<View>(R.id.view)
                 if (it.selected){
                     view.visibility = View.VISIBLE
                 }else{
                     view.visibility = View.GONE
                 }
+                if (!TextUtils.isEmpty(it.head_special)){
+                    svgaImageView.visibility = View.VISIBLE
+                    svgaParser.decodeFromURL(URL(item.head_special), object : SVGAParser.ParseCompletion{
+                        override fun onComplete(videoItem: SVGAVideoEntity) {
+                            val drawable = SVGADrawable(videoItem)
+                            svgaImageView.setImageDrawable(drawable)
+                            svgaImageView.startAnimation()
+                        }
+
+                        override fun onError() {
+                        }
+                    })
+                } else {
+                    svgaImageView.visibility = View.INVISIBLE
+                }
             }
         }
     }

+ 38 - 0
room/src/main/java/com/swago/room/gift/control/XSvgPlayer.kt

@@ -10,6 +10,7 @@ import com.opensource.svgaplayer.SVGACallback
 import com.opensource.svgaplayer.SVGADrawable
 import com.opensource.svgaplayer.SVGAParser
 import com.opensource.svgaplayer.SVGAVideoEntity
+import com.swago.baseswago.model.im.UserJoinRoomBean
 import com.swago.baseswago.model.live.gift.IMGiftModel
 import com.swago.baseswago.util.LogUtil
 import com.swago.room.databinding.ViewSvgaBinding
@@ -85,6 +86,43 @@ class XSvgPlayer : ConstraintLayout {
         }
     }
 
+    fun playJoinRoomSvga(userJoinRoomBean: UserJoinRoomBean?){
+        if (userJoinRoomBean == null || userJoinRoomBean.androidJoinSpecial.isNullOrEmpty()){
+            return
+        }
+        svgaParser!!.let {
+            LogUtil.d("svgPlayer","xxx--$isPlaying")
+            it.decodeFromURL(URL(userJoinRoomBean.androidJoinSpecial),object:SVGAParser.ParseCompletion{
+                override fun onComplete(videoItem: SVGAVideoEntity) {
+                    binding!!.apply {
+                        val drawable = SVGADrawable(videoItem)
+                        svgaImageView.visibility = View.VISIBLE
+                        svgaImageView.setImageDrawable(drawable)
+                        svgaImageView.loops = 1
+                        svgaImageView.callback = callback
+                        LogUtil.d("svgPlayer","onComplete--$isPlaying")
+                        if (!isPlaying){
+                            svgaImageView.startAnimation()
+                            isPlaying = true
+                        }
+
+                    }
+
+                }
+
+                override fun onError() {
+                    binding?.apply {
+                        isPlaying = false
+                        LogUtil.d("svgPlayer","onError--$isPlaying")
+                        svgaImageView.visibility = View.GONE
+                        nextSvgPlay?.invoke()
+                    }
+                }
+            })
+
+        }
+    }
+
     fun clear(){
         binding?.apply {
             isPlaying = false

+ 16 - 0
room/src/main/java/com/swago/room/giftdandao/GiftDanDaoView.kt

@@ -30,6 +30,7 @@ import com.swago.room.BuildConfig
 import com.swago.room.R
 import com.swago.room.databinding.ViewItemGiftBinding
 import java.io.File
+import java.net.URL
 
 /**
  *@date 2022/1/22 16:57
@@ -89,6 +90,21 @@ class GiftDanDaoView : FrameLayout {
                 .error(R.mipmap.default_avatar)
                 .into(ivGiftIcon)
 
+            if (!imGiftModel.androidHeadSpecial.isNullOrEmpty()){
+                svgAvatar.visibility =View.VISIBLE
+                svgParser?.decodeFromURL(URL(imGiftModel.androidHeadSpecial), object : SVGAParser.ParseCompletion{
+                    override fun onComplete(videoItem: SVGAVideoEntity) {
+                        val drawable = SVGADrawable(videoItem)
+                        svgAvatar.setImageDrawable(drawable)
+                        svgAvatar.startAnimation()
+                    }
+                    override fun onError() {
+                    }
+                })
+            } else {
+                svgAvatar.visibility =View.GONE
+            }
+
             tvSenderName.text = imGiftModel.senderName
             if (!tvSenderName.isSelected) {
                 tvSenderName.isSelected = true

+ 6 - 0
room/src/main/java/com/swago/room/hongbao/RedEnvelopResultDialog.kt

@@ -107,6 +107,9 @@ class RedEnvelopResultDialog : BaseXDFragment<DialogRedEnvelopeResultBinding>()
                 roomChatMsgBean.isCup = it.is_cup
                 roomChatMsgBean.isAdmin = SwagoRoomManager.iRoomInfo?.getRoomAdmin()?:0
                 roomChatMsgBean.isFans = SwagoRoomManager.iRoomInfo?.getIsFans()?:0
+                roomChatMsgBean.android_chat_special = it.android_chat_special
+                roomChatMsgBean.ios_chat_special = it.ios_chat_special
+                roomChatMsgBean.badge_special = it.android_badge_special
                 addSenderMsgToRoomChatList?.invoke(roomChatMsgBean)
 
                 val jsonObject = JSONObject()
@@ -123,6 +126,9 @@ class RedEnvelopResultDialog : BaseXDFragment<DialogRedEnvelopeResultBinding>()
                 jsonObject.put("isCup", it.is_cup)
                 jsonObject.put("isAdmin", SwagoRoomManager.iRoomInfo?.getRoomAdmin()?:0)
                 jsonObject.put("isFans", SwagoRoomManager.iRoomInfo?.getIsFans()?:0)
+                jsonObject.put("android_chat_special", it.android_chat_special)
+                jsonObject.put("ios_chat_special", it.ios_chat_special)
+                jsonObject.put("badge_special", it.android_badge_special)
 
                 val jsonObjectType = JSONObject()
                 jsonObjectType.put("type", ImConstant.room_chat_text)

+ 82 - 0
room/src/main/java/com/swago/room/manager/JoinAnimalManager.kt

@@ -0,0 +1,82 @@
+package com.swago.room.manager
+
+import android.content.Context
+import com.opensource.svgaplayer.SVGAParser
+import com.swago.baseswago.baseroom.IRoomActiveListener
+import com.swago.baseswago.baseroom.IRoomInfo
+import com.swago.baseswago.baseroom.SwagoRoomManager
+import com.swago.baseswago.model.im.UserJoinRoomBean
+import com.swago.baseswago.model.live.gift.IMGiftModel
+import com.swago.baseswago.util.LogUtil
+import com.swago.room.gift.control.XSvgPlayer
+import java.util.*
+
+/**
+ *@date 2021/12/11 16:42
+ *description:
+ */
+class JoinAnimalManager : IRoomActiveListener {
+
+    private val svgListQueue = LinkedList<UserJoinRoomBean>()
+    private var xSvgPlayer: XSvgPlayer? = null
+
+    fun init(context: Context, xSvgPlayer: XSvgPlayer) {
+        SVGAParser.shareParser().init(context)
+        this.xSvgPlayer = xSvgPlayer
+        SwagoRoomManager.addListener(this)
+
+        this.xSvgPlayer?.nextSvgPlay = {
+            svgListQueue.poll()
+            val uerJoinRoomBean = svgListQueue.peek()
+            LogUtil.d("SvgPlayerManager","${svgListQueue.size}")
+            if (uerJoinRoomBean==null){
+                LogUtil.d("SvgPlayerManager","clear svgListQueue")
+                svgListQueue.clear()
+            }else{
+                if (this.xSvgPlayer==null){
+                    svgListQueue.clear()
+                    LogUtil.d("SvgPlayerManager","xSvgPlayer 为空")
+                }else{
+                    this.xSvgPlayer!!.playJoinRoomSvga(uerJoinRoomBean)
+                }
+
+            }
+        }
+    }
+
+    override fun changeRoom(iRoomInfo: IRoomInfo) {
+        svgListQueue.clear()
+        xSvgPlayer?.clear()
+    }
+
+    override fun leaveRoom(iRoomInfo: IRoomInfo) {
+        svgListQueue.clear()
+        xSvgPlayer?.clear()
+    }
+
+    override fun joinedRoom(iRoomInfo: IRoomInfo) {
+
+    }
+
+    override fun endRoom(iRoomInfo: IRoomInfo?) {
+
+    }
+
+    override fun closeRoomed() {
+        svgListQueue.clear()
+        xSvgPlayer?.clear()
+        SwagoRoomManager.removeListener(this)
+    }
+
+    fun addSvgUrl(userJoinRoomBean: UserJoinRoomBean?) {
+        userJoinRoomBean?.let {
+            if (svgListQueue.isEmpty()) {
+                LogUtil.d("SvgPlayerManager","数据源没有数据 新增一条")
+                svgListQueue.add(it)
+                this.xSvgPlayer?.playJoinRoomSvga(it)
+            } else {
+                svgListQueue.add(it)
+            }
+        }
+    }
+}

+ 49 - 0
room/src/main/java/com/swago/room/manager/JoinRoomManager.kt

@@ -13,6 +13,7 @@ import android.widget.TextView
 import android.widget.Toast
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.fragment.app.FragmentActivity
+import androidx.transition.Visibility
 import com.opensource.svgaplayer.SVGADrawable
 import com.opensource.svgaplayer.SVGAImageView
 import com.opensource.svgaplayer.SVGAParser
@@ -29,6 +30,7 @@ import com.swago.loadUrl
 import com.swago.room.R
 import de.hdodenhof.circleimageview.CircleImageView
 import java.io.File
+import java.net.URL
 import java.util.LinkedList
 
 class JoinRoomManager : IRoomActiveListener {
@@ -46,6 +48,7 @@ class JoinRoomManager : IRoomActiveListener {
     private var clBg: ConstraintLayout? = null
     private var clTwo: ConstraintLayout? = null
     private var clOne: LinearLayout? = null
+    private var svgaAvatar: SVGAImageView? = null
     private var animationSet: AnimatorSet? = null
     private val waitingTime = 1000L
 
@@ -70,6 +73,7 @@ class JoinRoomManager : IRoomActiveListener {
             swagoLevel = view.findViewById(R.id.swagoLevel)
             swagoLevelOne = view.findViewById(R.id.swagoLevelOne)
             joinRoomRootView = view.findViewById(R.id.rootView)
+            svgaAvatar = view.findViewById(R.id.svgAvatar)
             initViewAnimation()
             loopStart()
             SwagoRoomManager.addListener(this@JoinRoomManager)
@@ -120,6 +124,21 @@ class JoinRoomManager : IRoomActiveListener {
                 clBg?.setBackgroundResource(R.mipmap.join_ten_fourteen)
                 animationSet?.start()
                 joinRoomRootView?.visibility = View.VISIBLE
+                if (!userJoinRoomBean.androidHeadSpecial.isNullOrEmpty()) {
+                    svgaAvatar?.visibility = View.VISIBLE
+                    svgParser?.decodeFromURL(URL(userJoinRoomBean.androidHeadSpecial), object :SVGAParser.ParseCompletion{
+                        override fun onComplete(videoItem: SVGAVideoEntity) {
+                            val drawable = SVGADrawable(videoItem)
+                            svgaAvatar?.setImageDrawable(drawable)
+                            svgaAvatar?.startAnimation()
+                        }
+
+                        override fun onError() {
+                        }
+                    })
+                } else {
+                    svgaAvatar?.visibility = View.INVISIBLE
+                }
             }
             in 15..19 -> {
                 clOne?.visibility = View.GONE
@@ -132,6 +151,21 @@ class JoinRoomManager : IRoomActiveListener {
                 clBg?.setBackgroundResource(R.mipmap.join_fifteen_nineteen)
                 animationSet?.start()
                 joinRoomRootView?.visibility = View.VISIBLE
+                if (!userJoinRoomBean.androidHeadSpecial.isNullOrEmpty()) {
+                    svgaAvatar?.visibility = View.VISIBLE
+                    svgParser?.decodeFromURL(URL(userJoinRoomBean.androidHeadSpecial), object :SVGAParser.ParseCompletion{
+                        override fun onComplete(videoItem: SVGAVideoEntity) {
+                            val drawable = SVGADrawable(videoItem)
+                            svgaAvatar?.setImageDrawable(drawable)
+                            svgaAvatar?.startAnimation()
+                        }
+
+                        override fun onError() {
+                        }
+                    })
+                } else {
+                    svgaAvatar?.visibility = View.INVISIBLE
+                }
             }
             else -> {
                 clOne?.visibility = View.GONE
@@ -178,6 +212,21 @@ class JoinRoomManager : IRoomActiveListener {
                     })
 
                 }
+                if (!userJoinRoomBean.androidHeadSpecial.isNullOrEmpty()) {
+                    svgaAvatar?.visibility = View.VISIBLE
+                    svgParser?.decodeFromURL(URL(userJoinRoomBean.androidHeadSpecial), object :SVGAParser.ParseCompletion{
+                        override fun onComplete(videoItem: SVGAVideoEntity) {
+                            val drawable = SVGADrawable(videoItem)
+                            svgaAvatar?.setImageDrawable(drawable)
+                            svgaAvatar?.startAnimation()
+                        }
+
+                        override fun onError() {
+                        }
+                    })
+                } else {
+                    svgaAvatar?.visibility = View.GONE
+                }
             }
         }
     }

+ 1 - 1
room/src/main/java/com/swago/room/music/LocalMusicActivity.kt

@@ -39,7 +39,7 @@ class LocalMusicActivity : BaseXActivity<ActivityLocalMusicBinding>() {
 
     override fun initOther() {
         setBackView(binding.toolbar.ivBack)
-        binding.toolbar.tvTitle.text = AppContext.getContext().resources.getString(R.string.swago_offical_msg)
+        binding.toolbar.tvTitle.text = getString(R.string.local_music)
 
         binding.rv.layoutManager = layoutManager
         binding.rv.adapter = adapter

+ 1 - 1
room/src/main/java/com/swago/room/music/MusicVm.kt

@@ -20,7 +20,7 @@ class MusicVm(application: Application) : BaseViewModel(application) {
     val selection = "${MediaStore.Audio.Media.SIZE} >= ? " +
             "and ${MediaStore.Audio.Media.DURATION} >= ? " +
             "and ${MediaStore.Audio.Artists.ARTIST} != ?"
-    val electionArgs = arrayOf("1000000", "200000", "Unknown Artist")
+    val electionArgs = arrayOf("1000", "30000", "Unknown Artist")
     val sortOrder = "${MediaStore.Audio.Media._ID} DESC"
 
     val musicListData by lazy {

+ 4 - 0
room/src/main/java/com/swago/room/music/MyMusicAdapter.kt

@@ -1,6 +1,7 @@
 package com.swago.room.music
 
 import android.view.View
+import android.widget.ImageView
 import com.chad.library.adapter.base.BaseQuickAdapter
 import com.chad.library.adapter.base.BaseViewHolder
 import com.opensource.svgaplayer.SVGAImageView
@@ -16,11 +17,14 @@ class MyMusicAdapter :
             setText(R.id.tvDuration, String.format("%02d:%02d", item.duration / 60000, (item.duration % 60000) / 1000))
             addOnClickListener(R.id.ivRecall)
             val svgaImageView = itemView.findViewById<SVGAImageView>(R.id.svgaImageView)
+            val ivPlay = itemView.findViewById<ImageView>(R.id.ivPlay)
             if (item.getIsPlaying()){
                 svgaImageView.visibility = View.VISIBLE
+                ivPlay.setImageResource(R.mipmap.ic_music_play)
                 svgaImageView.startAnimation()
             } else {
                 svgaImageView.visibility = View.INVISIBLE
+                ivPlay.setImageResource(R.mipmap.ic_music_stop)
                 svgaImageView.stopAnimation()
             }
         }

+ 28 - 13
room/src/main/java/com/swago/room/music/MyMusicDialog.kt

@@ -11,6 +11,7 @@ import com.swago.baseswago.agora.AgoraManager
 import com.swago.baseswago.constant.ARouteConstant
 import com.swago.baseswago.dialog.BaseXDFragment
 import com.swago.baseswago.dialog.ChoiceDialogFragment
+import com.swago.baseswago.model.live.pk.PKLiverModel
 import com.swago.baseswago.util.AppContext
 import com.swago.room.R
 import com.swago.room.database.DBHelper
@@ -19,9 +20,13 @@ import com.swago.room.databinding.DialogMyMusicBinding
 class MyMusicDialog : BaseXDFragment<DialogMyMusicBinding>() {
     val music_binding get() = binding
     var isLocalCome = false
+    var openChooseMusicFun:((musicModel: MusicModel?)->Unit)? =null
+    var musicModel : MusicModel? = null
+
     private val musicList by lazy {
         ArrayList<MusicModel>()
     }
+
     private val adapter by lazy {
         MyMusicAdapter()
     }
@@ -29,10 +34,10 @@ class MyMusicDialog : BaseXDFragment<DialogMyMusicBinding>() {
         get() = LinearLayoutManager(activity)
 
     companion object {
-        const val select_local_result = 10002
-        fun newInstance(): MyMusicDialog {
+        fun newInstance(chooseMusic: MusicModel?): MyMusicDialog {
             val args = Bundle()
             val fragment = MyMusicDialog()
+            args.putParcelable("chooseMusic",chooseMusic)
             fragment.arguments = args
             return fragment
         }
@@ -45,6 +50,10 @@ class MyMusicDialog : BaseXDFragment<DialogMyMusicBinding>() {
     }
 
     override fun initOther() {
+        arguments?.let {
+            musicModel =  it.getParcelable("chooseMusic")
+
+        }
         music_binding.rvMusic.layoutManager = layoutManager
         music_binding.rvMusic.adapter = adapter
         music_binding.ivClose.setOnClickListener {
@@ -56,12 +65,17 @@ class MyMusicDialog : BaseXDFragment<DialogMyMusicBinding>() {
         val data = DBHelper.getMusicModel()?.loadAll()
         if (!data.isNullOrEmpty()){
             music_binding.clAdd.visibility = View.VISIBLE
-            music_binding.clNoContent.visibility = View.GONE
+            data.forEachIndexed { index, item ->
+                if (musicModel != null && item.id == musicModel?.id){
+                    data[index].setIsPlaying(true)
+                    return@forEachIndexed
+                }
+
+            }
             musicList.addAll(data)
             adapter.setNewData(musicList)
         } else {
             music_binding.clAdd.visibility = View.GONE
-            music_binding.clNoContent.visibility = View.VISIBLE
         }
         music_binding.clAdd.setOnClickListener {
             isLocalCome = true
@@ -69,12 +83,6 @@ class MyMusicDialog : BaseXDFragment<DialogMyMusicBinding>() {
                 .build(ARouteConstant.Room.musicList)
                 .navigation()
         }
-        music_binding.clNoContent.setOnClickListener {
-            isLocalCome = true
-            ARouter.getInstance()
-                .build(ARouteConstant.Room.musicList)
-                .navigation()
-        }
 
         adapter.setOnItemChildClickListener { _, view, position ->
             when(view?.id){
@@ -85,9 +93,9 @@ class MyMusicDialog : BaseXDFragment<DialogMyMusicBinding>() {
                             DBHelper.getMusicModel()?.delete(adapter.data[position])
                             musicList.remove(adapter.data[position])
                             adapter.setNewData(musicList)
+                            AgoraManager.getRtcEngine()?.stopAudioMixing()
                             if (adapter.data.isEmpty()){
                                 music_binding.clAdd.visibility = View.GONE
-                                music_binding.clNoContent.visibility = View.VISIBLE
                             }
                         }
                     }.show(childFragmentManager,"ChoiceDialogFragment")
@@ -101,6 +109,7 @@ class MyMusicDialog : BaseXDFragment<DialogMyMusicBinding>() {
                 adapter.data[position].setIsPlaying(false)
                 adapter.notifyItemChanged(position)
                 AgoraManager.getRtcEngine()?.stopAudioMixing()
+                openChooseMusicFun?.invoke(null)
                 return@setOnItemClickListener
             }
             adapter.data.forEachIndexed { index, musicModel ->
@@ -110,6 +119,7 @@ class MyMusicDialog : BaseXDFragment<DialogMyMusicBinding>() {
                     return@forEachIndexed
                 }
             }
+            openChooseMusicFun?.invoke(adapter.data[position])
             adapter.data[position].setIsPlaying(true)
             AgoraManager.getRtcEngine()?.startAudioMixing(
                 adapter.data[position].data,
@@ -129,13 +139,18 @@ class MyMusicDialog : BaseXDFragment<DialogMyMusicBinding>() {
             val data = DBHelper.getMusicModel()?.loadAll()
             if (!data.isNullOrEmpty()){
                 binding.clAdd.visibility = View.VISIBLE
-                binding.clNoContent.visibility = View.GONE
                 musicList.clear()
+                data.forEachIndexed { index, item ->
+                    if (musicModel != null && item.id == musicModel?.id){
+                        data[index].setIsPlaying(true)
+                        return@forEachIndexed
+                    }
+
+                }
                 musicList.addAll(data)
                 adapter.setNewData(musicList)
             } else {
                 binding.clAdd.visibility = View.GONE
-                binding.clNoContent.visibility = View.VISIBLE
             }
         }
     }

+ 4 - 0
room/src/main/java/com/swago/room/user/UserRoomActivity.kt

@@ -429,6 +429,10 @@ class UserRoomActivity : AbsUserActivity<ActivityAbsRoomUserBinding, UserRoomMod
         LogUtil.d("onFacePositionChanged${faces?.size}")
     }
 
+    override fun onAudioMixingStateChanged(state: Int, reason: Int) {
+
+    }
+
     fun gotoTargetRoom(anchorId: String) {
         iRoomInfos.forEachIndexed { index, userRoomModel ->
             if (userRoomModel?.momentModel != null) {

+ 13 - 2
room/src/main/java/com/swago/room/vm/MsgVm.kt

@@ -56,6 +56,7 @@ import com.swago.baseswago.model.live.WishGift
 import com.swago.baseswago.model.live.audio.*
 import com.swago.baseswago.model.live.gift.IMGiftModel
 import com.swago.baseswago.util.AppContext
+import com.swago.baseswago.util.BitmapUtils
 import com.swago.baseswago.util.UserInfo
 import com.swago.room.audio.AudioRoomManager
 import com.swago.room.audio.IAudioRoomListener
@@ -155,6 +156,11 @@ class MsgVm(application: Application) : AbsMsgVm(application) {
 
     var changeNameChangeFun:((data: ChangeNameData) -> Unit)? = null
 
+    /**
+     * 进入直播间动画
+     * */
+    var joinRoomFun:((data: UserJoinRoomBean) -> Unit)? = null
+
     val joinRoomManager by lazy {
         JoinRoomManager()
     }
@@ -174,9 +180,12 @@ class MsgVm(application: Application) : AbsMsgVm(application) {
             ) {
                 if (SwagoRoomManager.roleType == RoleType.user || it.data?.senderCode != UserInfo.getUserInfo()?.user_account) {
                     it.data?.let {
-                        newChatMsgFun?.invoke(it)
                         updateHotValue?.invoke(it.hotValue)
                         joinRoomManager.addJoinRoomData(it)
+                        joinRoomFun?.invoke(it)
+                        BitmapUtils.loadFile(AppContext.getContext() , it.androidBadgeSpecial){ bitmap ->
+                            newChatMsgFun?.invoke(it)
+                        }
                     }
                 }
             }
@@ -547,7 +556,8 @@ class MsgVm(application: Application) : AbsMsgVm(application) {
                             it.maiSeatInfo.integration,
                             it.maiSeatInfo.voiceUserId,
                             it.maiSeatInfo.maiIndex,
-                            0
+                            0,
+                            it.maiSeatInfo.head_special
                         )
                         AudioRoomManager.dispatchUpdateData(audioSeatModel)
                         UserInfo.getUserInfo()?.let { userInfoModel ->
@@ -697,6 +707,7 @@ class MsgVm(application: Application) : AbsMsgVm(application) {
                                 imGiftModel.senderAvatar = it.senderAvatar
                                 imGiftModel.isCombo = it.isCombo
                                 imGiftModel.senderCode = it.senderCode
+                                imGiftModel.androidHeadSpecial = it.androidHeadSpecial
                                 imGiftModel.receiverUserId = receiverUserId.toString()
                                 showGiftDanDao?.invoke(imGiftModel)
                             } else {

+ 3 - 0
room/src/main/java/com/swago/room/vm/RoomVm.kt

@@ -101,6 +101,9 @@ class RoomVm(application: Application) : AbsRoomVm(application) {
             requestError {
                 if (it is SwagoException) {
                     if (it.code == 504) {
+                        SpUtil.putString("hotCloseRoomed",iRoomInfo.getRoomId())
+                        SpUtil.putString("newCloseRoomed",iRoomInfo.getRoomId())
+                        SpUtil.putString("followCloseRoomed",iRoomInfo.getRoomId())
                         Toast.makeText(AppContext.getContext(), it.message, Toast.LENGTH_SHORT)
                             .show()
                         if (SwagoRoomManager.iRoomInfo == null){

+ 22 - 4
room/src/main/java/com/swago/room/widget/AnchorFooterView.kt

@@ -1,5 +1,7 @@
 package com.swago.room.widget
 
+import android.animation.ObjectAnimator
+import android.animation.ValueAnimator
 import android.content.Context
 import android.util.AttributeSet
 import android.view.LayoutInflater
@@ -35,10 +37,11 @@ class AnchorFooterView : ConstraintLayout, IFooter, IRoomActiveListener {
     var switchCameraFun:(()->Unit)? = null
     var openPKFun:(()->Unit)? = null
     var openLianMaiFun:(()->Unit)? = null
-    var clearJiFen:(()->Unit)? = null
     var openAudioNoticeDialogFun:(()->Unit)? = null
     var openGiftPanelFun:(()->Unit)? = null
+    var openLocalMusicFun:(()->Unit)? = null
     var isMute = false
+    private lateinit var rotationAnimator: ObjectAnimator
 
     constructor(context: Context) : this(context, null)
     constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
@@ -55,6 +58,12 @@ class AnchorFooterView : ConstraintLayout, IFooter, IRoomActiveListener {
         SwagoRoomManager.addListener(this)
         binding = LayoutAnchorFooterViewBinding.inflate(LayoutInflater.from(context), this, true)
 
+        rotationAnimator = ObjectAnimator.ofFloat(binding.ivAudioMusic, "rotation", 0f, 360f).apply {
+            duration = 1500
+            repeatCount = ValueAnimator.INFINITE
+            repeatMode = ValueAnimator.RESTART
+            interpolator = null // 使用线性插值器
+        }
         UserInfo.getUserInfo()?.let {
             if (it.user_type == 1&&it.user_agent_id>0){
                 binding.ivPK.visibility = View.VISIBLE
@@ -131,9 +140,9 @@ class AnchorFooterView : ConstraintLayout, IFooter, IRoomActiveListener {
             }
         })
 
-        binding.ivClearJifen.setOnClickListener(object : NoDoubleClickListener() {
+        binding.ivAudioMusic.setOnClickListener(object : NoDoubleClickListener() {
             override fun onClick() {
-                clearJiFen?.invoke()
+                openLocalMusicFun?.invoke()
             }
         })
 
@@ -166,7 +175,7 @@ class AnchorFooterView : ConstraintLayout, IFooter, IRoomActiveListener {
             binding.ivPK.visibility = View.GONE
             binding.ivLianMai.visibility = View.GONE
             binding.ivMute.visibility = View.GONE
-            binding.ivClearJifen.visibility = View.VISIBLE
+            binding.ivAudioMusic.visibility = View.VISIBLE
             binding.ivNotice.visibility = View.VISIBLE
             binding.ivGift.visibility = View.VISIBLE
         }
@@ -188,5 +197,14 @@ class AnchorFooterView : ConstraintLayout, IFooter, IRoomActiveListener {
         binding.ivDot.visibility = View.VISIBLE
     }
 
+    fun playMusicAnimator(isPlaying:Boolean){
+        binding.ivAudioMusic.post{
+            if (isPlaying){
+                rotationAnimator.start()
+            } else {
+                rotationAnimator.cancel()
+            }
+        }
+    }
 
 }

+ 21 - 0
room/src/main/java/com/swago/room/widget/ComHeaderView.kt

@@ -2,6 +2,7 @@ package com.swago.room.widget
 
 import android.content.Context
 import android.graphics.drawable.Drawable
+import android.text.TextUtils
 import android.util.AttributeSet
 import android.util.Log
 import android.util.TimeUtils
@@ -16,6 +17,9 @@ import com.bumptech.glide.load.DataSource
 import com.bumptech.glide.load.engine.GlideException
 import com.bumptech.glide.request.RequestListener
 import com.bumptech.glide.request.target.Target
+import com.opensource.svgaplayer.SVGADrawable
+import com.opensource.svgaplayer.SVGAParser
+import com.opensource.svgaplayer.SVGAVideoEntity
 import com.swago.baseswago.R
 import com.swago.baseswago.baseroom.*
 import com.swago.baseswago.constant.ARouteConstant
@@ -29,6 +33,7 @@ import com.swago.room.databinding.LayoutUserHeaderViewBinding
 import com.swago.room.dialog.AudioNoticeDialog
 import com.swago.room.dialog.AudioNoticeUserDialog
 import com.swago.room.inter.IHeader
+import java.net.URL
 
 /**
  *@date 2022/3/4 14:56
@@ -52,6 +57,7 @@ class ComHeaderView  : ConstraintLayout, IRoomActiveListener, IHeader, RoomTimer
 
     private var timeL = 0L
 
+    var svgaParser:SVGAParser? = null
     private val adapter by lazy {
         RoomUserAdapter()
     }
@@ -72,6 +78,7 @@ class ComHeaderView  : ConstraintLayout, IRoomActiveListener, IHeader, RoomTimer
         binding = LayoutUserHeaderViewBinding.inflate(LayoutInflater.from(context), this, true)
         binding.rvUser.layoutManager = LinearLayoutManager(context,RecyclerView.HORIZONTAL,false)
         binding.rvUser.adapter = adapter
+        svgaParser = SVGAParser(context)
 
         binding.tvFollow.setOnClickListener(object : NoDoubleClickListener() {
             override fun onClick() {
@@ -179,6 +186,20 @@ class ComHeaderView  : ConstraintLayout, IRoomActiveListener, IHeader, RoomTimer
                 }
             })
             .into(binding.ivAvatar)
+
+        if (iRoomInfo.getHeadSpecial().isNotEmpty()){
+            svgaParser?.decodeFromURL(URL(iRoomInfo.getHeadSpecial()), object :SVGAParser.ParseCompletion{
+                override fun onComplete(videoItem: SVGAVideoEntity) {
+                    val drawable = SVGADrawable(videoItem)
+                    binding.svgAvatar.setImageDrawable(drawable)
+                    binding.svgAvatar.startAnimation()
+                }
+
+                override fun onError() {
+                }
+            })
+        }
+
         binding.tvName.text =iRoomInfo.getAnchorName()
         binding.tvId.text = "Likes:${iRoomInfo.getLikeNum()}"
         binding.tvHot.text = iRoomInfo.getRoomHot()

+ 6 - 0
room/src/main/java/com/swago/room/widget/UserShowAnchorCloseView.kt

@@ -11,6 +11,7 @@ import com.swago.baseswago.baseroom.SwagoRoomManager
 import com.swago.baseswago.model.im.AnchorRoomClosedBean
 import com.swago.baseswago.util.AppContext
 import com.swago.baseswago.util.NoDoubleClickListener
+import com.swago.baseswago.util.SpUtil
 import com.swago.room.R
 import com.swago.room.databinding.DialogUserForAnchorCloseBinding
 import jp.wasabeef.glide.transformations.BlurTransformation
@@ -22,6 +23,7 @@ import jp.wasabeef.glide.transformations.BlurTransformation
 class UserShowAnchorCloseView : ConstraintLayout {
 
     private lateinit var binding : DialogUserForAnchorCloseBinding
+    private var anchorRoomClosedBean:AnchorRoomClosedBean?= null
 
     constructor(context: Context) : this(context, null)
     constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
@@ -37,12 +39,16 @@ class UserShowAnchorCloseView : ConstraintLayout {
         binding = DialogUserForAnchorCloseBinding.inflate(LayoutInflater.from(context), this, true)
         binding.tvBack.setOnClickListener(object : NoDoubleClickListener() {
             override fun onClick() {
+                SpUtil.putString("hotCloseRoomed",anchorRoomClosedBean?.roomId ?: "0")
+                SpUtil.putString("newCloseRoomed",anchorRoomClosedBean?.roomId ?: "0")
+                SpUtil.putString("followCloseRoomed",anchorRoomClosedBean?.roomId ?: "0")
                 SwagoRoomManager.closeRoom()
             }
         })
     }
 
     fun setData(anchorRoomClosedBean: AnchorRoomClosedBean){
+        this.anchorRoomClosedBean = anchorRoomClosedBean
         RoomTimer.clear()
         binding.tvName.text = anchorRoomClosedBean.senderName
         binding.tvID.text = AppContext.getContext().resources.getString(R.string.id_x)

+ 17 - 1
room/src/main/res/layout/dialog_footer_more.xml

@@ -56,12 +56,28 @@
         android:layout_height="40dp"/>
 
         <ImageView
-            android:id="@+id/ivMusic"
+            android:id="@+id/ivClearJifen"
             android:layout_marginStart="16dp"
             android:background="@drawable/shape_80000000_20"
             app:layout_constraintTop_toTopOf="parent"
             app:layout_constraintStart_toEndOf="@+id/ivShare"
+            android:src="@mipmap/ic_clear_jifen"
+            android:visibility="gone"
+            tools:visibility="visible"
+            android:padding="6dp"
+            android:layout_marginTop="@dimen/dp_10"
+            android:layout_width="40dp"
+            android:layout_height="40dp"/>
+
+        <ImageView
+            android:id="@+id/ivVideoMusic"
+            android:layout_marginStart="16dp"
+            android:background="@drawable/shape_80000000_20"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintStart_toEndOf="@+id/ivClearJifen"
             android:src="@mipmap/live_music"
+            android:visibility="gone"
+            tools:visibility="visible"
             android:padding="6dp"
             android:layout_marginTop="@dimen/dp_10"
             android:layout_width="40dp"

+ 10 - 2
room/src/main/res/layout/dialog_game_play.xml

@@ -1,8 +1,16 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/cl"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
+    <ImageView
+        android:id="@+id/ivBg"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintDimensionRatio="h,1:0.86"/>
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 0 - 62
room/src/main/res/layout/dialog_my_music.xml

@@ -81,68 +81,6 @@
                 app:layout_constraintBottom_toBottomOf="parent"/>
         </androidx.constraintlayout.widget.ConstraintLayout>
 
-       <androidx.constraintlayout.widget.ConstraintLayout
-           android:id="@+id/clNoContent"
-           android:layout_width="wrap_content"
-           android:layout_height="wrap_content"
-           android:visibility="gone"
-           app:layout_constraintStart_toStartOf="parent"
-           app:layout_constraintEnd_toEndOf="parent"
-           app:layout_constraintTop_toTopOf="parent"
-           app:layout_constraintBottom_toBottomOf="parent">
-           <ImageView
-               android:id="@+id/iv_empty"
-               android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               app:layout_constraintStart_toStartOf="parent"
-               app:layout_constraintEnd_toEndOf="parent"
-               app:layout_constraintTop_toTopOf="parent"
-               android:src="@mipmap/state_error_empty"/>
-           <TextView
-               android:id="@+id/tv_empty"
-               android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               app:layout_constraintStart_toStartOf="parent"
-               app:layout_constraintEnd_toEndOf="parent"
-               app:layout_constraintTop_toBottomOf="@+id/iv_empty"
-               android:layout_marginTop="16dp"
-               android:text="@string/There_is_nothing_here"
-               android:textColor="#435568"
-               android:textSize="@dimen/sp_12"/>
-
-           <androidx.constraintlayout.widget.ConstraintLayout
-               android:layout_width="146dp"
-               android:layout_height="36dp"
-               app:layout_constraintStart_toStartOf="parent"
-               app:layout_constraintEnd_toEndOf="parent"
-               app:layout_constraintTop_toBottomOf="@+id/tv_empty"
-               android:layout_marginTop="27dp"
-               android:background="@drawable/shape_9b20fc_20">
-               <ImageView
-                   android:layout_width="16dp"
-                   android:layout_height="16dp"
-                   app:layout_constraintTop_toTopOf="parent"
-                   app:layout_constraintBottom_toBottomOf="parent"
-                   android:background="@mipmap/ic_add_music"
-                   android:layout_marginEnd="@dimen/dp_4"
-                   app:layout_constraintRight_toLeftOf="@+id/tv_no_add"
-                   />
-               <TextView
-                   android:id="@+id/tv_no_add"
-                   android:layout_width="wrap_content"
-                   android:layout_height="36dp"
-                   android:gravity="center"
-                   android:text="@string/add_music"
-                   android:textColor="#fff"
-                   android:textSize="@dimen/sp_16"
-                   android:layout_marginStart="@dimen/dp_10"
-                   app:layout_constraintEnd_toEndOf="parent"
-                   app:layout_constraintStart_toStartOf="parent"
-                   app:layout_constraintBottom_toBottomOf="parent"/>
-           </androidx.constraintlayout.widget.ConstraintLayout>
-
-       </androidx.constraintlayout.widget.ConstraintLayout>
-
     </androidx.constraintlayout.widget.ConstraintLayout>
 
 

+ 30 - 8
room/src/main/res/layout/item_audio_seat.xml

@@ -6,17 +6,39 @@
     tools:background="#000"
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
-    <com.swago.baseswago.cusview.SwagoImageView
-        android:id="@+id/ivImageView"
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/clAvatar"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        android:layout_width="68dp"
-        android:layout_height="68dp"/>
+        app:layout_constraintTop_toTopOf="parent">
+        <com.swago.baseswago.cusview.SwagoImageView
+            android:id="@+id/ivImageView"
+            android:layout_width="68dp"
+            android:layout_height="68dp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"/>
+
+        <com.opensource.svgaplayer.SVGAImageView
+            android:id="@+id/svgAvatar"
+            android:layout_width="68dp"
+            android:layout_height="68dp"
+            android:visibility="invisible"
+            app:autoPlay="true"
+            app:loopCount="0"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"/>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
 
     <ImageView
         android:id="@+id/ivAudioState"
-        app:layout_constraintEnd_toEndOf="@+id/ivImageView"
-        app:layout_constraintBottom_toBottomOf="@+id/ivImageView"
+        app:layout_constraintEnd_toEndOf="@+id/clAvatar"
+        app:layout_constraintBottom_toBottomOf="@+id/clAvatar"
         android:src="@mipmap/live_mute"
         android:visibility="invisible"
         tools:visibility="visible"
@@ -34,7 +56,7 @@
         android:ellipsize="end"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/ivImageView"
+        app:layout_constraintTop_toBottomOf="@+id/clAvatar"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"/>
 

+ 33 - 9
room/src/main/res/layout/item_dialog_audience.xml

@@ -5,18 +5,42 @@
     xmlns:tools="http://schemas.android.com/tools"
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
-    <de.hdodenhof.circleimageview.CircleImageView
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/clAvatar"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintBottom_toBottomOf="parent"
-        android:layout_marginStart="16dp"
-        android:id="@+id/ivAvatar"
-        android:layout_width="50dp"
-        android:layout_height="50dp"/>
+        android:layout_marginStart="16dp">
+
+        <de.hdodenhof.circleimageview.CircleImageView
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:id="@+id/ivAvatar"
+            android:layout_width="40dp"
+            android:layout_height="40dp"/>
+
+        <com.opensource.svgaplayer.SVGAImageView
+            android:id="@+id/svgAvatar"
+            android:layout_width="50dp"
+            android:layout_height="50dp"
+            android:visibility="visible"
+            app:autoPlay="true"
+            app:loopCount="0"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"/>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+
 
     <com.swago.baseswago.cusview.MediumTextView
         android:id="@+id/tvName"
-        app:layout_constraintStart_toEndOf="@+id/ivAvatar"
+        app:layout_constraintStart_toEndOf="@+id/clAvatar"
         android:layout_marginStart="8dp"
         android:layout_marginTop="4dp"
         android:textSize="18dp"
@@ -24,15 +48,15 @@
         tools:text="Chridfsfdsfdfs"
         android:maxLines="1"
         android:maxWidth="150dp"
-        app:layout_constraintTop_toTopOf="@+id/ivAvatar"
+        app:layout_constraintTop_toTopOf="@+id/clAvatar"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"/>
 
     <com.swago.baseswago.cusview.SwagoLevelView
         android:id="@+id/tvLevel"
         android:layout_marginStart="8dp"
-        app:layout_constraintStart_toEndOf="@+id/ivAvatar"
-        app:layout_constraintBottom_toBottomOf="@+id/ivAvatar"
+        app:layout_constraintStart_toEndOf="@+id/clAvatar"
+        app:layout_constraintBottom_toBottomOf="@+id/clAvatar"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"/>
 

+ 11 - 1
room/src/main/res/layout/item_mai_user.xml

@@ -13,7 +13,17 @@
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
-
+    <com.opensource.svgaplayer.SVGAImageView
+        android:id="@+id/svgAvatar"
+        android:layout_width="38dp"
+        android:layout_height="38dp"
+        android:visibility="visible"
+        app:autoPlay="true"
+        app:loopCount="0"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"/>
     <View
         android:id="@+id/view"
         android:visibility="gone"

+ 26 - 15
room/src/main/res/layout/item_my_music.xml

@@ -6,18 +6,13 @@
     android:layout_width="match_parent"
     android:layout_height="70dp">
 
-    <com.opensource.svgaplayer.SVGAImageView
-        android:id="@+id/svgaImageView"
-        android:layout_height="18dp"
-        android:layout_width="18dp"
-        app:source="music.svga"
-        app:autoPlay="true"
-        app:loopCount="0"
-        android:visibility="invisible"
-        android:background="#fff"
-        android:layout_marginTop="-16dp"
-        android:layout_marginStart="16dp"
-        app:layout_constraintLeft_toLeftOf="parent"
+    <ImageView
+        android:id="@+id/ivPlay"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingStart="16dp"
+        android:src="@mipmap/ic_music_stop"
+        app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintBottom_toBottomOf="parent"/>
 
@@ -25,8 +20,9 @@
         android:id="@+id/tvName"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        app:layout_constraintLeft_toRightOf="@+id/svgaImageView"
-        app:layout_constraintTop_toTopOf="@+id/svgaImageView"
+        app:layout_constraintStart_toEndOf="@+id/ivPlay"
+        app:layout_constraintTop_toTopOf="parent"
+        android:layout_marginTop="16dp"
         android:layout_marginEnd="@dimen/dp_40"
         android:lines="1"
         android:maxWidth="200dp"
@@ -36,11 +32,26 @@
         android:textColor="#131b23"
         android:layout_marginStart="@dimen/dp_10"/>
 
+    <com.opensource.svgaplayer.SVGAImageView
+        android:id="@+id/svgaImageView"
+        android:layout_height="18dp"
+        android:layout_width="18dp"
+        app:source="music.svga"
+        app:autoPlay="true"
+        app:loopCount="0"
+        android:visibility="invisible"
+        android:background="#fff"
+        android:layout_marginTop="16dp"
+        android:layout_marginStart="16dp"
+        app:layout_constraintStart_toEndOf="@+id/tvName"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent"/>
+
     <com.swago.baseswago.cusview.MediumTextView
         android:id="@+id/tvDuration"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        app:layout_constraintLeft_toRightOf="@+id/svgaImageView"
+        app:layout_constraintStart_toEndOf="@+id/ivPlay"
         app:layout_constraintTop_toBottomOf="@+id/tvName"
         android:layout_marginStart="@dimen/dp_10"
         android:layout_marginTop="@dimen/dp_4"

+ 18 - 2
room/src/main/res/layout/item_room_user.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="40dp"
     android:layout_height="30dp">
 
@@ -7,7 +8,22 @@
         android:id="@+id/ivAvatar"
         android:layout_marginStart="5dp"
         android:layout_marginEnd="5dp"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"/>
+        android:layout_width="22dp"
+        android:layout_height="22dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"/>
 
+    <com.opensource.svgaplayer.SVGAImageView
+        android:id="@+id/svgAvatar"
+        android:layout_width="30dp"
+        android:layout_height="30dp"
+        android:visibility="visible"
+        app:autoPlay="true"
+        app:loopCount="0"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"/>
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 3 - 3
room/src/main/res/layout/layout_anchor_footer_view.xml

@@ -105,7 +105,7 @@
         android:layout_marginEnd="10dp"
         android:background="@drawable/shape_80000000_20"
         app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/ivClearJifen"
+        app:layout_constraintEnd_toStartOf="@+id/ivAudioMusic"
         android:src="@mipmap/live_notice"
         android:padding="7dp"
         android:visibility="gone"
@@ -114,12 +114,12 @@
         android:layout_height="40dp"/>
 
     <ImageView
-        android:id="@+id/ivClearJifen"
+        android:id="@+id/ivAudioMusic"
         android:layout_marginEnd="10dp"
         android:background="@drawable/shape_80000000_20"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintEnd_toStartOf="@+id/ivMute"
-        android:src="@mipmap/ic_clear_jifen"
+        android:src="@mipmap/live_music"
         android:padding="7dp"
         android:visibility="gone"
         tools:visibility="visible"

+ 30 - 8
room/src/main/res/layout/layout_user_header_view.xml

@@ -18,19 +18,41 @@
         android:background="@drawable/shape_20000000_41"
         android:layout_height="34dp">
 
-        <de.hdodenhof.circleimageview.CircleImageView
-            android:id="@+id/ivAvatar"
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/clAvatar"
+            android:layout_width="30dp"
+            android:layout_height="30dp"
             android:layout_marginStart="2dp"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"
-            android:layout_width="30dp"
-            android:layout_height="30dp"/>
+            app:layout_constraintBottom_toBottomOf="parent">
+
+            <de.hdodenhof.circleimageview.CircleImageView
+                android:id="@+id/ivAvatar"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                android:layout_width="22dp"
+                android:layout_height="22dp"/>
+            <com.opensource.svgaplayer.SVGAImageView
+                android:id="@+id/svgAvatar"
+                android:layout_width="30dp"
+                android:layout_height="30dp"
+                android:visibility="visible"
+                app:autoPlay="true"
+                app:loopCount="0"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"/>
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
 
         <LinearLayout
             android:id="@+id/ll"
             android:orientation="vertical"
-            app:layout_constraintStart_toEndOf="@+id/ivAvatar"
+            app:layout_constraintStart_toEndOf="@+id/clAvatar"
             android:layout_width="wrap_content"
             android:layout_height="match_parent">
 
@@ -45,7 +67,7 @@
                 android:maxLines="1"
                 android:maxWidth="120dp"
                 app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintStart_toEndOf="@+id/ivAvatar"
+                app:layout_constraintStart_toEndOf="@+id/clAvatar"
                 tools:text="NickNamed"
                 app:layout_constraintHorizontal_bias="0"
                 android:layout_width="wrap_content"
@@ -61,7 +83,7 @@
                 android:layout_marginEnd="8dp"
                 android:maxWidth="120dp"
                 app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintStart_toEndOf="@+id/ivAvatar"
+                app:layout_constraintStart_toEndOf="@+id/clAvatar"
                 app:layout_constraintHorizontal_bias="0"
                 tools:text="ID:dddddddddd"
                 android:maxLines="1"

+ 31 - 10
room/src/main/res/layout/view_item_gift.xml

@@ -38,17 +38,38 @@
             android:layout_width="283dp"
             android:layout_height="60dp"/>
 
-        <de.hdodenhof.circleimageview.CircleImageView
-            android:id="@+id/ivAvatar"
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/clAvatar"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:layout_marginStart="12dp"
             android:layout_marginTop="2dp"
             android:layout_marginBottom="2dp"
-            android:src="@mipmap/default_avatar"
             app:layout_constraintTop_toTopOf="parent"
             app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            android:layout_width="36dp"
-            android:layout_height="36dp"/>
+            app:layout_constraintStart_toStartOf="parent">
+            <de.hdodenhof.circleimageview.CircleImageView
+                android:id="@+id/ivAvatar"
+                android:src="@mipmap/default_avatar"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                android:layout_width="30dp"
+                android:layout_height="30dp"/>
+
+            <com.opensource.svgaplayer.SVGAImageView
+                android:id="@+id/svgAvatar"
+                android:layout_width="36dp"
+                android:layout_height="36dp"
+                android:visibility="visible"
+                app:autoPlay="true"
+                app:loopCount="0"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"/>
+        </androidx.constraintlayout.widget.ConstraintLayout>
 
         <TextView
             android:id="@+id/tvSenderName"
@@ -60,9 +81,9 @@
             android:scrollHorizontally="true"
             android:singleLine="true"
             android:layout_marginStart="5dp"
-            app:layout_constraintStart_toEndOf="@+id/ivAvatar"
+            app:layout_constraintStart_toEndOf="@+id/clAvatar"
             android:layout_marginTop="2dp"
-            app:layout_constraintTop_toTopOf="@+id/ivAvatar"
+            app:layout_constraintTop_toTopOf="@+id/clAvatar"
             android:layout_width="80dp"
             android:layout_height="wrap_content"/>
 
@@ -77,9 +98,9 @@
             android:scrollHorizontally="true"
             android:singleLine="true"
             android:layout_marginStart="5dp"
-            app:layout_constraintStart_toEndOf="@+id/ivAvatar"
+            app:layout_constraintStart_toEndOf="@+id/clAvatar"
             android:layout_marginBottom="2dp"
-            app:layout_constraintBottom_toBottomOf="@+id/ivAvatar"
+            app:layout_constraintBottom_toBottomOf="@+id/clAvatar"
             android:layout_width="80dp"
             android:layout_height="wrap_content"/>
 

+ 11 - 1
room/src/main/res/layout/view_user_join_room.xml

@@ -85,7 +85,17 @@
                 android:layout_width="36dp"
                 android:layout_height="36dp"/>
 
-
+            <com.opensource.svgaplayer.SVGAImageView
+                android:id="@+id/svgAvatar"
+                android:layout_width="44dp"
+                android:layout_height="44dp"
+                android:visibility="invisible"
+                app:autoPlay="true"
+                app:loopCount="0"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                android:layout_marginStart="8dp"/>
             <com.swago.baseswago.cusview.SwagoLevelView
                 android:id="@+id/swagoLevel"
                 android:layout_marginStart="5dp"

binární
room/src/main/res/mipmap-xxhdpi/bg_food_wheel.png


binární
room/src/main/res/mipmap-xxhdpi/bg_frenzy_vagas.png


binární
room/src/main/res/mipmap-xxhdpi/bg_fruit_party.png


binární
room/src/main/res/mipmap-xxhdpi/bg_lucky_piggy.png


binární
room/src/main/res/mipmap-xxhdpi/bg_magical_piggy.png


binární
room/src/main/res/mipmap-xxhdpi/bg_three_card.png


binární
room/src/main/res/mipmap-xxhdpi/bg_three_card_duel.png


binární
room/src/main/res/mipmap-xxhdpi/bg_tigers.jpg


binární
room/src/main/res/mipmap-xxhdpi/ic_music_play.png


binární
room/src/main/res/mipmap-xxhdpi/ic_music_stop.png


+ 17 - 0
tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/chat/base/ChatManagerKit.java

@@ -6,6 +6,8 @@ import android.os.Message;
 import android.text.TextUtils;
 
 import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.swago.baseswago.util.UserInfo;
 import com.tencent.imsdk.BaseConstants;
 import com.tencent.imsdk.v2.V2TIMAdvancedMsgListener;
 import com.tencent.imsdk.v2.V2TIMCallback;
@@ -42,6 +44,9 @@ import java.util.List;
 
 import static com.tencent.imsdk.v2.V2TIMMessage.V2TIM_MSG_STATUS_SEND_FAIL;
 
+import org.json.JSONException;
+import org.json.JSONObject;
+
 public abstract class ChatManagerKit extends V2TIMAdvancedMsgListener implements MessageRevokedManager.MessageRevokeHandler, IBaseMessageSender {
     private static final String TAG = ChatManagerKit.class.getSimpleName();
 
@@ -472,6 +477,18 @@ public abstract class ChatManagerKit extends V2TIMAdvancedMsgListener implements
         }
 
         v2TIMMessage.setExcludedFromLastMessage(TUIKitConfigs.getConfigs().getGeneralConfig().isExcludedFromLastMessage());
+        if (!TextUtils.isEmpty(UserInfo.INSTANCE.getUserInfo().getAndroid_chat_special())){
+            V2TIMCustomElem elem = new V2TIMCustomElem();
+            JSONObject jsonObject = new JSONObject();
+            try {
+                jsonObject.put("android_chat_special", UserInfo.INSTANCE.getUserInfo().getAndroid_chat_special());
+                jsonObject.put("ios_chat_special", UserInfo.INSTANCE.getUserInfo().getIos_chat_special());
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+            elem.setData(jsonObject.toString().getBytes());
+            v2TIMMessage.getTextElem().appendElem(elem);
+        }
 
         String msgID = V2TIMManager.getMessageManager().sendMessage(v2TIMMessage, isGroup ? null : userID, isGroup ? groupID : null,
                 V2TIMMessage.V2TIM_PRIORITY_DEFAULT, false, v2TIMOfflinePushInfo, new V2TIMSendCallback<V2TIMMessage>() {

+ 30 - 0
tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/chat/interfaces/IMessageProperties.java

@@ -2,6 +2,8 @@ package com.tencent.qcloud.tim.uikit.modules.chat.interfaces;
 
 import android.graphics.drawable.Drawable;
 
+import com.opensource.svgaplayer.SVGAVideoEntity;
+
 public interface IMessageProperties {
 
     /// @name 设置头像
@@ -278,4 +280,32 @@ public interface IMessageProperties {
      * @param color
      */
     void setTipsMessageFontColor(int color);
+
+    /**
+     * 获取右边头像框
+     *
+     * @return
+     */
+    SVGAVideoEntity getRightSvgaAvatar();
+
+    /**
+     * 设置右边头像框
+     *
+     * @param drawable
+     */
+    void setRightSvgaAvatar(SVGAVideoEntity drawable);
+
+    /**
+     * 获取左边头像框
+     *
+     * @return
+     */
+    SVGAVideoEntity getLeftSvgaAvatar();
+
+    /**
+     * 设置左边头像框
+     *
+     * @param drawable
+     */
+    void setLeftSvgaAvatar(SVGAVideoEntity drawable);
 }

+ 42 - 0
tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/chat/layout/message/MessageLayoutUI.java

@@ -9,6 +9,7 @@ import androidx.recyclerview.widget.RecyclerView;
 
 import android.util.AttributeSet;
 
+import com.opensource.svgaplayer.SVGAVideoEntity;
 import com.tencent.qcloud.tim.uikit.component.CustomLinearLayoutManager;
 import com.tencent.qcloud.tim.uikit.component.action.PopMenuAction;
 import com.tencent.qcloud.tim.uikit.modules.chat.interfaces.IMessageLayout;
@@ -104,6 +105,26 @@ public abstract class MessageLayoutUI extends RecyclerView implements IMessageLa
         properties.setLeftBubble(bubble);
     }
 
+    @Override
+    public SVGAVideoEntity getRightSvgaAvatar() {
+        return properties.getRightSvgaAvatar();
+    }
+
+    @Override
+    public void setRightSvgaAvatar(SVGAVideoEntity drawable) {
+        properties.setRightSvgaAvatar(drawable);
+    }
+
+    @Override
+    public SVGAVideoEntity getLeftSvgaAvatar() {
+        return properties.getLeftSvgaAvatar();
+    }
+
+    @Override
+    public void setLeftSvgaAvatar(SVGAVideoEntity drawable) {
+        properties.setLeftSvgaAvatar(drawable);
+    }
+
     @Override
     public int getNameFontSize() {
         return properties.getNameFontSize();
@@ -285,6 +306,8 @@ public abstract class MessageLayoutUI extends RecyclerView implements IMessageLa
         private int mChatTimeFontSize;
         private int mChatTimeFontColor;
         private Drawable mChatTimeBubble;
+        private SVGAVideoEntity mMySvgaAvatar;
+        private SVGAVideoEntity mFriendSvgaAvatar;
 
         private Properties() {
 
@@ -481,5 +504,24 @@ public abstract class MessageLayoutUI extends RecyclerView implements IMessageLa
             this.mChatTimeFontColor = color;
         }
 
+        @Override
+        public SVGAVideoEntity getRightSvgaAvatar() {
+            return mMySvgaAvatar;
+        }
+
+        @Override
+        public void setRightSvgaAvatar(SVGAVideoEntity drawable) {
+            this.mMySvgaAvatar = drawable;
+        }
+
+        @Override
+        public SVGAVideoEntity getLeftSvgaAvatar() {
+            return mFriendSvgaAvatar;
+        }
+
+        @Override
+        public void setLeftSvgaAvatar(SVGAVideoEntity drawable) {
+            this.mFriendSvgaAvatar = drawable;
+        }
     }
 }

+ 51 - 9
tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/chat/layout/message/holder/MessageContentHolder.java

@@ -1,5 +1,6 @@
 package com.tencent.qcloud.tim.uikit.modules.chat.layout.message.holder;
 
+import android.graphics.drawable.NinePatchDrawable;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Gravity;
@@ -10,19 +11,34 @@ import android.widget.ProgressBar;
 import android.widget.TextView;
 
 import com.bumptech.glide.Glide;
+import com.opensource.svgaplayer.SVGADrawable;
+import com.opensource.svgaplayer.SVGAImageView;
 import com.swago.baseswago.util.AppContext;
+import com.swago.baseswago.util.DianJiuUtil;
+import com.swago.baseswago.util.StringUtils;
 import com.swago.baseswago.util.UserInfo;
+import com.tencent.imsdk.message.CustomElement;
+import com.tencent.imsdk.v2.V2TIMCustomElem;
 import com.tencent.imsdk.v2.V2TIMMessage;
 import com.tencent.qcloud.tim.uikit.R;
 import com.tencent.qcloud.tim.uikit.config.TUIKitConfigs;
 import com.tencent.qcloud.tim.uikit.modules.message.MessageInfo;
+import com.tencent.qcloud.tim.uikit.utils.ToastUtil;
+
+import org.json.JSONObject;
+
+import java.util.List;
 
 import de.hdodenhof.circleimageview.CircleImageView;
+import kotlin.Unit;
+import kotlin.jvm.functions.Function1;
 
 public abstract class MessageContentHolder extends MessageEmptyHolder {
 
     public CircleImageView leftUserIcon;
+    public SVGAImageView leftSvgaImage;
     public CircleImageView rightUserIcon;
+    public SVGAImageView rightSvgaImage;
     public TextView usernameText;
     public LinearLayout msgContentLinear;
     public ProgressBar sendingProgress;
@@ -36,6 +52,8 @@ public abstract class MessageContentHolder extends MessageEmptyHolder {
 
         leftUserIcon = itemView.findViewById(R.id.left_user_icon_view);
         rightUserIcon = itemView.findViewById(R.id.right_user_icon_view);
+        leftSvgaImage = itemView.findViewById(R.id.svgAvatar_left);
+        rightSvgaImage = itemView.findViewById(R.id.svgAvatar_right);
         usernameText = itemView.findViewById(R.id.user_name_tv);
         msgContentLinear = itemView.findViewById(R.id.msg_content_ll);
         statusImage = itemView.findViewById(R.id.message_status_iv);
@@ -114,20 +132,44 @@ public abstract class MessageContentHolder extends MessageEmptyHolder {
             sendingProgress.setVisibility(View.GONE);
         }
 
+        String customElem = msg.getTimMessage().toString();
+        List<JSONObject> customEle = StringUtils.INSTANCE.extractJsonObjects(customElem);
+        if (!customEle.isEmpty()){
+            String android_chat_special = customEle.get(0).optString("android_chat_special");
+            DianJiuUtil.INSTANCE.loadDian9Tu(AppContext.getContext(), android_chat_special, new Function1<NinePatchDrawable, Unit>() {
+                @Override
+                public Unit invoke(NinePatchDrawable ninePatchDrawable) {
+                    if (ninePatchDrawable != null){
+                        msgContentLinear.setBackground(ninePatchDrawable);
+                    }
+                    return null;
+                }
+            });
+        } else {
+            if (msg.isSelf()){
+                msgContentLinear.setBackgroundResource(R.drawable.bg_chat_purple);
+            } else {
+                msgContentLinear.setBackgroundResource(R.drawable.bg_chat_white);
+            }
+        }
+
         //// 聊天气泡设置
         if (msg.isSelf()) {
-            if (properties.getRightBubble() != null && properties.getRightBubble().getConstantState() != null) {
-                msgContentFrame.setBackground(properties.getRightBubble().getConstantState().newDrawable());
-            } else {
-                msgContentFrame.setBackgroundResource(R.drawable.chat_bubble_myself);
+            if (properties.getRightSvgaAvatar() != null){
+                SVGADrawable drawable = new SVGADrawable(properties.getRightSvgaAvatar());
+                rightSvgaImage.setVisibility(View.VISIBLE);
+                rightSvgaImage.setImageDrawable(drawable);
+                rightSvgaImage.startAnimation();
             }
+            leftSvgaImage.setVisibility(View.INVISIBLE);
         } else {
-            if (properties.getLeftBubble() != null && properties.getLeftBubble().getConstantState() != null) {
-                msgContentFrame.setBackground(properties.getLeftBubble().getConstantState().newDrawable());
-                msgContentFrame.setLayoutParams(msgContentFrame.getLayoutParams());
-            } else {
-                msgContentFrame.setBackgroundResource(R.drawable.chat_other_bg);
+            if (properties.getLeftSvgaAvatar() != null){
+                SVGADrawable drawable = new SVGADrawable(properties.getLeftSvgaAvatar());
+                leftSvgaImage.setVisibility(View.VISIBLE);
+                leftSvgaImage.setImageDrawable(drawable);
+                leftSvgaImage.startAnimation();
             }
+            rightSvgaImage.setVisibility(View.INVISIBLE);
         }
 
         //// 聊天气泡的点击事件处理

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů