9 Commity 419ce5c3dd ... 203f94e779

Autor SHA1 Wiadomość Data
  tongmengxiao 203f94e779 feat: android ios chat 4 miesięcy temu
  tongmengxiao fd36dceac8 feat:私聊背景图 4 miesięcy temu
  tongmengxiao bed8a4cbab feat: delete toastutils 4 miesięcy temu
  tongmengxiao 62b2697e8c feat: 聊天气泡 4 miesięcy temu
  tongmengxiao c03be2b9fb feat: home refresh 4 miesięcy temu
  tongmengxiao 9a01c6d64d feat: 头像框 4 miesięcy temu
  tongmengxiao b74ae9f34c feat: home refresh 4 miesięcy temu
  tongmengxiao 2d67f4aea7 feat: 分辨率 4 miesięcy temu
  tongmengxiao f5bf0641c6 feat : 头像 4 miesięcy temu
65 zmienionych plików z 959 dodań i 200 usunięć
  1. 33 10
      baseswago/src/main/java/com/swago/baseswago/PersonDataDFragment.kt
  2. 0 2
      baseswago/src/main/java/com/swago/baseswago/UserVm.kt
  3. 1 1
      baseswago/src/main/java/com/swago/baseswago/agora/AgoraManager.kt
  4. 5 0
      baseswago/src/main/java/com/swago/baseswago/baseroom/IRoomInfo.kt
  5. 44 0
      baseswago/src/main/java/com/swago/baseswago/model/MomentModel.java
  6. 29 20
      baseswago/src/main/java/com/swago/baseswago/model/UserInfoModel.java
  7. 3 0
      baseswago/src/main/java/com/swago/baseswago/model/im/RoomChatMsgBean.java
  8. 4 0
      baseswago/src/main/java/com/swago/baseswago/model/im/UserJoinRoomBean.java
  9. 37 0
      baseswago/src/main/java/com/swago/baseswago/model/live/RoomModel.java
  10. 27 1
      baseswago/src/main/java/com/swago/baseswago/model/live/RoomUserModel.java
  11. 5 2
      baseswago/src/main/java/com/swago/baseswago/model/live/audio/AudioSeatModel.kt
  12. 1 0
      baseswago/src/main/java/com/swago/baseswago/model/live/audio/IMAudioModel.kt
  13. 2 1
      baseswago/src/main/java/com/swago/baseswago/model/live/audio/IMAudioSeatUpdateModel.kt
  14. 1 0
      baseswago/src/main/java/com/swago/baseswago/model/live/audio/MaiUserModel.kt
  15. 44 47
      baseswago/src/main/java/com/swago/baseswago/util/BitmapUtils.kt
  16. 12 11
      baseswago/src/main/java/com/swago/baseswago/util/DianJiuUtil.kt
  17. 10 0
      baseswago/src/main/java/com/swago/glide.kt
  18. 0 1
      baseswago/src/main/res/layout/dialog_person_data.xml
  19. BIN
      baseswago/src/main/res/mipmap-xxhdpi/bg_chat_purple.9.png
  20. BIN
      baseswago/src/main/res/mipmap-xxhdpi/bg_chat_white.9.png
  21. 9 0
      baseswago/src/main/res/values-ar/strings.xml
  22. 9 0
      baseswago/src/main/res/values-in/strings.xml
  23. 9 0
      baseswago/src/main/res/values-ms/strings.xml
  24. 9 0
      baseswago/src/main/res/values-zh/strings.xml
  25. 9 0
      baseswago/src/main/res/values/strings.xml
  26. 64 19
      home/src/main/java/com/swago/home/ChatDetailActivity.kt
  27. 21 2
      home/src/main/java/com/swago/home/MineFragment.kt
  28. 7 2
      home/src/main/java/com/swago/home/innerhome/FollowFragment.kt
  29. 7 2
      home/src/main/java/com/swago/home/innerhome/HotFragment.kt
  30. 7 2
      home/src/main/java/com/swago/home/innerhome/NewFragment.kt
  31. 0 1
      home/src/main/res/layout/fragment_mine.xml
  32. 25 0
      room/src/main/java/com/swago/room/adapter/AudienceAdapter.kt
  33. 53 28
      room/src/main/java/com/swago/room/adapter/RoomChatAdapter.kt
  34. 25 1
      room/src/main/java/com/swago/room/adapter/RoomUserAdapter.kt
  35. 23 1
      room/src/main/java/com/swago/room/audio/AudioSeatAdapter.kt
  36. 28 0
      room/src/main/java/com/swago/room/bean/UserRoomModel.kt
  37. 12 2
      room/src/main/java/com/swago/room/dialog/SendMsgDialog.kt
  38. 22 0
      room/src/main/java/com/swago/room/gift/audio/MaiUserAdapter.kt
  39. 42 0
      room/src/main/java/com/swago/room/gift/control/XSvgPlayer.kt
  40. 6 0
      room/src/main/java/com/swago/room/hongbao/RedEnvelopResultDialog.kt
  41. 27 0
      room/src/main/java/com/swago/room/manager/JoinRoomManager.kt
  42. 1 0
      room/src/main/java/com/swago/room/user/UserRoomFragment.kt
  43. 6 2
      room/src/main/java/com/swago/room/vm/MsgVm.kt
  44. 3 0
      room/src/main/java/com/swago/room/vm/RoomVm.kt
  45. 21 0
      room/src/main/java/com/swago/room/widget/ComHeaderView.kt
  46. 6 0
      room/src/main/java/com/swago/room/widget/UserShowAnchorCloseView.kt
  47. 0 1
      room/src/main/res/layout/item_audio_seat.xml
  48. 0 1
      room/src/main/res/layout/item_dialog_audience.xml
  49. 11 1
      room/src/main/res/layout/item_mai_user.xml
  50. 0 1
      room/src/main/res/layout/item_room_user.xml
  51. 0 1
      room/src/main/res/layout/layout_user_header_view.xml
  52. 11 1
      room/src/main/res/layout/view_user_join_room.xml
  53. 28 0
      tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/chat/interfaces/IMessageProperties.java
  54. 41 0
      tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/chat/layout/message/MessageLayoutUI.java
  55. 14 0
      tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/chat/layout/message/holder/MessageContentHolder.java
  56. 3 0
      tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/conversation/holder/ConversationCommonHolder.java
  57. 21 1
      tuikit/src/main/res/layout/conversation_adapter.xml
  58. 19 0
      tuikit/src/main/res/layout/forward_message_adapter_item_content.xml
  59. 3 3
      tuikit/src/main/res/layout/message_adapter_content_text.xml
  60. 26 5
      tuikit/src/main/res/layout/message_adapter_item_content.xml
  61. 23 5
      user/src/main/java/com/swago/user/store/StoreBuyDialog.kt
  62. 32 12
      user/src/main/java/com/swago/user/store/StoreListActivity.kt
  63. 8 0
      user/src/main/java/com/swago/user/vm/StoreVm.kt
  64. 8 8
      user/src/main/res/layout/activity_store_list.xml
  65. 2 2
      user/src/main/res/layout/dialog_store_detail.xml

+ 33 - 10
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
@@ -21,6 +24,9 @@ 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
@@ -45,8 +51,8 @@ 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
-    private val badgeBitmap by lazy {
-        BitmapUtils.getBitmapFromPath(UserInfo.getUserInfo()?.badge_special)
+    val svgaParser by lazy {
+        SVGAParser(activity)
     }
 
     companion object{
@@ -121,7 +127,7 @@ 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())
                                     dismissAllowingStateLoss()
                                 } else {
                                     Toast.makeText(
@@ -239,15 +245,32 @@ class PersonDataDFragment : BaseXDFragment<DialogPersonDataBinding>() {
             }
 
             isAdmin = it.is_room_admin == 1
-        }
 
-        if (badgeBitmap == null){
-            binding.ivBadge.visibility = View.GONE
-        } else {
-            binding.ivBadge.setImageBitmap(badgeBitmap)
-            binding.ivBadge.visibility = View.VISIBLE
-        }
+            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

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

@@ -46,8 +46,6 @@ class UserVm(application: Application) : BaseViewModel(application) {
         requestData {
             val data = ApiManager.userApi.getUserInfo()
             userInfoLiveData.value = data
-            BitmapUtils.loadFile(AppContext.getContext() , data.badge_special)
-            BitmapUtils.loadFile(AppContext.getContext() , data.chat_special)
         }
     }
 

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

@@ -245,7 +245,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(

+ 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 //聊天气泡
 }

+ 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;
+    }
 }

+ 29 - 20
baseswago/src/main/java/com/swago/baseswago/model/UserInfoModel.java

@@ -98,10 +98,11 @@ public class UserInfoModel {
      * 是否充值用户
      */
     private int is_recharge;
-    private String join_special;
-    private String head_special;
-    private String badge_special;
-    private String chat_special;
+    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;
@@ -399,35 +400,43 @@ public class UserInfoModel {
         this.is_recharge = is_recharge;
     }
 
-    public String getJoin_special() {
-        return join_special;
+    public String getAndroid_join_special() {
+        return android_join_special;
     }
 
-    public void setJoin_special(String join_special) {
-        this.join_special = join_special;
+    public void setAndroid_join_special(String android_join_special) {
+        this.android_join_special = android_join_special;
     }
 
-    public String getHead_special() {
-        return head_special;
+    public String getAndroid_head_special() {
+        return android_head_special;
     }
 
-    public void setHead_special(String head_special) {
-        this.head_special = head_special;
+    public void setAndroid_head_special(String android_head_special) {
+        this.android_head_special = android_head_special;
     }
 
-    public String getBadge_special() {
-        return badge_special;
+    public String getAndroid_badge_special() {
+        return android_badge_special;
     }
 
-    public void setBadge_special(String badge_special) {
-        this.badge_special = badge_special;
+    public void setAndroid_badge_special(String android_badge_special) {
+        this.android_badge_special = android_badge_special;
     }
 
-    public String getChat_special() {
-        return chat_special;
+    public String getAndroid_chat_special() {
+        return android_chat_special;
     }
 
-    public void setChat_special(String chat_special) {
-        this.chat_special = 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;

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

@@ -29,6 +29,10 @@ 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 iosChatSpecial="";
 
     @NonNull
     @Override

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

@@ -55,6 +55,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() {
@@ -280,4 +285,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 {

+ 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?=""
 )

+ 44 - 47
baseswago/src/main/java/com/swago/baseswago/util/BitmapUtils.kt

@@ -5,42 +5,65 @@ 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 com.swago.baseswago.inter.ApiManager
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
 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()){
 
-    fun getBitmapFromPath(url:String?):Bitmap?{
-            val path = "${AppContext.getContext().getExternalFilesDir(null)!!.path}/swagoFile"
-            val pathFile = File("$path/${url?.substring(url.lastIndexOf("/"))}")
-            return if (pathFile.exists()) {
-                BitmapFactory.decodeFile(pathFile.absolutePath)
-            } else {
-                null
-            }
-
-    }
-
-    fun loadFile(context: Context, url: String) {
-        if (context is Activity){
-            if (context.isDestroyed)
-                return
+            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>?) {
-                    val pathFile = File("${UrlConstant.specialResourcePath}/${url.substring(url.lastIndexOf("/"))}")
+                    resource.density = 480
                     var outputStream: FileOutputStream? = null
                     try {
                         outputStream = FileOutputStream(pathFile)
@@ -51,6 +74,7 @@ object BitmapUtils {
                     } finally {
                         outputStream?.close()
                     }
+                    response?.invoke(resource.apply { density = 480 })
                 }
 
                 override fun onLoadCleared(placeholder: Drawable?) {
@@ -58,31 +82,4 @@ object BitmapUtils {
                 }
             })
     }
-
-     fun downLoadLottie(downloadUrl: String, name: String) {
-         val pathFile = File(UrlConstant.specialResourcePath)
-         pathFile.mkdirs()
-        GlobalScope.launch {
-            try {
-                val responseBody = ApiManager.homeApi.downFile(downloadUrl)
-                dowload(AppContext.getContext(), responseBody) {
-                    hasSelfPath = {
-                        UrlConstant.specialResourcePath
-                    }
-                    setFileName = {
-                        File.separator + name
-                    }
-                    success {
-                        LogUtil.d("资源","下载成功")
-                    }
-                    error {
-                        LogUtil.d("资源","下载失败")
-                    }
-
-                }.startDowload()
-            } catch (e: Exception) {
-                LogUtil.d("资源","下载失败")
-            }
-        }
-    }
 }

+ 12 - 11
baseswago/src/main/java/com/swago/baseswago/util/DianJiuUtil.kt

@@ -3,29 +3,29 @@ 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.widget.Toast
 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.FileOutputStream
-import java.io.IOException
+import java.io.FileInputStream
 
 object DianJiuUtil {
-    fun loadDian9Tu(context: Context, url: String, drawable: (e: Drawable?) -> Unit){
+    fun loadDian9Tu(context: Context, url: String, drawable: (e: NinePatchDrawable?) -> Unit){
         if (context is Activity){
             if (context.isDestroyed)
                 return
         }
         Glide.with(context)
-            .asBitmap()
+            .asFile()
             .load(url)
-            .into(object : CustomTarget<Bitmap>() {
-                override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
-                    drawable.invoke(setNinePatchImage(context , resource))
+            .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?) {
@@ -34,11 +34,12 @@ object DianJiuUtil {
             })
     }
 
-    fun setNinePatchImage(context: Context, bitmap: Bitmap): NinePatchDrawable? {
+    fun ninePatchImageDrawable(context: Context, bitmap: Bitmap, drawable: (e: NinePatchDrawable?) -> Unit) {
+        bitmap.density = 480
         val chunk = bitmap.ninePatchChunk
         if (NinePatch.isNinePatchChunk(chunk)){
-            return NinePatchDrawable(context.resources,bitmap,chunk,NinePatchChunk.deserialize(chunk)?.mPaddings,null)
+            drawable.invoke(NinePatchDrawable(context.resources,bitmap,chunk,NinePatchChunk.deserialize(chunk)?.mPaddings,null))
         }
-        return null
+        drawable.invoke(null)
     }
 }

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

@@ -8,6 +8,7 @@ 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.swago.baseswago.R
 import jp.wasabeef.glide.transformations.BlurTransformation
@@ -35,6 +36,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)

+ 0 - 1
baseswago/src/main/res/layout/dialog_person_data.xml

@@ -362,7 +362,6 @@
                 android:layout_width="80dp"
                 android:layout_height="80dp"
                 android:visibility="visible"
-                app:source="avatar.svga"
                 app:autoPlay="true"
                 app:loopCount="0"
                 app:layout_constraintStart_toStartOf="parent"

BIN
baseswago/src/main/res/mipmap-xxhdpi/bg_chat_purple.9.png


BIN
baseswago/src/main/res/mipmap-xxhdpi/bg_chat_white.9.png


+ 9 - 0
baseswago/src/main/res/values-ar/strings.xml

@@ -313,4 +313,13 @@
     <string name="dress_up">إرتد ملابس</string>
     <string name="mall">مجمع تجاري</string>
     <string name="buy_it_now">اشتر الآن</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>
 </resources>

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

@@ -317,4 +317,13 @@
     <string name="dress_up">Berpakaian</string>
     <string name="mall">Toko</string>
     <string name="buy_it_now">Beli sekarang</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>
 </resources>

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

@@ -314,4 +314,13 @@
     <string name="dress_up">Berpakaian</string>
     <string name="mall">Toko</string>
     <string name="buy_it_now">Beli sekarang</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>
 </resources>

+ 9 - 0
baseswago/src/main/res/values-zh/strings.xml

@@ -313,4 +313,13 @@
     <string name="dress_up">装扮</string>
     <string name="mall">商城</string>
     <string name="buy_it_now">立即购买</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>
 </resources>

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

@@ -335,4 +335,13 @@
     <string name="dress_up">Dress up</string>
     <string name="mall">Mall</string>
     <string name="buy_it_now">Buy it now</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>
 </resources>

+ 64 - 19
home/src/main/java/com/swago/home/ChatDetailActivity.kt

@@ -1,11 +1,7 @@
 package com.swago.home
 
-import android.graphics.BitmapFactory
-import android.graphics.NinePatch
-import android.graphics.drawable.BitmapDrawable
-import android.graphics.drawable.Drawable
-import android.graphics.drawable.NinePatchDrawable
 import android.os.Bundle
+import android.text.TextUtils
 import android.view.View
 import androidx.activity.viewModels
 import androidx.core.content.ContextCompat
@@ -14,14 +10,15 @@ 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.activity.BaseXActivity
 import com.swago.baseswago.constant.ARouteConstant
 import com.swago.baseswago.dialog.ReportBlockDialogFragment
-import com.swago.baseswago.util.AppContext
 import com.swago.baseswago.util.DianJiuUtil
-import com.swago.baseswago.util.NinePatchChunk
 import com.swago.baseswago.util.NoDoubleClickListener
 import com.swago.baseswago.util.SpUtil
 import com.swago.baseswago.util.UserInfo
@@ -30,7 +27,8 @@ import com.tencent.imsdk.v2.V2TIMConversation
 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 java.io.FileInputStream
+import com.tencent.qcloud.tim.uikit.utils.ToastUtil
+import java.net.URL
 
 
 /**
@@ -49,6 +47,7 @@ class ChatDetailActivity  : BaseXActivity<ActivityChatDetailBinding>() {
     @JvmField
     var chatName: String = ""
 
+    private var svgaParser:SVGAParser? = null
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -66,6 +65,10 @@ class ChatDetailActivity  : BaseXActivity<ActivityChatDetailBinding>() {
     override fun initOther() {
         ARouter.getInstance().inject(this)
 
+        svgaParser = SVGAParser(this)
+        if (!TextUtils.isEmpty(account)){
+            userVm.getOtherUserInfo(account,"")
+        }
         val chatInfo = ChatInfo()
         chatInfo.type = V2TIMConversation.V2TIM_C2C
         chatInfo.chatName = chatName
@@ -90,7 +93,7 @@ class ChatDetailActivity  : BaseXActivity<ActivityChatDetailBinding>() {
         }
 
         val messageRecyclerView = binding.chatLayout.messageLayout
-        messageRecyclerView.setOnItemClickListener(object : MessageLayout.OnItemLongClickListener{
+        messageRecyclerView?.setOnItemClickListener(object : MessageLayout.OnItemLongClickListener{
             override fun onMessageLongClick(view: View?, position: Int, messageInfo: MessageInfo?) {
 
             }
@@ -119,18 +122,56 @@ class ChatDetailActivity  : BaseXActivity<ActivityChatDetailBinding>() {
 
             }
         })
-//        val path = "${AppContext.getContext().getExternalFilesDir(null)!!.path}/swagoFile/mmexport1718256766828.png"
-//        val bitmap = BitmapFactory.decodeStream(FileInputStream(path))
-//        val chunk = bitmap.ninePatchChunk
-//        if (NinePatch.isNinePatchChunk(chunk)){
-//            val patchy = NinePatchDrawable(resources,bitmap,chunk,NinePatchChunk.deserialize(chunk)?.mPaddings,null)
-//            messageRecyclerView.rightBubble = patchy
-//        }
-//        DianJiuUtil.loadDian9Tu(this ,"https://apple-1304432552.cos.ap-shanghai.myqcloud.com/android.png") {
-//            messageRecyclerView.rightBubble = it
-//        }
 
+        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
+                    }
+                }
+            }
+        } else {
+            messageRecyclerView?.rightBubble = ContextCompat.getDrawable(this ,R.mipmap.bg_chat_purple)
+        }
+
+        userVm.otherUserInfoLiveData.observe(this){
+            if (TextUtils.isEmpty(it.android_chat_special)){
+                messageRecyclerView?.leftBubble = ContextCompat.getDrawable(this ,R.mipmap.bg_chat_white)
+            } else {
+                DianJiuUtil.loadDian9Tu(this ,it.android_chat_special ){ drawable ->
+                    drawable?.let {
+                        messageRecyclerView?.leftBubble = it
+                    }
+                }
+            }
+            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)
+                        messageRecyclerView?.leftSvgaAvatar = drawable
+                    }
+
+                    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) {
+                        val drawable = SVGADrawable(videoItem)
+                        messageRecyclerView?.rightSvgaAvatar = drawable
+                    }
+
+                    override fun onError() {
+                    }
+                })
+            }
+        }
     }
 
     override fun initLiveData() {
@@ -142,5 +183,9 @@ class ChatDetailActivity  : BaseXActivity<ActivityChatDetailBinding>() {
         userVm.getUserInfo()
     }
 
+    override fun onDestroy() {
+        super.onDestroy()
+
+    }
 
 }

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

@@ -5,6 +5,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.fragment.BaseXFragment
 import com.swago.baseswago.model.ConfigModel
 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 viewModels<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{
@@ -210,6 +216,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
     }

+ 0 - 1
home/src/main/res/layout/fragment_mine.xml

@@ -60,7 +60,6 @@
             android:layout_width="50dp"
             android:layout_height="50dp"
             android:visibility="visible"
-            app:source="avatar.svga"
             app:autoPlay="true"
             app:loopCount="0"
             app:layout_constraintStart_toStartOf="parent"

+ 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
+            }
         }
     }
 }

+ 53 - 28
room/src/main/java/com/swago/room/adapter/RoomChatAdapter.kt

@@ -2,7 +2,7 @@ package com.swago.room.adapter
 
 import android.graphics.Bitmap
 import android.graphics.Color
-import android.graphics.drawable.BitmapDrawable
+import android.graphics.drawable.NinePatchDrawable
 import android.os.Build
 import android.text.*
 import android.text.method.LinkMovementMethod
@@ -18,7 +18,6 @@ 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
@@ -27,8 +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.UserInfo
+import com.swago.baseswago.util.DianJiuUtil
 import com.swago.formatAr
 import com.swago.room.R
 import com.swago.room.adapter.bitmap.CenterAlignImageSpan
@@ -49,15 +49,6 @@ class RoomChatAdapter :
      */
     private val iconBitmapCachePool: HashMap<String, Bitmap> = HashMap()
     private val localImageKey = ArrayList<String>()
-    private val badgeBitmap by lazy {
-        BitmapUtils.getBitmapFromPath(UserInfo.getUserInfo()?.badge_special)
-    }
-    private val bubbleChat by lazy {
-       BitmapUtils.getBitmapFromPath(UserInfo.getUserInfo()?.chat_special)
-    }
-    private val userid by lazy {
-        UserInfo.getUserInfo()?.id
-    }
 
     companion object {
         const val LEVEL_KEY = "level"
@@ -87,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
@@ -152,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")
@@ -164,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) {
@@ -205,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 -> {
@@ -289,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(
@@ -381,7 +390,7 @@ class RoomChatAdapter :
                             .append("'> ")
                     }
 
-                    if (item is UserJoinRoomBean && badgeBitmap != null) {
+                    if (item is UserJoinRoomBean && !item.androidBadgeSpecial.isNullOrEmpty()) {
                         count++
                         sb.append("<img src='" + "file:///xx/")
                             .append(BADGE_KEY).append(".png")
@@ -400,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(
@@ -456,9 +465,7 @@ class RoomChatAdapter :
 
                 }
             }
-            if (bubbleChat != null && item.getSenderId() == userid){
-                tvContent.background =  BitmapDrawable(mContext.resources , bubbleChat)
-            }
+
             tvContent.movementMethod = LinkMovementMethod.getInstance()
             tvContent.highlightColor = Color.TRANSPARENT
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -470,7 +477,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
@@ -552,12 +559,30 @@ class RoomChatAdapter :
                         Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                     )
                 }else if (imageSpan.source != null && imageSpan!!.source!!.contains(BADGE_KEY)) {
-                span.setSpan(
-                    setBadge(helper.itemView as ViewGroup),
-                    start,
-                    end,
-                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
-                )
+                    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)
                 }
@@ -755,10 +780,10 @@ class RoomChatAdapter :
         return CustomImageSpan(mContext, bm, CustomImageSpan.ALIGN_FONTCENTER)
     }
 
-    private fun setBadge(viewGroup: ViewGroup): CustomImageSpan {
+    private fun setBadge(bitmap: Bitmap,viewGroup: ViewGroup): CustomImageSpan {
         val imageView = ImageView(mContext)
         viewGroup.addView(imageView)
-        return CustomImageSpan(mContext, badgeBitmap, CustomImageSpan.ALIGN_FONTCENTER)
+        return CustomImageSpan(mContext, bitmap, CustomImageSpan.ALIGN_FONTCENTER)
     }
 
     private fun setLevel(iSenderLevel: Int, viewGroup: ViewGroup): CustomImageSpan {

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

@@ -1,24 +1,48 @@
 package com.swago.room.adapter
 
+import android.text.TextUtils
 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()){
+                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() {
+                    }
+                })
+            }
+
         }
     }
 }

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

@@ -2,13 +2,20 @@ package com.swago.room.audio
 
 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 {
@@ -24,6 +31,7 @@ class AudioSeatAdapter :
                             .loadImage(R.mipmap.ic_audio_seat)
                     }
                 } else {
+                    val svgAvatar = itemView.findViewById<SVGAImageView>(R.id.svgAvatar)
                     itemView.findViewById<SwagoImageView>(R.id.ivImageView)
                         .loadImage(it.user_head_img_url ?: "")
                     setText(R.id.tvName, it.user_name)
@@ -48,6 +56,20 @@ class AudioSeatAdapter :
                         }
 
                     }
+
+                    if (!it.head_special.isNullOrEmpty()){
+                        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() {
+                            }
+                        })
+                    }
+
                 }
             }
         }

+ 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 ?: ""
+        }
+    }
 }

+ 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()
                                             }
 
                                         }

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

@@ -1,25 +1,47 @@
 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)){
+                    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() {
+                        }
+                    })
+                }
             }
         }
     }

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

@@ -85,6 +85,48 @@ class XSvgPlayer : ConstraintLayout {
         }
     }
 
+    fun playJoinRoomSvga(svgaUrl:String?){
+        if (svgaUrl.isNullOrEmpty()){
+            return
+        }
+        svgaParser!!.let {
+            LogUtil.d("svgPlayer","xxx--$isPlaying")
+            it.decodeFromURL(URL(svgaUrl),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()
+                    }
+                }
+            },object:SVGAParser.PlayCallback{
+                override fun onPlay(file: List<File>) {
+                    LogUtil.d("svgPlayer","onPlay--${file.size}")
+                }
+
+            })
+
+        }
+    }
+
     fun clear(){
         binding?.apply {
             isPlaying = false

+ 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)

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

@@ -29,6 +29,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 +47,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 +72,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 +123,18 @@ class JoinRoomManager : IRoomActiveListener {
                 clBg?.setBackgroundResource(R.mipmap.join_ten_fourteen)
                 animationSet?.start()
                 joinRoomRootView?.visibility = View.VISIBLE
+                if (!userJoinRoomBean.androidHeadSpecial.isNullOrEmpty()) {
+                    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() {
+                        }
+                    })
+                }
             }
             in 15..19 -> {
                 clOne?.visibility = View.GONE
@@ -132,6 +147,18 @@ class JoinRoomManager : IRoomActiveListener {
                 clBg?.setBackgroundResource(R.mipmap.join_fifteen_nineteen)
                 animationSet?.start()
                 joinRoomRootView?.visibility = View.VISIBLE
+                if (!userJoinRoomBean.androidHeadSpecial.isNullOrEmpty()) {
+                    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 -> {
                 clOne?.visibility = View.GONE

+ 1 - 0
room/src/main/java/com/swago/room/user/UserRoomFragment.kt

@@ -246,6 +246,7 @@ class UserRoomFragment : BaseComFragment<FragmentBaseComBinding>() {
     override fun joinedRoom(iRoomInfo: IRoomInfo) {
         super.joinedRoom(iRoomInfo)
         SwagoRoomManager.iRoomInfo?.let {
+            binding.xSvgaPlayer.playJoinRoomSvga(iRoomInfo.getJoinSpecial())
             if (it.getAudioNotice().isNotEmpty()){
                 AudioNoticeUserDialog.newInstance().show(childFragmentManager,"AudioNoticeUserDialog")
             }

+ 6 - 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
@@ -174,9 +175,11 @@ 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)
+                        BitmapUtils.loadFile(AppContext.getContext() , it.androidBadgeSpecial){ bitmap ->
+                            newChatMsgFun?.invoke(it)
+                        }
                     }
                 }
             }
@@ -547,7 +550,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 ->

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

@@ -103,6 +103,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){

+ 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)

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

@@ -26,7 +26,6 @@
             android:layout_width="68dp"
             android:layout_height="68dp"
             android:visibility="visible"
-            app:source="avatar.svga"
             app:autoPlay="true"
             app:loopCount="0"
             app:layout_constraintStart_toStartOf="parent"

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

@@ -28,7 +28,6 @@
             android:layout_width="50dp"
             android:layout_height="50dp"
             android:visibility="visible"
-            app:source="avatar.svga"
             app:autoPlay="true"
             app:loopCount="0"
             app:layout_constraintStart_toStartOf="parent"

+ 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"

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

@@ -20,7 +20,6 @@
         android:layout_width="30dp"
         android:layout_height="30dp"
         android:visibility="visible"
-        app:source="avatar.svga"
         app:autoPlay="true"
         app:loopCount="0"
         app:layout_constraintStart_toStartOf="parent"

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

@@ -40,7 +40,6 @@
                 android:layout_width="30dp"
                 android:layout_height="30dp"
                 android:visibility="visible"
-                app:source="avatar.svga"
                 app:autoPlay="true"
                 app:loopCount="0"
                 app:layout_constraintStart_toStartOf="parent"

+ 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="visible"
+                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"

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

@@ -278,4 +278,32 @@ public interface IMessageProperties {
      * @param color
      */
     void setTipsMessageFontColor(int color);
+
+    /**
+     * 获取右边头像框
+     *
+     * @return
+     */
+    Drawable getRightSvgaAvatar();
+
+    /**
+     * 设置右边头像框
+     *
+     * @param drawable
+     */
+    void setRightSvgaAvatar(Drawable drawable);
+
+    /**
+     * 获取左边头像框
+     *
+     * @return
+     */
+    Drawable getLeftSvgaAvatar();
+
+    /**
+     * 设置左边头像框
+     *
+     * @param drawable
+     */
+    void setLeftSvgaAvatar(Drawable drawable);
 }

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

@@ -104,6 +104,26 @@ public abstract class MessageLayoutUI extends RecyclerView implements IMessageLa
         properties.setLeftBubble(bubble);
     }
 
+    @Override
+    public Drawable getRightSvgaAvatar() {
+        return properties.getRightSvgaAvatar();
+    }
+
+    @Override
+    public void setRightSvgaAvatar(Drawable drawable) {
+        properties.setRightSvgaAvatar(drawable);
+    }
+
+    @Override
+    public Drawable getLeftSvgaAvatar() {
+        return properties.getLeftSvgaAvatar();
+    }
+
+    @Override
+    public void setLeftSvgaAvatar(Drawable drawable) {
+        properties.setLeftSvgaAvatar(drawable);
+    }
+
     @Override
     public int getNameFontSize() {
         return properties.getNameFontSize();
@@ -285,6 +305,8 @@ public abstract class MessageLayoutUI extends RecyclerView implements IMessageLa
         private int mChatTimeFontSize;
         private int mChatTimeFontColor;
         private Drawable mChatTimeBubble;
+        private Drawable mMySvgaAvatar;
+        private Drawable mFriendSvgaAvatar;
 
         private Properties() {
 
@@ -481,5 +503,24 @@ public abstract class MessageLayoutUI extends RecyclerView implements IMessageLa
             this.mChatTimeFontColor = color;
         }
 
+        @Override
+        public Drawable getRightSvgaAvatar() {
+            return mMySvgaAvatar;
+        }
+
+        @Override
+        public void setRightSvgaAvatar(Drawable drawable) {
+            this.mMySvgaAvatar = drawable;
+        }
+
+        @Override
+        public Drawable getLeftSvgaAvatar() {
+            return mFriendSvgaAvatar;
+        }
+
+        @Override
+        public void setLeftSvgaAvatar(Drawable drawable) {
+            this.mFriendSvgaAvatar = drawable;
+        }
     }
 }

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

@@ -10,19 +10,23 @@ import android.widget.ProgressBar;
 import android.widget.TextView;
 
 import com.bumptech.glide.Glide;
+import com.opensource.svgaplayer.SVGAImageView;
 import com.swago.baseswago.util.AppContext;
 import com.swago.baseswago.util.UserInfo;
 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 de.hdodenhof.circleimageview.CircleImageView;
 
 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 +40,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);
@@ -121,6 +127,10 @@ public abstract class MessageContentHolder extends MessageEmptyHolder {
             } else {
                 msgContentFrame.setBackgroundResource(R.drawable.chat_bubble_myself);
             }
+            if (properties.getRightSvgaAvatar() != null){
+                rightSvgaImage.setImageDrawable(properties.getRightSvgaAvatar());
+                rightSvgaImage.startAnimation();
+            }
         } else {
             if (properties.getLeftBubble() != null && properties.getLeftBubble().getConstantState() != null) {
                 msgContentFrame.setBackground(properties.getLeftBubble().getConstantState().newDrawable());
@@ -128,6 +138,10 @@ public abstract class MessageContentHolder extends MessageEmptyHolder {
             } else {
                 msgContentFrame.setBackgroundResource(R.drawable.chat_other_bg);
             }
+            if (properties.getLeftSvgaAvatar() != null){
+                leftSvgaImage.setImageDrawable(properties.getLeftSvgaAvatar());
+                leftSvgaImage.startAnimation();
+            }
         }
 
         //// 聊天气泡的点击事件处理

+ 3 - 0
tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/conversation/holder/ConversationCommonHolder.java

@@ -11,6 +11,7 @@ import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import com.bumptech.glide.Glide;
+import com.opensource.svgaplayer.SVGAImageView;
 import com.tencent.imsdk.v2.V2TIMManager;
 import com.tencent.imsdk.v2.V2TIMUserFullInfo;
 import com.tencent.imsdk.v2.V2TIMValueCallback;
@@ -48,6 +49,7 @@ public class ConversationCommonHolder extends ConversationBaseHolder {
     protected TextView tvOfficial;
     protected ImageView ivCrown;
     protected ImageView ivCup;
+    protected SVGAImageView svgaImageView;
 
     public ConversationCommonHolder(View itemView) {
         super(itemView);
@@ -63,6 +65,7 @@ public class ConversationCommonHolder extends ConversationBaseHolder {
         tvOfficial = rootView.findViewById(R.id.tvOfficial);
         ivCrown = rootView.findViewById(R.id.ivCrown);
         ivCup = rootView.findViewById(R.id.ivCup);
+        svgaImageView = rootView.findViewById(R.id.svgAvatar);
     }
 
     public void layoutViews(ConversationInfo conversation, int position) {

+ 21 - 1
tuikit/src/main/res/layout/conversation_adapter.xml

@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/item_left"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
@@ -18,11 +19,30 @@
         android:button="@drawable/checkbox_selector"
         android:layout_marginEnd="6.23dp"
         android:visibility="gone" />
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
 
         <de.hdodenhof.circleimageview.CircleImageView
             android:id="@+id/conversation_icon"
             android:layout_width="@dimen/conversation_avatar_width"
-            android:layout_height="@dimen/conversation_avatar_height" />
+            android:layout_height="@dimen/conversation_avatar_height"
+            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="@dimen/conversation_avatar_width"
+            android:layout_height="@dimen/conversation_avatar_height"
+            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>
 
         <RelativeLayout
             android:layout_width="match_parent"

+ 19 - 0
tuikit/src/main/res/layout/forward_message_adapter_item_content.xml

@@ -52,6 +52,16 @@
             app:default_image="@drawable/default_user_icon"
             app:image_radius="20dp" />
 
+        <com.opensource.svgaplayer.SVGAImageView
+            android:id="@+id/svgAvatar_left"
+            android:layout_width="41dp"
+            android:layout_height="41dp"
+            android:visibility="visible"
+            app:autoPlay="true"
+            app:loopCount="0"
+            android:layout_alignParentLeft="true"
+            android:layout_marginRight="6.23dp"/>
+
         <com.tencent.qcloud.tim.uikit.component.gatherimage.UserIconView
             android:id="@+id/right_user_icon_view"
             android:layout_width="41dp"
@@ -61,6 +71,15 @@
             android:visibility="gone"
             app:default_image="@drawable/default_user_icon"
             app:image_radius="20dp" />
+        <com.opensource.svgaplayer.SVGAImageView
+            android:id="@+id/svgAvatar_right"
+            android:layout_width="41dp"
+            android:layout_height="41dp"
+            android:visibility="visible"
+            app:autoPlay="true"
+            app:loopCount="0"
+            android:layout_alignParentLeft="true"
+            android:layout_marginLeft="6.23dp"/>
     </RelativeLayout>
 
     <TextView

+ 3 - 3
tuikit/src/main/res/layout/message_adapter_content_text.xml

@@ -3,7 +3,7 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:gravity="center_vertical"
-    android:minHeight="36dp"
+    android:minHeight="31dp"
     android:orientation="horizontal">
 
     <TextView
@@ -14,8 +14,8 @@
         android:textColor="@color/black_font_color"
         android:paddingLeft="7dp"
         android:paddingRight="7dp"
-        android:paddingTop="10dp"
-        android:paddingBottom="10dp"
+        android:paddingTop="7dp"
+        android:paddingBottom="7dp"
         android:maxWidth="276dp"
         android:textSize="16.5sp" />
 </LinearLayout>

+ 26 - 5
tuikit/src/main/res/layout/message_adapter_item_content.xml

@@ -41,22 +41,43 @@
 
         <de.hdodenhof.circleimageview.CircleImageView
             android:id="@+id/left_user_icon_view"
-            android:layout_width="41dp"
-            android:layout_height="41dp"
+            android:layout_width="36dp"
+            android:layout_height="36dp"
             android:layout_alignParentLeft="true"
             android:layout_marginRight="6.23dp"
+            android:layout_marginTop="@dimen/dp_4"
+            android:layout_marginLeft="2dp"
             android:visibility="gone"
             android:scaleType="centerCrop"/>
+        <com.opensource.svgaplayer.SVGAImageView
+            android:id="@+id/svgAvatar_left"
+            android:layout_width="41dp"
+            android:layout_height="41dp"
+            android:visibility="visible"
+            app:autoPlay="true"
+            app:loopCount="0"
+            android:layout_alignParentLeft="true"
+            android:layout_marginRight="6.23dp"/>
 
         <de.hdodenhof.circleimageview.CircleImageView
             android:id="@+id/right_user_icon_view"
-            android:layout_width="41dp"
-            android:layout_height="41dp"
+            android:layout_width="36dp"
+            android:layout_height="36dp"
             android:layout_alignParentRight="true"
             android:layout_marginLeft="6.23dp"
+            android:layout_marginTop="@dimen/dp_4"
+            android:layout_marginRight="2dp"
             android:scaleType="centerCrop"
             android:visibility="gone"/>
-
+        <com.opensource.svgaplayer.SVGAImageView
+            android:id="@+id/svgAvatar_right"
+            android:layout_width="41dp"
+            android:layout_height="41dp"
+            android:visibility="visible"
+            app:autoPlay="true"
+            app:loopCount="0"
+            android:layout_alignParentRight="true"
+            android:layout_marginLeft="6.23dp"/>
         <TextView
             android:id="@+id/user_name_tv"
             android:layout_width="wrap_content"

+ 23 - 5
user/src/main/java/com/swago/user/store/StoreBuyDialog.kt

@@ -3,6 +3,7 @@ package com.swago.user.store
 import android.os.Bundle
 import android.view.Gravity
 import android.view.View
+import android.widget.Toast
 import androidx.activity.viewModels
 import androidx.fragment.app.viewModels
 import com.opensource.svgaplayer.SVGADrawable
@@ -13,6 +14,7 @@ import com.swago.baseswago.model.mine.StoreItemBean
 import com.swago.baseswago.util.AppContext
 import com.swago.baseswago.util.NoDoubleClickListener
 import com.swago.loadUrl
+import com.swago.user.R
 import com.swago.user.databinding.DialogStoreDetailBinding
 import com.swago.user.vm.StoreVm
 import java.io.File
@@ -23,6 +25,7 @@ class StoreBuyDialog : BaseXDFragment<DialogStoreDetailBinding>(){
 
     private var svgaParser: SVGAParser? = null
     var storeBean: StoreItemBean ?= null
+    var buySuccessFun:(()->Unit)? = null
     init {
         setGravity(Gravity.BOTTOM)
         setDimAmount(0.5f)
@@ -48,10 +51,9 @@ class StoreBuyDialog : BaseXDFragment<DialogStoreDetailBinding>(){
         storeBean?.let {
             binding.tvName.text = it.product_name
             binding.tvCoin.text = "${it.product_coin}"
-            binding.ivIcon.visibility = if (it.product_url?.endsWith("svga") == true) View.GONE else View.VISIBLE
-            binding.ivIcon.loadUrl(AppContext.getContext(),it.product_url?:"")
-            svgaParser?.let { svgaParser ->
-                svgaParser.decodeFromURL(URL(it.product_url), object : SVGAParser.ParseCompletion{
+            if (!it.product_svg_url.isNullOrEmpty() && it.product_svg_url?.endsWith(".svga") == true){
+                binding.ivIcon.visibility = View.GONE
+                svgaParser?.decodeFromURL(URL(it.product_svg_url), object : SVGAParser.ParseCompletion{
                     override fun onComplete(videoItem: SVGAVideoEntity) {
                         val drawable = SVGADrawable(videoItem)
                         binding.svgContent.setImageDrawable(drawable)
@@ -62,8 +64,15 @@ class StoreBuyDialog : BaseXDFragment<DialogStoreDetailBinding>(){
 
                     }
                 })
-
+            } else {
+                binding.ivIcon.visibility = View.VISIBLE
+                it.product_url?.let { imageUrl ->
+                    binding.ivIcon.loadUrl(AppContext.getContext(),imageUrl)
+                }
             }
+
+
+
         }
     }
 
@@ -71,7 +80,16 @@ class StoreBuyDialog : BaseXDFragment<DialogStoreDetailBinding>(){
         binding.tvBuy.setOnClickListener(object: NoDoubleClickListener(){
             override fun onClick() {
                 storeBean?.let {
+                    if (it.product_status ==1){
+                        Toast.makeText(
+                            AppContext.getContext(),
+                            AppContext.getContext().resources.getString(R.string.this_product_has_been_purchased),
+                            Toast.LENGTH_SHORT
+                        ).show()
+                        return@let
+                    }
                     storeVm.buyProduct(it.id)
+                    buySuccessFun?.invoke()
                     dismissAllowingStateLoss()
                 }
 

+ 32 - 12
user/src/main/java/com/swago/user/store/StoreListActivity.kt

@@ -225,11 +225,11 @@ class StoreListActivity : BaseXActivity<ActivityStoreListBinding>() {
             isEnterExpanded = !isEnterExpanded
             if (isEnterExpanded) {
                 enterAdapter.setNewData(enterList)
-                binding.tvEnterMore.text = "Show Less"
+                binding.tvEnterMore.text = getString(R.string.take_back)
                 binding.ivEnterMore.setImageResource(R.mipmap.ic_show_less)
             } else {
                 enterAdapter.setNewData(enterList.subList(0, enterList.size.coerceAtMost(3)))
-                binding.tvEnterMore.text = "Show More"
+                binding.tvEnterMore.text = getString(R.string.more)
                 binding.ivEnterMore.setImageResource(R.mipmap.ic_show_more)
             }
         }
@@ -240,11 +240,11 @@ class StoreListActivity : BaseXActivity<ActivityStoreListBinding>() {
             isAvatarExpanded = !isAvatarExpanded
             if (isAvatarExpanded) {
                 avatarAdapter.setNewData(avatarList)
-                binding.tvAvatarMore.text = "Show Less"
+                binding.tvAvatarMore.text = getString(R.string.take_back)
                 binding.ivAvatarMore.setImageResource(R.mipmap.ic_show_less)
             } else {
                 avatarAdapter.setNewData(avatarList.subList(0, avatarList.size.coerceAtMost(3)))
-                binding.tvAvatarMore.text = "Show More"
+                binding.tvAvatarMore.text = getString(R.string.more)
                 binding.ivAvatarMore.setImageResource(R.mipmap.ic_show_more)
             }
         }
@@ -255,11 +255,11 @@ class StoreListActivity : BaseXActivity<ActivityStoreListBinding>() {
             isBadgeExpanded = !isBadgeExpanded
             if (isBadgeExpanded) {
                 badgeAdapter.setNewData(badgeList)
-                binding.tvBadgeMore.text = "Show Less"
+                binding.tvBadgeMore.text = getString(R.string.take_back)
                 binding.ivBadgeMore.setImageResource(R.mipmap.ic_show_less)
             } else {
                 badgeAdapter.setNewData(badgeList.subList(0, badgeList.size.coerceAtMost(3)))
-                binding.tvBadgeMore.text = "Show More"
+                binding.tvBadgeMore.text = getString(R.string.more)
                 binding.ivBadgeMore.setImageResource(R.mipmap.ic_show_more)
             }
         }
@@ -270,17 +270,22 @@ class StoreListActivity : BaseXActivity<ActivityStoreListBinding>() {
             isBubbleExpanded = !isBubbleExpanded
             if (isBubbleExpanded) {
                 bubbleAdapter.setNewData(bubbleList)
-                binding.tvBubbleMore.text = "Show Less"
+                binding.tvBubbleMore.text = getString(R.string.take_back)
                 binding.ivBubbleMore.setImageResource(R.mipmap.ic_show_less)
             } else {
                 bubbleAdapter.setNewData(bubbleList.subList(0, bubbleList.size.coerceAtMost(3)))
-                binding.tvBubbleMore.text = "Show More"
+                binding.tvBubbleMore.text = getString(R.string.more)
                 binding.ivBubbleMore.setImageResource(R.mipmap.ic_show_more)
             }
         }
         enterAdapter.setOnItemClickListener { _, _, position ->
             if (type == 1){
-                StoreBuyDialog.newInstance(enterAdapter.data[position]).show(supportFragmentManager ,"StoreBuyDialog")
+                StoreBuyDialog.newInstance(enterAdapter.data[position]).apply {
+                    this.buySuccessFun = {
+                        enterAdapter.data[position].product_status = 1
+                        enterAdapter.notifyItemChanged(position)
+                    }
+                }.show(supportFragmentManager ,"StoreBuyDialog")
             } else if (type == 2){
                 storeVm.chooseProduct(enterAdapter.data[position].id)
                 enterList.forEachIndexed { index, storeItemBean ->
@@ -293,7 +298,12 @@ class StoreListActivity : BaseXActivity<ActivityStoreListBinding>() {
         }
         avatarAdapter.setOnItemClickListener { _, _, position ->
             if (type == 1){
-                StoreBuyDialog.newInstance(avatarAdapter.data[position]).show(supportFragmentManager ,"StoreBuyDialog")
+                StoreBuyDialog.newInstance(avatarAdapter.data[position]).apply {
+                    this.buySuccessFun = {
+                        avatarAdapter.data[position].product_status = 1
+                        avatarAdapter.notifyItemChanged(position)
+                    }
+                }.show(supportFragmentManager ,"StoreBuyDialog")
             } else if (type == 2){
                 storeVm.chooseProduct(avatarAdapter.data[position].id)
                 avatarList.forEachIndexed { index, storeItemBean ->
@@ -306,7 +316,12 @@ class StoreListActivity : BaseXActivity<ActivityStoreListBinding>() {
         }
         badgeAdapter.setOnItemClickListener { _, _, position ->
             if (type == 1){
-                StoreBuyDialog.newInstance(badgeAdapter.data[position]).show(supportFragmentManager ,"StoreBuyDialog")
+                StoreBuyDialog.newInstance(badgeAdapter.data[position]).apply {
+                    this.buySuccessFun = {
+                        badgeAdapter.data[position].product_status = 1
+                        badgeAdapter.notifyItemChanged(position)
+                    }
+                }.show(supportFragmentManager ,"StoreBuyDialog")
             } else if (type == 2){
                 storeVm.chooseProduct(badgeAdapter.data[position].id)
                 badgeList.forEachIndexed { index, storeItemBean ->
@@ -319,7 +334,12 @@ class StoreListActivity : BaseXActivity<ActivityStoreListBinding>() {
         }
         bubbleAdapter.setOnItemClickListener { _, _, position ->
             if (type == 1){
-                StoreBuyDialog.newInstance(bubbleAdapter.data[position]).show(supportFragmentManager ,"StoreBuyDialog")
+                StoreBuyDialog.newInstance(bubbleAdapter.data[position]).apply {
+                    this.buySuccessFun = {
+                        bubbleAdapter.data[position].product_status = 1
+                        bubbleAdapter.notifyItemChanged(position)
+                    }
+                }.show(supportFragmentManager ,"StoreBuyDialog")
             } else if (type == 2){
                 storeVm.chooseProduct(bubbleAdapter.data[position].id)
                 bubbleList.forEachIndexed { index, storeItemBean ->

+ 8 - 0
user/src/main/java/com/swago/user/vm/StoreVm.kt

@@ -1,13 +1,16 @@
 package com.swago.user.vm
 
 import android.app.Application
+import android.widget.Toast
 import androidx.lifecycle.MutableLiveData
 import com.swago.baseswago.inter.ApiManager
 import com.swago.baseswago.model.mine.StoreItemBean
 import com.swago.baseswago.model.mine.TaskModel
 import com.swago.baseswago.util.ActivityManagerUtil
+import com.swago.baseswago.util.AppContext
 import com.swago.baseswago.util.BaseViewModel
 import com.swago.baseswago.util.SwagoLoading
+import com.swago.user.R
 
 class StoreVm(application: Application) : BaseViewModel(application){
 
@@ -31,6 +34,11 @@ class StoreVm(application: Application) : BaseViewModel(application){
         requestData2 {
             requestData {
                 ApiManager.userApi.buyProduct(productId)
+                Toast.makeText(
+                    AppContext.getContext(),
+                    AppContext.getContext().resources.getString(R.string.purchase_successful),
+                    Toast.LENGTH_SHORT
+                ).show()
             }
 
         }

+ 8 - 8
user/src/main/res/layout/activity_store_list.xml

@@ -51,7 +51,7 @@
                     app:layout_constraintBottom_toBottomOf="parent"
                     app:layout_constraintStart_toStartOf="parent"
                     app:layout_constraintTop_toTopOf="parent"
-                    android:text="入场特效" />
+                    android:text="@string/entrance_effects" />
 
                 <com.swago.baseswago.cusview.MediumTextView
                     android:id="@+id/tvEnterMore"
@@ -64,7 +64,7 @@
                     app:layout_constraintBottom_toBottomOf="parent"
                     app:layout_constraintEnd_toStartOf="@+id/ivEnterMore"
                     app:layout_constraintTop_toTopOf="parent"
-                    android:text="Show Less" />
+                    android:text="@string/more" />
                 <ImageView
                     android:id="@+id/ivEnterMore"
                     android:layout_width="wrap_content"
@@ -103,7 +103,7 @@
                     app:layout_constraintBottom_toBottomOf="parent"
                     app:layout_constraintStart_toStartOf="parent"
                     app:layout_constraintTop_toTopOf="parent"
-                    android:text="头像框" />
+                    android:text="@string/avatar_frame" />
 
                 <com.swago.baseswago.cusview.MediumTextView
                     android:id="@+id/tvAvatarMore"
@@ -116,7 +116,7 @@
                     app:layout_constraintBottom_toBottomOf="parent"
                     app:layout_constraintEnd_toStartOf="@+id/ivAvatarMore"
                     app:layout_constraintTop_toTopOf="parent"
-                    android:text="Show Less" />
+                    android:text="@string/more" />
                 <ImageView
                     android:id="@+id/ivAvatarMore"
                     android:layout_width="wrap_content"
@@ -155,7 +155,7 @@
                     app:layout_constraintBottom_toBottomOf="parent"
                     app:layout_constraintStart_toStartOf="parent"
                     app:layout_constraintTop_toTopOf="parent"
-                    android:text="徽章" />
+                    android:text="@string/badge" />
 
                 <com.swago.baseswago.cusview.MediumTextView
                     android:id="@+id/tvBadgeMore"
@@ -168,7 +168,7 @@
                     app:layout_constraintBottom_toBottomOf="parent"
                     app:layout_constraintEnd_toStartOf="@+id/ivBadgeMore"
                     app:layout_constraintTop_toTopOf="parent"
-                    android:text="Show Less" />
+                    android:text="@string/more" />
                 <ImageView
                     android:id="@+id/ivBadgeMore"
                     android:layout_width="wrap_content"
@@ -207,7 +207,7 @@
                     app:layout_constraintBottom_toBottomOf="parent"
                     app:layout_constraintStart_toStartOf="parent"
                     app:layout_constraintTop_toTopOf="parent"
-                    android:text="聊天气泡" />
+                    android:text="@string/chat_bubble" />
 
                 <com.swago.baseswago.cusview.MediumTextView
                     android:id="@+id/tvBubbleMore"
@@ -220,7 +220,7 @@
                     app:layout_constraintBottom_toBottomOf="parent"
                     app:layout_constraintEnd_toStartOf="@+id/ivBubbleMore"
                     app:layout_constraintTop_toTopOf="parent"
-                    android:text="Show Less" />
+                    android:text="@string/more" />
                 <ImageView
                     android:id="@+id/ivBubbleMore"
                     android:layout_width="wrap_content"

+ 2 - 2
user/src/main/res/layout/dialog_store_detail.xml

@@ -14,7 +14,7 @@
             app:layout_constraintDimensionRatio="h,1:1"
             app:layout_constraintBottom_toTopOf="@+id/cl_bottom"
             app:layout_constraintTop_toTopOf="parent"
-            app:loopCount="1" />
+            app:loopCount="0" />
 
         <androidx.constraintlayout.widget.ConstraintLayout
             android:id="@+id/cl_bottom"
@@ -40,7 +40,7 @@
                 android:maxWidth="120dp"
                 android:textColor="#ffffff"
                 android:textSize="16sp"
-                android:layout_marginTop="@dimen/dp_4"
+                android:layout_marginTop="@dimen/dp_10"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toBottomOf="@+id/ivIcon"