feat(home): 랭킹 API 기반 상태를 추가한다
This commit is contained in:
@@ -3042,6 +3042,16 @@ If you block this user, the following features will be restricted.
|
||||
}
|
||||
}
|
||||
|
||||
enum HomeRanking {
|
||||
static var emptyStateMessage: String {
|
||||
pick(
|
||||
ko: "순위 집계 중입니다.\n잠시 후 다시 시도해 주세요.",
|
||||
en: "Rankings are being calculated.\nPlease try again later.",
|
||||
ja: "ランキングを集計中です。\nしばらくしてからもう一度お試しください。"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
enum HomeRecommendation {
|
||||
static var activityLive: String {
|
||||
pick(ko: "라이브", en: "Live", ja: "ライブ")
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
final class MainHomeRankingViewModel: ObservableObject {
|
||||
private let repository = MainHomeRankingRepository()
|
||||
private var subscription = Set<AnyCancellable>()
|
||||
|
||||
@Published var isLoading = false
|
||||
@Published var items = [MainHomeCreatorRankingItem]()
|
||||
@Published var showRankChange = false
|
||||
@Published var emptyMessage = ""
|
||||
@Published var hasLoaded = false
|
||||
|
||||
func fetchRankings() {
|
||||
isLoading = true
|
||||
emptyMessage = ""
|
||||
|
||||
repository.getCreatorRankings()
|
||||
.sink { [weak self] result in
|
||||
guard let self else { return }
|
||||
|
||||
switch result {
|
||||
case .finished:
|
||||
DEBUG_LOG("finish")
|
||||
case .failure(let error):
|
||||
ERROR_LOG(error.localizedDescription)
|
||||
self.items = []
|
||||
self.showRankChange = false
|
||||
self.emptyMessage = I18n.HomeRanking.emptyStateMessage
|
||||
self.hasLoaded = true
|
||||
self.isLoading = false
|
||||
}
|
||||
} receiveValue: { [weak self] response in
|
||||
guard let self else { return }
|
||||
|
||||
let responseData = response.data
|
||||
|
||||
do {
|
||||
let jsonDecoder = JSONDecoder()
|
||||
let decoded = try jsonDecoder.decode(ApiResponse<MainHomeCreatorRankingResponse>.self, from: responseData)
|
||||
|
||||
if let data = decoded.data, decoded.success, !data.items.isEmpty {
|
||||
self.items = Array(data.items.prefix(20))
|
||||
self.showRankChange = data.showRankChange
|
||||
self.emptyMessage = ""
|
||||
} else {
|
||||
self.items = []
|
||||
self.showRankChange = false
|
||||
self.emptyMessage = I18n.HomeRanking.emptyStateMessage
|
||||
}
|
||||
} catch {
|
||||
ERROR_LOG(error.localizedDescription)
|
||||
self.items = []
|
||||
self.showRankChange = false
|
||||
self.emptyMessage = I18n.HomeRanking.emptyStateMessage
|
||||
}
|
||||
|
||||
self.hasLoaded = true
|
||||
self.isLoading = false
|
||||
}
|
||||
.store(in: &subscription)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import Foundation
|
||||
|
||||
struct MainHomeCreatorRankingResponse: Decodable {
|
||||
let showRankChange: Bool
|
||||
let items: [MainHomeCreatorRankingItem]
|
||||
}
|
||||
|
||||
struct MainHomeCreatorRankingItem: Decodable, Identifiable {
|
||||
let rank: Int
|
||||
let rankChange: Int?
|
||||
let isNew: Bool
|
||||
let creatorId: Int
|
||||
let nickname: String
|
||||
let profileImageUrl: String?
|
||||
|
||||
var id: Int { creatorId }
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import Foundation
|
||||
|
||||
import Moya
|
||||
|
||||
enum MainHomeRankingApi {
|
||||
case getCreatorRankings
|
||||
}
|
||||
|
||||
extension MainHomeRankingApi: TargetType {
|
||||
var baseURL: URL {
|
||||
return URL(string: BASE_URL)!
|
||||
}
|
||||
|
||||
var path: String {
|
||||
switch self {
|
||||
case .getCreatorRankings:
|
||||
return "/api/v2/home/rankings/creators"
|
||||
}
|
||||
}
|
||||
|
||||
var method: Moya.Method {
|
||||
switch self {
|
||||
case .getCreatorRankings:
|
||||
return .get
|
||||
}
|
||||
}
|
||||
|
||||
var task: Moya.Task {
|
||||
switch self {
|
||||
case .getCreatorRankings:
|
||||
return .requestPlain
|
||||
}
|
||||
}
|
||||
|
||||
var headers: [String: String]? {
|
||||
return ["Authorization": "Bearer \(UserDefaults.string(forKey: UserDefaultsKey.token))"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
import CombineMoya
|
||||
import Moya
|
||||
|
||||
final class MainHomeRankingRepository {
|
||||
private let api = MoyaProvider<MainHomeRankingApi>()
|
||||
|
||||
func getCreatorRankings() -> AnyPublisher<Response, MoyaError> {
|
||||
return api.requestPublisher(.getCreatorRankings)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user