Parcourir la source

feat: 陪玩,个人页关注,聊天

DoggyZhang il y a 3 mois
Parent
commit
caec19e7cf
18 fichiers modifiés avec 368 ajouts et 30 suppressions
  1. 59 2
      app/src/main/java/com/adealink/weparty/commonui/widget/CommonButton.kt
  2. 5 0
      app/src/main/java/com/adealink/weparty/module/profile/IProfileService.kt
  3. 9 0
      app/src/main/java/com/adealink/weparty/module/profile/ProfileModule.kt
  4. 20 0
      app/src/main/java/com/adealink/weparty/module/profile/data/FollowData.kt
  5. 21 0
      app/src/main/java/com/adealink/weparty/module/profile/viewmodel/IFollowViewModel.kt
  6. 2 0
      app/src/main/res/values/attrs.xml
  7. 2 0
      module/playmate/src/main/java/com/adealink/weparty/playmate/detail/PlaymateDetailActivity.kt
  8. 27 1
      module/playmate/src/main/java/com/adealink/weparty/playmate/detail/comp/PlaymateToolBarViewComp.kt
  9. 6 0
      module/profile/src/main/java/com/adealink/weparty/profile/ProfileServiceImpl.kt
  10. 14 0
      module/profile/src/main/java/com/adealink/weparty/profile/UserProfileActivity.kt
  11. 53 12
      module/profile/src/main/java/com/adealink/weparty/profile/comp/ProfileBottomComp.kt
  12. 8 0
      module/profile/src/main/java/com/adealink/weparty/profile/datasource/remote/FollowHttpService.kt
  13. 14 0
      module/profile/src/main/java/com/adealink/weparty/profile/relation/data/RelationShipData.kt
  14. 117 5
      module/profile/src/main/java/com/adealink/weparty/profile/relation/viewmodel/FollowViewModel.kt
  15. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_chat_ic.png
  16. BIN
      module/profile/src/main/res/drawable-xhdpi/profile_follow_ic.png
  17. 1 3
      module/profile/src/main/res/layout/activity_user_profile.xml
  18. 10 7
      module/profile/src/main/res/layout/layout_profile_bottom.xml

+ 59 - 2
app/src/main/java/com/adealink/weparty/commonui/widget/CommonButton.kt

@@ -44,6 +44,12 @@ class CommonButton @JvmOverloads constructor(
             setLeftDrawable(value)
         }
 
+    var leftDrawableWidth: Int? = null
+        set(value) {
+            field = value
+            setLeftDrawableSize(value)
+        }
+
     private var rightDrawableMargin: Int = 0
 
     var rightDrawableRes: Int? = 0
@@ -52,6 +58,12 @@ class CommonButton @JvmOverloads constructor(
             setRightDrawable(value)
         }
 
+    var rightDrawableWidth: Int? = null
+        set(value) {
+            field = value
+            setRightDrawableSize(value)
+        }
+
     var text: CharSequence? = null
         set(value) {
             field = value
@@ -95,10 +107,18 @@ class CommonButton @JvmOverloads constructor(
                     BUTTON_CONFIRM
                 )
                 leftDrawableRes = getResourceId(R.styleable.CommonButton_button_left_drawable, 0)
+                leftDrawableWidth = getDimensionPixelSize(
+                    R.styleable.CommonButton_button_left_drawable_width,
+                    0
+                )
                 leftDrawableMargin =
                     getDimensionPixelSize(R.styleable.CommonButton_button_left_drawable_margin, 2)
 
                 rightDrawableRes = getResourceId(R.styleable.CommonButton_button_right_drawable, 0)
+                rightDrawableWidth = getDimensionPixelSize(
+                    R.styleable.CommonButton_button_right_drawable_width,
+                    0
+                )
                 rightDrawableMargin =
                     getDimensionPixelSize(R.styleable.CommonButton_button_right_drawable_margin, 2)
             }
@@ -119,17 +139,25 @@ class CommonButton @JvmOverloads constructor(
                 BUTTON_CONFIRM
             )
             leftDrawableRes = getResourceId(R.styleable.CommonButton_button_left_drawable, 0)
+            leftDrawableWidth = getDimensionPixelSize(
+                R.styleable.CommonButton_button_left_drawable_width,
+                0
+            )
             leftDrawableMargin =
                 getDimensionPixelSize(
                     R.styleable.CommonButton_button_left_drawable_margin,
-                    2.dp()
+                    4.dp()
                 )
 
             rightDrawableRes = getResourceId(R.styleable.CommonButton_button_right_drawable, 0)
+            rightDrawableWidth = getDimensionPixelSize(
+                R.styleable.CommonButton_button_right_drawable_width,
+                0
+            )
             rightDrawableMargin =
                 getDimensionPixelSize(
                     R.styleable.CommonButton_button_right_drawable_margin,
-                    2.dp()
+                    4.dp()
                 )
         }
         strokeWidth = 1.dp()
@@ -302,6 +330,20 @@ class CommonButton @JvmOverloads constructor(
         }
     }
 
+    private fun setLeftDrawableSize(size: Int?) {
+        if (size == null || size == 0) {
+            binding.ivLeft.updateLayoutParams<LayoutParams> {
+                this.width = LayoutParams.WRAP_CONTENT
+                this.height = 0
+            }
+        } else {
+            binding.ivLeft.updateLayoutParams<LayoutParams> {
+                this.width = size
+                this.height = size
+            }
+        }
+    }
+
     private fun setRightDrawable(drawableRes: Int?) {
         if (drawableRes == null || drawableRes == 0) {
             binding.ivRight.gone()
@@ -311,6 +353,21 @@ class CommonButton @JvmOverloads constructor(
         }
     }
 
+
+    private fun setRightDrawableSize(size: Int?) {
+        if (size == null || size == 0) {
+            binding.ivRight.updateLayoutParams<LayoutParams> {
+                this.width = LayoutParams.WRAP_CONTENT
+                this.height = 0
+            }
+        } else {
+            binding.ivRight.updateLayoutParams<LayoutParams> {
+                this.width = size
+                this.height = size
+            }
+        }
+    }
+
     private fun setButtonText(text: CharSequence?) {
         binding.tvName.text = text
     }

+ 5 - 0
app/src/main/java/com/adealink/weparty/module/profile/IProfileService.kt

@@ -6,6 +6,7 @@ import com.adealink.weparty.aab.IService
 import com.adealink.weparty.module.profile.data.UserConfigType
 import com.adealink.weparty.module.profile.data.UserConfigType.Companion.NECESSARY_USER_ATTR_SET
 import com.adealink.weparty.module.profile.data.UserInfo
+import com.adealink.weparty.module.profile.viewmodel.IFollowViewModel
 import com.adealink.weparty.module.profile.viewmodel.IProfileViewModel
 
 interface IProfileService : IService<IProfileService> {
@@ -34,5 +35,9 @@ interface IProfileService : IService<IProfileService> {
         attrSet: Set<UserConfigType>? = NECESSARY_USER_ATTR_SET,
     ): Rlt<Map<String, UserInfo>>
 
+
     fun getProfileViewModel(owner: ViewModelStoreOwner): IProfileViewModel?
+
+
+    fun getFollowViewModel(owner: ViewModelStoreOwner): IFollowViewModel?
 }

+ 9 - 0
app/src/main/java/com/adealink/weparty/module/profile/ProfileModule.kt

@@ -7,6 +7,7 @@ import com.adealink.frame.base.Rlt
 import com.adealink.weparty.R
 import com.adealink.weparty.module.profile.data.UserConfigType
 import com.adealink.weparty.module.profile.data.UserInfo
+import com.adealink.weparty.module.profile.viewmodel.IFollowViewModel
 import com.adealink.weparty.module.profile.viewmodel.IProfileViewModel
 
 object ProfileModule : BaseDynamicModule<IProfileService>(IProfileService::class), IProfileService {
@@ -66,6 +67,10 @@ object ProfileModule : BaseDynamicModule<IProfileService>(IProfileService::class
                 return null
             }
 
+            override fun getFollowViewModel(owner: ViewModelStoreOwner): IFollowViewModel? {
+                return null
+            }
+
             override fun logout() {
 
             }
@@ -116,6 +121,10 @@ object ProfileModule : BaseDynamicModule<IProfileService>(IProfileService::class
         return getService().getProfileViewModel(owner)
     }
 
+    override fun getFollowViewModel(owner: ViewModelStoreOwner): IFollowViewModel? {
+        return getService().getFollowViewModel(owner)
+    }
+
     override fun logout() {
         getService().logout()
     }

+ 20 - 0
app/src/main/java/com/adealink/weparty/module/profile/data/FollowData.kt

@@ -0,0 +1,20 @@
+package com.adealink.weparty.module.profile.data
+
+enum class FollowStatus(val status: Int) {
+    NONE(0b00), //无关注
+    FOLLOW(0b01), //关注(我关注了ta)
+    FANS(0b10), //粉丝(ta关注了我)
+    MUTUAL_FOLLOW(0b11); //互相关注
+
+    companion object {
+        @JvmStatic
+        fun map(status: Int?): FollowStatus {
+            status ?: return NONE
+            return entries.find { it.status == status } ?: NONE
+        }
+    }
+}
+
+fun FollowStatus?.isFollowed(): Boolean {
+    return this == FollowStatus.FOLLOW || this == FollowStatus.MUTUAL_FOLLOW
+}

+ 21 - 0
app/src/main/java/com/adealink/weparty/module/profile/viewmodel/IFollowViewModel.kt

@@ -0,0 +1,21 @@
+package com.adealink.weparty.module.profile.viewmodel
+
+import androidx.lifecycle.LiveData
+import com.adealink.frame.base.Rlt
+import com.adealink.frame.mvvm.livedata.ExtLiveData
+import com.adealink.frame.mvvm.livedata.ExtMutableLiveData
+import com.adealink.weparty.module.profile.data.FollowStatus
+import com.adealink.weparty.module.profile.data.UserInfo
+
+interface IFollowViewModel {
+
+    val isFollowLD: ExtLiveData<Map<String, FollowStatus>>
+
+    fun isFollow(uid: String): LiveData<Rlt<FollowStatus>>
+
+    fun isFollow(uids: List<String>): LiveData<Rlt<Map<String, FollowStatus>>>
+
+    fun follow(uid: String): LiveData<Rlt<Any>>
+
+    fun unFollow(uid: String): LiveData<Rlt<Any>>
+}

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

@@ -68,8 +68,10 @@
             <enum name="normal" value="2" />
         </attr>
         <attr name="button_left_drawable" format="reference" />
+        <attr name="button_left_drawable_width" format="dimension" />
         <attr name="button_left_drawable_margin" format="dimension" />
         <attr name="button_right_drawable" format="reference" />
+        <attr name="button_right_drawable_width" format="dimension" />
         <attr name="button_right_drawable_margin" format="dimension" />
     </declare-styleable>
 

+ 2 - 0
module/playmate/src/main/java/com/adealink/weparty/playmate/detail/PlaymateDetailActivity.kt

@@ -12,6 +12,7 @@ import com.adealink.weparty.commonui.BaseActivity
 import com.adealink.weparty.commonui.ext.dp
 import com.adealink.weparty.commonui.toast.util.showFailedToast
 import com.adealink.weparty.module.playmate.Playmate
+import com.adealink.weparty.module.profile.ProfileModule
 import com.adealink.weparty.playmate.R
 import com.adealink.weparty.playmate.databinding.ActivityPlaymateDetailBinding
 import com.adealink.weparty.playmate.detail.comp.PlaymateDetailBottomComp
@@ -34,6 +35,7 @@ class PlaymateDetailActivity : BaseActivity() {
 
     private val binding by viewBinding(ActivityPlaymateDetailBinding::inflate)
     private val detailViewModel by viewModels<PlaymateDetailViewModel> { PlaymateViewModelFactory() }
+    private val followViewModel by fastLazy { ProfileModule.getFollowViewModel(this) }
     private val detailFragment by fastLazy { PlaymateDetailFragment() }
 
     override fun onBeforeCreate() {

+ 27 - 1
module/playmate/src/main/java/com/adealink/weparty/playmate/detail/comp/PlaymateToolBarViewComp.kt

@@ -10,6 +10,7 @@ import androidx.core.graphics.toColorInt
 import androidx.core.view.updateLayoutParams
 import androidx.lifecycle.LifecycleOwner
 import com.adealink.frame.aab.util.getCompatDimension
+import com.adealink.frame.base.fastLazy
 import com.adealink.frame.log.Log
 import com.adealink.frame.mvvm.view.ViewComponent
 import com.adealink.frame.mvvm.viewmodel.activityViewModels
@@ -20,13 +21,17 @@ import com.adealink.frame.util.statusBarHeight
 import com.adealink.weparty.commonui.dialogfragment.CommonTextActionDialog
 import com.adealink.weparty.commonui.ext.dp
 import com.adealink.weparty.commonui.ext.dpf
+import com.adealink.weparty.commonui.toast.util.showFailedToast
 import com.adealink.weparty.module.profile.Profile
+import com.adealink.weparty.module.profile.ProfileModule
+import com.adealink.weparty.module.profile.data.isFollowed
 import com.adealink.weparty.playmate.R
 import com.adealink.weparty.playmate.databinding.ActivityPlaymateDetailBinding
 import com.adealink.weparty.playmate.detail.viewmodel.PlaymateDetailViewModel
 import com.adealink.weparty.playmate.viewmodel.PlaymateViewModelFactory
 import com.google.android.material.appbar.AppBarLayout
 import com.qmuiteam.qmui.widget.util.QMUIStatusBarHelper
+import kotlin.getValue
 import kotlin.math.abs
 import com.adealink.weparty.R as APP_R
 
@@ -36,6 +41,7 @@ class PlaymateToolBarViewComp(
 ) : ViewComponent(lifecycleOwner) {
 
     private val detailViewModel by activityViewModels<PlaymateDetailViewModel> { PlaymateViewModelFactory() }
+    private val followViewModel by fastLazy { ProfileModule.getFollowViewModel(requireActivity()) }
     private var uid: String? = null
     private var isFollow: Boolean = false
 
@@ -169,6 +175,11 @@ class PlaymateToolBarViewComp(
             binding.topBar.ivAvatar.setImageUrl(it?.avatar)
             binding.topBar.tvUserName.text = it?.nickname
         }
+
+        followViewModel?.isFollowLD?.observe(viewLifecycleOwner) {
+            isFollow = it[this@PlaymateToolBarViewComp.uid]?.isFollowed() ?: false
+            updateFollow()
+        }
     }
 
     private fun goProfile() {
@@ -184,7 +195,22 @@ class PlaymateToolBarViewComp(
     }
 
     private fun clickFollow() {
-        isFollow = !isFollow
+        val uid = this@PlaymateToolBarViewComp.uid
+        if (uid.isNullOrEmpty()) {
+            return
+        }
+        if (isFollow) {
+            followViewModel?.unFollow(uid)?.observe(viewLifecycleOwner) {
+                showFailedToast(it)
+            }
+        } else {
+            followViewModel?.follow(uid)?.observe(viewLifecycleOwner) {
+                showFailedToast(it)
+            }
+        }
+    }
+
+    private fun updateFollow() {
         if (isFollow) {
             binding.topBar.btnFollow.setImageResource(R.drawable.playmate_followed_ic)
         } else {

+ 6 - 0
module/profile/src/main/java/com/adealink/weparty/profile/ProfileServiceImpl.kt

@@ -8,9 +8,11 @@ import com.adealink.weparty.App
 import com.adealink.weparty.module.profile.IProfileService
 import com.adealink.weparty.module.profile.data.UserConfigType
 import com.adealink.weparty.module.profile.data.UserInfo
+import com.adealink.weparty.module.profile.viewmodel.IFollowViewModel
 import com.adealink.weparty.module.profile.viewmodel.IProfileViewModel
 import com.adealink.weparty.profile.datasource.remote.ProfileHttpService
 import com.adealink.weparty.profile.manager.profileManager
+import com.adealink.weparty.profile.relation.viewmodel.FollowViewModel
 import com.adealink.weparty.profile.viewmodel.ProfileViewModel
 import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
 
@@ -65,6 +67,10 @@ class ProfileServiceImpl : IProfileService {
         return ViewModelProvider(owner, ProfileViewModelFactory())[ProfileViewModel::class.java]
     }
 
+    override fun getFollowViewModel(owner: ViewModelStoreOwner): IFollowViewModel? {
+        return ViewModelProvider(owner, ProfileViewModelFactory())[FollowViewModel::class.java]
+    }
+
     override fun logout() {
         profileManager.clear()
     }

+ 14 - 0
module/profile/src/main/java/com/adealink/weparty/profile/UserProfileActivity.kt

@@ -6,6 +6,7 @@ import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.view.updateLayoutParams
 import androidx.fragment.app.Fragment
 import com.adealink.frame.aab.util.getCompatDimension
+import com.adealink.frame.base.fastLazy
 import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.frame.router.Router
 import com.adealink.frame.router.annotation.BindExtra
@@ -15,13 +16,16 @@ import com.adealink.weparty.commonui.BaseActivity
 import com.adealink.weparty.commonui.recycleview.adapter.BaseActivityTabFragmentStateAdapter
 import com.adealink.weparty.commonui.widget.EmptyFragment
 import com.adealink.weparty.module.profile.Profile
+import com.adealink.weparty.module.profile.ProfileModule
 import com.adealink.weparty.module.profile.data.TAB_INDEX_PERSONAL
 import com.adealink.weparty.profile.comp.ProfileBottomComp
 import com.adealink.weparty.profile.comp.ProfileHeaderComp
 import com.adealink.weparty.profile.comp.ProfileToolBarViewComp
 import com.adealink.weparty.profile.databinding.ActivityUserProfileBinding
+import com.adealink.weparty.profile.relation.viewmodel.FollowViewModel
 import com.adealink.weparty.profile.viewmodel.ProfileViewModel
 import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
+import kotlin.getValue
 
 @RouterUri(
     path = [Profile.UserProfile.PATH],
@@ -32,9 +36,12 @@ class UserProfileActivity : BaseActivity() {
     @BindExtra(name = Profile.Common.EXTRA_UID)
     var userUid: String = ""
 
+    val isSelf by fastLazy { userUid == ProfileModule.getMyUid() }
+
     private val binding by viewBinding(ActivityUserProfileBinding::inflate)
 
     private val profileViewModel by viewModels<ProfileViewModel> { ProfileViewModelFactory() }
+    private val followViewModel by viewModels<FollowViewModel> { ProfileViewModelFactory() }
     private lateinit var profilePageAdapter: ProfilePageAdapter
 
     override fun onBeforeCreate() {
@@ -71,6 +78,13 @@ class UserProfileActivity : BaseActivity() {
         profileViewModel.pullUserInfoBy(userUid, false)
     }
 
+    override fun loadData() {
+        super.loadData()
+        if (!isSelf) {
+            followViewModel.isFollow(userUid)
+        }
+    }
+
     internal inner class ProfilePageAdapter : BaseActivityTabFragmentStateAdapter(this) {
 
         override fun getTabName(pos: Int): String {

+ 53 - 12
module/profile/src/main/java/com/adealink/weparty/profile/comp/ProfileBottomComp.kt

@@ -1,28 +1,69 @@
 package com.adealink.weparty.profile.comp
 
 import androidx.lifecycle.LifecycleOwner
+import com.adealink.frame.mvvm.viewmodel.activityViewModels
+import com.adealink.frame.util.onClick
+import com.adealink.weparty.commonui.ext.gone
 import com.adealink.weparty.commonui.ext.show
+import com.adealink.weparty.commonui.toast.util.showFailedToast
+import com.adealink.weparty.module.im.IMModule
+import com.adealink.weparty.module.profile.data.FollowStatus
 import com.adealink.weparty.profile.databinding.LayoutProfileBottomBinding
-import com.adealink.weparty.profile.dialog.CreateOrderDialog
+import com.adealink.weparty.profile.relation.viewmodel.FollowViewModel
+import com.adealink.weparty.profile.viewmodel.ProfileViewModelFactory
+import kotlin.getValue
 
 class ProfileBottomComp(
     lifecycleOwner: LifecycleOwner,
-    private val userUid: String,
+    private val uid: String,
     private val binding: LayoutProfileBottomBinding,
-) : BaseProfileViewComp(lifecycleOwner, userUid) {
+) : BaseProfileViewComp(lifecycleOwner, uid) {
+
+    private val followViewModel by activityViewModels<FollowViewModel> { ProfileViewModelFactory() }
 
     override fun initView() {
-//        if (isSelf) {
-//            binding.root.gone()
-//        } else {
-//            binding.root.show()
-//        }
-        // TODO: 测试
-        binding.root.show()
+        binding.btnFollow.onClick {
+            follow()
+        }
+        binding.btnChat.onClick {
+            goChat()
+        }
     }
 
-    private fun clickPay() {
-        CreateOrderDialog().show(fragmentManager)
+    override fun observeViewModel() {
+        super.observeViewModel()
+        followViewModel.isFollowLD.observe(viewLifecycleOwner) {
+            updateFollow(it[uid] ?: FollowStatus.NONE)
+        }
     }
 
+    private fun updateFollow(followStatus: FollowStatus) {
+        when (followStatus) {
+            FollowStatus.NONE,
+            FollowStatus.FANS -> {
+                //未关注,对方关注了你
+                binding.btnFollow.show()
+            }
+
+            FollowStatus.MUTUAL_FOLLOW,
+            FollowStatus.FOLLOW -> {
+                //互关,已经关注对方
+                binding.btnFollow.gone()
+            }
+        }
+    }
+
+    private fun follow() {
+        followViewModel.follow(uid).observe(viewLifecycleOwner) {
+            showFailedToast(it)
+        }
+    }
+
+    private fun goChat() {
+        activity?.let { act ->
+            IMModule.goSession(act, uid)
+        }
+    }
+
+
 }

+ 8 - 0
module/profile/src/main/java/com/adealink/weparty/profile/datasource/remote/FollowHttpService.kt

@@ -7,11 +7,19 @@ import com.adealink.weparty.profile.relation.data.FansLlistRes
 import com.adealink.weparty.profile.relation.data.FollowListReq
 import com.adealink.weparty.profile.relation.data.FollowListRes
 import com.adealink.weparty.profile.relation.data.FollowReq
+import com.adealink.weparty.profile.relation.data.FollowStatusReq
+import com.adealink.weparty.profile.relation.data.FollowStatusRes
 import retrofit2.http.Body
 import retrofit2.http.POST
 
 interface FollowHttpService {
 
+
+    @POST("user/followRelateions/get")
+    suspend fun isFollow(
+        @Body req: FollowStatusReq
+    ): Rlt<Res<FollowStatusRes>>
+
     @POST("user/follow")
     suspend fun follow(
         @Body req: FollowReq

+ 14 - 0
module/profile/src/main/java/com/adealink/weparty/profile/relation/data/RelationShipData.kt

@@ -12,6 +12,20 @@ data class FollowReq(
 )
 
 
+data class FollowStatusReq(
+    @SerializedName("userNos") val uids: List<String>
+)
+
+data class FollowStatusRes(
+    @SerializedName("list") val list: List<FollowStatusData>
+)
+
+data class FollowStatusData(
+    @SerializedName("userNo") val uid: String,
+    @SerializedName("relateion") val followStatus: Int, //详见: FollowStatus
+)
+
+
 data class FollowListReq(
     @SerializedName("page") val page: PageReq
 )

+ 117 - 5
module/profile/src/main/java/com/adealink/weparty/profile/relation/viewmodel/FollowViewModel.kt

@@ -3,39 +3,151 @@ package com.adealink.weparty.profile.relation.viewmodel
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import com.adealink.frame.base.Rlt
+import com.adealink.frame.mvvm.livedata.ExtMutableLiveData
 import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
 import com.adealink.frame.mvvm.viewmodel.BaseViewModel
 import com.adealink.weparty.App
+import com.adealink.weparty.module.profile.data.FollowStatus
+import com.adealink.weparty.module.profile.viewmodel.IFollowViewModel
 import com.adealink.weparty.profile.datasource.remote.FollowHttpService
 import com.adealink.weparty.profile.relation.data.FansItemData
+import com.adealink.weparty.profile.relation.data.FollowData
 import com.adealink.weparty.profile.relation.data.FollowItemData
 import com.adealink.weparty.profile.relation.data.FollowReq
+import com.adealink.weparty.profile.relation.data.FollowStatusData
+import com.adealink.weparty.profile.relation.data.FollowStatusReq
 import com.adealink.weparty.util.PageHandler
 import kotlinx.coroutines.launch
+import kotlin.String
 
-class FollowViewModel : BaseViewModel() {
+class FollowViewModel : BaseViewModel(), IFollowViewModel {
 
     private val followHttpService by lazy {
         App.instance.networkService.getHttpService(FollowHttpService::class.java)
     }
 
-    fun follow(uid: String): LiveData<Rlt<Any>> {
+    private val followStatusMap = mutableMapOf<String, FollowStatus>()
+    override val isFollowLD = ExtMutableLiveData<Map<String, FollowStatus>>()
+    override fun isFollow(uid: String): LiveData<Rlt<FollowStatus>> {
+        val liveData = OnceMutableLiveData<Rlt<FollowStatus>>()
+        viewModelScope.launch {
+            val rlt = followHttpService.isFollow(FollowStatusReq(listOf(uid)))
+            when (rlt) {
+                is Rlt.Failed -> {
+                    liveData.send(rlt)
+                }
+
+                is Rlt.Success -> {
+                    val followStatus =
+                        FollowStatus.map(rlt.data.data?.list?.find { it.uid == uid }?.followStatus)
+                    followStatusMap[uid] = followStatus
+                    isFollowLD.send(followStatusMap)
+                    liveData.send(Rlt.Success(followStatus))
+                }
+            }
+        }
+        return liveData
+    }
+
+
+    override fun isFollow(uids: List<String>): LiveData<Rlt<Map<String, FollowStatus>>> {
+        val liveData = OnceMutableLiveData<Rlt<Map<String, FollowStatus>>>()
+        viewModelScope.launch {
+            val rlt = followHttpService.isFollow(FollowStatusReq(uids.distinct()))
+            when (rlt) {
+                is Rlt.Failed -> {
+                    liveData.send(rlt)
+                }
+
+                is Rlt.Success -> {
+                    rlt.data.data?.list?.forEach {
+                        followStatusMap[it.uid] = FollowStatus.map(it.followStatus)
+                    }
+                    isFollowLD.send(followStatusMap)
+                    liveData.send(Rlt.Success(followStatusMap))
+                }
+            }
+        }
+        return liveData
+    }
+
+    override fun follow(uid: String): LiveData<Rlt<Any>> {
         val liveData = OnceMutableLiveData<Rlt<Any>>()
         viewModelScope.launch {
-            liveData.send(followHttpService.follow(FollowReq(uid, true)))
+            val rlt = followHttpService.follow(FollowReq(uid, true))
+            when (rlt) {
+                is Rlt.Failed -> {
+                    //ntd.
+                }
+
+                is Rlt.Success -> {
+                    onFollowStatusChanged(uid, true)
+                }
+            }
+            liveData.send(rlt)
         }
         return liveData
     }
 
-    fun unFollow(uid: String): LiveData<Rlt<Any>> {
+    override fun unFollow(uid: String): LiveData<Rlt<Any>> {
         val liveData = OnceMutableLiveData<Rlt<Any>>()
         viewModelScope.launch {
-            liveData.send(followHttpService.follow(FollowReq(uid, false)))
+            val rlt = followHttpService.follow(FollowReq(uid, false))
+            when (rlt) {
+                is Rlt.Failed -> {
+                    //ntd.
+                }
+
+                is Rlt.Success -> {
+                    onFollowStatusChanged(uid, false)
+                }
+            }
+            liveData.send(rlt)
         }
         return liveData
     }
 
 
+    private fun onFollowStatusChanged(uid: String, follow: Boolean) {
+        val currentStatus = followStatusMap[uid]
+        val nextStatus = when (currentStatus) {
+            FollowStatus.NONE, null -> {
+                if (follow) {
+                    FollowStatus.FOLLOW
+                } else {
+                    FollowStatus.NONE
+                }
+            }
+
+            FollowStatus.MUTUAL_FOLLOW -> {
+                if (follow) {
+                    FollowStatus.MUTUAL_FOLLOW
+                } else {
+                    FollowStatus.FANS
+                }
+            }
+
+            FollowStatus.FANS -> {
+                if (follow) {
+                    FollowStatus.MUTUAL_FOLLOW
+                } else {
+                    FollowStatus.FANS
+                }
+            }
+
+            FollowStatus.FOLLOW -> {
+                if (follow) {
+                    FollowStatus.FOLLOW
+                } else {
+                    FollowStatus.NONE
+                }
+            }
+        }
+        followStatusMap[uid] = nextStatus
+        isFollowLD.send(followStatusMap)
+    }
+
+
     private val followList = mutableListOf<FollowItemData>()
     private val followPageHandler = PageHandler()
     val followListLD = MutableLiveData<List<FollowItemData>>()

BIN
module/profile/src/main/res/drawable-xhdpi/profile_chat_ic.png


BIN
module/profile/src/main/res/drawable-xhdpi/profile_follow_ic.png


+ 1 - 3
module/profile/src/main/res/layout/activity_user_profile.xml

@@ -78,8 +78,6 @@
         layout="@layout/layout_profile_bottom"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_gravity="bottom"
-        android:visibility="gone"
-        tools:visibility="visible" />
+        android:layout_gravity="bottom" />
 
 </androidx.coordinatorlayout.widget.CoordinatorLayout>

+ 10 - 7
module/profile/src/main/res/layout/layout_profile_bottom.xml

@@ -13,14 +13,17 @@
         android:layout_width="wrap_content"
         android:layout_height="48dp"
         android:layout_marginStart="16dp"
+        android:paddingHorizontal="24dp"
         android:visibility="gone"
+        app:button_left_drawable="@drawable/profile_follow_ic"
+        app:button_left_drawable_margin="4dp"
+        app:button_left_drawable_width="16dp"
         app:layout_constraintEnd_toStartOf="@id/btn_chat"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
-        app:text="@string/profile_pay_with_her"
+        app:text="@string/common_follow"
         app:textColor="@color/white"
-        app:textSize="16sp"
-        tools:visibility="visible" />
+        app:textSize="16sp" />
 
     <com.adealink.weparty.commonui.widget.CommonButton
         android:id="@+id/btn_chat"
@@ -28,14 +31,14 @@
         android:layout_height="48dp"
         android:layout_marginStart="10dp"
         android:layout_marginEnd="16dp"
-        android:visibility="gone"
+        app:button_left_drawable="@drawable/profile_chat_ic"
+        app:button_left_drawable_width="16dp"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toEndOf="@id/btn_follow"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_goneMarginStart="16dp"
-        app:text="@string/profile_pay_with_her"
+        app:text="@string/common_chat"
         app:textColor="@color/white"
-        app:textSize="16sp"
-        tools:visibility="visible" />
+        app:textSize="16sp" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>