fix: 메인 홈 - 인기 크리에이터
- 팔로우 수 제거 - 팔로우 버튼 추가 - 배경: 그라데이션 제거, 하나의 색으로 설정
This commit is contained in:
@@ -151,28 +151,28 @@ struct ContentMainTabHomeRankCreatorView: View {
|
||||
nickname: "User1",
|
||||
tags: "",
|
||||
profileImageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
||||
followerCount: 1000
|
||||
follow: false
|
||||
),
|
||||
GetExplorerSectionCreatorResponse(
|
||||
id: 2,
|
||||
nickname: "User2",
|
||||
tags: "",
|
||||
profileImageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
||||
followerCount: 1000
|
||||
follow: false
|
||||
),
|
||||
GetExplorerSectionCreatorResponse(
|
||||
id: 3,
|
||||
nickname: "User3",
|
||||
tags: "",
|
||||
profileImageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
||||
followerCount: 1000
|
||||
follow: false
|
||||
),
|
||||
GetExplorerSectionCreatorResponse(
|
||||
id: 4,
|
||||
nickname: "User4",
|
||||
tags: "",
|
||||
profileImageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
||||
followerCount: 1000
|
||||
follow: false
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
@@ -24,6 +24,6 @@ struct GetExplorerSectionCreatorResponse: Decodable, Hashable {
|
||||
let nickname: String
|
||||
let tags: String
|
||||
let profileImageUrl: String
|
||||
let followerCount: Int
|
||||
var follow: Bool
|
||||
}
|
||||
|
||||
|
||||
@@ -11,54 +11,55 @@ import Kingfisher
|
||||
struct HomeCreatorRankingItemView: View {
|
||||
|
||||
let rank: Int
|
||||
let item: GetExplorerSectionCreatorResponse
|
||||
@State var item: GetExplorerSectionCreatorResponse
|
||||
|
||||
let onClickFollow: (Int, Bool) -> Void
|
||||
|
||||
let crowns = ["rank_1", "rank_2", "rank_3"]
|
||||
|
||||
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
|
||||
|
||||
var body: some View {
|
||||
ZStack(alignment: .topLeading) {
|
||||
VStack(spacing: 0) {
|
||||
KFImage(URL(string: item.profileImageUrl))
|
||||
.cancelOnDisappear(true)
|
||||
.resizable()
|
||||
.frame(width: 70, height: 70)
|
||||
.frame(width: 84, height: 84)
|
||||
.clipShape(Circle())
|
||||
|
||||
Text(item.nickname)
|
||||
.font(.custom(Font.preRegular.rawValue, size: 18))
|
||||
.font(.custom(Font.preRegular.rawValue, size: 16))
|
||||
.foregroundColor(.white)
|
||||
.padding(.top, 8)
|
||||
.padding(.top, 20)
|
||||
|
||||
Text("팔로워")
|
||||
.font(.custom(Font.preBold.rawValue, size: 14))
|
||||
.foregroundColor(Color(hex: "78909C"))
|
||||
.padding(.top, 12)
|
||||
Spacer()
|
||||
|
||||
Text("\(item.followerCount)")
|
||||
.font(.custom(Font.preRegular.rawValue, size: 14))
|
||||
.foregroundColor(Color(hex: "78909C"))
|
||||
.padding(.top, 4)
|
||||
if item.id != UserDefaults.int(forKey: .userId) {
|
||||
Text(item.follow ? "팔로잉" : "팔로우")
|
||||
.font(.custom(Font.preRegular.rawValue, size: 14))
|
||||
.padding(.vertical, 4)
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(
|
||||
item.follow ? Color(hex: "455a64") : Color.white
|
||||
)
|
||||
.cornerRadius(999)
|
||||
.foregroundColor(
|
||||
item.follow ? .white : Color(hex: "263238")
|
||||
)
|
||||
.onTapGesture {
|
||||
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
||||
item.follow = !item.follow
|
||||
}
|
||||
|
||||
onClickFollow(item.id, item.follow)
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(width: 133, height: 188)
|
||||
.background(
|
||||
LinearGradient(
|
||||
gradient: Gradient(colors: [Color(hex: "5ACDE1"), Color(hex: "2A339D")]),
|
||||
startPoint: .topLeading,
|
||||
endPoint: .bottom
|
||||
)
|
||||
)
|
||||
.padding(16)
|
||||
.frame(width: 144, height: 204)
|
||||
.background(Color(hex: "263238"))
|
||||
.cornerRadius(16)
|
||||
.overlay {
|
||||
RoundedRectangle(cornerRadius: 16)
|
||||
.strokeBorder(
|
||||
LinearGradient(
|
||||
gradient: Gradient(colors: [Color(hex: "9AE2F6"), .white.opacity(0)]),
|
||||
startPoint: .top,
|
||||
endPoint: .bottom
|
||||
),
|
||||
lineWidth: 1
|
||||
)
|
||||
}
|
||||
.padding(.top, 20)
|
||||
|
||||
if rank <= 3 {
|
||||
@@ -79,7 +80,8 @@ struct HomeCreatorRankingItemView: View {
|
||||
nickname: "유빈ASMR",
|
||||
tags: "",
|
||||
profileImageUrl: "https://cf.sodalive.net/profile/34806/34806-profile-49db6b45-bb1e-4dc7-917e-1a614a853f5f-4232-1752158072656",
|
||||
followerCount: 1000
|
||||
)
|
||||
follow: true
|
||||
),
|
||||
onClickFollow: { _, _ in }
|
||||
)
|
||||
}
|
||||
|
||||
@@ -109,7 +109,22 @@ struct HomeTabView: View {
|
||||
HStack(spacing: 16) {
|
||||
ForEach(0..<viewModel.creatorRanking.count, id: \.self) {
|
||||
let item = viewModel.creatorRanking[$0]
|
||||
HomeCreatorRankingItemView(rank: $0 + 1, item: item)
|
||||
HomeCreatorRankingItemView(
|
||||
rank: $0 + 1,
|
||||
item: item,
|
||||
onClickFollow: { creatorId, follow in
|
||||
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
||||
if follow {
|
||||
viewModel.creatorFollow(creatorId: item.id, follow: true, notify: true)
|
||||
} else {
|
||||
viewModel.creatorFollow(creatorId: item.id, follow: false, notify: false)
|
||||
}
|
||||
} else {
|
||||
AppState.shared
|
||||
.setAppStep(step: .login)
|
||||
}
|
||||
}
|
||||
)
|
||||
.onTapGesture {
|
||||
if !token.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
||||
AppState.shared
|
||||
|
||||
@@ -14,6 +14,7 @@ enum SeriesPublishedDaysOfWeek: String, Encodable {
|
||||
|
||||
final class HomeTabViewModel: ObservableObject {
|
||||
private let repository = HomeTabRepository()
|
||||
private let userRepository = UserRepository()
|
||||
private var subscription = Set<AnyCancellable>()
|
||||
|
||||
@Published var errorMessage = ""
|
||||
@@ -160,4 +161,40 @@ final class HomeTabViewModel: ObservableObject {
|
||||
}
|
||||
.store(in: &subscription)
|
||||
}
|
||||
|
||||
func creatorFollow(creatorId: Int, follow: Bool = true, notify: Bool = true) {
|
||||
isLoading = true
|
||||
|
||||
userRepository.creatorFollow(creatorId: creatorId, follow: follow, notify: notify)
|
||||
.sink { result in
|
||||
switch result {
|
||||
case .finished:
|
||||
DEBUG_LOG("finish")
|
||||
case .failure(let error):
|
||||
ERROR_LOG(error.localizedDescription)
|
||||
}
|
||||
} receiveValue: { [unowned self] response in
|
||||
self.isLoading = false
|
||||
let responseData = response.data
|
||||
|
||||
do {
|
||||
let jsonDecoder = JSONDecoder()
|
||||
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
|
||||
|
||||
if !decoded.success {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
} else {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
}
|
||||
|
||||
self.isShowPopup = true
|
||||
}
|
||||
} catch {
|
||||
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
.store(in: &subscription)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user