인기 크리에이터 팔로우 해제 시 확인 다이얼로그 추가

This commit is contained in:
Yu Sung
2026-01-22 19:04:48 +09:00
parent 75452f0ffd
commit 4b9cdeb824
3 changed files with 64 additions and 11 deletions

View File

@@ -11,7 +11,7 @@ import Kingfisher
struct HomeCreatorRankingItemView: View { struct HomeCreatorRankingItemView: View {
let rank: Int let rank: Int
@State var item: GetExplorerSectionCreatorResponse @Binding var item: GetExplorerSectionCreatorResponse
let onClickFollow: (Int, Bool) -> Void let onClickFollow: (Int, Bool) -> Void
@@ -57,11 +57,18 @@ struct HomeCreatorRankingItemView: View {
item.follow ? .white : Color(hex: "263238") item.follow ? .white : Color(hex: "263238")
) )
.onTapGesture { .onTapGesture {
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { let trimmedToken = token.trimmingCharacters(in: .whitespacesAndNewlines)
item.follow = !item.follow guard !trimmedToken.isEmpty else {
onClickFollow(item.id, item.follow)
return
}
if item.follow {
onClickFollow(item.id, false)
} else {
item.follow = true
onClickFollow(item.id, true)
} }
onClickFollow(item.id, item.follow)
} }
} }
} }
@@ -76,12 +83,14 @@ struct HomeCreatorRankingItemView: View {
#Preview { #Preview {
HomeCreatorRankingItemView( HomeCreatorRankingItemView(
rank: 1, rank: 1,
item: GetExplorerSectionCreatorResponse( item: .constant(
GetExplorerSectionCreatorResponse(
id: 1, id: 1,
nickname: "유빈ASMR", nickname: "유빈ASMR",
tags: "", tags: "",
profileImageUrl: "https://cf.sodalive.net/profile/34806/34806-profile-49db6b45-bb1e-4dc7-917e-1a614a853f5f-4232-1752158072656", profileImageUrl: "https://cf.sodalive.net/profile/34806/34806-profile-49db6b45-bb1e-4dc7-917e-1a614a853f5f-4232-1752158072656",
follow: true follow: true
)
), ),
onClickFollow: { _, _ in } onClickFollow: { _, _ in }
) )

View File

@@ -22,6 +22,9 @@ struct HomeTabView: View {
@State private var isShowAuthConfirmView: Bool = false @State private var isShowAuthConfirmView: Bool = false
@State private var pendingAction: (() -> Void)? = nil @State private var pendingAction: (() -> Void)? = nil
@State private var payload = Payload() @State private var payload = Payload()
@State private var isShowUnfollowConfirmDialog = false
@State private var pendingUnfollowCreatorId: Int? = nil
@State private var pendingUnfollowCreatorName = ""
var onTapPopularCharacterAllView: (() -> Void)? = nil var onTapPopularCharacterAllView: (() -> Void)? = nil
@@ -124,17 +127,19 @@ struct HomeTabView: View {
ScrollView(.horizontal, showsIndicators: false) { ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 16) { LazyHStack(spacing: 16) {
ForEach(0..<viewModel.creatorRanking.count, id: \.self) { ForEach(viewModel.creatorRanking.indices, id: \.self) { index in
let item = viewModel.creatorRanking[$0] let item = viewModel.creatorRanking[index]
HomeCreatorRankingItemView( HomeCreatorRankingItemView(
rank: $0 + 1, rank: index + 1,
item: item, item: $viewModel.creatorRanking[index],
onClickFollow: { creatorId, follow in onClickFollow: { creatorId, follow in
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
if follow { if follow {
viewModel.creatorFollow(creatorId: item.id, follow: true, notify: true) viewModel.creatorFollow(creatorId: item.id, follow: true, notify: true)
} else { } else {
viewModel.creatorFollow(creatorId: item.id, follow: false, notify: false) pendingUnfollowCreatorId = creatorId
pendingUnfollowCreatorName = item.nickname
isShowUnfollowConfirmDialog = true
} }
} else { } else {
AppState.shared AppState.shared
@@ -430,6 +435,37 @@ struct HomeTabView: View {
) )
} }
if isShowUnfollowConfirmDialog {
SodaDialog(
title: I18n.MemberChannel.unfollowConfirmTitle,
desc: I18n.MemberChannel.unfollowConfirmDescription(pendingUnfollowCreatorName),
confirmButtonTitle: I18n.Common.confirm,
confirmButtonAction: {
isShowUnfollowConfirmDialog = false
guard let creatorId = pendingUnfollowCreatorId else {
pendingUnfollowCreatorId = nil
pendingUnfollowCreatorName = ""
return
}
if let index = viewModel.creatorRanking.firstIndex(
where: { $0.id == creatorId }
) {
viewModel.creatorRanking[index].follow = false
}
pendingUnfollowCreatorId = nil
pendingUnfollowCreatorName = ""
viewModel.creatorFollow(creatorId: creatorId, follow: false, notify: false)
},
cancelButtonTitle: I18n.Common.cancel,
cancelButtonAction: {
isShowUnfollowConfirmDialog = false
pendingUnfollowCreatorId = nil
pendingUnfollowCreatorName = ""
},
textAlignment: .center
)
}
if liveViewModel.isShowPasswordDialog { if liveViewModel.isShowPasswordDialog {
LiveRoomPasswordDialog( LiveRoomPasswordDialog(
isShowing: $liveViewModel.isShowPasswordDialog, isShowing: $liveViewModel.isShowPasswordDialog,

View File

@@ -792,6 +792,14 @@ enum I18n {
static var all: String { pick(ko: "모두 알림", en: "All notifications", ja: "すべて通知") } static var all: String { pick(ko: "모두 알림", en: "All notifications", ja: "すべて通知") }
static var none: String { pick(ko: "알림 없음", en: "No notifications", ja: "通知なし") } static var none: String { pick(ko: "알림 없음", en: "No notifications", ja: "通知なし") }
static var unfollow: String { pick(ko: "팔로우 취소", en: "Unfollow", ja: "フォロー解除") } static var unfollow: String { pick(ko: "팔로우 취소", en: "Unfollow", ja: "フォロー解除") }
static var unfollowConfirmTitle: String { pick(ko: "팔로우 해제", en: "Unfollow", ja: "フォロー解除") }
static func unfollowConfirmDescription(_ nickname: String) -> String {
pick(
ko: "\(nickname)님을 팔로우 해제 하시겠습니까?",
en: "Do you want to unfollow \(nickname)?",
ja: "\(nickname)さんのフォローを解除しますか?"
)
}
static var liveOnNow: String { pick(ko: "현재 라이브 중입니다.", en: "Live is currently ongoing.", ja: "現在ライブ配信中です。") } static var liveOnNow: String { pick(ko: "현재 라이브 중입니다.", en: "Live is currently ongoing.", ja: "現在ライブ配信中です。") }
static var cannotReserveOwnLive: String { pick(ko: "내가 만든 라이브는 예약할 수 없습니다.", en: "reserve a live you created is required.", ja: "自分が作ったライブは予約できません。") } static var cannotReserveOwnLive: String { pick(ko: "내가 만든 라이브는 예약할 수 없습니다.", en: "reserve a live you created is required.", ja: "自分が作ったライブは予約できません。") }