Browse Source

feat: yoki svip (#15)

* feat: SVIP 标签 View

* feat: 调整部分svip的实现

* feat: 增加SVIP礼物面板

* feat: SVIP动态头像选择

* feat: SVIP标签View

* feat: 动态头像+进房隐身

* feat: SVIP礼物,隐身

* feat: Me页面入口svip标签

* feat: 列表场景,增加标签显示

* feat: 列表场景,增加标签显示

* feat: 防踢权限

* feat: 防踢权限

* feat: 防禁言权限

* feat: svip升级弹窗

* feat: svip升级弹窗

* feat: 神秘人弹窗

* fix: UserEnterBannerView

* fix: UserEnterBannerView

* feat: me页面入口展示

* feat: svip全服横幅、弹窗样式完善

* feat: svip进场座驾

* feat: 标签展示场景补充

* feat: 删除和替换updateSVipLabel

* feat: 删除和替换updateSVipLabel

* feat: 进场座驾显示

* feat: svip链接替换,跟vip一致

* feat: svip升级弹窗动效背景,当前等级字段修改

* feat: svip礼物弹窗

* feat: svip标签展示+替换资源

* feat: me页面入口展示

* feat: me页面红点

* feat: 合并主分支

* feat: vip svip标签展示

* feat: vip svip标签展示

* feat: 进场座驾调整

* feat: 更换 githubAntiBanConfigUrl

* feat: svip全服横幅跳转、神秘人点击跳转问题

* feat: svip弹窗勋章格式

* feat: 更换资源

* feat: 背包页面修改

* feat: svip链接更新

* fix: svip升级弹窗bug

* feat: 幸运数字,破除隐身

* feat: 代码自己review修改

* feat: 代码自己review修改

---------

Co-authored-by: pengwuliang <1097674484@qq.com>
LXD312569496 8 months ago
parent
commit
f770ccbbbb
100 changed files with 641 additions and 1024 deletions
  1. 1 0
      app/build.gradle
  2. 24 68
      app/src/main/java/com/adealink/weparty/imageselect/ImageSelectActivity.kt
  3. 2 0
      app/src/main/java/com/adealink/weparty/imageselect/SelectImageContract.kt
  4. 3 1
      app/src/main/java/com/adealink/weparty/imageselect/SelectImageLifecycleObserver.kt
  5. 29 0
      app/src/main/java/com/adealink/weparty/imageselect/constant/ImageSelectTopTips.kt
  6. 11 82
      app/src/main/java/com/adealink/weparty/module/entereffect/effect/CarEffectView.kt
  7. 20 45
      app/src/main/java/com/adealink/weparty/module/entereffect/view/CarCustomizedUserView.kt
  8. 1 2
      app/src/main/java/com/adealink/weparty/module/entereffect/view/UserEnterBannerView.kt
  9. 8 1
      app/src/main/java/com/adealink/weparty/module/gift/data/GiftData.kt
  10. 60 37
      app/src/main/java/com/adealink/weparty/module/level/data/LevelData.kt
  11. 0 55
      app/src/main/java/com/adealink/weparty/module/level/svip/SvipFunctionDisableDialog.kt
  12. 0 96
      app/src/main/java/com/adealink/weparty/module/level/util/SVipUIUtil.kt
  13. 0 25
      app/src/main/java/com/adealink/weparty/module/level/util/VipUIUtil.kt
  14. 61 0
      app/src/main/java/com/adealink/weparty/module/level/view/UserSVipLevelView.kt
  15. 6 4
      app/src/main/java/com/adealink/weparty/module/level/viewmodel/ILevelViewModel.kt
  16. 5 2
      app/src/main/java/com/adealink/weparty/module/network/data/ServerCode.kt
  17. 11 51
      app/src/main/java/com/adealink/weparty/module/profile/data/ProfileData2.kt
  18. 31 69
      app/src/main/java/com/adealink/weparty/module/profile/data/UserConfigType.kt
  19. 1 1
      app/src/main/java/com/adealink/weparty/module/profile/decorate/data/ExtraConfigData.kt
  20. 9 9
      app/src/main/java/com/adealink/weparty/module/rank/widget/RankTopUserView.kt
  21. 1 0
      app/src/main/java/com/adealink/weparty/module/room/data/RoomFlowData.kt
  22. 1 2
      app/src/main/java/com/adealink/weparty/module/room/data/RoomNotifyData.kt
  23. 3 0
      app/src/main/java/com/adealink/weparty/module/room/datasource/local/RoomLocalService.kt
  24. 10 1
      app/src/main/java/com/adealink/weparty/module/userlist/binder/UserInfoItemViewBinder.kt
  25. 1 1
      app/src/main/java/com/adealink/weparty/network/NetworkConfig.kt
  26. 2 2
      app/src/main/java/com/adealink/weparty/url/UrlConfig.kt
  27. BIN
      app/src/main/res/drawable-xhdpi/commonui_svip10_tag_ic.webp
  28. BIN
      app/src/main/res/drawable-xhdpi/commonui_svip1_tag_ic.webp
  29. BIN
      app/src/main/res/drawable-xhdpi/commonui_svip2_tag_ic.webp
  30. BIN
      app/src/main/res/drawable-xhdpi/commonui_svip3_tag_ic.webp
  31. BIN
      app/src/main/res/drawable-xhdpi/commonui_svip4_tag_ic.webp
  32. BIN
      app/src/main/res/drawable-xhdpi/commonui_svip5_tag_ic.webp
  33. BIN
      app/src/main/res/drawable-xhdpi/commonui_svip6_tag_ic.webp
  34. BIN
      app/src/main/res/drawable-xhdpi/commonui_svip7_tag_ic.webp
  35. BIN
      app/src/main/res/drawable-xhdpi/commonui_svip8_tag_ic.webp
  36. BIN
      app/src/main/res/drawable-xhdpi/commonui_svip9_tag_ic.webp
  37. BIN
      app/src/main/res/drawable-xhdpi/message_session_detail_svip_default_bg_1.webp
  38. BIN
      app/src/main/res/drawable-xhdpi/message_session_detail_svip_default_bg_2.webp
  39. 3 4
      app/src/main/res/layout/entereffect_layout_user_enter_banner_view.xml
  40. 37 63
      app/src/main/res/layout/item_home_user_info.xml
  41. 21 51
      app/src/main/res/layout/layout_car_cutomized_user.xml
  42. 20 0
      app/src/main/res/layout/layout_svip_level_view.xml
  43. 3 2
      app/src/main/res/values-ar/strings.xml
  44. 2 0
      app/src/main/res/values-zh/strings.xml
  45. 6 0
      app/src/main/res/values/colors.xml
  46. 1 1
      app/src/main/res/values/dimens.xml
  47. 2 0
      app/src/main/res/values/strings.xml
  48. 2 1
      frame/room/src/main/java/com/adealink/frame/room/data/RoomFlowData.kt
  49. 2 2
      gradle/libs.versions.toml
  50. 3 3
      module/backpack/src/main/java/com/adealink/weparty/backpack/adapter/BackpackGoodsUsingItemViewBinder.kt
  51. 5 8
      module/backpack/src/main/java/com/adealink/weparty/backpack/fragment/BackpackUsingTabFragment.kt
  52. 1 3
      module/call/src/main/java/com/adealink/weparty/call/comp/UserInfoComp.kt
  53. 3 3
      module/call/src/main/res/layout/layout_call_userinfo.xml
  54. 4 5
      module/family/src/main/java/com/adealink/weparty/family/apply/adapter/FamilyJoinApplyItemViewBinder.kt
  55. 2 6
      module/family/src/main/java/com/adealink/weparty/family/view/FamilyMemberView.kt
  56. 3 6
      module/family/src/main/java/com/adealink/weparty/family/view/FamilyOwnerView.kt
  57. 3 4
      module/family/src/main/res/layout/item_family_join_apply.xml
  58. 3 4
      module/family/src/main/res/layout/layout_family_member_view.xml
  59. 3 4
      module/family/src/main/res/layout/layout_family_owner_view.xml
  60. 5 0
      module/gift/src/main/java/com/adealink/weparty/gift/GiftPanelFragment.kt
  61. 4 10
      module/gift/src/main/java/com/adealink/weparty/gift/SendGiftPanelFragment.kt
  62. 1 1
      module/gift/src/main/java/com/adealink/weparty/gift/viewmodel/GiftPanelViewModel.kt
  63. 5 0
      module/gift/src/main/java/com/adealink/weparty/gift/viewmodel/GiftViewModel.kt
  64. 1 2
      module/headline/src/main/java/com/adealink/weparty/headline/data/Constants.kt
  65. 9 1
      module/headline/src/main/java/com/adealink/weparty/headline/fragment/HeadlineFragment.kt
  66. 3 3
      module/headline/src/main/java/com/adealink/weparty/headline/view/HeadlineViewBuilder.kt
  67. 16 19
      module/headline/src/main/java/com/adealink/weparty/headline/view/SvipLevelUpGlobalHeadline.kt
  68. BIN
      module/headline/src/main/res/drawable-xhdpi/headline_global_svip_bg.webp
  69. 8 10
      module/headline/src/main/res/layout/layout_svip_level_up_global_headline.xml
  70. BIN
      module/level/src/main/assets/svip_level_1.svga
  71. BIN
      module/level/src/main/assets/svip_level_10.svga
  72. BIN
      module/level/src/main/assets/svip_level_2.svga
  73. BIN
      module/level/src/main/assets/svip_level_3.svga
  74. BIN
      module/level/src/main/assets/svip_level_4.svga
  75. BIN
      module/level/src/main/assets/svip_level_5.svga
  76. BIN
      module/level/src/main/assets/svip_level_6.svga
  77. BIN
      module/level/src/main/assets/svip_level_7.svga
  78. BIN
      module/level/src/main/assets/svip_level_8.svga
  79. BIN
      module/level/src/main/assets/svip_level_9.svga
  80. 0 1
      module/level/src/main/java/com/adealink/weparty/level/LevelServiceImpl.kt
  81. 52 177
      module/level/src/main/java/com/adealink/weparty/level/SVIPLevelUpgradeDialog.kt
  82. 45 0
      module/level/src/main/java/com/adealink/weparty/level/adapter/itembinder/SVipRewardItemViewBinder.kt
  83. 1 0
      module/level/src/main/java/com/adealink/weparty/level/constants/Constants.kt
  84. 1 31
      module/level/src/main/java/com/adealink/weparty/level/data/LevelData.kt
  85. 4 0
      module/level/src/main/java/com/adealink/weparty/level/data/LevelSVipData.kt
  86. 5 0
      module/level/src/main/java/com/adealink/weparty/level/datasource/remote/LevelHttpService.kt
  87. 8 40
      module/level/src/main/java/com/adealink/weparty/level/dialog/SVipGuideDialog.kt
  88. 2 3
      module/level/src/main/java/com/adealink/weparty/level/manager/LevelManager.kt
  89. 41 2
      module/level/src/main/java/com/adealink/weparty/level/viewmodel/LevelViewModel.kt
  90. BIN
      module/level/src/main/res/drawable-ldrtl-xhdpi/level_svip_left_ic.png
  91. BIN
      module/level/src/main/res/drawable-ldrtl-xhdpi/level_svip_right_ic.png
  92. BIN
      module/level/src/main/res/drawable-xhdpi/gift_svip_tips_bg.png
  93. BIN
      module/level/src/main/res/drawable-xhdpi/level_svip_left_ic.png
  94. BIN
      module/level/src/main/res/drawable-xhdpi/level_svip_right_ic.png
  95. BIN
      module/level/src/main/res/drawable-xhdpi/svip_frame_1.webp
  96. BIN
      module/level/src/main/res/drawable-xhdpi/svip_frame_10.webp
  97. BIN
      module/level/src/main/res/drawable-xhdpi/svip_frame_2.webp
  98. BIN
      module/level/src/main/res/drawable-xhdpi/svip_frame_3.webp
  99. BIN
      module/level/src/main/res/drawable-xhdpi/svip_frame_4.webp
  100. BIN
      module/level/src/main/res/drawable-xhdpi/svip_frame_5.webp

+ 1 - 0
app/build.gradle

@@ -502,6 +502,7 @@ dependencies {
         implementation (libs.frame.trace.api)
     }
 
+    api libs.flexbox
 }
 
 

+ 24 - 68
app/src/main/java/com/adealink/weparty/imageselect/ImageSelectActivity.kt

@@ -5,28 +5,22 @@ import android.annotation.SuppressLint
 import android.app.Activity
 import android.content.Intent
 import android.os.Build
-import android.text.Spannable
-import android.text.SpannableStringBuilder
-import android.text.style.ForegroundColorSpan
 import android.view.View
 import androidx.activity.viewModels
-import androidx.annotation.ColorInt
 import androidx.recyclerview.widget.GridLayoutManager
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import com.adealink.frame.aab.util.getCompatColor
 import com.adealink.frame.aab.util.getCompatString
 import com.adealink.frame.base.Rlt
 import com.adealink.frame.base.fastLazy
-import com.adealink.frame.ext.safeSetSpan
 import com.adealink.frame.log.Log
 import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.frame.util.DisplayUtil
 import com.adealink.frame.util.FileProvider7
-import com.adealink.frame.util.timeToYMD
 import com.adealink.weparty.App
 import com.adealink.weparty.R
 import com.adealink.weparty.commonui.BaseActivity
+import com.adealink.weparty.commonui.ext.gone
 import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.commonui.recycleview.adapter.multitype.MultiTypeAdapter
 import com.adealink.weparty.commonui.recycleview.itemdecoration.GridSpacingItemDecoration
@@ -37,8 +31,6 @@ import com.adealink.weparty.hardware.Hardware
 import com.adealink.weparty.imageselect.cache.videoCoverCache
 import com.adealink.weparty.imageselect.clip.ClipImageLifecycleObserver
 import com.adealink.weparty.imageselect.clip.ClipParamData
-import com.adealink.weparty.imageselect.clip.MesTipData
-import com.adealink.weparty.imageselect.clip.MesType
 import com.adealink.weparty.imageselect.clip.avatarClipParam
 import com.adealink.weparty.imageselect.listener.OnOperateListener
 import com.adealink.weparty.imageselect.model.AddInfo
@@ -83,6 +75,7 @@ class ImageSelectActivity : BaseActivity(), OnOperateListener {
         const val KEY_IMAGE_MIN_SIZE = "image_min_size" //图片最小尺寸,默认800px
         const val MIN_IMAGE_AVATAR_SIZE = 800 //图片最小尺寸,默认800px
         const val MIN_IMAGE_NORMAL_SIZE = 400 //常规的图片最小尺寸,默认400px
+        const val TOP_TIPS_STRING = "top_tips_string" //顶部提示文字
     }
 
     private val binding by viewBinding(ActivityImageSelectBinding::inflate)
@@ -103,14 +96,13 @@ class ImageSelectActivity : BaseActivity(), OnOperateListener {
     private var mediaType: MediaType = MediaType.ALL
     private var clipParamData: ClipParamData? = null
     private var gifOpt: Boolean? = null
-    private var showMesTip: MesTipData? = null
-    private var coverExpireTime: Long = 0L
     private val fromPosition by fastLazy { intent.getIntExtra(KEY_FROM_POSITION, -1) }
     private val checkedMedias by fastLazy {
         intent.getParcelableArrayListExtra<LocalMedia>(KEY_SELECTED_MEDIA_LIST) ?: ArrayList()
     }
     private val videoMaxSecond by fastLazy { intent.getIntExtra(KEY_VIDEO_MAX_SECOND, -1) }
     private val imageMinSize by fastLazy { intent.getIntExtra(KEY_IMAGE_MIN_SIZE, -1) }
+    private var topTipsString: CharSequence? = null // 顶部提示文字
 
     override fun onBeforeCreate() {
         super.onBeforeCreate()
@@ -120,8 +112,8 @@ class ImageSelectActivity : BaseActivity(), OnOperateListener {
         clipParamData = intent.getParcelableExtra(KEY_CLIP_PARAM_DATA)
         mediaType = (intent.getSerializableExtra(KEY_MEDIA_TYPE) as? MediaType) ?: MediaType.ALL
         gifOpt = intent.getBooleanExtra(KEY_GIF_OPTION, false)
-        showMesTip = intent.getParcelableExtra(SHOW_MES_TIP)
-        coverExpireTime = intent.getLongExtra(COVER_EXPIRE_TIME, 0L)
+        topTipsString = intent.getCharSequenceExtra(TOP_TIPS_STRING)
+
     }
 
     override fun initViews() {
@@ -386,7 +378,12 @@ class ImageSelectActivity : BaseActivity(), OnOperateListener {
         if (mediaType != MediaType.VIDEO) {
             mediaInfoList.add(AddInfo(mediaType = MediaType.getMediaType(folder.ofAllType)))
         }
-        mediaInfoList.addAll(folder.getImages())
+        val localMediaList = folder.getImages()
+        if (gifOpt == true) {
+            localMediaList.sortBy { !PictureMimeType.isGif(it.mimeType) }
+        }
+
+        mediaInfoList.addAll(localMediaList)
         selectImageListAdapter.items = mediaInfoList
         selectImageListAdapter.notifyDataSetChanged()
     }
@@ -410,7 +407,10 @@ class ImageSelectActivity : BaseActivity(), OnOperateListener {
     }
 
     override fun onSelectImage(imageInfo: LocalMedia) {
-        if (imageMinSize > 0 && PictureMimeType.eqImage(imageInfo.mimeType)&& !PictureMimeType.isGif(imageInfo.mimeType)) {
+        if (imageMinSize > 0 && PictureMimeType.eqImage(imageInfo.mimeType) && !PictureMimeType.isGif(
+                imageInfo.mimeType
+            )
+        ) {
             if (imageInfo.width < imageMinSize || imageInfo.height < imageMinSize) {
                 showToast(R.string.photo_size_not_valid)
                 return
@@ -432,7 +432,10 @@ class ImageSelectActivity : BaseActivity(), OnOperateListener {
                 return
             }
 
-            if (imageMinSize > 0 && PictureMimeType.eqImage(item.mimeType)&& !PictureMimeType.isGif(item.mimeType)) {
+            if (imageMinSize > 0 && PictureMimeType.eqImage(item.mimeType) && !PictureMimeType.isGif(
+                    item.mimeType
+                )
+            ) {
                 if (item.width < imageMinSize || item.height < imageMinSize) {
                     showToast(R.string.photo_size_not_valid)
                     return
@@ -551,61 +554,14 @@ class ImageSelectActivity : BaseActivity(), OnOperateListener {
     }
 
     private fun updateMesText() {
-        if (showMesTip == null) {
-            binding.imageDirNameTv.text = ""
+        //具体的文案由外部根据业务逻辑进行设置,内部只做展示处理
+        if (topTipsString.isNullOrEmpty()){
+            binding.selectMesTipTv.gone()
             return
-        } else {
-            var canAble = ""
-            var color = 0
-            if (gifOpt == true) {
-                canAble = getCompatString(R.string.image_select_earned)
-                color = getCompatColor(R.color.color_FF00CAC1)
-            } else {
-                canAble = getCompatString(R.string.image_select_not_earned)
-                color = getCompatColor(R.color.color_FFFA5353)
-            }
-            getCompatString(R.string.image_select_room_cover_select_gif_tip, canAble)
-            val tipMes = when (showMesTip?.showMes ?: return) {
-                MesType.Avatar -> getCompatString(
-                    R.string.image_select_avatar_select_gif_tip,
-                    canAble
-                )  //头像
-                MesType.RoomCover ->
-                    if (gifOpt == true) {
-                        //房间封面
-                        getCompatString(
-                            R.string.image_select_room_cover_family,
-                            canAble,
-                            timeToYMD(coverExpireTime)
-                        )
-                    } else {
-                        ""
-                    }
-
-                else -> ""
-            }
-            binding.selectMesTipTv.text = SpannableStringBuilder(tipMes).apply {
-                highLightText(this, tipMes, canAble, color)
-            }
         }
+        binding.selectMesTipTv.show()
+        binding.selectMesTipTv.text = topTipsString
     }
 
-    private fun highLightText(
-        ssb: SpannableStringBuilder,
-        text: String,
-        highLightStr: String,
-        @ColorInt color: Int
-    ) {
-        if (highLightStr.isNotEmpty()) {
-            val index = text.indexOf(highLightStr)
-            if (index != -1) {
-                ssb.safeSetSpan(
-                    ForegroundColorSpan(color),
-                    index, index + highLightStr.length,
-                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
-                )
-            }
-        }
-    }
 
 }

+ 2 - 0
app/src/main/java/com/adealink/weparty/imageselect/SelectImageContract.kt

@@ -22,6 +22,7 @@ data class SelectImageRequest(
     val selectedLocalMedia: List<LocalMedia>? = null, //已选择图片列表
     val videoMaxSecond: Int? = null, //视频最长秒数限制
     val imageMinSize: Int? = null, //图片最小尺寸限制,宽度高度
+    val topTipsString: CharSequence? = null //顶部提示文字,支持富文本
 ) {
     companion object {
         const val SOURCE_EDIT_PROFILE_COVER = "3" //用户资料页封面
@@ -55,6 +56,7 @@ class SelectImageContract : ActivityResultContract<SelectImageRequest, SelectIma
             putParcelableArrayListExtra(ImageSelectActivity.KEY_SELECTED_MEDIA_LIST, input.selectedLocalMedia as? ArrayList)
             putExtra(ImageSelectActivity.KEY_VIDEO_MAX_SECOND, input.videoMaxSecond)
             putExtra(ImageSelectActivity.KEY_IMAGE_MIN_SIZE,input.imageMinSize)
+            putExtra(ImageSelectActivity.TOP_TIPS_STRING, input.topTipsString)
         }
     }
 

+ 3 - 1
app/src/main/java/com/adealink/weparty/imageselect/SelectImageLifecycleObserver.kt

@@ -84,6 +84,7 @@ abstract class SelectImageLifecycleObserver(
         selectedMediaList: List<LocalMedia>? = null,
         videoMaxSecond: Int? = null,
         imageMinSize : Int? = null, //图片最小尺寸限制,宽度高度
+        topTipsString: CharSequence? = null
     ) {
         launcher.launch(
             SelectImageRequest(
@@ -97,7 +98,8 @@ abstract class SelectImageLifecycleObserver(
                 fromPosition,
                 selectedMediaList,
                 videoMaxSecond,
-                imageMinSize
+                imageMinSize,
+                topTipsString
             )
         )
     }

+ 29 - 0
app/src/main/java/com/adealink/weparty/imageselect/constant/ImageSelectTopTips.kt

@@ -0,0 +1,29 @@
+package com.adealink.weparty.imageselect.constant
+
+import android.text.SpannableStringBuilder
+import com.adealink.frame.aab.util.getCompatString
+import com.adealink.weparty.R
+import com.adealink.weparty.module.profile.ProfileModule
+import com.adealink.weparty.module.profile.data.SVIPLevel
+import com.adealink.weparty.module.profile.data.SVIPLevel.Companion.isSatisfyLevel
+
+/**
+ * Created by XiaoDongLin.
+ * Date: 2025/7/21
+ */
+object ImageSelectTopTips {
+
+    /**
+     * 按需构造相应的tips提示
+     */
+    fun gifAvatarTips(): CharSequence {
+        val gifEnable = SVIPLevel.SEVEN.isSatisfyLevel(ProfileModule.getMyUserInfo()?.sVipLevel)
+        if (!gifEnable) {
+            return ""
+        }
+        return SpannableStringBuilder(getCompatString(R.string.set_gif_avatar_tips)).apply {
+
+        }
+    }
+
+}

+ 11 - 82
app/src/main/java/com/adealink/weparty/module/entereffect/effect/CarEffectView.kt

@@ -9,9 +9,9 @@ import android.util.AttributeSet
 import android.view.Gravity
 import android.view.View
 import android.view.ViewGroup
+import android.view.animation.DecelerateInterpolator
 import android.widget.FrameLayout
 import androidx.annotation.Keep
-import androidx.core.view.updateLayoutParams
 import com.adealink.frame.aab.util.getCompatString
 import com.adealink.frame.base.fastLazy
 import com.adealink.frame.effect.data.ERROR_ENTITY_NULL
@@ -30,13 +30,10 @@ import com.adealink.weparty.commonui.ext.gone
 import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.effect.EffectAnimType
 import com.adealink.weparty.module.entereffect.data.CarBannerType
-import com.adealink.weparty.module.entereffect.data.FamilyEnterConfig
 import com.adealink.weparty.module.entereffect.effect.data.CarEffectEntity
 import com.adealink.weparty.module.entereffect.view.CarCustomizedUserView
 import com.adealink.weparty.module.entereffect.view.CoupleEnterBannerView
-import com.adealink.weparty.module.entereffect.view.FamilyEnterView
 import com.adealink.weparty.module.entereffect.view.UserEnterBannerView
-import com.adealink.weparty.module.family.view.toFamilyInfo
 import com.tencent.qgame.animplayer.util.ScaleType as VIDEO_SCALE_TYPE
 
 @Keep
@@ -56,8 +53,6 @@ class CarEffectView @JvmOverloads constructor(
     private val effectViewHeight by fastLazy { DisplayUtil.dp2px(667f) }
     private val defaultCustomizedUserViewMarginBottom by fastLazy { DisplayUtil.dp2px(50f) }
 
-    private val familyEnterView by fastLazy { FamilyEnterView(context) }
-
     private var enterAnimatorSet: AnimatorSet? = null
     private var leaveAnimatorSet: AnimatorSet? = null
 
@@ -69,6 +64,8 @@ class CarEffectView @JvmOverloads constructor(
         addView(cpEnterBannerView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
 
         addView(effectView, LayoutParams.MATCH_PARENT, DisplayUtil.dp2px(667f))
+        addView(carCustomizedUserView, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
+
         val effectViewLp = effectView.layoutParams as LayoutParams
         effectViewLp.gravity = Gravity.BOTTOM
         effectView.layoutParams = effectViewLp
@@ -201,13 +198,6 @@ class CarEffectView @JvmOverloads constructor(
             val bottomMarginRatio = customizedConfig.bottomMarginRatio
             carCustomizedUserView.alpha = 0f
             carCustomizedUserView.show()
-            if (carCustomizedUserView.parent == null) {
-                addView(
-                    carCustomizedUserView,
-                    LayoutParams.WRAP_CONTENT,
-                    LayoutParams.WRAP_CONTENT
-                )
-            }
             carCustomizedUserView.updateUserInfo(customizedConfig, entity.userEnterAttr)
             if (customizedUserViewEnterDuration == null) {
                 // 随座驾动效消失
@@ -285,68 +275,6 @@ class CarEffectView @JvmOverloads constructor(
             }
         }
 
-        if (entity.userEnterAttr.familyInfo != null && entity.userEnterAttr.isFamilyDataValid()) {
-            val familyEnterConfig = entity.userEnterAttr.familyEnterConfig ?: FamilyEnterConfig()
-            val familyEnterTime = familyEnterConfig.enterTs
-
-            familyEnterView.alpha = 0f
-            familyEnterView.show()
-            familyEnterView.updateData(
-                familyInfo = entity.userEnterAttr.familyInfo.toFamilyInfo(),
-                userInfo = entity.userEnterAttr.roomUserInfo?.userInfo,
-                config = familyEnterConfig
-            )
-            if (familyEnterView.parent == null) {
-                addView(
-                    familyEnterView,
-                    LayoutParams.MATCH_PARENT,
-                    LayoutParams.WRAP_CONTENT
-                )
-                familyEnterView.updateLayoutParams<LayoutParams> {
-                    gravity = Gravity.BOTTOM
-                }
-            }
-
-            // 随座驾动效消失
-            playListener = object : IPlayListener {
-
-                override fun onComplete() {
-                    familyEnterView.animate()
-                        .alpha(0f)
-                        .setDuration(500)
-                        .setStartDelay(0)
-                        .withEndAction {
-                            familyEnterView.gone()
-                            carEntity.playListener?.onComplete()
-                            l?.onComplete()
-                        }
-                        .start()
-                }
-
-                override fun onError(errCode: Int) {
-                    familyEnterView.animate()
-                        .alpha(0f)
-                        .setDuration(500)
-                        .setStartDelay(3000)
-                        .withEndAction {
-                            familyEnterView.gone()
-                            carEntity.playListener?.onComplete()
-                            l?.onComplete()
-                        }
-                        .start()
-                }
-            }
-
-            familyEnterView.post {
-                familyEnterView.animate()
-                    .alpha(1f)
-                    .setDuration(500)
-                    .setStartDelay(familyEnterTime)
-                    .start()
-            }
-        } else {
-            familyEnterView.gone()
-        }
 
         when (showBannerType) {
             CarBannerType.CP -> {
@@ -467,7 +395,6 @@ class CarEffectView @JvmOverloads constructor(
                             override fun onAnimationEnd(animation: Animator) {
                                 super.onAnimationEnd(animation)
                                 carCustomizedUserView.gone()
-                                familyEnterView.gone()
                                 carEntity.playListener?.onComplete()
                                 l?.onComplete()
                             }
@@ -493,7 +420,6 @@ class CarEffectView @JvmOverloads constructor(
                             override fun onAnimationEnd(animation: Animator) {
                                 super.onAnimationEnd(animation)
                                 carCustomizedUserView.gone()
-                                familyEnterView.gone()
                                 carEntity.playListener?.onError(errCode)
                                 l?.onError(errCode)
                             }
@@ -577,12 +503,10 @@ class CarEffectView @JvmOverloads constructor(
         Log.d(TAG, "stop")
         enterBannerView.visibility = View.GONE
         cpEnterBannerView.visibility = View.GONE
-        familyEnterView.visibility = View.GONE
         effectView.stop()
         carCustomizedUserView.gone()
         enterBannerView.animate().cancel()
         cpEnterBannerView.animate().cancel()
-        familyEnterView.animate().cancel()
         enterAnimatorSet?.cancel()
         leaveAnimatorSet?.cancel()
     }
@@ -592,10 +516,15 @@ class CarEffectView @JvmOverloads constructor(
     private fun moveViewCenterTo(view: View, x: Int, y: Int) {
         val cx = x - view.width / 2
         val cy = y - view.height / 2
+
+        view.translationX = screenWidth.toFloat()
+//        view.x = (cx.toFloat())
+        view.y = (cy.toFloat())
+
         view.animate()
-            .x(cx.toFloat())
-            .y(cy.toFloat())
-            .setDuration(0)
+            .translationX(0f)
+            .setInterpolator(DecelerateInterpolator()) // 先快后慢
+            .setDuration(500)
             .start()
     }
 

+ 20 - 45
app/src/main/java/com/adealink/weparty/module/entereffect/view/CarCustomizedUserView.kt

@@ -2,25 +2,17 @@ package com.adealink.weparty.module.entereffect.view
 
 import android.content.Context
 import android.graphics.Color
-import android.text.TextUtils
 import android.util.AttributeSet
 import android.view.LayoutInflater
 import androidx.constraintlayout.widget.ConstraintLayout
-import androidx.core.view.updateLayoutParams
 import com.adealink.frame.aab.util.getCompatColor
-import com.adealink.frame.aab.util.getCompatDimensionPixelSize
-import com.adealink.frame.base.fastLazy
-import com.adealink.frame.data.json.froJsonErrorNull
+import com.adealink.frame.image.imageService
 import com.adealink.weparty.R
-import com.adealink.weparty.commonui.ext.dpf
-import com.adealink.weparty.commonui.ext.gone
-import com.adealink.weparty.commonui.ext.isSVGAImage
-import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.databinding.LayoutCarCutomizedUserBinding
+import com.adealink.weparty.effect.AnimExtraConfig
+import com.adealink.weparty.effect.SVGAExtraConfig
 import com.adealink.weparty.module.entereffect.data.RoomUserEnterAttr
-import com.adealink.weparty.module.profile.decorate.data.AvatarFrame
 import com.adealink.weparty.module.profile.decorate.data.CarCustomizedConfig
-import com.adealink.weparty.module.profile.decorate.data.DecorType
 import com.adealink.weparty.module.profile.view.UserNameTextView.Companion.getDisplayName
 import com.opensource.svgaplayer.SVGADynamicEntity
 
@@ -28,52 +20,35 @@ class CarCustomizedUserView @JvmOverloads constructor(
     context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0,
 ) : ConstraintLayout(context, attrs, defStyleAttr) {
     val binding = LayoutCarCutomizedUserBinding.inflate(LayoutInflater.from(context), this, true)
-    private val avatarDefaultSize: Int by fastLazy {
-        getCompatDimensionPixelSize(R.dimen.car_customized_user_avatar_size)
-    }
 
     fun updateUserInfo(config: CarCustomizedConfig, userEnterAttr: RoomUserEnterAttr) {
-        val avatarFrameRatio = config.avatarBgRatio ?: 1f
-        if (avatarFrameRatio > 0 && avatarFrameRatio != 1f) {
-            binding.afCl.updateLayoutParams<LayoutParams> {
-                width = (avatarDefaultSize * avatarFrameRatio).toInt()
-                height = (avatarDefaultSize * avatarFrameRatio).toInt()
-            }
-        }
-        if (isSVGAImage(config.avatarBg)) {
-            binding.avatarFrameIv.gone()
-            binding.avatarFrameSvga.show()
-            val frameExtra =
-                userEnterAttr.roomUserInfo?.configInfo?.get(DecorType.AVATAR_FRAME.value)
-            val avatarFrame = froJsonErrorNull<AvatarFrame>(frameExtra)
-            binding.avatarFrameSvga.setUrl(
-                url = config.avatarBg,
-                supplier = avatarFrame?.extraConfig?.createSVGADynamicSupplier()
+        binding.nameBgIv.setUrl(
+            config.nickBg,
+            extraConfig = AnimExtraConfig(
+                loop = 1,
+                svgaExtraConfig = SVGAExtraConfig(dynamicEntitySupplier = {
+                    SVGADynamicEntity().apply {
+                        val bitmap = imageService.getBitmapSync(
+                            url = userEnterAttr.roomUserInfo?.userInfo?.url
+                                ?: userEnterAttr.userAvatarUrl, 90
+                        )
+                        bitmap?.let {
+                            setDynamicImage(bitmap = it, forKey = "avatar")
+                        }
+                    }
+                })
             )
-        } else {
-            binding.avatarFrameIv.show()
-            binding.avatarFrameSvga.gone()
-            binding.avatarFrameIv.setImageUrl(config.avatarBg)
-        }
-        binding.avatarIv.setImageUrl(
-            userEnterAttr.roomUserInfo?.userInfo?.url ?: userEnterAttr.userAvatarUrl
         )
-        binding.nameBgIv.setImageUrl(config.nickBg)
-        val resultText =
-            TextUtils.ellipsize(getDisplayName(userEnterAttr.uid, userEnterAttr.userNick), binding.nameTv.paint, 84.dpf(), TextUtils.TruncateAt.END)
+        val resultText = getDisplayName(userEnterAttr.uid, userEnterAttr.userNick)
         binding.nameTv.text = resultText
         binding.nameTv.setTextColor(parseNameColor(config.nickColor))
-        binding.nameTv.updateLayoutParams<LayoutParams> {
-            horizontalBias =
-                userEnterAttr.userCarExtraConfig?.carCustomizedConfig?.horizontalBias ?: 0.5f
-        }
     }
 
     private fun parseNameColor(colorString: String): Int {
         return try {
             Color.parseColor(colorString)
         } catch (e: Exception) {
-            getCompatColor(R.color.color_FFFFE2B7)
+            getCompatColor(R.color.white)
         }
     }
 }

+ 1 - 2
app/src/main/java/com/adealink/weparty/module/entereffect/view/UserEnterBannerView.kt

@@ -11,7 +11,6 @@ import com.adealink.weparty.commonui.ext.isSVGAImage
 import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.databinding.EntereffectLayoutUserEnterBannerViewBinding
 import com.adealink.weparty.module.entereffect.data.RoomUserEnterAttr
-import com.adealink.weparty.module.level.util.updateSVipLabel
 import com.adealink.weparty.module.profile.view.UserNameTextView.Companion.getDisplayName
 import com.opensource.svgaplayer.WenextSvgaView
 import com.opensource.svgaplayer.control.ControllerListener
@@ -54,7 +53,7 @@ class UserEnterBannerView @JvmOverloads constructor(
         binding.avatar.setImageUrl(userEnterAttr.userImgUrl)
         binding.tvName.text = getDisplayName(userEnterAttr.uid, userEnterAttr.userNick)
         binding.tvContent.text = content
-        updateSVipLabel(userEnterAttr.sVipLevel, binding.vSVipLevel)
+        binding.vSVipLevel.updateLevel(userEnterAttr.sVipLevel)
         if (userEnterAttr.roomUserInfo?.userInfo?.isOfficial() == true) {
             binding.ivOfficial.show()
         } else {

+ 8 - 1
app/src/main/java/com/adealink/weparty/module/gift/data/GiftData.kt

@@ -169,6 +169,10 @@ data class GiftInfo(
         return vipType > 0 && type == GiftType.GOLD_COIN.type
     }
 
+    fun isSVipGift(): Boolean {
+        return type == GiftType.SVIP.type
+    }
+
     fun isNormalGift(): Boolean {
         return vipType == 0 && type == GiftType.GOLD_COIN.type
     }
@@ -490,6 +494,8 @@ enum class GiftType(val type: Int) {
     EXCLUSIVE(3), //专属礼物
     LUCKY(4), //幸运礼物
     FREE(5), //免费礼物
+
+    SVIP(8), //SVIP礼物
 }
 
 /**
@@ -657,7 +663,8 @@ enum class GiftPageType(val type: Int) {
     FLAG(4),
     EXCLUSIVE(5),
     BACKPACK(6),
-    LUCKY(7);
+    LUCKY(7),
+    SVIP(8); //SVIP礼物
 
     companion object {
         fun map(type: Int?): GiftPageType {

+ 60 - 37
app/src/main/java/com/adealink/weparty/module/level/data/LevelData.kt

@@ -177,37 +177,10 @@ data class VipUserInfoDynamicCard(
 )
 
 enum class VipBlockType(val type: Int) {
-    SendVipGift(1),
+    SendSVipGift(1),
     OpenSuperMic(2)
 }
 
-@Parcelize
-data class UserLevelConfigData(
-    @SerializedName("type") val type: Int,
-    @SerializedName("level") val level: Int,
-    @SerializedName("maxLevel") val maxLevel: Int,
-    @SerializedName("url") val url: String,
-    @SerializedName("name") val name: String,
-    @SerializedName("rewardPackageId") val rewardPackageId: Long,
-    @SerializedName("rewards") val rewards: List<RewardDetailData>?,
-    @SerializedName("status") val status: Int,//0是未达成,1已领取,2未领取
-) : Parcelable {
-
-    fun isReceived(): Boolean {
-        return status == 1
-    }
-
-    companion object {
-        const val TYPE_CUSTOM_ID = "12"
-        const val TYPE_BIRTHDAY_BAG = "21"
-        const val TYPE_LEVEL_UPGRADE = "24"
-
-
-        //确定一下这些值
-        const val TYPE_LEVEL_UPGRADE_BAG = "21"
-
-    }
-}
 
 
 // ============= start 用户物料配置新接口(结构跟其他项目不一样)=========
@@ -603,14 +576,6 @@ data class SVipConfig(
 @Parcelize
 data class SVIPLevelChangeNotify(
     @SerializedName("uid") val uid: Long,
-    /**
-     * 弹窗消息内容
-     */
-    @SerializedName("content") val content: String,
-    /**
-     * 弹窗静态图片
-     */
-    @SerializedName("url") val url: String,
     /**
      * "弹窗图片信息 - 勋章动态"
      */
@@ -631,6 +596,10 @@ data class SVIPLevelChangeNotify(
      * SVIP变更之前等级
      */
     @SerializedName("currentLevel") val currentLevel: Int,
+    /**
+     * SVIP等级奖励
+     */
+    @SerializedName("rewards") val rewards: List<RewardDetailData>? = null,
 ) : Parcelable
 
 @Parcelize
@@ -927,4 +896,58 @@ enum class LevelType(val type: Int) {
             }
         }
     }
-}
+}
+
+
+data class CommonLevelInfo(
+    @SerializedName("commonLevelConfigInfo")
+    val commonLevelConfigInfo: CommonLevelConfigInfo,
+    @SerializedName("createTime")
+    val createTime: String,
+    @SerializedName("currLevel")
+    val currLevel: Int,
+    @SerializedName("expire")
+    val expire: Long,
+    @SerializedName("lastLevel")
+    val lastLevel: Int,
+    @SerializedName("lastScore")
+    val lastScore: Long,
+    @SerializedName("levelTime")
+    val levelTime: String,
+    @SerializedName("levelType")
+    val levelType: Int,
+    @SerializedName("nextLevel")
+    val nextLevel: Int,
+    @SerializedName("nextLevelName")
+    val nextLevelName: String,
+    @SerializedName("nextScore")
+    val nextScore: Long,
+    @SerializedName("objectId")
+    val objectId: String,
+    @SerializedName("region")
+    val region: String,
+    @SerializedName("score")
+    val score: Long
+)
+
+data class UserSvipLevelReq(
+    @SerializedName("uid") val uid: Long
+)
+data class UserSvipLevelRes(
+    @SerializedName("userSvipInfo") val userSvipInfo: UserSvipLevelInfo
+)
+
+//后端来不及搞通用的数据结构
+data class UserSvipLevelInfo(
+    @SerializedName("uid") val uid: Long,//用户id
+    @SerializedName("svipLevel") val svipLevel: Int, //svip等级
+    @SerializedName("expire") val expire: Long, //svip过期时间
+    @SerializedName("score") val score: Int, //svip积分
+    @SerializedName("minScore") val minScore: Long, //svip保级分数
+    @SerializedName("lastSvipLevel") val lastSvipLevel: Int, //上次svip等级
+    @SerializedName("lastScore") val lastScore: Long, //上次svip积分
+    @SerializedName("nextSvipLevel") val nextSvipLevel: Int, //下次svip等级
+    @SerializedName("nextScore") val nextScore: Int, //下次svip积分
+    @SerializedName("levelTime") val levelTime: Long, //svip等级时间
+    @SerializedName("createTime") val createTime: Long //svip创建时间
+)

+ 0 - 55
app/src/main/java/com/adealink/weparty/module/level/svip/SvipFunctionDisableDialog.kt

@@ -1,55 +0,0 @@
-package com.adealink.weparty.module.level.svip
-
-import android.graphics.Color
-import android.graphics.drawable.ColorDrawable
-import android.view.Gravity
-import android.view.Window
-import android.view.WindowManager
-import com.adealink.frame.mvvm.view.viewBinding
-import com.adealink.frame.router.Router
-import com.adealink.frame.util.onClick
-import com.adealink.weparty.R
-import com.adealink.weparty.commonui.dialogfragment.BaseDialogFragment
-import com.adealink.weparty.databinding.DialogSvipFuntionDisableBinding
-import com.adealink.weparty.module.webview.Web
-import com.adealink.weparty.url.H5Page
-import com.adealink.weparty.url.urlConfigService
-
-/**
- * author : qimingfeng
- * e-mail : qimingfengwy@163.com
- * time   : 2024/10/22
- * desc   : svip功能不可用弹窗
- * version: 1.0
- */
-class SvipFunctionDisableDialog: BaseDialogFragment(R.layout.dialog_svip_funtion_disable) {
-
-    private val binding by viewBinding(DialogSvipFuntionDisableBinding::bind)
-
-    override fun resetWindowAttributes(window: Window) {
-        super.resetWindowAttributes(window)
-        window.setLayout(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT)
-        window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
-        val attr = window.attributes
-        attr.gravity = Gravity.CENTER
-        attr.dimAmount = 0.7f
-        window.attributes = attr
-    }
-
-    override fun initViews() {
-        super.initViews()
-        binding.ivClose.onClick { dismiss() }
-        binding.tvGo.onClick { onCheckSvipClick() }
-    }
-
-    /**
-     * 跳转svip页面
-     */
-    private fun onCheckSvipClick() {
-        val activity = activity ?: return
-        Router.build(activity, Web.FullScreen.PATH)
-            .putExtra(Web.Common.EXTRA_URL, urlConfigService.getH5Url(H5Page.SVIP))
-            .start()
-    }
-
-}

+ 0 - 96
app/src/main/java/com/adealink/weparty/module/level/util/SVipUIUtil.kt

@@ -1,40 +1,9 @@
 package com.adealink.weparty.module.level.util
 
-import android.net.Uri
-import android.view.View
-import android.widget.ImageView
-import com.adealink.frame.image.view.NetworkImageView
-import com.adealink.frame.util.isFileExists
 import com.adealink.weparty.R
-import com.adealink.weparty.commonui.ext.gone
-import com.adealink.weparty.commonui.ext.show
-import com.adealink.weparty.module.level.LevelModule
-import com.adealink.weparty.module.level.data.SVIP_CHAT_DEFAULT_BG_DEFAULT
-import com.adealink.weparty.module.level.data.SVIP_CHAT_DEFAULT_BG_LIST
-import com.adealink.weparty.module.level.data.SVIP_CHAT_DEFAULT_BG_PATH_1
-import com.adealink.weparty.module.level.data.SVIP_CHAT_DEFAULT_BG_PATH_2
 import com.adealink.weparty.module.profile.data.SVIPLevel
-import com.adealink.weparty.module.profile.data.SVIPLevel.Companion.isSatisfyLevel
-import com.adealink.weparty.module.profile.data.UserInfo
-import java.io.File
 
 
-fun updateSVipLabel(sVipLevel: Int, sVipLabelIv: NetworkImageView) {
-    if (sVipLevel <= 0) {
-        sVipLabelIv.gone()
-        return
-    }
-    val sVipLevelUrl = LevelModule.getSVipConfig(sVipLevel)?.labelUrl
-    if (sVipLevelUrl.isNullOrEmpty().not()) {
-        sVipLabelIv.show()
-        sVipLabelIv.post {
-            sVipLabelIv.setImageUrl(sVipLevelUrl)
-        }
-    } else {
-        sVipLabelIv.gone()
-    }
-}
-
 fun getSVipTagIcon(sVipLevel: Int?): Int? {
     return when (sVipLevel) {
         SVIPLevel.ONE.level -> R.drawable.commonui_svip1_tag_ic
@@ -49,70 +18,5 @@ fun getSVipTagIcon(sVipLevel: Int?): Int? {
     }
 }
 
-/**
- * 设置svip私聊背景图
- */
-fun setSVipSessionDetailDefaultTheme(iv: ImageView, path: String, vBg: View? = null) {
-    when (path) {
-        SVIP_CHAT_DEFAULT_BG_DEFAULT -> {
-            vBg?.show()
-            iv.setImageDrawable(null)
-        }
-
-        SVIP_CHAT_DEFAULT_BG_PATH_1 -> {
-            vBg?.gone()
-            iv.setImageResource(R.drawable.message_session_detail_svip_default_bg_1)
 
-        }
-
-        SVIP_CHAT_DEFAULT_BG_PATH_2 -> {
-            vBg?.gone()
-            iv.setImageResource(R.drawable.message_session_detail_svip_default_bg_2)
-        }
-
-        else -> {
-            if (isFileExists(path)) {
-                vBg?.gone()
-                iv.setImageURI(Uri.fromFile(File(path)))
-            } else {
-                vBg?.show()
-                iv.setImageDrawable(null)
-            }
-        }
-    }
-}
-
-/**
- * 是否用户自定义主题
- */
-fun isCustomTheme(path: String): Boolean {
-    return SVIP_CHAT_DEFAULT_BG_LIST.contains(path).not()
-}
-
-/**
- * 是否默认主题
- */
-fun isDefaultTheme(path: String): Boolean {
-    return path == SVIP_CHAT_DEFAULT_BG_DEFAULT
-}
-
-/**
- * 是否可用gif头像
- */
-fun isGifAvatarEnable(level: SVIPLevel): Boolean {
-    return level.level >= SVIPLevel.FIVE.level
-}
-
-fun isBigGiftNotice(level: Int): Boolean {
-    return level >= SVIPLevel.SIX.level
-}
 
-/**
- * 是否可用gif封面
- */
-fun isGitCoverEnable(userInfo: UserInfo?): Boolean {
-    userInfo ?: return false
-    return (userInfo.level ?: 0) >= LevelModule.LEVEL_CUSTOM_PROFILE_BG && SVIPLevel.SEVEN.isSatisfyLevel(
-        userInfo.sVipLevel
-    )
-}

+ 0 - 25
app/src/main/java/com/adealink/weparty/module/level/util/VipUIUtil.kt

@@ -1,22 +1,8 @@
 package com.adealink.weparty.module.level.util
 
-import android.view.View
 import androidx.appcompat.widget.AppCompatTextView
 import com.adealink.frame.image.view.NetworkImageView
-import com.adealink.weparty.R
-import com.adealink.weparty.commonui.ext.setHorizontalLinearGradient
-import com.adealink.weparty.module.level.LevelModule
-import com.adealink.weparty.module.profile.data.VIPLevel
 
-fun updateVipMedal(vipLevel: Int, vipMedalIv: NetworkImageView) {
-//    val vipMedal = LevelModule.getVipConfig(vipLevel)?.vipMedal()
-//    if (vipMedal?.icon.isNullOrEmpty().not()) {
-//        vipMedalIv.visibility = View.VISIBLE
-//        vipMedalIv.setImageUrl(vipMedal?.icon)
-//    } else {
-        vipMedalIv.visibility = View.GONE
-//    }
-}
 
 fun updateVipColorName(vipLevel: Int, nameTv: AppCompatTextView) {
 //    val vipColorName = LevelModule.getVipConfig(vipLevel)?.vipColorName
@@ -32,14 +18,3 @@ fun updateVipOnlineBg(vipLevel: Int, bgIv: NetworkImageView) {
 //    bgIv.setImageUrl(LevelModule.getVipConfig(vipLevel)?.vipOnlineListBg)
 }
 
-fun getVipTagIcon(vipLevel: Int?): Int? {
-    return when (vipLevel) {
-        VIPLevel.ONE.level -> R.drawable.vip_medal_vip1
-        VIPLevel.TWO.level -> R.drawable.vip_medal_vip2
-        VIPLevel.THREE.level -> R.drawable.vip_medal_vip3
-        VIPLevel.FOUR.level -> R.drawable.vip_medal_vip4
-        VIPLevel.FIVE.level -> R.drawable.vip_medal_vip5
-        VIPLevel.SIX.level -> R.drawable.vip_medal_vip6
-        else -> null
-    }
-}

+ 61 - 0
app/src/main/java/com/adealink/weparty/module/level/view/UserSVipLevelView.kt

@@ -0,0 +1,61 @@
+package com.adealink.weparty.module.level.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.view.updateLayoutParams
+import com.adealink.weparty.commonui.ext.gone
+import com.adealink.weparty.commonui.ext.show
+import com.adealink.weparty.databinding.LayoutSvipLevelViewBinding
+import com.opensource.svgaplayer.control.ControllerListener
+import com.opensource.svgaplayer.entities.SvgaInfo
+
+/**
+ * SVIP等级标签View,外部只需要指定高度就行
+ * Created by XiaoDongLin.
+ * Date: 2025/7/18
+ */
+interface IUserSVipLevelView {
+    /**
+     * 更新SVIP等级
+     * @param level SVIP等级
+     */
+    fun updateLevel(level: Int)
+}
+
+class UserSVipLevelView @JvmOverloads constructor(
+    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+) : ConstraintLayout(context, attrs, defStyleAttr), IUserSVipLevelView {
+
+    private val binding = LayoutSvipLevelViewBinding.inflate(LayoutInflater.from(context), this)
+
+    init {
+        //默认不可见
+        gone()
+    }
+
+    override fun updateLevel(level: Int) {
+        if (level <= 0) {
+            gone()
+            return
+        }
+        show()
+
+        binding.svgaSvip.setAsset("svip_level_$level.svga", listener = object : ControllerListener {
+            override fun onBeforeImageSet(id: String?, svgaInfo: SvgaInfo?) {
+                super.onBeforeImageSet(id, svgaInfo)
+                svgaInfo ?: return
+                val svgaWidth = svgaInfo.width
+                val svgaHeight = svgaInfo.height
+                if (svgaWidth > 0 && svgaHeight > 0) {
+                    binding.svgaSvip.updateLayoutParams<ConstraintLayout.LayoutParams> {
+                        dimensionRatio = "${svgaWidth}:${svgaHeight}"
+                    }
+                }
+            }
+        })
+        binding.svgaSvip.startAnimation()
+    }
+
+}

+ 6 - 4
app/src/main/java/com/adealink/weparty/module/level/viewmodel/ILevelViewModel.kt

@@ -1,11 +1,13 @@
 package com.adealink.weparty.module.level.viewmodel
 
 import androidx.lifecycle.LiveData
-import com.adealink.frame.base.Rlt
-import com.adealink.frame.network.data.Res
-import com.adealink.weparty.module.level.data.LevelUpgradeNotify
-import com.adealink.weparty.module.level.data.UserLevelInfo
+import com.adealink.weparty.module.level.data.CommonLevelInfo
+import com.adealink.weparty.module.level.data.LevelType
+import com.adealink.weparty.module.level.data.UserSvipLevelInfo
 
 interface ILevelViewModel {
 
+    fun getCommonLevelInfo(levelType: LevelType): LiveData<CommonLevelInfo>
+
+    fun getUserSVipInfo(): LiveData<UserSvipLevelInfo>
 }

+ 5 - 2
app/src/main/java/com/adealink/weparty/module/network/data/ServerCode.kt

@@ -97,7 +97,6 @@ enum class ServerCode(val code: Int) {
     ROOM_MIC_ONLY_PERMIT_INVITE(3041),//房间只允许邀请上麦
     ROOM_TEXT_ONLY_OPEN_FOR_ADMIN_AND_MIC_USER(3044),//公屏只对麦上用户以及房间管理员开放
     NO_RANKING(3047),//用户活动没有上榜
-    CANT_KICK_ANTIKICK_VIP(3049),//不能踢具有防踢权限的贵族用户
     INVISIABLE_FORBIDDEN(3051),//房间内隐身用户不能做该操作
     FUNCTION_LIMIT_FOR_SENSITIVE_WORD(3060),//单天敏感词命中太多次,功能被封禁
     PK_ACCEPTED(3071),//PK已经被接受了
@@ -126,5 +125,9 @@ enum class ServerCode(val code: Int) {
     CHARISAMA_LEVEL_NOT_ENOUGH(4124),//魅力等级不够
     GOOGLE_AUTHOR_FAILED(4500),//谷歌封禁地区授权
     GAME_IN_PROGRESS(4061), //存在进行中的游戏
-    GAME_COIN_NOT_ENOUGH(4209); //游戏币不足
+    GAME_COIN_NOT_ENOUGH(4209), //游戏币不足
+
+    CANNOT_KICK_OUT_ANITKICK(5719),//不能踢具有防踢权限的用户(比如SVIP)
+    CANNOT_MUTE_ANITKICK(5720) //不能禁言具有防禁言权限的用户(比如SVIP)
+    ;
 }

+ 11 - 51
app/src/main/java/com/adealink/weparty/module/profile/data/ProfileData2.kt

@@ -109,10 +109,6 @@ data class UserInfo(
     @GsonNullable
     @SerializedName("vipLevel") var vipLevel: Int? = null,
     @GsonNullable
-    @SerializedName("svipLevel") var sVipLevel: Int? = null,
-    @GsonNullable
-    @SerializedName("userSvipConfigInfo") val userSvipConfigInfo: UserSvipConfigInfo? = null,
-    @GsonNullable
     @SerializedName("showNewTag") var showNewTag: Boolean? = null,//是否显示new标签
 //    @SerializedName("whitelistForNewTag") var whitelistForNewTag: Boolean = false,//白名单用户可看到new标签
     @SerializedName("highPotential") var highPotential: Boolean = false,//是否为高潜用户
@@ -404,32 +400,18 @@ data class UserInfo(
             UserConfigType.USER_CHARM_LEVEL,
             UserConfigType.ACTIVITY_TAG,
             UserConfigType.USER_PRIVACY_ALBUM,
-            UserConfigType.USER_CHAT_ACHIEVEMENT
-        )
-
-        val ALL_PROFILE_ATTR_SET = setOf(
-            *NECESSARY_USER_ATTR_SET.toTypedArray(),
-            UserConfigType.USER_COUNTRY,
-            UserConfigType.USER_INVISIBLE_JOIN,
-            UserConfigType.USER_ATTR_PHOTO_WALL,
-            UserConfigType.USER_ATTR_PHOTO_COVER,
-//            UserConfigType.BUY_NEW_USER,
-            UserConfigType.USER_ATTR_FAMILY
-        )
-
-        val SVIP_INFO_ATTR_SET = setOf(
-//            UserConfigType.AVATAR_FRAME,
-            UserConfigType.USER_ATTR_BASIC,
-            UserConfigType.USER_ATTR_SVIP
+            UserConfigType.USER_CHAT_ACHIEVEMENT,
+            UserConfigType.USER_ATTR_SVIP,
+            UserConfigType.USER_INVISIBLE_JOIN
         )
 
-        val USER_INFO_AVATAR_FRAME_SET = setOf(
-//            UserConfigType.AVATAR_FRAME,
-            UserConfigType.USER_ATTR_BASIC,
-        )
+    }
 
+    val sVipLevel: Int
+        get() {
+            return commonConfigInfo?.getUserSVipConfigContent()?.getSVipLevel() ?: 0
+        }
 
-    }
 
     fun isOfficial(): Boolean = role == UserRole.OFFICIAL.role
 
@@ -781,7 +763,9 @@ enum class SVIPLevel(val level: Int) {
     FIVE(5),
     SIX(6),
     SEVEN(7),
-    EIGHT(8);
+    EIGHT(8),
+    NINE(9),
+    TEN(10);
 
     companion object {
         fun map(type: Int): SVIPLevel {
@@ -792,30 +776,6 @@ enum class SVIPLevel(val level: Int) {
          * 满足指定等级等级要求
          */
         fun SVIPLevel.isSatisfyLevel(level: Int?): Boolean {
-//            return (level ?: ZERO.level) >= this.level
-            return false
-        }
-    }
-}
-
-enum class VIPLevel(val level: Int) {
-    ZERO(0),
-    ONE(1),
-    TWO(2),
-    THREE(3),
-    FOUR(4),
-    FIVE(5),
-    SIX(6);
-
-    companion object {
-        fun map(type: Int): VIPLevel {
-            return VIPLevel.values().firstOrNull { it.level == type } ?: ZERO
-        }
-
-        /**
-         * 满足指定等级等级要求
-         */
-        fun VIPLevel.isSatisfyLevel(level: Int?): Boolean {
             return (level ?: ZERO.level) >= this.level
         }
     }

+ 31 - 69
app/src/main/java/com/adealink/weparty/module/profile/data/UserConfigType.kt

@@ -248,6 +248,11 @@ data class UserCommonConfig(
             intDataValue4 = collection.videoInvitePermission
         }
     }
+
+    fun getUserSVipConfigContent(): UserSVipConfigContent? {
+        return (userConfigValue?.get(UserConfigType.USER_ATTR_SVIP.type)
+            ?.convertToUserConfigContent() as? UserSVipConfigContent)
+    }
 }
 
 @Parcelize
@@ -300,21 +305,12 @@ data class UserCommonConfigInfo(
 //                UserIsInvisible(intDataValue1)
 //            }
 //
-//            UserConfigType.USER_ATTR_SVIP -> {
-//                UserSVipConfigContent(
-//                    intDataValue1,
-//                    intDataValue2,
-//                    intDataValue3,
-//                    intDataValue4,
-//                    intDataValue5,
-//                    intDataValue6,
-//                    intDataValue7,
-//                    intDataValue8,
-//                    intDataValue9,
-//                    stringDataValue1,
-//                    stringDataValue2
-//                )
-//            }
+            UserConfigType.USER_ATTR_SVIP -> {
+                UserSVipConfigContent(
+                    stringDataValue1,
+                    stringDataValue2
+                )
+            }
 
 //            UserConfigType.AVATAR_FRAME -> {
 //                UserAvatarConfigContent(stringDataValue1)
@@ -394,6 +390,10 @@ data class UserCommonConfigInfo(
                 AvatarQualityResultContent(stringDataValue1)
             }
 
+            UserConfigType.USER_INVISIBLE_JOIN -> {
+                UserIsInvisible(intDataValue1)
+            }
+
             else -> {
                 EmptyUserConfigContent()
             }
@@ -456,72 +456,19 @@ data class IsNewBieUser(
 }
 
 class UserSVipConfigContent(
-    @SerializedName("intDataValue1") val isChatBubblesOpen: Long, //聊天气泡开关
-    @SerializedName("intDataValue2") val isSpeakingRippleOpen: Long, //麦位动效开关
-    @SerializedName("intDataValue3") val isPrivateChatBubblesOpen: Long, //私聊气泡开关
-    @SerializedName("intDataValue4") val isRoomMemberInfoBackground: Long, //是否显示SVIP房间资料卡背景
-    @SerializedName("intDataValue5") val isMicStyleOpen: Long, //麦位样式开关
-    @SerializedName("intDataValue6") val isProfileThemeOpen: Long, //资料页主题开关
-    @SerializedName("intDataValue7") val isDisableFollowOpen: Long, //无法关注开关
-    @SerializedName("intDataValue8") val isRankMysteryOpen: Long, //榜单神秘人开关
-    @SerializedName("intDataValue9") val isRoomMysteryOpen: Long, //房间神秘人开关
     @SerializedName("strDataValue1") val sVipLevelStr: String, //svip等级
     @SerializedName("strDataValue2") val sVipMedal: String //等级勋章信息
 ) :
     UserConfigContent() {
     override fun areContentsTheSame(newItem: UserConfigContent): Boolean {
         val other = newItem as? UserSVipConfigContent ?: return false
-        return isChatBubblesOpen == other.isChatBubblesOpen
-                && isSpeakingRippleOpen == other.isSpeakingRippleOpen
-                && isPrivateChatBubblesOpen == other.isPrivateChatBubblesOpen
-                && isRoomMemberInfoBackground == other.isRoomMemberInfoBackground
-                && isMicStyleOpen == other.isMicStyleOpen
-                && isProfileThemeOpen == other.isProfileThemeOpen
-                && isDisableFollowOpen == other.isDisableFollowOpen
-                && isRankMysteryOpen == other.isRankMysteryOpen
-                && isRoomMysteryOpen == other.isRoomMysteryOpen
+        return sVipLevelStr == other.sVipLevelStr
                 && sVipMedal == other.sVipMedal
     }
 
-    fun isChatBubblesOpen(): Boolean {
-        return isChatBubblesOpen == 1L
-    }
-
-    fun isSpeakingRippleOpen(): Boolean {
-        return isSpeakingRippleOpen == 1L
-    }
-
-    fun isPrivateChatBubblesOpen(): Boolean {
-        return isPrivateChatBubblesOpen == 1L
-    }
-
-    fun isMicStyleOpen(): Boolean {
-        return isMicStyleOpen == 1L
-    }
-
-    fun isProfileThemeOpen(): Boolean {
-        return isProfileThemeOpen == 1L
-    }
-
-    fun isDisableFollowOpen(): Boolean {
-        return isDisableFollowOpen == 1L
-    }
-
-    fun isRankMysteryOpen(): Boolean {
-        return isRankMysteryOpen == 1L
-    }
-
-    fun isRoomMysteryOpen(): Boolean {
-        return isRoomMysteryOpen == 1L
-    }
-
     fun getSVipLevel(): Int {
         return sVipLevelStr.toIntOrNull() ?: 0
     }
-
-    fun isRoomMemberInfoBackground(): Boolean {
-        return isRoomMemberInfoBackground == 1L
-    }
 }
 
 data class RoomMemberEnterEffectConfigContent(
@@ -802,3 +749,18 @@ data class NewUserCustomerAcceptanceContent(
         return flag == 1L
     }
 }
+
+
+class UserIsInvisible(
+    @SerializedName("intDataValue1") val isInvisible: Long, //是否开启房间隐身
+) :
+    UserConfigContent() {
+    override fun areContentsTheSame(newItem: UserConfigContent): Boolean {
+        val other = newItem as? UserIsInvisible ?: return false
+        return isInvisible == other.isInvisible
+    }
+
+    fun userIsInvisible(): Boolean {
+        return isInvisible.toInt() == 1
+    }
+}

+ 1 - 1
app/src/main/java/com/adealink/weparty/module/profile/decorate/data/ExtraConfigData.kt

@@ -31,7 +31,7 @@ data class GoodsExtraConfig(
     @GsonNullable
     @SerializedName("commonLevel") val commonLevel: CommonLevelConfig? = null,
     @GsonNullable
-    @SerializedName("carExtraConfig") val carCustomizedConfig: CarCustomizedConfig? = null,
+    @SerializedName("carExtraConfigV2") val carCustomizedConfig: CarCustomizedConfig? = null,
     @GsonNullable
     @SerializedName("subResourceUrl") val subResourceUrl: String? = null,//副资源动效文件
 ) : Parcelable {

+ 9 - 9
app/src/main/java/com/adealink/weparty/module/rank/widget/RankTopUserView.kt

@@ -34,7 +34,7 @@ class RankTopUserView @JvmOverloads constructor(
     private val autoRollTask by fastLazy { AutoSwitchTask(this) }
 
     private var index = 0
-    private var rankUserList: List<List<com.adealink.weparty.module.profile.data.UserInfo?>>? = null
+    private var rankUserList: List<List<UserInfo?>>? = null
 
     private var defaultAvatarResource: Int? = null
 
@@ -45,7 +45,7 @@ class RankTopUserView @JvmOverloads constructor(
     /**
      * 设置头像信息
      */
-    fun setUserInfos(userInfos: List<List<com.adealink.weparty.module.profile.data.UserInfo?>>?, autoSwitch: Boolean = true, delay: Long = DEFAULT_ROLL_INTERVAL_MS) {
+    fun setUserInfos(userInfos: List<List<UserInfo?>>?, autoSwitch: Boolean = true, delay: Long = DEFAULT_ROLL_INTERVAL_MS) {
         reset()
         index = 0
         rankUserList = userInfos
@@ -64,7 +64,7 @@ class RankTopUserView @JvmOverloads constructor(
         updateViewBy(currentView, getIntroAt(index))
     }
 
-    private fun updateViewBy(view: View, useInfos: List<com.adealink.weparty.module.profile.data.UserInfo?>?) {
+    private fun updateViewBy(view: View, useInfos: List<UserInfo?>?) {
         val viewBinding = RankLayoutTopUserBinding.bind(view)
         setDefaultAvatar(viewBinding.avatarCenter)
         setAvatarUrl(viewBinding.avatarCenter, useInfos?.getOrNull(0))
@@ -87,16 +87,16 @@ class RankTopUserView @JvmOverloads constructor(
         }
     }
 
-    private fun setAvatarUrl(avatarView: NetworkImageView, userInfo: com.adealink.weparty.module.profile.data.UserInfo?) {
+    private fun setAvatarUrl(avatarView: NetworkImageView, userInfo: UserInfo?) {
         if (userInfo != null) {
             if (userInfo.url?.isEmpty()==true) {
                 avatarView.setActualImageResource(R.drawable.common_default_avatar_ic)
             } else {
-                if (userInfo.userSvipConfigInfo?.isRankMysteryOpen() == true) { //开启榜单神秘人
-                    avatarView.setActualImageResource(R.drawable.common_default_avatar_mystery_ic)
-                } else {
-                    avatarView.setImageUrl(userInfo.url)
-                }
+//                if (userInfo.userSvipConfigInfo?.isRankMysteryOpen() == true) { //开启榜单神秘人
+//                    avatarView.setActualImageResource(R.drawable.common_default_avatar_mystery_ic)
+//                } else {
+//                    avatarView.setImageUrl(userInfo.url)
+//                }
             }
         } else {
             avatarView.setActualImageResource(

+ 1 - 0
app/src/main/java/com/adealink/weparty/module/room/data/RoomFlowData.kt

@@ -160,6 +160,7 @@ data class SocketJoinRoomReq(
     @SerializedName("roomId") val roomId: Long,
     @SerializedName("password") val password: String? = null,
     @SerializedName("reconnectJoinRoom") val reconnectJoinRoom: Boolean = false,
+    @SerializedName("invisibleJoin") val invisibleJoin: Boolean? = null,
     @SerializedName("versionCode") val versionCode: Int = PackageUtil.getVersionCode(),
     @SerializedName("platform") val platform: String = AppBaseInfo.platform,
     @SerializedName("packageName") val packageName: String = PackageUtil.getPackageName(),

+ 1 - 2
app/src/main/java/com/adealink/weparty/module/room/data/RoomNotifyData.kt

@@ -7,7 +7,6 @@ import com.adealink.weparty.module.level.data.CongratulateUserLevelUpNotify
 import com.adealink.weparty.module.profile.data.UserInfo
 import com.adealink.weparty.module.profile.decorate.data.DecorType
 import com.google.gson.annotations.GsonNullable
-import com.google.gson.annotations.JsonAdapter
 import com.google.gson.annotations.Must
 import com.google.gson.annotations.SerializedName
 import kotlinx.parcelize.Parcelize
@@ -70,7 +69,7 @@ enum class RoomNotifyType(val uri: String) {
     TEXAS_COWBOY_REWARD_NOTIFY("TEXAS_POKER_REWARD_NOTIFY"),
     GREEDY_PERSONAL_REWARD_NOTIFY("PERSONAL_LOTTERY_REWARD_NOTIFY"),//greedy personal
 
-    //    SVIP_GLOBAL_NOTIFY("URI_SVIP_GLOBAL_NOTIFY");   // SVIP 升级全服通知
+    SVIP_GLOBAL_NOTIFY("URI_SVIP_GLOBAL_NOTIFY"),   // SVIP 升级全服通知
     COMMON_LEVEL_CHANGE_NOTIFY("COMMON_LEVEL_CHANGE_NOTIFY"),
     URI_CONGRATULATE_LEVEL_UP_NOTIFY("URI_CONGRATULATE_LEVEL_UP_NOTIFY"),  //财富等级升级通知
     // Q:拉新活动相关奖励的Notify应不仅仅隶属Room,目前只有房间可见通知横幅,故沿用写法;

+ 3 - 0
app/src/main/java/com/adealink/weparty/module/room/datasource/local/RoomLocalService.kt

@@ -93,4 +93,7 @@ object RoomLocalService : TypeDelegationPrefs(
     var clickedRoomWeddingPrivilege: Boolean by PrefKey("key_clicked_room_wedding_privilege", false)
 
     var mediaConflictRemind: Boolean by PrefUserKey("key_room_media_conflict_remind", true)
+
+    // 是否开启隐身进房
+    var isOpenInvisible: Boolean by PrefUserKey("key_user_is_open_invisible", false)
 }

+ 10 - 1
app/src/main/java/com/adealink/weparty/module/userlist/binder/UserInfoItemViewBinder.kt

@@ -63,7 +63,16 @@ class UserInfoItemViewBinder(val lifecycleOwner: LifecycleOwner) :
             } else {
                 svgaInRoom.hide()
             }
-            vipRechargeLabelView.updateVipRechargeLevel(item.userInfo.getVipRechargeLevel())
+            if (item.userInfo.sVipLevel > 0) {
+                svipLevelView.updateLevel(item.userInfo.sVipLevel)
+                vipRechargeLabelView.gone()
+            } else if (item.userInfo.getVipRechargeLevel()>0){
+                svipLevelView.gone()
+                vipRechargeLabelView.updateVipRechargeLevel(item.userInfo.getVipRechargeLevel())
+            }else{
+                svipLevelView.gone()
+                vipRechargeLabelView.gone()
+            }
 
             updateChatAchievementLabel(
                 item.userInfo.commonConfigInfo?.getChatAchievement()?.identityType,

+ 1 - 1
app/src/main/java/com/adealink/weparty/network/NetworkConfig.kt

@@ -67,7 +67,7 @@ class NetworkConfig : INetworkConfig {
     override val httpAntiBanConfigUrl: String
         get() = "http://49.51.172.109:8080/api/config/getHostEndpointConfig"
     override val githubAntiBanConfigUrl: String
-        get() = "https://raw.githubusercontent.com/wenext09/config/main/yoki/host.json"
+        get() = "https://raw.githubusercontent.com/wenext-09/config/main/yoki/host.json"
     override val hardcodeMainHosts: List<String>
         get() {
             return when {

+ 2 - 2
app/src/main/java/com/adealink/weparty/url/UrlConfig.kt

@@ -122,8 +122,8 @@ object UrlConfig {
     }
 
     internal val svip = when {
-        isProdEnv -> "https://web.wenext.chat/web/yoki-svip"
-        else -> "http://web-test.wenext.chat/web/yoki-svip"
+        isProdEnv -> "https://web.yoki.chat/web/yoki-vip/index/svip"
+        else -> "http://web-test.yoki.chat/web/yoki-vip/index/svip"
     }
 
     internal val familyTaskList = when {

BIN
app/src/main/res/drawable-xhdpi/commonui_svip10_tag_ic.webp


BIN
app/src/main/res/drawable-xhdpi/commonui_svip1_tag_ic.webp


BIN
app/src/main/res/drawable-xhdpi/commonui_svip2_tag_ic.webp


BIN
app/src/main/res/drawable-xhdpi/commonui_svip3_tag_ic.webp


BIN
app/src/main/res/drawable-xhdpi/commonui_svip4_tag_ic.webp


BIN
app/src/main/res/drawable-xhdpi/commonui_svip5_tag_ic.webp


BIN
app/src/main/res/drawable-xhdpi/commonui_svip6_tag_ic.webp


BIN
app/src/main/res/drawable-xhdpi/commonui_svip7_tag_ic.webp


BIN
app/src/main/res/drawable-xhdpi/commonui_svip8_tag_ic.webp


BIN
app/src/main/res/drawable-xhdpi/commonui_svip9_tag_ic.webp


BIN
app/src/main/res/drawable-xhdpi/message_session_detail_svip_default_bg_1.webp


BIN
app/src/main/res/drawable-xhdpi/message_session_detail_svip_default_bg_2.webp


+ 3 - 4
app/src/main/res/layout/entereffect_layout_user_enter_banner_view.xml

@@ -40,14 +40,13 @@
             app:layout_constraintBottom_toBottomOf="@id/avatar"
             app:layout_constraintEnd_toEndOf="@id/avatar" />
 
-        <com.adealink.frame.image.view.NetworkImageView
+        <com.adealink.weparty.module.level.view.UserSVipLevelView
             android:id="@+id/v_s_vip_level"
-            android:layout_width="0dp"
-            android:layout_height="18dp"
+            android:layout_width="wrap_content"
+            android:layout_height="15dp"
             android:layout_marginStart="4dp"
             android:visibility="gone"
             app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintDimensionRatio="376:148"
             app:layout_constraintStart_toEndOf="@id/avatar"
             app:layout_constraintTop_toTopOf="parent" />
 

+ 37 - 63
app/src/main/res/layout/item_home_user_info.xml

@@ -3,8 +3,9 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
-    android:layout_height="98dp"
-    android:background="@color/white">
+    android:layout_height="wrap_content"
+    android:background="@color/white"
+    android:minHeight="98dp">
 
     <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/avatar_layout"
@@ -74,12 +75,12 @@
         app:layout_constraintStart_toEndOf="@+id/tv_user_name"
         app:layout_constraintTop_toTopOf="@+id/tv_user_name" />
 
-
-    <HorizontalScrollView
+    <com.google.android.flexbox.FlexboxLayout
         android:id="@+id/other_info_layout"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginStart="5dp"
+        app:alignItems="center"
         app:layout_constrainedWidth="true"
         app:layout_constraintBottom_toTopOf="@+id/tv_introduction"
         app:layout_constraintEnd_toStartOf="@+id/barrier_right"
@@ -87,66 +88,39 @@
         app:layout_constraintStart_toEndOf="@+id/avatar_layout"
         app:layout_constraintTop_toBottomOf="@+id/tv_user_name">
 
-        <androidx.constraintlayout.widget.ConstraintLayout
+        <com.adealink.weparty.module.profile.view.UserCountryView
+            android:id="@+id/user_country_view"
+            android:layout_width="18dp"
+            android:layout_height="18dp"
+            tools:background="@drawable/label_good_id_bg" />
+
+        <com.adealink.weparty.module.profile.view.UserSexView
+            android:id="@+id/user_sex_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="4dp" />
+
+        <com.adealink.weparty.module.level.view.UserSVipLevelView
+            android:id="@+id/svip_level_view"
+            android:layout_width="wrap_content"
+            android:layout_height="15dp" />
+
+        <com.adealink.weparty.module.level.view.VipRechargeLabelView
+            android:id="@+id/vip_recharge_label_view"
+            android:layout_width="wrap_content"
+            android:layout_height="14.5dp"
+            android:layout_marginStart="4dp"
+            tools:background="@drawable/label_good_id_bg"
+            tools:visibility="visible" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_chat_achievement"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content">
-
-            <com.adealink.weparty.module.profile.view.UserCountryView
-                android:id="@+id/user_country_view"
-                android:layout_width="18dp"
-                android:layout_height="18dp"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toTopOf="parent"
-                tools:background="@drawable/label_good_id_bg" />
-
-            <com.adealink.weparty.module.profile.view.UserSexView
-                android:id="@+id/user_sex_view"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginStart="4dp"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintStart_toEndOf="@id/user_country_view"
-                app:layout_constraintTop_toTopOf="parent" />
-
-            <com.adealink.weparty.module.level.view.VipRechargeLabelView
-                android:id="@+id/vip_recharge_label_view"
-                android:layout_width="wrap_content"
-                android:layout_height="14.5dp"
-                android:layout_marginStart="4dp"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintStart_toEndOf="@id/user_sex_view"
-                app:layout_constraintTop_toTopOf="parent"
-                tools:background="@drawable/label_good_id_bg"
-                tools:visibility="visible" />
-
-            <com.adealink.frame.image.view.NetworkImageView
-                android:id="@+id/iv_svip_level"
-                android:layout_width="0dp"
-                android:layout_height="18dp"
-                android:layout_marginStart="4dp"
-                android:visibility="gone"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintDimensionRatio="376:148"
-                app:layout_constraintStart_toEndOf="@id/vip_recharge_label_view"
-                app:layout_constraintTop_toTopOf="parent"
-                tools:background="@drawable/label_good_id_bg"
-                tools:visibility="visible" />
-
-            <androidx.appcompat.widget.AppCompatImageView
-                android:id="@+id/iv_chat_achievement"
-                android:layout_width="wrap_content"
-                android:layout_height="18dp"
-                android:layout_marginStart="4dp"
-                android:adjustViewBounds="true"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintStart_toEndOf="@id/iv_svip_level"
-                app:layout_constraintTop_toTopOf="parent"
-                tools:src="@drawable/profile_chat_achievement_label_star_ic" />
-
-        </androidx.constraintlayout.widget.ConstraintLayout>
-
-    </HorizontalScrollView>
+            android:layout_height="18dp"
+            android:layout_marginStart="4dp"
+            android:adjustViewBounds="true"
+            tools:src="@drawable/profile_chat_achievement_label_star_ic" />
+    </com.google.android.flexbox.FlexboxLayout>
 
     <androidx.appcompat.widget.AppCompatTextView
         android:id="@+id/tv_introduction"

+ 21 - 51
app/src/main/res/layout/layout_car_cutomized_user.xml

@@ -1,65 +1,35 @@
 <?xml version="1.0" encoding="utf-8"?>
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content">
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="70dp"
+    tools:background="#625F5F">
 
-    <com.adealink.weparty.commonui.imageview.AvatarView
-        android:id="@+id/avatar_iv"
-        android:layout_width="@dimen/car_customized_user_avatar_size"
-        android:layout_height="@dimen/car_customized_user_avatar_size"
-        app:layout_constraintBottom_toBottomOf="@id/af_cl"
-        app:layout_constraintEnd_toEndOf="@id/af_cl"
-        app:layout_constraintStart_toStartOf="@id/af_cl"
-        app:layout_constraintTop_toTopOf="@id/af_cl" />
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:id="@+id/af_cl"
-        android:layout_width="@dimen/car_customized_user_avatar_frame_size"
-        android:layout_height="@dimen/car_customized_user_avatar_frame_size"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent">
-
-        <com.adealink.frame.image.view.NetworkImageView
-            android:id="@+id/avatar_frame_iv"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            app:failureImage="@drawable/enter_effect_car_customized_af_default"
-            app:placeholderImage="@drawable/enter_effect_car_customized_af_default" />
-
-        <com.opensource.svgaplayer.WenextSvgaView
-            android:id="@+id/avatar_frame_svga"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent" />
-
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-    <com.adealink.frame.image.view.NetworkImageView
+    <com.adealink.weparty.effect.WeAnimView
         android:id="@+id/name_bg_iv"
-        android:layout_width="177dp"
-        android:layout_height="52dp"
-        app:actualImageScaleType="fitXY"
-        app:failureImage="@drawable/enter_effect_car_customized_name_bg_default"
-        app:failureImageScaleType="centerInside"
+        android:layout_width="228dp"
+        android:layout_height="70dp"
+        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/af_cl" />
+        app:layout_constraintTop_toTopOf="parent" />
 
-    <androidx.appcompat.widget.AppCompatTextView
+    <com.adealink.weparty.commonui.widget.MediumTextView
         android:id="@+id/name_tv"
-        android:layout_width="84dp"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginHorizontal="5dp"
+        android:layout_marginStart="74dp"
         android:ellipsize="end"
-        android:gravity="center"
         android:lines="1"
-        android:textColor="@color/color_FFFFE2B7"
-        android:textSize="13dp"
-        android:textStyle="bold"
-        app:layout_constraintBottom_toBottomOf="@id/name_bg_iv"
-        app:layout_constraintEnd_toEndOf="@id/name_bg_iv"
-        app:layout_constraintStart_toStartOf="@id/name_bg_iv"
-        app:layout_constraintTop_toTopOf="@id/name_bg_iv" />
+        android:textColor="@color/white"
+        android:textSize="14sp"
+        app:layout_constrainedWidth="true"
+        app:layout_constraintBottom_toBottomOf="@+id/name_bg_iv"
+        app:layout_constraintEnd_toEndOf="@+id/name_bg_iv"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintStart_toStartOf="@+id/name_bg_iv"
+        app:layout_constraintTop_toTopOf="@+id/name_bg_iv"
+        tools:text="UserNameUserNameUserName" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 20 - 0
app/src/main/res/layout/layout_svip_level_view.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"
+    tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
+
+    <!--> 高度外部指定,宽度自适应 -->
+    <com.opensource.svgaplayer.WenextSvgaView
+        android:id="@+id/svga_svip"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        tools:layout_constraintDimensionRatio="280:100"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:layout_height="50dp" />
+
+</merge>

+ 3 - 2
app/src/main/res/values-ar/strings.xml

@@ -303,9 +303,9 @@
    <string name="enter_effect_enter">دخل</string>
    <string name="family_news">أخبار العائلة</string>
    <string name="family_news_message">يوجد طلب جديد للانضمام للعائلة</string>
-   <string name="family_send_gift_rank_1">المركز الأول" 
+   <string name="family_send_gift_rank_1">المركز الأول"
  "إرسال هدايا</string>
-   <string name="family_received_gift_rank_1">المركز الأول" 
+   <string name="family_received_gift_rank_1">المركز الأول"
  "استلام هدايا</string>
    <string name="family_best_send_gift">إرسال الهدايا</string>
    <string name="family_best_received_gift">تلقي الهدايا</string>
@@ -691,4 +691,5 @@
    <string name="rank_charm">جاذبية</string>
    <string name="rank_room">غرفة</string>
    <string name="commonui_mic_anim">رسوم متحركة للميكروفون</string>
+    <string name="set_gif_avatar_tips">قم بتعيين صورة GIF كصورة رمزية لك.</string>
 </resources>

+ 2 - 0
app/src/main/res/values-zh/strings.xml

@@ -100,6 +100,7 @@
    <string name="common_add">添加</string>
    <string name="common_can_not_open_super_mic">您需要成为%1$s才能使用super mic</string>
    <string name="common_can_not_send_vip_gift">你还不是贵族,不能送贵族礼物</string>
+   <string name="common_can_not_send_svip_gift">你还不是SVIP,不能送SVIP礼物</string>
    <string name="common_complete">完成</string>
    <string name="common_please_enter">请输入</string>
    <string name="common_choose">选择</string>
@@ -689,4 +690,5 @@
    <string name="rank_charm">魅力</string>
    <string name="rank_room">房间</string>
    <string name="commonui_mic_anim">麦克风动画</string>
+   <string name="set_gif_avatar_tips">支持设置gif头像</string>
 </resources>

+ 6 - 0
app/src/main/res/values/colors.xml

@@ -770,6 +770,7 @@
     <color name="color_240D36">#240D36</color>
     <color name="color_FDF6AE00">#FDF6AE00</color>
     <color name="color_FFE500">#FFE500</color>
+
     <color name="color_77410F">#77410F</color>
 
     <color name="color_FF3F918D">#3F918D</color>
@@ -1137,6 +1138,7 @@
     <color name="color_FECFFF">#FECFFF</color>
     <color name="color_0D0334">#0D0334</color>
     <color name="color_5B2100">#5B2100</color>
+    <color name="color_FF633609">#FF633609</color>
     <color name="color_FF5F1908">#FF5F1908</color>
     <color name="color_FF863515">#FF863515</color>
     <color name="color_FFFE8F60">#FFFE8F60</color>
@@ -1146,4 +1148,8 @@
     <color name="color_FF04133A">#FF04133A</color>
     <color name="color_FFA8365D">#FFA8365D</color>
     <color name="color_FF022039">#FF022039</color>
+    <color name="color_FFEAEFEF">#FFEAEFEF</color>
+    <color name="color_FFB8CACB">#FFB8CACB</color>
+    <color name="color_FFF9E88D">#FFF9E88D</color>
+    <color name="color_FFFFE6CA">#FFFFE6CA</color>
 </resources>

+ 1 - 1
app/src/main/res/values/dimens.xml

@@ -21,7 +21,7 @@
     <dimen name="cocos_game_quick_chat_margin_bottom">6dp</dimen>
     <dimen name="cocos_game_landscape_chat_quick_chat_bubble_width">114dp</dimen>
 
-    <dimen name="car_customized_user_avatar_size">72.8dp</dimen>
+    <dimen name="car_customized_user_avatar_size">45dp</dimen>
     <dimen name="car_customized_user_avatar_frame_size">120dp</dimen>
 
     <dimen name="top_float_view_height">90dp</dimen>

+ 2 - 0
app/src/main/res/values/strings.xml

@@ -105,6 +105,7 @@
    <string name="common_add">Add</string>
    <string name="common_can_not_open_super_mic">You need to become %1$s to use Super Mic</string>
    <string name="common_can_not_send_vip_gift">You are not Aristocracy now, can not send Aristocracy exclusive gift, please become Aristocracy first.</string>
+   <string name="common_can_not_send_svip_gift">You are not SVIP now, can not send SVIP exclusive gift, please become SVIP first.</string>
    <string name="common_complete">Complete</string>
    <string name="common_please_enter">Please enter</string>
    <string name="common_choose">choose</string>
@@ -805,4 +806,5 @@
    <string name="common_coin_value">%1$s Coin Value</string>
    <string name="common_no_records">No records</string>
    <string name="commonui_mic_anim">Mic Animation</string>
+   <string name="set_gif_avatar_tips">Set a GIF as your avatar.</string>
 </resources>

+ 2 - 1
frame/room/src/main/java/com/adealink/frame/room/data/RoomFlowData.kt

@@ -51,7 +51,8 @@ data class JoinRoomReq(
     val roomId: Long,
     val from: String, /*进房来源*/
     val password: String? = null,
-    val reconnectJoinRoom: Boolean = false
+    val reconnectJoinRoom: Boolean = false,
+    @SerializedName("invisibleJoin") val invisibleJoin: Boolean? = null,
 )
 
 /**

+ 2 - 2
gradle/libs.versions.toml

@@ -116,6 +116,7 @@ smartRefreshLayout = "3.0.0-alpha"
 androidAutoSize = "v1.2.1"
 baseRecyclerViewAdapterHelper = "2.9.50"
 rangeseekbar = "v2.0.4"
+flexbox = "3.0.0"
 
 # apm
 xcrash = "3.1.0"
@@ -173,7 +174,6 @@ tencnetTimpushFcm = "8.5.6864"
 
 # rong cloud
 rongcloud = "5.22.0"
-flexbox = "3.0.0"
 
 [libraries]
 # plugin
@@ -327,6 +327,7 @@ smart-refresh-footer-classics = { group = "io.github.scwang90", name = "refresh-
 android-auto-size = { group = "com.github.JessYanCoding", name = "AndroidAutoSize", version.ref = "androidAutoSize" }
 base-recyclerview-adapter-helper = { group = "com.github.CymChad", name = "BaseRecyclerViewAdapterHelper", version.ref = "baseRecyclerViewAdapterHelper" }
 rangeseekbar = { module = "com.github.Jay-Goo:RangeSeekBar", version.ref = "rangeseekbar" }
+flexbox = { module = "com.google.android.flexbox:flexbox", version.ref = "flexbox" }
 
 # apm
 xcrash = { group = "com.iqiyi.xcrash", name = "xcrash-android-lib", version.ref = "xcrash" }
@@ -429,7 +430,6 @@ androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-co
 
 toolargetool = { module = "com.gu.android:toolargetool", version.ref = "toolargetool" }
 fixandroid14debuggablelag = { module = "com.github.BzCoder:FixAndroid14DebuggableLag", version.ref = "fixandroid14debuggablelag" }
-flexbox = { group = "com.google.android.flexbox", name = "flexbox", version.ref = "flexbox" }
 
 [plugins]
 android-application = { id = "com.android.application", version.ref = "agp" }

+ 3 - 3
module/backpack/src/main/java/com/adealink/weparty/backpack/adapter/BackpackGoodsUsingItemViewBinder.kt

@@ -327,9 +327,9 @@ class BackpackGoodsUsingItemViewBinder(
                 getCompatString(APP_R.string.module_wealthlevel)
             }
 
-//            PrivilegeActivityType.SVIP.type -> {
-//                getCompatString(APP_R.string.commonui_svip)
-//            }
+            PrivilegeActivityType.SVIP.type -> {
+                getCompatString(APP_R.string.commonui_svip)
+            }
 
             else -> {
                 ""

+ 5 - 8
module/backpack/src/main/java/com/adealink/weparty/backpack/fragment/BackpackUsingTabFragment.kt

@@ -184,15 +184,12 @@ class BackpackUsingTabFragment : BaseFragment(R.layout.fragment_backpack), IBack
                         ProfileModule.getMyUid()
                     ).start()
             }
+            PrivilegeActivityType.SVIP.type -> {
+                Router.build(activity, Web.FullScreen.PATH)
+                    .putExtra(Web.Common.EXTRA_URL, urlConfigService.getH5Url(H5Page.SVIP))
+                    .start()
+            }
         }
-//
-//            PrivilegeActivityType.SVIP.type -> {
-//                Router.build(activity, Web.FullScreen.PATH)
-//                    .putExtra(Web.Common.EXTRA_URL, UrlConfig.svip)
-//                    .start()
-//            }
-//
-//        }
     }
 
 

+ 1 - 3
module/call/src/main/java/com/adealink/weparty/call/comp/UserInfoComp.kt

@@ -10,10 +10,8 @@ import com.adealink.weparty.call.databinding.LayoutCallUserinfoBinding
 import com.adealink.weparty.commonui.widget.BottomDialogFragment
 import com.adealink.weparty.module.account.util.isUidValid
 import com.adealink.weparty.module.call.Call
-import com.adealink.weparty.module.level.util.updateSVipLabel
 import com.adealink.weparty.module.profile.ProfileModule
 import com.adealink.weparty.module.profile.data.UserInfo
-import com.adealink.weparty.module.profile.util.updateCharmLevelLabel
 import com.adealink.weparty.module.profile.util.updateChatAchievementLabel
 import com.tencent.qcloud.tuikit.tuicallkit.state.TUICallState
 
@@ -77,7 +75,7 @@ class UserInfoComp(
         binding.vSex.setSex(userInfo?.gender, userInfo?.birthday)
 
         binding.merchantLabel.setMerchantType(userInfo?.merchantType)
-        updateSVipLabel(userInfo?.sVipLevel ?: 0, binding.vSVipLevel)
+        binding.vSVipLevel.updateLevel(userInfo?.sVipLevel?:0)
 
         binding.userCertificationView.setCertificationStatus(userInfo?.commonConfigInfo)
         binding.merchantLabel.setMerchantType(userInfo?.merchantType)

+ 3 - 3
module/call/src/main/res/layout/layout_call_userinfo.xml

@@ -75,10 +75,10 @@
                 app:layout_constraintBottom_toBottomOf="@id/v_sex"
                 android:layout_marginStart="4dp"/>
 
-            <com.adealink.frame.image.view.NetworkImageView
+            <com.adealink.weparty.module.level.view.UserSVipLevelView
                 android:id="@+id/v_s_vip_level"
-                android:layout_width="46dp"
-                android:layout_height="18dp"
+                android:layout_width="wrap_content"
+                android:layout_height="15dp"
                 android:layout_marginStart="4dp"
                 android:visibility="gone"
                 tools:visibility="visible" />

+ 4 - 5
module/family/src/main/java/com/adealink/weparty/family/apply/adapter/FamilyJoinApplyItemViewBinder.kt

@@ -5,16 +5,15 @@ import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import com.adealink.frame.aab.util.getCompatString
+import com.adealink.frame.router.Router
 import com.adealink.weparty.commonui.ext.getActivity
 import com.adealink.weparty.commonui.recycleview.adapter.BindingViewHolder
 import com.adealink.weparty.commonui.recycleview.adapter.multitype.ItemViewBinder
-import com.adealink.frame.router.Router
 import com.adealink.weparty.family.R
-import com.adealink.weparty.module.family.data.FamilyApplyRecord
-import com.adealink.weparty.module.family.data.FamilyApplyStatus
 import com.adealink.weparty.family.databinding.ItemFamilyJoinApplyBinding
 import com.adealink.weparty.family.listener.OnFamilyOperateListener
-import com.adealink.weparty.module.level.util.updateSVipLabel
+import com.adealink.weparty.module.family.data.FamilyApplyRecord
+import com.adealink.weparty.module.family.data.FamilyApplyStatus
 import com.adealink.weparty.module.profile.Profile
 
 /**
@@ -39,7 +38,7 @@ class FamilyJoinApplyItemViewBinder(
     ) {
         holder.binding.avatarIv.setImageUrl(item.userInfo?.url)
         holder.binding.nameTv.text = item.userInfo?.name
-        updateSVipLabel(item.userInfo?.sVipLevel ?: 0, holder.binding.vSVipLevel)
+        holder.binding.vSVipLevel.updateLevel(item.userInfo?.vipLevel ?: 0)
         holder.binding.idTv.text = "ID:${item.userInfo?.getGoodIdOrSid() ?: ""}"
         when (FamilyApplyStatus.map(item.status)) {
             FamilyApplyStatus.INVALID -> {

+ 2 - 6
module/family/src/main/java/com/adealink/weparty/family/view/FamilyMemberView.kt

@@ -3,20 +3,16 @@ package com.adealink.weparty.family.view
 import android.content.Context
 import android.util.AttributeSet
 import android.view.LayoutInflater
-import android.view.View
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.view.isVisible
-import com.adealink.frame.base.Rlt
 import com.adealink.frame.router.Router
 import com.adealink.frame.util.getAgeFromBirthDay
+import com.adealink.frame.util.onClick
 import com.adealink.weparty.commonui.ext.gone
 import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.family.databinding.LayoutFamilyMemberViewBinding
 import com.adealink.weparty.module.family.config.FamilyLevelConfig
-import com.adealink.weparty.module.level.util.updateSVipLabel
-import com.adealink.weparty.module.profile.decorate.data.DecorInfo
 import com.adealink.weparty.module.profile.Profile
-import com.adealink.frame.util.onClick
 import com.adealink.weparty.module.profile.data.UserInfo
 import com.adealink.weparty.R as APP_R
 
@@ -41,7 +37,7 @@ class FamilyMemberView @JvmOverloads constructor(
 
         binding.avatarView.setImageUrl(userInfo.url)
         binding.tvName.text = userInfo.name
-        updateSVipLabel(userInfo.sVipLevel?:0, binding.vSVipLevel)
+        binding.vSVipLevel.updateLevel(userInfo.sVipLevel)
         showGender(userInfo)
 
         binding.avatarFrame.showAvatarFrame(userInfo.uid)

+ 3 - 6
module/family/src/main/java/com/adealink/weparty/family/view/FamilyOwnerView.kt

@@ -6,22 +6,19 @@ import android.view.LayoutInflater
 import android.view.View
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.view.isVisible
-import com.adealink.frame.aab.util.getCompatString
 import com.adealink.frame.router.Router
 import com.adealink.frame.util.getAgeFromBirthDay
+import com.adealink.frame.util.onClick
 import com.adealink.weparty.commonui.ext.gone
 import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.family.databinding.LayoutFamilyOwnerViewBinding
 import com.adealink.weparty.module.family.config.FamilyLevelConfig
 import com.adealink.weparty.module.family.data.FamilyInfo
-import com.adealink.weparty.module.level.util.updateSVipLabel
 import com.adealink.weparty.module.medal.view.MedalItem
 import com.adealink.weparty.module.medal.view.MedalProfileView
+import com.adealink.weparty.module.profile.Profile
 import com.adealink.weparty.module.profile.ProfileModule
 import com.adealink.weparty.module.profile.data.UserInfo
-
-import com.adealink.weparty.module.profile.Profile
-import com.adealink.frame.util.onClick
 import com.adealink.weparty.R as APP_R
 
 /**
@@ -52,7 +49,7 @@ class FamilyOwnerView @JvmOverloads constructor(
         binding.tvName.text = userInfo.name
         binding.tvId.setUserInfo(userInfo)
 
-        updateSVipLabel(userInfo.sVipLevel?:0, binding.vSVipLevel)
+        binding.vSVipLevel.updateLevel(userInfo.sVipLevel)
 //        updateVipMedal(userInfo.vipLevel, binding.vipLevel)
         showGender(userInfo)
         showCountry(userInfo)

+ 3 - 4
module/family/src/main/res/layout/item_family_join_apply.xml

@@ -92,14 +92,13 @@
         app:layout_constraintStart_toStartOf="@+id/name_tv"
         app:layout_constraintTop_toBottomOf="@+id/name_tv">
 
-        <com.adealink.frame.image.view.NetworkImageView
+        <com.adealink.weparty.module.level.view.UserSVipLevelView
             android:id="@+id/v_s_vip_level"
-            android:layout_width="0dp"
-            android:layout_height="18dp"
+            android:layout_width="wrap_content"
+            android:layout_height="15dp"
             android:layout_marginStart="4dp"
             android:visibility="gone"
             app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintDimensionRatio="376:148"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent" />
 

+ 3 - 4
module/family/src/main/res/layout/layout_family_member_view.xml

@@ -120,13 +120,12 @@
                 app:srcCompat="@drawable/ic_family_manager"
                 tools:visibility="visible" />
 
-            <com.adealink.frame.image.view.NetworkImageView
+            <com.adealink.weparty.module.level.view.UserSVipLevelView
                 android:id="@+id/v_s_vip_level"
-                android:layout_width="0dp"
-                android:layout_height="20dp"
+                android:layout_width="wrap_content"
+                android:layout_height="15dp"
                 android:layout_marginStart="4dp"
                 app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintDimensionRatio="376:148"
                 app:layout_constraintStart_toEndOf="@+id/iv_family_manager"
                 app:layout_constraintTop_toTopOf="parent" />
 

+ 3 - 4
module/family/src/main/res/layout/layout_family_owner_view.xml

@@ -166,12 +166,11 @@
             tools:layout_height="20dp">
 
 
-            <com.adealink.frame.image.view.NetworkImageView
+            <com.adealink.weparty.module.level.view.UserSVipLevelView
                 android:id="@+id/v_s_vip_level"
-                android:layout_width="0dp"
-                android:layout_height="18dp"
+                android:layout_width="wrap_content"
+                android:layout_height="15dp"
                 app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintDimensionRatio="376:148"
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toTopOf="parent" />
 

+ 5 - 0
module/gift/src/main/java/com/adealink/weparty/gift/GiftPanelFragment.kt

@@ -167,6 +167,11 @@ class GiftPanelFragment : BaseFragment(R.layout.fragment_gift_panel), IGiftPanel
                     GiftPageFragment.newInstance(GiftPageType.NORMAL)
                 }
             }
+            GiftPageType.SVIP -> {
+                Tab(APP_R.string.commonui_svip) {
+                    GiftPageFragment.newInstance(GiftPageType.SVIP)
+                }
+            }
 
             GiftPageType.UN_KNOW,
             GiftPageType.ACTIVITY,

+ 4 - 10
module/gift/src/main/java/com/adealink/weparty/gift/SendGiftPanelFragment.kt

@@ -46,7 +46,6 @@ import com.adealink.weparty.module.gift.data.LimitTimeGiftInvalidError
 import com.adealink.weparty.module.gift.datasource.local.GiftExportLocalService
 import com.adealink.weparty.module.level.Level
 import com.adealink.weparty.module.level.LevelModule
-import com.adealink.weparty.module.level.data.VipBlockType
 import com.adealink.weparty.module.network.data.ServerCode
 import com.adealink.weparty.module.operation.OperationModule
 import com.adealink.weparty.module.profile.ProfileModule
@@ -238,16 +237,11 @@ class SendGiftPanelFragment : BaseFragment(R.layout.fragment_send_gift_panel) {
         }
 
         val gift = giftPanelFragment.getSelectedGift()
-        if (gift?.isVipGift() == true
-            && (ProfileModule.getMyUserInfo()?.vipLevel ?: 0) < gift.vipType
-        ) {
+        if (gift?.isSVipGift() == true && (ProfileModule.getMyUserInfo()?.sVipLevel ?: 0) <= 0) {
             val fm = activity?.supportFragmentManager ?: return
-            Router.getRouterInstance<BaseDialogFragment>(Level.VipGuideDialog.PATH)?.apply {
-                arguments = Bundle().apply {
-                    putInt(Level.Common.EXTRA_BLOCK_TYPE, VipBlockType.SendVipGift.type)
-                    putInt(Level.Common.EXTRA_BLOCK_VIP_LEVEL, gift.vipType)
-                }
-            }?.show(fm)
+            //展示SVIP拦截弹窗
+            Router.getRouterInstance<BaseDialogFragment>(Level.VipGuideDialog.PATH)?.apply {}
+                ?.show(fm)
             return
         }
 

+ 1 - 1
module/gift/src/main/java/com/adealink/weparty/gift/viewmodel/GiftPanelViewModel.kt

@@ -29,7 +29,7 @@ class GiftPanelViewModel : BaseViewModel() {
 //                if (isActivityGiftAvailable()) {
 //                    add(GiftPageType.ACTIVITY)
 //                }
-//                add(GiftPageType.VIP)
+                add(GiftPageType.SVIP)
                 add(GiftPageType.EXCLUSIVE)
 //                add(GiftPageType.CUSTOMIZE)
                 if (ProfileModule.getMyUserInfo()?.region != Region.CNA.region) {

+ 5 - 0
module/gift/src/main/java/com/adealink/weparty/gift/viewmodel/GiftViewModel.kt

@@ -501,6 +501,11 @@ class GiftViewModel : BaseViewModel(), IGiftViewModel, IGiftListener {
                     gifts.filter { it.isExclusiveGift() }), false
             )
 
+            GiftPageType.SVIP -> pageGiftsLD.send(
+                Pair(giftPageType,
+                    gifts.filter { it.isSVipGift() }), false
+            )
+
             else -> giftsLD.send(gifts, false)
         }
     }

+ 1 - 2
module/headline/src/main/java/com/adealink/weparty/headline/data/Constants.kt

@@ -10,5 +10,4 @@ import com.adealink.weparty.App
  * version: 1.0
  */
 
-val HEADLINE_SEND_GIFT_GLOBAL_URL = App.instance.ossService.getUrlByPath("/big_img/headline/")
-    .plus("headline_send_gift_global_new.svga")
+val HEADLINE_SVIP_GLOBAL_URL = App.instance.ossService.getUrlByPath("/big_img/headline/headline_svip_global.svga")

+ 9 - 1
module/headline/src/main/java/com/adealink/weparty/headline/fragment/HeadlineFragment.kt

@@ -18,7 +18,6 @@ import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.frame.room.data.FlowStateInfo
 import com.adealink.frame.router.Router
 import com.adealink.frame.router.annotation.RouterUri
-import com.adealink.frame.util.DisplayUtil
 import com.adealink.frame.util.runOnUiThread
 import com.adealink.weparty.commonui.BaseFragment
 import com.adealink.weparty.commonui.dialogfragment.BaseDialogFragment
@@ -348,6 +347,15 @@ class HeadlineFragment : BaseFragment(R.layout.fragment_healine), IHeadlineOpLis
                 }
             }
 
+            RoomNotifyType.SVIP_GLOBAL_NOTIFY -> {
+                val svipParams = params ?: return
+                val roomId = svipParams.getLong(Headline.Common.EXTRA_ROOM_ID)
+                if(roomId > 0L) {
+                    enterRoomClick(roomId, svipParams.getString(Headline.Common.EXTRA_ENTER_ROOM_FROM, ""))
+                } else {
+                    goUserProfile(svipParams.getLong(Headline.Common.EXTRA_UID))
+                }
+            }
             RoomNotifyType.SuperGift -> {
                 goSuperGiftWeb()
             }

+ 3 - 3
module/headline/src/main/java/com/adealink/weparty/headline/view/HeadlineViewBuilder.kt

@@ -93,9 +93,9 @@ class HeadlineViewBuilder {
             RoomNotifyType.COMMON_LEVEL_CHANGE_NOTIFY.uri -> {
                 CommonLevelUpgradeHeadline(context)
             }
-//            RoomNotifyType.SVIP_GLOBAL_NOTIFY.uri -> {
-//                SvipLevelUpGlobalHeadline(context)
-//            }
+            RoomNotifyType.SVIP_GLOBAL_NOTIFY.uri -> {
+                SvipLevelUpGlobalHeadline(context)
+            }
             RoomNotifyType.URI_INVITE_TASK_REWARD_NOTIFY.uri -> {
                 InviteTaskRewardGlobalHeadline(context)
             }

+ 16 - 19
module/headline/src/main/java/com/adealink/weparty/headline/view/SvipLevelUpGlobalHeadline.kt

@@ -1,6 +1,7 @@
 package com.adealink.weparty.headline.view
 
 import android.content.Context
+import android.os.Bundle
 import android.text.SpannableStringBuilder
 import android.text.Spanned
 import android.text.style.ForegroundColorSpan
@@ -11,13 +12,15 @@ import com.adealink.frame.aab.util.getCompatString
 import com.adealink.frame.ext.safeSetSpan
 import com.adealink.frame.util.onClick
 import com.adealink.weparty.headline.R
-import com.adealink.weparty.headline.data.HEADLINE_SEND_GIFT_GLOBAL_URL
+import com.adealink.weparty.headline.data.HEADLINE_SVIP_GLOBAL_URL
 import com.adealink.weparty.headline.databinding.LayoutSvipLevelUpGlobalHeadlineBinding
+import com.adealink.weparty.module.headline.Headline
 import com.adealink.weparty.module.headline.view.BaseHeadlineView
-import com.adealink.weparty.module.level.LevelModule
 import com.adealink.weparty.module.profile.view.UserNameTextView.Companion.getDisplayName
 import com.adealink.weparty.module.room.data.GlobalRoomBroadcastNotify
+import com.adealink.weparty.module.room.data.RoomNotifyType
 import com.adealink.weparty.module.room.data.SvipChangeGlobalNotify
+import com.adealink.weparty.room.data.JoinRoomFrom
 import com.adealink.weparty.R as APP_R
 
 /**
@@ -39,13 +42,7 @@ class SvipLevelUpGlobalHeadline @JvmOverloads constructor(
         }
         // 背景动效,现在使用送礼全服横幅的背景
         val level = notify.currentLevel
-        val globalNotify = LevelModule.getSVipConfig(level)?.globalNotify?: false
-        val globalNotifyUrl =  LevelModule.getSVipConfig(level)?.globalNotifyUrl
-        if (globalNotify && globalNotifyUrl.isNullOrEmpty().not()) {
-            binding.svgaBg.setUrl(globalNotifyUrl)
-        } else {
-            binding.svgaBg.setUrl(HEADLINE_SEND_GIFT_GLOBAL_URL)
-        }
+        binding.svgaBg.setUrl(HEADLINE_SVIP_GLOBAL_URL)
 
         // 显示头像
         notify.info?.url?.let {
@@ -69,20 +66,20 @@ class SvipLevelUpGlobalHeadline @JvmOverloads constructor(
         }
 
         binding.root.onClick {
-//            headlineOpListener?.onHeadlineRightBtnClick(
-//                RoomNotifyType.SVIP_GLOBAL_NOTIFY,
-//                Bundle().apply {
-//                    putLong(Headline.Common.EXTRA_ROOM_ID, notify.roomId)
-//                    putString(Headline.Common.EXTRA_ENTER_ROOM_FROM, JoinRoomFrom.SVIP_LEVEL_UP_HEADLINE.from)
-//                    putLong(Headline.Common.EXTRA_UID, notify.uid)
-//                })
+            headlineOpListener?.onHeadlineRightBtnClick(
+                RoomNotifyType.SVIP_GLOBAL_NOTIFY,
+                Bundle().apply {
+                    putLong(Headline.Common.EXTRA_ROOM_ID, notify.roomId)
+                    putString(Headline.Common.EXTRA_ENTER_ROOM_FROM, JoinRoomFrom.SVIP_LEVEL_UP_HEADLINE.from)
+                    putLong(Headline.Common.EXTRA_UID, notify.uid)
+                })
         }
 
     }
 
     override fun updateUI(notify: GlobalRoomBroadcastNotify) {
-//        if (notify.broadcastUri == RoomNotifyType.SVIP_GLOBAL_NOTIFY.uri) {
-//            updateUI(notify.svipChangeGlobalNotify)
-//        }
+        if (notify.broadcastUri == RoomNotifyType.SVIP_GLOBAL_NOTIFY.uri) {
+            updateUI(notify.svipChangeGlobalNotify)
+        }
     }
 }

BIN
module/headline/src/main/res/drawable-xhdpi/headline_global_svip_bg.webp


+ 8 - 10
module/headline/src/main/res/layout/layout_svip_level_up_global_headline.xml

@@ -11,12 +11,12 @@
         android:id="@+id/svga_bg"
         android:layout_width="match_parent"
         android:layout_height="0dp"
-        app:layout_constraintDimensionRatio="496:137"
+        app:layout_constraintDimensionRatio="1416:392"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         android:rotationY="@integer/locale_mirror_flip"
-        tools:src="@drawable/headline_send_gift_global_svip_bg"
+        tools:src="@drawable/headline_global_svip_bg"
         app:autoPlay="true" />
 
     <!-- 头像 -->
@@ -26,14 +26,14 @@
         android:layout_height="0dp"
         app:layout_constraintDimensionRatio="h,1:1"
         app:layout_constraintHeight_percent="0.34"
-        app:layout_constraintHorizontal_bias="0.11"
-        app:layout_constraintVertical_bias="0.82"
+        app:layout_constraintHorizontal_bias="0.1"
+        app:layout_constraintVertical_bias="0.75"
         app:layout_constraintBottom_toBottomOf="@id/svga_bg"
         app:layout_constraintStart_toStartOf="@id/svga_bg"
         app:layout_constraintEnd_toEndOf="@id/svga_bg"
         app:layout_constraintTop_toTopOf="@id/svga_bg"
         app:roundAsCircle="true"
-        app:roundingBorderColor="@color/color_FF97C7FF"
+        app:roundingBorderColor="@color/color_FFFFE6CA"
         app:roundingBorderWidth="1dp" />
 
     <!-- 升级文案 -->
@@ -45,9 +45,8 @@
         app:layout_constraintBottom_toBottomOf="@+id/iv_avatar"
         app:layout_constraintTop_toTopOf="@+id/iv_avatar"
         app:layout_constraintStart_toEndOf="@+id/iv_avatar"
-        app:layout_constraintEnd_toStartOf="@+id/btn_go"
-        android:layout_marginStart="7dp"
-        android:layout_marginEnd="20dp"
+        app:layout_constraintEnd_toStartOf="@id/btn_go"
+        android:layout_marginHorizontal="7dp"
         android:text="@string/headline_svip_level_up_tips"
         android:textColor="@color/color_FFFFFF"
         android:textSize="12sp"
@@ -73,6 +72,5 @@
         app:layout_constraintTop_toTopOf="@+id/iv_avatar"
         app:layout_constraintStart_toStartOf="@id/svga_bg"
         app:layout_constraintEnd_toEndOf="@id/svga_bg"
-        app:layout_constraintHorizontal_bias="0.89" />
-
+        app:layout_constraintHorizontal_bias="0.9" />
 </androidx.constraintlayout.widget.ConstraintLayout>

BIN
module/level/src/main/assets/svip_level_1.svga


BIN
module/level/src/main/assets/svip_level_10.svga


BIN
module/level/src/main/assets/svip_level_2.svga


BIN
module/level/src/main/assets/svip_level_3.svga


BIN
module/level/src/main/assets/svip_level_4.svga


BIN
module/level/src/main/assets/svip_level_5.svga


BIN
module/level/src/main/assets/svip_level_6.svga


BIN
module/level/src/main/assets/svip_level_7.svga


BIN
module/level/src/main/assets/svip_level_8.svga


BIN
module/level/src/main/assets/svip_level_9.svga


+ 0 - 1
module/level/src/main/java/com/adealink/weparty/level/LevelServiceImpl.kt

@@ -6,7 +6,6 @@ import com.adealink.frame.aab.util.getCompatString
 import com.adealink.frame.spi.RegisterService
 import com.adealink.frame.util.AppUtil
 import com.adealink.weparty.commonui.widget.floatview.data.IFloatData
-import com.adealink.weparty.commonui.widget.floatview.view.BaseFloatView
 import com.adealink.weparty.level.floatview.LevelUpgradeHeadlineFloatData
 import com.adealink.weparty.level.floatview.LevelUpgradeHeadlineFloatView
 import com.adealink.weparty.level.manager.levelManager

+ 52 - 177
module/level/src/main/java/com/adealink/weparty/level/SVIPLevelUpgradeDialog.kt

@@ -1,26 +1,30 @@
 package com.adealink.weparty.level
 
-import android.animation.AnimatorSet
-import android.animation.ObjectAnimator
-import android.graphics.Color
 import android.os.Bundle
-import android.view.View
-import android.view.animation.AccelerateDecelerateInterpolator
-import androidx.core.view.isVisible
+import com.adealink.frame.aab.util.getCompatColor
 import com.adealink.frame.aab.util.getCompatString
 import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.frame.router.Router
 import com.adealink.frame.router.annotation.BindExtra
 import com.adealink.frame.router.annotation.RouterUri
+import com.adealink.frame.util.onClick
 import com.adealink.weparty.commonui.dialogfragment.BaseDialogFragment
-import com.adealink.weparty.commonui.ext.hide
-import com.adealink.weparty.commonui.ext.isSVGAImage
+import com.adealink.weparty.commonui.ext.gone
 import com.adealink.weparty.commonui.ext.show
-import com.adealink.weparty.commonui.shimmer.Shimmer
+import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
+import com.adealink.weparty.commonui.recycleview.diffutil.BaseListDiffUtil
+import com.adealink.weparty.commonui.recycleview.itemdecoration.HorizontalItemDecoration
+import com.adealink.weparty.effect.AnimExtraConfig
+import com.adealink.weparty.effect.EffectAnimType
+import com.adealink.weparty.level.adapter.itembinder.SVipReward
+import com.adealink.weparty.level.adapter.itembinder.SVipRewardItemViewBinder
+import com.adealink.weparty.level.constants.WealthLevelOSS.Companion.SVIP_LEVEL_UP_BG
+import com.adealink.weparty.level.data.LEVEL_DROP
+import com.adealink.weparty.level.data.LEVEL_KEEP
+import com.adealink.weparty.level.data.LEVEL_UP
 import com.adealink.weparty.level.databinding.DialogSvipLevelUpgradeBinding
 import com.adealink.weparty.module.level.Level
 import com.adealink.weparty.module.level.data.SVIPLevelChangeNotify
-import com.adealink.frame.util.onClick
 import com.adealink.weparty.module.webview.Web
 import com.adealink.weparty.url.H5Page
 import com.adealink.weparty.url.urlConfigService
@@ -34,25 +38,20 @@ class SVIPLevelUpgradeDialog : BaseDialogFragment(R.layout.dialog_svip_level_upg
     @BindExtra(Level.SVIPUpgrade.EXTRA_UPGRADE_DATA)
     var upgradeData: SVIPLevelChangeNotify? = null
 
-    private var animatorSet1: AnimatorSet? = null
-    private var animatorSet2: AnimatorSet? = null
+    private val listAdapter by lazy{ MultiTypeListAdapter(BaseListDiffUtil()) }
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setStyle(STYLE_NO_TITLE, APP_R.style.FullScreenDialogTheme)
-
-    }
-
-    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         Router.bind(this)
-        super.onViewCreated(view, savedInstanceState)
     }
 
     override fun initViews() {
-        binding.ivDialogClose.onClick {
+        val data = upgradeData ?: return
+        binding.ivClose.onClick {
             dismiss()
         }
-        binding.tvViewPrivileges.onClick {
+        binding.tvGoPrivileges.onClick {
             activity?.let {
                 Router.build(it, Web.FullScreen.PATH)
                     .putExtra(Web.Common.EXTRA_URL, urlConfigService.getH5Url(H5Page.SVIP))
@@ -60,168 +59,44 @@ class SVIPLevelUpgradeDialog : BaseDialogFragment(R.layout.dialog_svip_level_upg
             }
             dismiss()
         }
-        upgradeData?.let { updateData ->
-            var stateSvgaPath = ""
-            var bgSvgaPath = ""
-            when (updateData.type) {
-                //保级
-                0 -> {
-                    stateSvgaPath = "svip_relegation_title.svga"
-                    bgSvgaPath = "svip_upgrade_light_bg.svga"
-                }
-                //升级
-                1 -> {
-                    stateSvgaPath = "svip_upgrade_title.svga"
-                    bgSvgaPath = "svip_upgrade_light_bg.svga"
-                }
-                //降级
-                2 -> {
-                    stateSvgaPath = "svip_downgrade_title.svga"
-                    bgSvgaPath = ""
-                }
+        listAdapter.register(SVipRewardItemViewBinder(data.nextLevel))
+        binding.rvRewards.apply {
+            adapter = listAdapter
+            addItemDecoration(HorizontalItemDecoration(28f, 14f, 14f))
+        }
+        listAdapter.submitList(data.rewards?.map { SVipReward(it) } ?: emptyList())
+        when(data.type) {
+            LEVEL_KEEP -> {
+                binding.ivBg.setImageResource(R.drawable.svip_level_up_bg)
+                binding.tvTitle.text = getCompatString(R.string.level_keep_title, data.nextLevel.toString())
+                binding.levelUpDecorGroup.gone()
+                binding.tvSvipTips.text = getCompatString(R.string.level_up_tips)
             }
-            binding.wsvSvipLevelState.setAsset(stateSvgaPath)
-            if (bgSvgaPath.isBlank()) {
-                binding.wsvLigthBg.hide()
-            } else {
-                binding.wsvLigthBg.setAsset(bgSvgaPath)
+            LEVEL_UP -> {
+                binding.ivBg.setImageResource(R.drawable.svip_level_up_bg)
+                binding.wavBg.show()
+                binding.wavBg.setUrl(SVIP_LEVEL_UP_BG, EffectAnimType.MP4, AnimExtraConfig(-1))
+                binding.tvTitle.text = getCompatString(R.string.level_up_title, data.nextLevel.toString())
+                binding.levelUpDecorGroup.show()
+                binding.tvSvipTips.text = getCompatString(R.string.level_up_tips)
             }
-
-            if (isSVGAImage(updateData.svipMedalUrl)) {
-                binding.ivSvipMedal.show()
-                binding.ivSvipMedal.setUrl(updateData.svipMedalUrl)
-            } else {
-                binding.ivSvipMedal.hide()
-                binding.ivSvipZeroMedal.show()
-                binding.ivSvipZeroMedal.setImageUrl(updateData.svipMedalUrl)
+            LEVEL_DROP -> {
+                binding.ivBg.setImageResource(R.drawable.svip_level_drop_bg)
+                val colorList = listOf(
+                    getCompatColor(APP_R.color.color_FFEAEFEF),
+                    getCompatColor(APP_R.color.color_FFB8CACB)
+                )
+                binding.tvTitle.setVerticalLinearGradient(colorList, listOf(0f, 1f))
+                binding.tvTitle.text = getCompatString(R.string.level_drop_title, data.nextLevel.toString())
+                binding.levelUpDecorGroup.gone()
+                binding.tvSvipTips.text = getCompatString(R.string.level_drop_tips)
             }
-            binding.tvSvipLevel.setImageUrl(updateData.svipLabelUrl)
-            binding.tvSvipLevelTips.text =
-                getCompatString(APP_R.string.profile_svip_level_upgrade_tip)
-            startAnimation(if (binding.ivSvipMedal.visibility == View.INVISIBLE) binding.ivSvipZeroMedal else binding.ivSvipMedal, binding.sflSvipLevel, binding.wsvLigthBg)
-            binding.sflSvipLevel.shimmer = generateShimmer(1000)
         }
-    }
-
-    private fun generateShimmer(delay: Long): Shimmer {
-        return Shimmer.ColorHighlightBuilder().apply {
-            setBaseAlpha(0f)
-            setBaseColor(Color.TRANSPARENT)
-            setHighlightColor(Color.parseColor("#80FFFFFF"))
-            setRepeatCount(0)
-            setDropoff(0.1f)
-            setDuration(2000)
-            setStartDelay(delay)
-            setIntensity(0.1f)
-        }.build()
-    }
-
-    override fun onResume() {
-        super.onResume()
-        if (binding.wsvLigthBg.isVisible) {
-            binding.wsvLigthBg.startAnimation()
+        //0级特殊样式
+        if(data.nextLevel == 0) {
+            binding.ivBg.setImageResource(R.drawable.svip_level_0_bg)
+            binding.tvGoPrivileges.gone()
         }
-        binding.wsvSvipLevelState.startAnimation()
-        binding.sflSvipLevel.startShimmer()
-        binding.ivSvipMedal.startAnimation()
-    }
-
-    override fun onPause() {
-        super.onPause()
-        if (binding.wsvLigthBg.isVisible) {
-            binding.wsvLigthBg.stopAnimation()
-        }
-        binding.wsvSvipLevelState.stopAnimation()
-        binding.ivSvipMedal.stopAnimation()
-        animatorSet1?.end()
-        animatorSet2?.end()
-    }
-
-    private fun startAnimation(view1: View, view2: View, view3: View) {
-        // 缩放和透明度动画1(0%-110%)
-        val scaleUpX1 = ObjectAnimator.ofFloat(view1, "scaleX", 0f, 1.1f)
-        val scaleUpY1 = ObjectAnimator.ofFloat(view1, "scaleY", 0f, 1.1f)
-        val alphaUp1 = ObjectAnimator.ofFloat(view1, "alpha", 0f, 1f)
-
-        val scaleUpX2 = ObjectAnimator.ofFloat(view2, "scaleX", 0f, 1.1f)
-        val scaleUpY2 = ObjectAnimator.ofFloat(view2, "scaleY", 0f, 1.1f)
-        val alphaUp2 = ObjectAnimator.ofFloat(view2, "alpha", 0f, 1f)
-
-        val scaleUpX3 = ObjectAnimator.ofFloat(view3, "scaleX", 0f, 1.1f)
-        val scaleUpY3 = ObjectAnimator.ofFloat(view3, "scaleY", 0f, 1.1f)
-        val alphaUp3 = ObjectAnimator.ofFloat(view3, "alpha", 0f, 1f)
-
-        // 设置动画1的时间
-        scaleUpX1.duration = 750
-        scaleUpY1.duration = 750
-        alphaUp1.duration = 750
-
-        scaleUpX2.duration = 750
-        scaleUpY2.duration = 750
-        alphaUp2.duration = 750
-
-        scaleUpX3.duration = 750
-        scaleUpY3.duration = 750
-        alphaUp3.duration = 750
-
-        // 设置动画1的插值器
-        scaleUpX1.interpolator = AccelerateDecelerateInterpolator()
-        scaleUpY1.interpolator = AccelerateDecelerateInterpolator()
-        alphaUp1.interpolator = AccelerateDecelerateInterpolator()
-
-        scaleUpX2.interpolator = AccelerateDecelerateInterpolator()
-        scaleUpY2.interpolator = AccelerateDecelerateInterpolator()
-        alphaUp2.interpolator = AccelerateDecelerateInterpolator()
-
-        scaleUpX3.interpolator = AccelerateDecelerateInterpolator()
-        scaleUpY3.interpolator = AccelerateDecelerateInterpolator()
-        alphaUp3.interpolator = AccelerateDecelerateInterpolator()
-
-        // 缩放和透明度动画2(110%-100%)
-        val scaleDownX1 = ObjectAnimator.ofFloat(view1, "scaleX", 1.1f, 1f)
-        val scaleDownY1 = ObjectAnimator.ofFloat(view1, "scaleY", 1.1f, 1f)
-
-        val scaleDownX2 = ObjectAnimator.ofFloat(view2, "scaleX", 1.1f, 1f)
-        val scaleDownY2 = ObjectAnimator.ofFloat(view2, "scaleY", 1.1f, 1f)
-
-        val scaleDownX3 = ObjectAnimator.ofFloat(view3, "scaleX", 1.1f, 1f)
-        val scaleDownY3 = ObjectAnimator.ofFloat(view3, "scaleY", 1.1f, 1f)
-
-        // 设置动画2的时间
-        scaleDownX1.duration = 500
-        scaleDownY1.duration = 500
-
-        scaleDownX2.duration = 500
-        scaleDownY2.duration = 500
-
-        scaleDownX3.duration = 500
-        scaleDownY3.duration = 500
-
-        // 设置动画2的插值器
-        scaleDownX1.interpolator = AccelerateDecelerateInterpolator()
-        scaleDownY1.interpolator = AccelerateDecelerateInterpolator()
-
-        scaleDownX2.interpolator = AccelerateDecelerateInterpolator()
-        scaleDownY2.interpolator = AccelerateDecelerateInterpolator()
-
-        scaleDownX3.interpolator = AccelerateDecelerateInterpolator()
-        scaleDownY3.interpolator = AccelerateDecelerateInterpolator()
-
-        // 创建动画集合
-        animatorSet1 = AnimatorSet()
-        animatorSet2 = AnimatorSet()
-
-        // 添加动画到集合
-        animatorSet1?.playTogether(scaleUpX1, scaleUpY1, alphaUp1)
-        animatorSet1?.playTogether(scaleUpX2, scaleUpY2, alphaUp2)
-        animatorSet1?.playTogether(scaleUpX3, scaleUpY3, alphaUp3)
-
-        animatorSet2?.play(scaleDownX1)?.with(scaleDownY1)?.with(scaleDownX2)?.with(scaleDownX3)?.with(scaleDownY3)
-            ?.with(scaleDownY2)?.after(animatorSet1)
-
-        // 开始动画
-        animatorSet1?.start()
-        animatorSet2?.start()
+        binding.animMdeal.setUrl(data.svipMedalUrl, EffectAnimType.MP4, AnimExtraConfig(-1))
     }
-
 }

+ 45 - 0
module/level/src/main/java/com/adealink/weparty/level/adapter/itembinder/SVipRewardItemViewBinder.kt

@@ -0,0 +1,45 @@
+package com.adealink.weparty.level.adapter.itembinder
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import com.adealink.weparty.commonui.recycleview.adapter.BindingViewHolder
+import com.adealink.weparty.commonui.recycleview.adapter.multitype.ItemViewBinder
+import com.adealink.weparty.commonui.recycleview.diffutil.BaseListItemData
+import com.adealink.weparty.level.R
+import com.adealink.weparty.level.databinding.ItemSvipLevelRewardBinding
+import com.adealink.weparty.module.operation.data.RewardDetailData
+
+data class SVipReward(val reward: RewardDetailData): BaseListItemData
+class SVipRewardItemViewBinder(private val level: Int): ItemViewBinder<SVipReward, BindingViewHolder<ItemSvipLevelRewardBinding>>() {
+    override fun onCreateViewHolder(
+        inflater: LayoutInflater,
+        parent: ViewGroup
+    ): BindingViewHolder<ItemSvipLevelRewardBinding> {
+        return BindingViewHolder(ItemSvipLevelRewardBinding.inflate(inflater, parent, false))
+    }
+
+    override fun onBindViewHolder(
+        holder: BindingViewHolder<ItemSvipLevelRewardBinding>,
+        item: SVipReward
+    ) {
+        holder.binding.ivFrame.setImageResource(getRewardFrame())
+        holder.binding.ivReward.setImageUrl(item.reward.rewardResourceUrl)
+        holder.binding.tvReward.text = item.reward.getRewardName()
+    }
+
+    private fun getRewardFrame(): Int {
+        return when(level) {
+            1 -> R.drawable.svip_frame_1
+            2 -> R.drawable.svip_frame_2
+            3 -> R.drawable.svip_frame_3
+            4 -> R.drawable.svip_frame_4
+            5 -> R.drawable.svip_frame_5
+            6 -> R.drawable.svip_frame_6
+            7 -> R.drawable.svip_frame_7
+            8 -> R.drawable.svip_frame_8
+            9 -> R.drawable.svip_frame_9
+            10 -> R.drawable.svip_frame_10
+            else -> 0
+        }
+    }
+}

+ 1 - 0
module/level/src/main/java/com/adealink/weparty/level/constants/Constants.kt

@@ -10,5 +10,6 @@ interface WealthLevelOSS {
     companion object {
         val WEALTH_LEVEL_USER_INFO_BG = ossService.getUrlByPath("/activity/user_level/wealth_level/level_user_info_bg.mp4")
         val WEALTH_LEVEL_USER_INFO_BG_RTL = ossService.getUrlByPath("/activity/user_level/wealth_level/level_user_info_bg_rtl.mp4")
+        val SVIP_LEVEL_UP_BG = ossService.getUrlByPath("/svip/svip_level_up_bg.mp4")
     }
 }

+ 1 - 31
module/level/src/main/java/com/adealink/weparty/level/data/LevelData.kt

@@ -4,6 +4,7 @@ import android.os.Parcelable
 import com.adealink.weparty.commonui.recycleview.diffutil.BaseListItemData
 import com.adealink.weparty.level.adapter.base.BaseLevelItem
 import com.adealink.weparty.module.level.data.CommonLevelConfigInfo
+import com.adealink.weparty.module.level.data.CommonLevelInfo
 import com.adealink.weparty.module.level.data.RewardItem
 import com.adealink.weparty.module.level.data.UserLevelInfo
 import com.adealink.weparty.module.level.data.VipConfig
@@ -214,34 +215,3 @@ data class CommonLevelConfigRes(
     @SerializedName("commonLevelConfigMap")
     val commonLevelConfigMap: Map<Int, CommonLevelConfigInfo>,
 )
-
-data class CommonLevelInfo(
-    @SerializedName("commonLevelConfigInfo")
-    val commonLevelConfigInfo: CommonLevelConfigInfo,
-    @SerializedName("createTime")
-    val createTime: String,
-    @SerializedName("currLevel")
-    val currLevel: Int,
-    @SerializedName("expire")
-    val expire: Long,
-    @SerializedName("lastLevel")
-    val lastLevel: Int,
-    @SerializedName("lastScore")
-    val lastScore: Long,
-    @SerializedName("levelTime")
-    val levelTime: String,
-    @SerializedName("levelType")
-    val levelType: Int,
-    @SerializedName("nextLevel")
-    val nextLevel: Int,
-    @SerializedName("nextLevelName")
-    val nextLevelName: String,
-    @SerializedName("nextScore")
-    val nextScore: Long,
-    @SerializedName("objectId")
-    val objectId: String,
-    @SerializedName("region")
-    val region: String,
-    @SerializedName("score")
-    val score: Long
-)

+ 4 - 0
module/level/src/main/java/com/adealink/weparty/level/data/LevelSVipData.kt

@@ -16,3 +16,7 @@ data class GetSVipConfigRes(
     @SerializedName("svipConfigMap") val svipConfigMap: MutableMap<Int, SVipConfig>,
     @SerializedName("svipConfigs") val svipConfigs: List<SVipConfig>
 )
+
+const val LEVEL_KEEP = 0
+const val LEVEL_UP = 1
+const val LEVEL_DROP = 2

+ 5 - 0
module/level/src/main/java/com/adealink/weparty/level/datasource/remote/LevelHttpService.kt

@@ -16,6 +16,8 @@ import com.adealink.weparty.module.level.data.ReceiveBirthdayBagReq
 import com.adealink.weparty.module.level.data.RewardItem
 import com.adealink.weparty.module.level.data.UserLevelConfigRes
 import com.adealink.weparty.module.level.data.UserLevelInfo
+import com.adealink.weparty.module.level.data.UserSvipLevelReq
+import com.adealink.weparty.module.level.data.UserSvipLevelRes
 import retrofit2.http.Body
 import retrofit2.http.Core
 import retrofit2.http.GET
@@ -65,4 +67,7 @@ interface LevelHttpService {
     @GET("activity/getRewardPackageInfoByIds")
     suspend fun getRewardPackageInfoByIds(@Query("packageIds") packageIds: List<Long>): Rlt<Res<Map<Long, List<RewardItem>>>>
 
+    @POST("config/getUserSVipInfo")
+    suspend fun getUserSVipInfo(@Body req: UserSvipLevelReq): Rlt<Res<UserSvipLevelRes>>
+
 }

+ 8 - 40
module/level/src/main/java/com/adealink/weparty/level/dialog/VipGuideDialog.kt → module/level/src/main/java/com/adealink/weparty/level/dialog/SVipGuideDialog.kt

@@ -6,25 +6,23 @@ import android.os.Bundle
 import android.view.Gravity
 import android.view.WindowManager
 import com.adealink.frame.aab.util.getCompatString
-import com.adealink.weparty.commonui.dialogfragment.BaseDialogFragment
 import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.frame.router.Router
 import com.adealink.frame.router.annotation.BindExtra
 import com.adealink.frame.router.annotation.RouterUri
 import com.adealink.frame.util.DisplayUtil
-import com.adealink.weparty.module.level.Level
-import com.adealink.weparty.module.level.LevelModule
+import com.adealink.weparty.commonui.dialogfragment.BaseDialogFragment
 import com.adealink.weparty.level.R
-import com.adealink.weparty.module.level.data.VipBlockType
 import com.adealink.weparty.level.databinding.DialogVipGuideBinding
+import com.adealink.weparty.module.level.Level
 import com.adealink.weparty.module.webview.Web
 import com.adealink.weparty.url.H5Page
 import com.adealink.weparty.url.urlConfigService
 import com.adealink.weparty.R as APP_R
 
 
-@RouterUri(path = [Level.VipGuideDialog.PATH], desc = "非vip操作拦截")
-class VipGuideDialog : BaseDialogFragment(R.layout.dialog_vip_guide) {
+@RouterUri(path = [Level.VipGuideDialog.PATH], desc = "非svip操作拦截")
+class SVipGuideDialog : BaseDialogFragment(R.layout.dialog_vip_guide) {
     private val binding by viewBinding(DialogVipGuideBinding::bind)
 
     @BindExtra(Level.Common.EXTRA_BLOCK_TYPE)
@@ -40,48 +38,18 @@ class VipGuideDialog : BaseDialogFragment(R.layout.dialog_vip_guide) {
 
     override fun initViews() {
         super.initViews()
-        binding.btnClose.setOnClickListener {
-            dismiss()
-        }
         binding.btnJoinVip.setOnClickListener {
             val activity = activity ?: return@setOnClickListener
             Router.build(activity, Web.FullScreen.PATH)
                 .putExtra(
                     Web.Common.EXTRA_URL,
-                    urlConfigService.getH5Url(H5Page.VIP) + when (blockVipLevel) {
-                        null -> ""
-                        else -> "?buyLevel=${blockVipLevel}"
-                    })
+                    urlConfigService.getH5Url(H5Page.SVIP)
+                )
                 .start()
             dismiss()
         }
-        var iconRes = 0
-        var desc = ""
-        when (blockType) {
-            VipBlockType.SendVipGift.type -> {
-                iconRes = R.drawable.level_vip_gift_icon
-                val blockVipLevel = blockVipLevel ?: 0
-                if (blockVipLevel > 4) {
-                    val vipName = LevelModule.getVipName(blockVipLevel)
-                    desc = getCompatString(APP_R.string.common_can_not_send_level_vip_gift,
-                        vipName,
-                        vipName)
-                    binding.btnJoinVip.text =
-                        getCompatString(APP_R.string.common_go_open_vip, vipName)
-                } else {
-                    desc = getCompatString(APP_R.string.common_can_not_send_vip_gift)
-                    binding.btnJoinVip.text =
-                        getCompatString(R.string.level_join_vip)
-                }
-            }
-            VipBlockType.OpenSuperMic.type -> {
-                iconRes = R.drawable.level_super_mic_ic
-                desc = getCompatString(APP_R.string.common_can_not_open_super_mic,
-                    LevelModule.getVipName(4))
-            }
-        }
-        binding.ivIcon.setImageResource(iconRes)
-        binding.tvDesc.text = desc
+
+        binding.tvTips.text = getCompatString(APP_R.string.common_can_not_send_svip_gift)
     }
 
     override fun onStart() {

+ 2 - 3
module/level/src/main/java/com/adealink/weparty/level/manager/LevelManager.kt

@@ -216,7 +216,7 @@ class LevelManager : BaseFrame<ILevelListener>(), ILevelManager, ILoginListener
     private val charmLevelMedal = HashMap<Int, RewardItem>()
 
     init {
-//        App.instance.networkService.subscribeNotify(svipLevelChangeNotify)
+        App.instance.networkService.subscribeNotify(svipLevelChangeNotify)
         App.instance.networkService.subscribeNotify(gameAwCompensateNotify)
         App.instance.networkService.subscribeNotify(gameLevelChangeNotify)
 //        App.instance.networkService.subscribeNotify(familyLevelChangeNotify)
@@ -327,8 +327,7 @@ class LevelManager : BaseFrame<ILevelListener>(), ILevelManager, ILoginListener
             pullSVipConfigs()
 
             //刷新用户数据
-            val userInfo = ProfileModule.getMyUserInfo()
-            userInfo?.sVipLevel = notify.nextLevel
+            ProfileModule.getUserInfoByUid(uid = ProfileModule.getMyUid(), cache = false)
         }
     }
 

+ 41 - 2
module/level/src/main/java/com/adealink/weparty/level/viewmodel/LevelViewModel.kt

@@ -1,9 +1,20 @@
 package com.adealink.weparty.level.viewmodel
 
+import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import com.adealink.frame.mvvm.viewmodel.BaseViewModel
+import com.adealink.weparty.App
+import com.adealink.weparty.commonui.ext.onSuccess
+import com.adealink.weparty.level.data.CommonLevelInfoReq
 import com.adealink.weparty.level.data.LevelTitleData
+import com.adealink.weparty.level.datasource.remote.LevelHttpService
+import com.adealink.weparty.module.level.data.CommonLevelInfo
+import com.adealink.weparty.module.level.data.LevelType
+import com.adealink.weparty.module.level.data.UserSvipLevelInfo
+import com.adealink.weparty.module.level.data.UserSvipLevelReq
 import com.adealink.weparty.module.level.viewmodel.ILevelViewModel
+import com.adealink.weparty.module.profile.ProfileModule
+import kotlinx.coroutines.launch
 
 class LevelViewModel : ILevelViewModel, BaseViewModel() {
 
@@ -16,7 +27,35 @@ class LevelViewModel : ILevelViewModel, BaseViewModel() {
     val itemToTitlePositionLiveData = MutableLiveData<List<Int>>()
 
 
-    companion object {
-        private const val TAG = "LevelViewModel"
+    private val levelHttpService by lazy {
+        App.instance.networkService.getHttpService(LevelHttpService::class.java)
     }
+
+    override fun getCommonLevelInfo(levelType: LevelType): LiveData<CommonLevelInfo> {
+        val onceMutableLiveData = MutableLiveData<CommonLevelInfo>()
+        viewModelScope.launch {
+            val rlt = levelHttpService.getCommonLevelInfo(req = CommonLevelInfoReq(levelType.type))
+            rlt.onSuccess { data ->
+                if (data.data != null) {
+                    onceMutableLiveData.send(data.data!!.commonLevelInfo)
+                }
+            }
+        }
+        return onceMutableLiveData
+    }
+
+    override fun getUserSVipInfo(): LiveData<UserSvipLevelInfo> {
+        val onceMutableLiveData = MutableLiveData<UserSvipLevelInfo>()
+        viewModelScope.launch {
+            val rlt =
+                levelHttpService.getUserSVipInfo(req = UserSvipLevelReq(uid = ProfileModule.getMyUid()))
+            rlt.onSuccess { data ->
+                if (data.data != null) {
+                    onceMutableLiveData.send(data.data!!.userSvipInfo)
+                }
+            }
+        }
+        return onceMutableLiveData
+    }
+
 }

BIN
module/level/src/main/res/drawable-ldrtl-xhdpi/level_svip_left_ic.png


BIN
module/level/src/main/res/drawable-ldrtl-xhdpi/level_svip_right_ic.png


BIN
module/level/src/main/res/drawable-xhdpi/gift_svip_tips_bg.png


BIN
module/level/src/main/res/drawable-xhdpi/level_svip_left_ic.png


BIN
module/level/src/main/res/drawable-xhdpi/level_svip_right_ic.png


BIN
module/level/src/main/res/drawable-xhdpi/svip_frame_1.webp


BIN
module/level/src/main/res/drawable-xhdpi/svip_frame_10.webp


BIN
module/level/src/main/res/drawable-xhdpi/svip_frame_2.webp


BIN
module/level/src/main/res/drawable-xhdpi/svip_frame_3.webp


BIN
module/level/src/main/res/drawable-xhdpi/svip_frame_4.webp


BIN
module/level/src/main/res/drawable-xhdpi/svip_frame_5.webp


Some files were not shown because too many files changed in this diff