Ver código fonte

feat: android ios chat

tongmengxiao 6 meses atrás
pai
commit
203f94e779
22 arquivos alterados com 292 adições e 158 exclusões
  1. 4 7
      baseswago/src/main/java/com/swago/baseswago/PersonDataDFragment.kt
  2. 0 1
      baseswago/src/main/java/com/swago/baseswago/UserVm.kt
  3. 29 20
      baseswago/src/main/java/com/swago/baseswago/model/UserInfoModel.java
  4. 3 1
      baseswago/src/main/java/com/swago/baseswago/model/im/RoomChatMsgBean.java
  5. 4 4
      baseswago/src/main/java/com/swago/baseswago/model/im/UserJoinRoomBean.java
  6. 18 0
      baseswago/src/main/java/com/swago/baseswago/model/live/RoomUserModel.java
  7. 26 50
      baseswago/src/main/java/com/swago/baseswago/util/BitmapUtils.kt
  8. 1 11
      baseswago/src/main/java/com/swago/baseswago/util/DianJiuUtil.kt
  9. 50 25
      home/src/main/java/com/swago/home/ChatDetailActivity.kt
  10. 2 2
      home/src/main/java/com/swago/home/MineFragment.kt
  11. 22 16
      room/src/main/java/com/swago/room/adapter/RoomChatAdapter.kt
  12. 2 2
      room/src/main/java/com/swago/room/adapter/RoomUserAdapter.kt
  13. 6 2
      room/src/main/java/com/swago/room/dialog/SendMsgDialog.kt
  14. 6 2
      room/src/main/java/com/swago/room/hongbao/RedEnvelopResultDialog.kt
  15. 4 4
      room/src/main/java/com/swago/room/manager/JoinRoomManager.kt
  16. 2 4
      room/src/main/java/com/swago/room/vm/MsgVm.kt
  17. 28 0
      tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/chat/interfaces/IMessageProperties.java
  18. 41 0
      tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/chat/layout/message/MessageLayoutUI.java
  19. 14 0
      tuikit/src/main/java/com/tencent/qcloud/tim/uikit/modules/chat/layout/message/holder/MessageContentHolder.java
  20. 19 0
      tuikit/src/main/res/layout/forward_message_adapter_item_content.xml
  21. 3 3
      tuikit/src/main/res/layout/message_adapter_content_text.xml
  22. 8 4
      tuikit/src/main/res/layout/message_adapter_item_content.xml

+ 4 - 7
baseswago/src/main/java/com/swago/baseswago/PersonDataDFragment.kt

@@ -42,7 +42,6 @@ class PersonDataDFragment : BaseXDFragment<DialogPersonDataBinding>() {
     var nickName = ""
     var nickIcon = ""
     var account = ""
-    var chatSpecial = ""
     var roomId:String = ""
     var isAnchor = false //是否是主播点击了资料卡
     var isAdmin = false
@@ -129,7 +128,6 @@ class PersonDataDFragment : BaseXDFragment<DialogPersonDataBinding>() {
                                     ARouter.getInstance().build(ARouteConstant.Home.chatDetail)
                                         .withString("account",account)
                                         .withString("chatName",binding.tvName.text.toString())
-                                        .withString("chatSpecial",chatSpecial).navigation()
                                     dismissAllowingStateLoss()
                                 } else {
                                     Toast.makeText(
@@ -177,7 +175,6 @@ class PersonDataDFragment : BaseXDFragment<DialogPersonDataBinding>() {
             nickName = it.user_name
             nickIcon = it.user_head_img_url
             account = it.user_account
-            chatSpecial = it.chat_special
             binding.ivVip.visibility = if (it.is_benefit==1) View.VISIBLE else View.GONE
             Glide.with(this).load(it.user_head_img_url)
                 .placeholder(R.mipmap.default_avatar)
@@ -249,8 +246,8 @@ class PersonDataDFragment : BaseXDFragment<DialogPersonDataBinding>() {
 
             isAdmin = it.is_room_admin == 1
 
-            if (!TextUtils.isEmpty(it.head_special)){
-                svgaParser.decodeFromURL(URL(it.head_special), object :SVGAParser.ParseCompletion{
+            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)
@@ -261,12 +258,12 @@ class PersonDataDFragment : BaseXDFragment<DialogPersonDataBinding>() {
                     }
                 })
             }
-            if (TextUtils.isEmpty(it.badge_special)){
+            if (TextUtils.isEmpty(it.android_badge_special)){
                 binding.ivBadge.visibility = View.GONE
             } else {
                 activity?.let { activity ->
                     Glide.with(activity)
-                        .load(it.badge_special)
+                        .load(it.android_badge_special)
                         .override(200)
                         .into(binding.ivBadge)
                     binding.ivBadge.visibility = View.VISIBLE

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

@@ -46,7 +46,6 @@ class UserVm(application: Application) : BaseViewModel(application) {
         requestData {
             val data = ApiManager.userApi.getUserInfo()
             userInfoLiveData.value = data
-            BitmapUtils.loadFile(AppContext.getContext() , "https://apple-1304432552.cos.ap-shanghai.myqcloud.com/1.png",207,60)
         }
     }
 

+ 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 - 1
baseswago/src/main/java/com/swago/baseswago/model/im/RoomChatMsgBean.java

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

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

@@ -29,10 +29,10 @@ public class UserJoinRoomBean implements IRoomChat {
     public int isCrown;
     public int isCup;
     public int isFans;
-    public String joinSpecial="";
-    public String headSpecial="";
-    public String badgeSpecial="";
-    public String chatSpecial="";
+    public String androidJoinSpecial="";
+    public String androidHeadSpecial="";
+    public String androidBadgeSpecial="";
+    public String iosChatSpecial="";
 
     @NonNull
     @Override

+ 18 - 0
baseswago/src/main/java/com/swago/baseswago/model/live/RoomUserModel.java

@@ -55,7 +55,9 @@ public class RoomUserModel {
         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;
@@ -170,6 +172,22 @@ public class RoomUserModel {
             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;
         }

+ 26 - 50
baseswago/src/main/java/com/swago/baseswago/util/BitmapUtils.kt

@@ -5,7 +5,6 @@ import android.content.Context
 import android.graphics.Bitmap
 import android.graphics.BitmapFactory
 import android.graphics.drawable.Drawable
-import android.graphics.drawable.NinePatchDrawable
 import android.text.TextUtils
 import com.bumptech.glide.Glide
 import com.bumptech.glide.load.DataSource
@@ -15,65 +14,31 @@ 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 getBitmapFromPath(url: String?): Bitmap? {
-        if (TextUtils.isEmpty(url)) {
-            return null
+    fun loadFile(context: Context, url:String?, response: ((resource: Bitmap?) -> Unit)?=null){
+        if (TextUtils.isEmpty(url)){
+            response?.invoke(null)
+            return
         }
-        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
+        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 loadFile(context: Context, url: String,width:Int,height:Int) {
-        if (context is Activity) {
-            if (context.isDestroyed)
-                return
+            response?.invoke(BitmapFactory.decodeFile(path).apply { density = 480 })
+            return
         }
         Glide.with(context)
             .asBitmap()
-            .override(width,height)
-            .load(url)
-            .into(object : CustomTarget<Bitmap>() {
-                override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
-                    val pathFile =
-                        File("${UrlConstant.specialResourcePath}/${url.substring(url.lastIndexOf("/"))}")
-                    var outputStream: FileOutputStream? = null
-                    try {
-                        outputStream = FileOutputStream(pathFile)
-                        resource.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
-                        outputStream.flush()
-                    } catch (e: IOException) {
-                        e.printStackTrace()
-                    } finally {
-                        outputStream?.close()
-                    }
-                }
-
-                override fun onLoadCleared(placeholder: Drawable?) {
-
-                }
-            })
-    }
-
-    fun loadFile(context: Context, url:String, size:Int,response: ((resource: Bitmap?) -> Unit)?=null){
-        Glide.with(context)
-            .asBitmap()
-            .override(size)
             .load(url)
             .listener(object : RequestListener<Bitmap>{
                 override fun onLoadFailed(
@@ -98,7 +63,18 @@ object BitmapUtils {
             } )
             .into(object : CustomTarget<Bitmap>() {
                 override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
-                    response?.invoke(resource)
+                    resource.density = 480
+                    var outputStream: FileOutputStream? = null
+                    try {
+                        outputStream = FileOutputStream(pathFile)
+                        resource.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
+                        outputStream.flush()
+                    } catch (e: IOException) {
+                        e.printStackTrace()
+                    } finally {
+                        outputStream?.close()
+                    }
+                    response?.invoke(resource.apply { density = 480 })
                 }
 
                 override fun onLoadCleared(placeholder: Drawable?) {

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

@@ -7,14 +7,11 @@ 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.FileInputStream
-import java.io.FileOutputStream
-import java.io.IOException
 
 object DianJiuUtil {
     fun loadDian9Tu(context: Context, url: String, drawable: (e: NinePatchDrawable?) -> Unit){
@@ -38,18 +35,11 @@ object DianJiuUtil {
     }
 
     fun ninePatchImageDrawable(context: Context, bitmap: Bitmap, drawable: (e: NinePatchDrawable?) -> Unit) {
+        bitmap.density = 480
         val chunk = bitmap.ninePatchChunk
         if (NinePatch.isNinePatchChunk(chunk)){
             drawable.invoke(NinePatchDrawable(context.resources,bitmap,chunk,NinePatchChunk.deserialize(chunk)?.mPaddings,null))
         }
         drawable.invoke(null)
     }
-
-    fun setNinePatchImage(context: Context, bitmap: Bitmap): NinePatchDrawable? {
-        val chunk = bitmap.ninePatchChunk
-        if (NinePatch.isNinePatchChunk(chunk)){
-            return NinePatchDrawable(context.resources,bitmap,chunk,NinePatchChunk.deserialize(chunk)?.mPaddings,null)
-        }
-        return null
-    }
 }

+ 50 - 25
home/src/main/java/com/swago/home/ChatDetailActivity.kt

@@ -1,10 +1,5 @@
 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
@@ -13,18 +8,17 @@ import androidx.core.content.ContextCompat
 import com.alibaba.android.arouter.facade.annotation.Autowired
 import com.alibaba.android.arouter.facade.annotation.Route
 import com.alibaba.android.arouter.launcher.ARouter
-import com.google.firebase.firestore.auth.User
 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.BitmapUtils
 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
@@ -33,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
 
 
 /**
@@ -52,10 +47,7 @@ class ChatDetailActivity  : BaseXActivity<ActivityChatDetailBinding>() {
     @JvmField
     var chatName: String = ""
 
-    @Autowired(required = true)
-    @JvmField
-    var chatSpecial: String = ""
-
+    private var svgaParser:SVGAParser? = null
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -73,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
@@ -97,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?) {
 
             }
@@ -127,30 +123,55 @@ class ChatDetailActivity  : BaseXActivity<ActivityChatDetailBinding>() {
             }
         })
 
-        if (UserInfo.getUserInfo() != null && !TextUtils.isEmpty(UserInfo.getUserInfo()?.chat_special)){
-            UserInfo.getUserInfo()?.chat_special?.let {chatUrl ->
+        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
+                        messageRecyclerView?.rightBubble = it
                     }
                 }
             }
         } else {
-            messageRecyclerView.rightBubble = ContextCompat.getDrawable(this ,R.mipmap.bg_chat_white)
+            messageRecyclerView?.rightBubble = ContextCompat.getDrawable(this ,R.mipmap.bg_chat_purple)
         }
 
-        if (!TextUtils.isEmpty(chatSpecial)){
-            DianJiuUtil.loadDian9Tu(this ,chatSpecial ){ drawable ->
-                drawable?.let {
-                    messageRecyclerView.leftBubble = it
+        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
+                    }
                 }
             }
-        } else {
-            messageRecyclerView.leftBubble = ContextCompat.getDrawable(this ,R.mipmap.bg_chat_purple)
+            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() {
@@ -162,5 +183,9 @@ class ChatDetailActivity  : BaseXActivity<ActivityChatDetailBinding>() {
         userVm.getUserInfo()
     }
 
+    override fun onDestroy() {
+        super.onDestroy()
+
+    }
 
 }

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

@@ -217,8 +217,8 @@ class MineFragment : BaseXFragment<FragmentMineBinding>() {
                 binding.tvModifyPassword.visibility = View.GONE
             }
 
-            if (!it.head_special.isNullOrEmpty()){
-                svgaParser?.decodeFromURL(URL(it.head_special), object :SVGAParser.ParseCompletion{
+            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)

+ 22 - 16
room/src/main/java/com/swago/room/adapter/RoomChatAdapter.kt

@@ -2,8 +2,6 @@ package com.swago.room.adapter
 
 import android.graphics.Bitmap
 import android.graphics.Color
-import android.graphics.drawable.BitmapDrawable
-import android.graphics.drawable.Drawable
 import android.graphics.drawable.NinePatchDrawable
 import android.os.Build
 import android.text.*
@@ -18,13 +16,8 @@ import android.widget.ImageView
 import android.widget.TextView
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.content.ContextCompat
-import com.bumptech.glide.Glide
-import com.bumptech.glide.request.target.CustomTarget
-import com.bumptech.glide.request.transition.Transition
 import com.chad.library.adapter.base.BaseQuickAdapter
 import com.chad.library.adapter.base.BaseViewHolder
-import com.swago.baseswago.baseroom.SwagoRoomManager
-import com.swago.baseswago.constant.UrlConstant
 import com.swago.baseswago.cusview.LiangView
 import com.swago.baseswago.cusview.SwagoLevelView
 import com.swago.baseswago.im.IRoomChat
@@ -36,15 +29,11 @@ import com.swago.baseswago.model.im.UserJoinRoomBean
 import com.swago.baseswago.util.AppContext
 import com.swago.baseswago.util.BitmapUtils
 import com.swago.baseswago.util.DianJiuUtil
-import com.swago.baseswago.util.UserInfo
 import com.swago.formatAr
 import com.swago.room.R
 import com.swago.room.adapter.bitmap.CenterAlignImageSpan
 import com.swago.room.adapter.bitmap.CustomImageSpan
 import com.swago.room.adapter.bitmap.HtmlImageGetter
-import java.io.File
-import java.io.FileOutputStream
-import java.io.IOException
 import java.util.*
 import kotlin.collections.ArrayList
 
@@ -157,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")
@@ -211,8 +206,8 @@ class RoomChatAdapter :
                         setBackgroundRes(R.id.tvContent, R.drawable.shape_20000000_14)
                     }
                     mContext?.let {
-                        if (item is RoomChatMsgBean&&!item.chat_special.isNullOrEmpty()){
-                            DianJiuUtil.loadDian9Tu(it ,item.chat_special ){ drawable ->
+                        if (item is RoomChatMsgBean&&!item.android_chat_special.isNullOrEmpty()){
+                            DianJiuUtil.loadDian9Tu(it ,item.android_chat_special ){ drawable ->
                                 drawable?.let { drawable ->
                                     tvContent.background = drawable
                                 }
@@ -395,7 +390,7 @@ class RoomChatAdapter :
                             .append("'> ")
                     }
 
-                    if (item is UserJoinRoomBean && !item.badgeSpecial.isNullOrEmpty()) {
+                    if (item is UserJoinRoomBean && !item.androidBadgeSpecial.isNullOrEmpty()) {
                         count++
                         sb.append("<img src='" + "file:///xx/")
                             .append(BADGE_KEY).append(".png")
@@ -564,8 +559,19 @@ class RoomChatAdapter :
                         Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                     )
                 }else if (imageSpan.source != null && imageSpan!!.source!!.contains(BADGE_KEY)) {
-                    if(item is UserJoinRoomBean && !TextUtils.isEmpty(item.badgeSpecial)){
-                        BitmapUtils.loadFile(mContext,item.badgeSpecial,50){
+                    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),

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

@@ -30,8 +30,8 @@ class RoomUserAdapter : BaseQuickAdapter<RoomUserModel.ListBean,BaseViewHolder>(
                 .placeholder(R.mipmap.default_avatar)
                 .error(R.mipmap.default_avatar).into(ivAvatar)
 
-            if (!item.head_special.isNullOrEmpty()){
-                svgaParser.decodeFromURL(URL(item.head_special), object :SVGAParser.ParseCompletion{
+            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)

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

@@ -157,7 +157,9 @@ class SendMsgDialog : BaseXDFragment<DialogSendMsgBinding>() {
                             roomChatMsgBean.isCup = it.is_cup
                             roomChatMsgBean.isAdmin = SwagoRoomManager.iRoomInfo?.getRoomAdmin()?:0
                             roomChatMsgBean.isFans = SwagoRoomManager.iRoomInfo?.getIsFans()?:0
-                            roomChatMsgBean.chat_special = it.chat_special
+                            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)
@@ -173,7 +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("chat_special", it.chat_special)
+                            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)

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

@@ -107,7 +107,9 @@ class RedEnvelopResultDialog : BaseXDFragment<DialogRedEnvelopeResultBinding>()
                 roomChatMsgBean.isCup = it.is_cup
                 roomChatMsgBean.isAdmin = SwagoRoomManager.iRoomInfo?.getRoomAdmin()?:0
                 roomChatMsgBean.isFans = SwagoRoomManager.iRoomInfo?.getIsFans()?:0
-                roomChatMsgBean.chat_special = it.chat_special
+                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()
@@ -124,7 +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("chat_special", it.chat_special)
+                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)

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

@@ -123,8 +123,8 @@ class JoinRoomManager : IRoomActiveListener {
                 clBg?.setBackgroundResource(R.mipmap.join_ten_fourteen)
                 animationSet?.start()
                 joinRoomRootView?.visibility = View.VISIBLE
-                if (!userJoinRoomBean.headSpecial.isNullOrEmpty()) {
-                    svgParser?.decodeFromURL(URL(userJoinRoomBean.headSpecial), object :SVGAParser.ParseCompletion{
+                if (!userJoinRoomBean.androidHeadSpecial.isNullOrEmpty()) {
+                    svgParser?.decodeFromURL(URL(userJoinRoomBean.androidHeadSpecial), object :SVGAParser.ParseCompletion{
                         override fun onComplete(videoItem: SVGAVideoEntity) {
                             val drawable = SVGADrawable(videoItem)
                             svgaAvatar?.setImageDrawable(drawable)
@@ -147,8 +147,8 @@ class JoinRoomManager : IRoomActiveListener {
                 clBg?.setBackgroundResource(R.mipmap.join_fifteen_nineteen)
                 animationSet?.start()
                 joinRoomRootView?.visibility = View.VISIBLE
-                if (!userJoinRoomBean.headSpecial.isNullOrEmpty()) {
-                    svgParser?.decodeFromURL(URL(userJoinRoomBean.headSpecial), object :SVGAParser.ParseCompletion{
+                if (!userJoinRoomBean.androidHeadSpecial.isNullOrEmpty()) {
+                    svgParser?.decodeFromURL(URL(userJoinRoomBean.androidHeadSpecial), object :SVGAParser.ParseCompletion{
                         override fun onComplete(videoItem: SVGAVideoEntity) {
                             val drawable = SVGADrawable(videoItem)
                             svgaAvatar?.setImageDrawable(drawable)

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

@@ -177,10 +177,8 @@ class MsgVm(application: Application) : AbsMsgVm(application) {
                     it.data?.let {
                         updateHotValue?.invoke(it.hotValue)
                         joinRoomManager.addJoinRoomData(it)
-                        it.badgeSpecial?.let {badgeSpecial ->
-                            BitmapUtils.loadFile(AppContext.getContext() , badgeSpecial, 50){ bitmap ->
-                                newChatMsgFun?.invoke(it)
-                            }
+                        BitmapUtils.loadFile(AppContext.getContext() , it.androidBadgeSpecial){ bitmap ->
+                            newChatMsgFun?.invoke(it)
                         }
                     }
                 }

+ 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();
+            }
         }
 
         //// 聊天气泡的点击事件处理

+ 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="5dp"
-        android:paddingBottom="5dp"
+        android:paddingTop="7dp"
+        android:paddingBottom="7dp"
         android:maxWidth="276dp"
         android:textSize="16.5sp" />
 </LinearLayout>

+ 8 - 4
tuikit/src/main/res/layout/message_adapter_item_content.xml

@@ -41,10 +41,12 @@
 
         <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
@@ -59,10 +61,12 @@
 
         <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