후원 랭킹 기간 선택 추가

프로필 후원 랭킹 조회와 프로필 갱신 요청에 기간 값을 전달한다.
This commit is contained in:
2026-02-03 19:09:55 +09:00
parent 84803c171c
commit 21c87f95ef
11 changed files with 242 additions and 6 deletions

View File

@@ -48,6 +48,7 @@ interface ExplorerApi {
@Path("id") id: Long,
@Query("page") page: Int,
@Query("size") size: Int,
@Query("period") period: String?,
@Header("Authorization") authHeader: String
): Single<ApiResponse<GetDonationAllResponse>>

View File

@@ -80,12 +80,14 @@ class ExplorerRepository(
id: Long,
page: Int,
size: Int,
donationRankingPeriod: String?,
token: String
): Single<ApiResponse<GetDonationAllResponse>> {
return api.getCreatorProfileDonationRanking(
id = id,
page = page - 1,
size = size,
period = donationRankingPeriod,
authHeader = token
)
}

View File

@@ -0,0 +1,12 @@
package kr.co.vividnext.sodalive.explorer.profile.donation
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName
@Keep
enum class DonationRankingPeriod {
@SerializedName("WEEKLY")
WEEKLY,
@SerializedName("CUMULATIVE")
CUMULATIVE
}

View File

@@ -16,6 +16,8 @@ data class GetDonationAllResponse(
val isVisibleDonationRank: Boolean,
@SerializedName("totalCount")
val totalCount: Int,
@SerializedName("donationRankingPeriod")
val donationRankingPeriod: DonationRankingPeriod? = null,
@SerializedName("userDonationRanking")
val userDonationRanking: List<UserDonationRankingResponse>,
)

View File

@@ -7,6 +7,7 @@ import android.view.View
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.tabs.TabLayout
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.base.BaseActivity
import kr.co.vividnext.sodalive.common.Constants
@@ -27,15 +28,19 @@ class UserProfileDonationAllViewActivity : BaseActivity<ActivityUserProfileLiveA
private lateinit var adapter: UserProfileDonationAllAdapter
private var userId: Long = 0
private var isCreator: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
userId = intent.getLongExtra(Constants.EXTRA_USER_ID, 0)
isCreator = SharedPreferenceManager.userId == userId
super.onCreate(savedInstanceState)
if (userId > 0) {
bindData()
viewModel.getCreatorProfileDonationRanking(userId)
if (!isCreator) {
viewModel.getCreatorProfileDonationRanking(userId)
}
} else {
Toast.makeText(
applicationContext,
@@ -120,15 +125,26 @@ class UserProfileDonationAllViewActivity : BaseActivity<ActivityUserProfileLiveA
binding.swipeRefreshLayout.isRefreshing = false
}
if (SharedPreferenceManager.userId == userId) {
if (isCreator) {
binding.llTotal.visibility = View.VISIBLE
binding.llVisibleDonationRanking.visibility = View.VISIBLE
binding.llDonationRankingPeriod.visibility = View.VISIBLE
binding.tabDonationRankingPeriod.visibility = View.VISIBLE
binding.ivVisibleDonationRank.setOnClickListener {
viewModel.onClickToggleVisibleDonationRank()
}
binding.llPeriodWeekly.setOnClickListener {
viewModel.updateDonationRankingPeriod(DonationRankingPeriod.WEEKLY)
}
binding.llPeriodCumulative.setOnClickListener {
viewModel.updateDonationRankingPeriod(DonationRankingPeriod.CUMULATIVE)
}
setupDonationRankingTabs()
} else {
binding.llTotal.visibility = View.GONE
binding.llVisibleDonationRanking.visibility = View.GONE
binding.llDonationRankingPeriod.visibility = View.GONE
binding.tabDonationRankingPeriod.visibility = View.GONE
}
}
@@ -156,6 +172,10 @@ class UserProfileDonationAllViewActivity : BaseActivity<ActivityUserProfileLiveA
adapter.notifyDataSetChanged()
}
viewModel.selectedDonationRankingPeriod.observe(this) {
updateDonationRankingPeriodSelection(it)
}
viewModel.isVisibleDonationRank.observe(this) {
binding.ivVisibleDonationRank.setImageResource(
if (it) {
@@ -166,4 +186,57 @@ class UserProfileDonationAllViewActivity : BaseActivity<ActivityUserProfileLiveA
)
}
}
private fun setupDonationRankingTabs() {
binding.tabDonationRankingPeriod.apply {
addTab(
newTab()
.setText(R.string.screen_user_profile_donation_period_weekly)
.setTag(DonationRankingPeriod.WEEKLY)
)
addTab(
newTab()
.setText(R.string.screen_user_profile_donation_period_cumulative)
.setTag(DonationRankingPeriod.CUMULATIVE)
)
addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
@SuppressLint("NotifyDataSetChanged")
override fun onTabSelected(tab: TabLayout.Tab) {
val period = tab.tag as DonationRankingPeriod
adapter.items.clear()
adapter.notifyDataSetChanged()
viewModel.refresh(userId, period)
}
override fun onTabUnselected(tab: TabLayout.Tab) = Unit
@SuppressLint("NotifyDataSetChanged")
override fun onTabReselected(tab: TabLayout.Tab) {
val period = tab.tag as DonationRankingPeriod
adapter.items.clear()
adapter.notifyDataSetChanged()
viewModel.refresh(userId, period)
}
})
}
binding.tabDonationRankingPeriod.getTabAt(0)?.select()
}
private fun updateDonationRankingPeriodSelection(period: DonationRankingPeriod) {
binding.ivPeriodWeekly.setImageResource(
if (period == DonationRankingPeriod.WEEKLY) {
R.drawable.btn_square_select_checked
} else {
R.drawable.btn_square_select_normal
}
)
binding.ivPeriodCumulative.setImageResource(
if (period == DonationRankingPeriod.CUMULATIVE) {
R.drawable.btn_square_select_checked
} else {
R.drawable.btn_square_select_normal
}
)
}
}

View File

@@ -34,19 +34,29 @@ class UserProfileDonationAllViewModel(
val isVisibleDonationRank: LiveData<Boolean>
get() = _isVisibleDonationRank
private val _selectedDonationRankingPeriod = MutableLiveData<DonationRankingPeriod>()
val selectedDonationRankingPeriod: LiveData<DonationRankingPeriod>
get() = _selectedDonationRankingPeriod
private var isLast = false
private var page = 1
private val size = 10
private var currentRankingPeriod: DonationRankingPeriod? = null
fun getCreatorProfileDonationRanking(userId: Long) {
fun getCreatorProfileDonationRanking(userId: Long, period: DonationRankingPeriod? = null) {
if (!_isLoading.value!! && !isLast) {
if (period != null) {
currentRankingPeriod = period
}
_isLoading.value = true
val requestPeriod = period ?: currentRankingPeriod
compositeDisposable.add(
repository.getCreatorProfileDonationRanking(
id = userId,
page = page,
size = size,
donationRankingPeriod = requestPeriod?.name,
token = "Bearer ${SharedPreferenceManager.token}"
)
.subscribeOn(Schedulers.io())
@@ -54,6 +64,12 @@ class UserProfileDonationAllViewModel(
.subscribe(
{
if (it.success && it.data != null) {
it.data.donationRankingPeriod?.let { donationRankingPeriod ->
_selectedDonationRankingPeriod.postValue(donationRankingPeriod)
if (currentRankingPeriod == null) {
currentRankingPeriod = donationRankingPeriod
}
}
if (it.data.userDonationRanking.isNotEmpty()) {
page += 1
_donationLiveData.postValue(it.data!!)
@@ -87,10 +103,10 @@ class UserProfileDonationAllViewModel(
}
}
fun refresh(userId: Long) {
fun refresh(userId: Long, period: DonationRankingPeriod? = null) {
page = 1
isLast = false
getCreatorProfileDonationRanking(userId)
getCreatorProfileDonationRanking(userId, period)
}
fun onClickToggleVisibleDonationRank() {
@@ -135,4 +151,45 @@ class UserProfileDonationAllViewModel(
)
)
}
fun updateDonationRankingPeriod(period: DonationRankingPeriod) {
_isLoading.value = true
compositeDisposable.add(
memberRepository.updateProfile(
request = ProfileUpdateRequest(
email = SharedPreferenceManager.email,
donationRankingPeriod = period
),
token = "Bearer ${SharedPreferenceManager.token}"
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
if (it.success) {
_selectedDonationRankingPeriod.postValue(period)
} else {
if (it.message != null) {
_toastLiveData.postValue(it.message)
} else {
_toastLiveData.postValue(
SodaLiveApplicationHolder.get()
.getString(R.string.common_error_unknown)
)
}
}
_isLoading.value = false
},
{
_isLoading.value = false
it.message?.let { message -> Logger.e(message) }
_toastLiveData.postValue(
SodaLiveApplicationHolder.get()
.getString(R.string.common_error_unknown)
)
}
)
)
}
}

View File

@@ -2,6 +2,7 @@ package kr.co.vividnext.sodalive.mypage.profile
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName
import kr.co.vividnext.sodalive.explorer.profile.donation.DonationRankingPeriod
import kr.co.vividnext.sodalive.user.Gender
@Keep
@@ -19,5 +20,6 @@ data class ProfileUpdateRequest(
@SerializedName("websiteUrl") val websiteUrl: String? = null,
@SerializedName("blogUrl") val blogUrl: String? = null,
@SerializedName("isVisibleDonationRank") val isVisibleDonationRank: Boolean? = null,
@SerializedName("donationRankingPeriod") val donationRankingPeriod: DonationRankingPeriod? = null,
@SerializedName("container") val container: String = "aos"
)

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
@@ -54,11 +55,76 @@
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_donation_ranking_period"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="13.3dp"
android:layout_marginTop="13.3dp"
android:gravity="center"
android:orientation="horizontal"
android:visibility="gone">
<LinearLayout
android:id="@+id/ll_period_weekly"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:gravity="center_vertical">
<ImageView
android:id="@+id/iv_period_weekly"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/btn_square_select_checked"
tools:src="@drawable/btn_square_select_checked" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6.7dp"
android:fontFamily="@font/medium"
android:text="@string/screen_user_profile_donation_period_weekly"
android:textColor="@color/color_eeeeee"
android:textSize="14.7sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_period_cumulative"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:clickable="true"
android:focusable="true"
android:gravity="center_vertical">
<ImageView
android:id="@+id/iv_period_cumulative"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/btn_square_select_normal"
tools:src="@drawable/btn_square_select_normal" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6.7dp"
android:fontFamily="@font/medium"
android:text="@string/screen_user_profile_donation_period_cumulative"
android:textColor="@color/color_eeeeee"
android:textSize="14.7sp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_total"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="13.3dp"
android:layout_marginHorizontal="13.3dp"
android:layout_marginTop="13.3dp"
android:background="@drawable/bg_round_corner_8_13181b"
android:orientation="vertical"
android:padding="16.7dp"
@@ -167,9 +233,24 @@
</LinearLayout>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_donation_ranking_period"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="13.3dp"
android:background="@color/black"
android:visibility="gone"
app:tabIndicatorColor="@color/color_3bb9f1"
app:tabIndicatorFullWidth="true"
app:tabIndicatorHeight="4dp"
app:tabSelectedTextColor="@color/color_3bb9f1"
app:tabTextAppearance="@style/tabText"
app:tabTextColor="@color/color_b0bec5" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="13.3dp"
android:gravity="center_vertical"
android:paddingHorizontal="13.3dp">

View File

@@ -810,6 +810,8 @@
<string name="screen_user_profile_donation_total_label">All</string>
<string name="screen_user_profile_donation_total_unit">items</string>
<string name="screen_user_profile_donation_total_can_format">%1$s %2$s</string>
<string name="screen_user_profile_donation_period_weekly">Weekly</string>
<string name="screen_user_profile_donation_period_cumulative">Cumulative</string>
<string name="screen_user_profile_community_title">Community</string>
<string name="screen_user_profile_community_create">Create post</string>
<string name="screen_user_profile_community_empty_desc">After posting, your post will appear here\nand be visible in the community.</string>

View File

@@ -810,6 +810,8 @@
<string name="screen_user_profile_donation_total_label"></string>
<string name="screen_user_profile_donation_total_unit"></string>
<string name="screen_user_profile_donation_total_can_format">%1$s %2$s</string>
<string name="screen_user_profile_donation_period_weekly">週間</string>
<string name="screen_user_profile_donation_period_cumulative">累計</string>
<string name="screen_user_profile_community_title">コミュニティ</string>
<string name="screen_user_profile_community_create">投稿作成</string>
<string name="screen_user_profile_community_empty_desc">投稿するとここに表示され、\nコミュニティに公開されます。</string>

View File

@@ -809,6 +809,8 @@
<string name="screen_user_profile_donation_total_label">전체</string>
<string name="screen_user_profile_donation_total_unit"></string>
<string name="screen_user_profile_donation_total_can_format">%1$s %2$s</string>
<string name="screen_user_profile_donation_period_weekly">주간</string>
<string name="screen_user_profile_donation_period_cumulative">누적</string>
<string name="screen_user_profile_community_title">커뮤니티</string>
<string name="screen_user_profile_community_create">게시물 등록</string>
<string name="screen_user_profile_community_empty_desc">게시 후에 게시물이 여기에 표시되고\n커뮤니티에 공개됩니다.</string>