feat(home): 보온 주간 차트 콘텐츠 정렬 기준 추가

- 매출, 판매량, 댓글 수, 좋아요 수
This commit is contained in:
Yu Sung
2025-11-14 02:53:46 +09:00
parent 74212405a4
commit e5810766b1
6 changed files with 89 additions and 4 deletions

View File

@@ -19,7 +19,7 @@ struct CharacterSectionView: View {
VStack(alignment: .leading, spacing: 16) { VStack(alignment: .leading, spacing: 16) {
HStack(spacing: 0) { HStack(spacing: 0) {
Text(title) Text(title)
.font(.custom(Font.preBold.rawValue, size: 20)) .font(.custom(Font.preBold.rawValue, size: 24))
.foregroundColor(.white) .foregroundColor(.white)
Spacer() Spacer()
if let trailingTitle = trailingTitle { if let trailingTitle = trailingTitle {

View File

@@ -13,6 +13,7 @@ enum HomeApi {
case getLatestContentByTheme(theme: String, isAdultContentVisible: Bool, contentType: ContentType) case getLatestContentByTheme(theme: String, isAdultContentVisible: Bool, contentType: ContentType)
case getDayOfWeekSeriesList(dayOfWeek: SeriesPublishedDaysOfWeek, isAdultContentVisible: Bool, contentType: ContentType) case getDayOfWeekSeriesList(dayOfWeek: SeriesPublishedDaysOfWeek, isAdultContentVisible: Bool, contentType: ContentType)
case getRecommendContents(isAdultContentVisible: Bool, contentType: ContentType) case getRecommendContents(isAdultContentVisible: Bool, contentType: ContentType)
case getContentRankingBySort(sort: ContentRankingSortType, isAdultContentVisible: Bool, contentType: ContentType)
} }
extension HomeApi: TargetType { extension HomeApi: TargetType {
@@ -33,6 +34,9 @@ extension HomeApi: TargetType {
case .getRecommendContents: case .getRecommendContents:
return "/api/home/recommend-contents" return "/api/home/recommend-contents"
case .getContentRankingBySort:
return "/api/home/content-ranking"
} }
} }
@@ -75,6 +79,15 @@ extension HomeApi: TargetType {
"contentType": contentType "contentType": contentType
] as [String: Any] ] as [String: Any]
return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
case .getContentRankingBySort(let sort, let isAdultContentVisible, let contentType):
let parameters = [
"sort": sort,
"isAdultContentVisible": isAdultContentVisible,
"contentType": contentType
] as [String: Any]
return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString) return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString)
} }
} }

View File

@@ -50,4 +50,14 @@ class HomeTabRepository {
) )
) )
} }
func getContentRankingBySort(sort: ContentRankingSortType) -> AnyPublisher<Response, MoyaError> {
return api.requestPublisher(
.getContentRankingBySort(
sort: sort,
isAdultContentVisible: UserDefaults.isAdultContentVisible(),
contentType: ContentType(rawValue: UserDefaults.string(forKey: .contentPreference)) ?? ContentType.ALL
)
)
}
} }

View File

@@ -251,8 +251,8 @@ struct HomeTabView: View {
) )
} }
if !viewModel.contentRanking.isEmpty { HomeWeeklyChartView(contentList: viewModel.contentRanking) {
HomeWeeklyChartView(contentList: viewModel.contentRanking) viewModel.getContentRankingBySort(sort: $0)
} }
if !viewModel.recommendChannelList.isEmpty { if !viewModel.recommendChannelList.isEmpty {

View File

@@ -12,6 +12,10 @@ enum SeriesPublishedDaysOfWeek: String, Encodable {
case SUN, MON, TUE, WED, THU, FRI, SAT, RANDOM case SUN, MON, TUE, WED, THU, FRI, SAT, RANDOM
} }
enum ContentRankingSortType: String, Encodable {
case REVENUE, SALES_COUNT, COMMENT_COUNT, LIKE_COUNT
}
final class HomeTabViewModel: ObservableObject { final class HomeTabViewModel: ObservableObject {
private let repository = HomeTabRepository() private let repository = HomeTabRepository()
private let userRepository = UserRepository() private let userRepository = UserRepository()
@@ -35,6 +39,13 @@ final class HomeTabViewModel: ObservableObject {
@Published var pointAvailableContentList: [AudioContentMainItem] = [] @Published var pointAvailableContentList: [AudioContentMainItem] = []
@Published var recommendContentList: [AudioContentMainItem] = [] @Published var recommendContentList: [AudioContentMainItem] = []
private let sortType = [
"매출": ContentRankingSortType.REVENUE,
"판매량": ContentRankingSortType.SALES_COUNT,
"댓글": ContentRankingSortType.COMMENT_COUNT,
"좋아요": ContentRankingSortType.LIKE_COUNT
]
func fetchData() { func fetchData() {
isLoading = true isLoading = true
@@ -237,4 +248,42 @@ final class HomeTabViewModel: ObservableObject {
} }
.store(in: &subscription) .store(in: &subscription)
} }
func getContentRankingBySort(sort: String) {
isLoading = true
repository.getContentRankingBySort(sort: sortType[sort] ?? ContentRankingSortType.REVENUE)
.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(ApiResponse<[GetAudioContentRankingItem]>.self, from: responseData)
if let data = decoded.data, decoded.success {
self.contentRanking = data
} else {
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)
}
} }

View File

@@ -18,6 +18,10 @@ struct HomeWeeklyChartView: View {
] ]
let contentList: [GetAudioContentRankingItem] let contentList: [GetAudioContentRankingItem]
let onTapSort: (String) -> Void
let sortList = ["매출", "판매량", "댓글", "좋아요"]
@State private var selectedSort = "매출"
var body: some View { var body: some View {
VStack(spacing: 16) { VStack(spacing: 16) {
@@ -34,6 +38,14 @@ struct HomeWeeklyChartView: View {
} }
.padding(.horizontal, 24) .padding(.horizontal, 24)
HStack(spacing: 16) {
ContentMainContentThemeView(
themeList: sortList,
selectTheme: onTapSort,
selectedTheme: $selectedSort
)
}
ScrollView(.horizontal, showsIndicators: false) { ScrollView(.horizontal, showsIndicators: false) {
LazyHGrid(rows: rows, spacing: 16) { LazyHGrid(rows: rows, spacing: 16) {
ForEach(0..<contentList.count, id: \.self) { index in ForEach(0..<contentList.count, id: \.self) { index in
@@ -205,6 +217,7 @@ struct HomeWeeklyChartView: View {
isPointAvailable: true, isPointAvailable: true,
creatorProfileImageUrl: "https://test-cf.sodalive.net/profile/default-profile.png" creatorProfileImageUrl: "https://test-cf.sodalive.net/profile/default-profile.png"
) )
] ],
onTapSort: { _ in }
) )
} }