feat(main-home): 추천 홈 데이터 계층을 추가한다
This commit is contained in:
@@ -3060,6 +3060,68 @@ If you block this user, the following features will be restricted.
|
||||
}
|
||||
}
|
||||
|
||||
enum HomeRecommendation {
|
||||
static var activityLive: String {
|
||||
pick(ko: "라이브", en: "Live", ja: "ライブ")
|
||||
}
|
||||
|
||||
static var activityAudio: String {
|
||||
pick(ko: "오디오", en: "Audio", ja: "オーディオ")
|
||||
}
|
||||
|
||||
static var activityCommunity: String {
|
||||
pick(ko: "커뮤니티", en: "Community", ja: "コミュニティ")
|
||||
}
|
||||
|
||||
static var liveSectionTitle: String {
|
||||
pick(ko: "현재 라이브", en: "Live now", ja: "現在ライブ")
|
||||
}
|
||||
|
||||
static var activeCreatorSectionTitle: String {
|
||||
pick(ko: "방금 활동한 크리에이터", en: "Recently active creators", ja: "最近活動したクリエイター")
|
||||
}
|
||||
|
||||
static var recentDebutCreatorSectionTitle: String {
|
||||
pick(ko: "최근 데뷔한 크리에이터", en: "Recently debuted creators", ja: "最近デビューしたクリエイター")
|
||||
}
|
||||
|
||||
static var firstAudioContentSectionTitle: String {
|
||||
pick(ko: "처음 만나는 오디오", en: "First audio to discover", ja: "初めて出会うオーディオ")
|
||||
}
|
||||
|
||||
static var aiCharacterSectionTitle: String {
|
||||
pick(ko: "AI 캐릭터", en: "AI characters", ja: "AIキャラクター")
|
||||
}
|
||||
|
||||
static var genreCreatorSectionTitle: String {
|
||||
pick(ko: "장르의 크리에이터", en: "Creators by genre", ja: "ジャンルのクリエイター")
|
||||
}
|
||||
|
||||
static var cheerCreatorSectionTitle: String {
|
||||
pick(ko: "최근 응원이 많은 크리에이터", en: "Recently cheered creators", ja: "最近応援が多いクリエイター")
|
||||
}
|
||||
|
||||
static var popularCommunitySectionTitle: String {
|
||||
pick(ko: "인기 커뮤니티", en: "Popular community", ja: "人気コミュニティ")
|
||||
}
|
||||
|
||||
static var followAll: String {
|
||||
pick(ko: "모두 팔로우하기", en: "Follow all", ja: "すべてフォロー")
|
||||
}
|
||||
|
||||
static var followAllCompleted: String {
|
||||
pick(ko: "모두 팔로우 완료", en: "All followed", ja: "すべてフォロー済み")
|
||||
}
|
||||
|
||||
static var more: String {
|
||||
pick(ko: "더보기", en: "More", ja: "もっと見る")
|
||||
}
|
||||
|
||||
static var collapse: String {
|
||||
pick(ko: "접기", en: "Collapse", ja: "閉じる")
|
||||
}
|
||||
}
|
||||
|
||||
enum Explorer {
|
||||
static var channel: String {
|
||||
pick(ko: "채널", en: "Channel", ja: "チャンネル")
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import Foundation
|
||||
|
||||
struct FollowRecommendedCreatorsRequest: Encodable {
|
||||
let creatorIds: [Int]?
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
import Foundation
|
||||
|
||||
struct HomeRecommendationResponse: Decodable {
|
||||
let lives: [HomeLiveItem]
|
||||
let banners: [HomeBannerItem]
|
||||
let recentlyActiveCreators: [HomeActiveCreatorItem]
|
||||
let recentDebutCreators: [HomeCreatorItem]
|
||||
let firstAudioContents: [HomeFirstAudioContentItem]
|
||||
let aiCharacters: [HomeAiCharacterItem]
|
||||
let genreCreators: [HomeGenreCreatorGroupItem]
|
||||
let cheerCreators: [HomeCreatorItem]
|
||||
let popularCommunityPosts: [HomePopularCommunityPostItem]
|
||||
}
|
||||
|
||||
struct HomeLiveItem: Decodable, Hashable {
|
||||
let liveRoomId: Int?
|
||||
let roomId: Int?
|
||||
let creatorId: Int?
|
||||
let creatorNickname: String?
|
||||
let title: String?
|
||||
let profileImageUrl: String?
|
||||
let thumbnailUrl: String?
|
||||
let imageUrl: String?
|
||||
let beginDateTime: String?
|
||||
let participantCount: Int?
|
||||
}
|
||||
|
||||
struct HomeBannerItem: Decodable, Hashable {
|
||||
let bannerId: Int?
|
||||
let type: String?
|
||||
let title: String?
|
||||
let imageUrl: String?
|
||||
let link: String?
|
||||
let eventId: Int?
|
||||
let creatorId: Int?
|
||||
let seriesId: Int?
|
||||
}
|
||||
|
||||
struct HomeActiveCreatorItem: Decodable, Hashable {
|
||||
let creatorId: Int?
|
||||
let creatorNickname: String?
|
||||
let profileImageUrl: String?
|
||||
let activityType: RecommendedActivityType?
|
||||
let activityAt: String?
|
||||
}
|
||||
|
||||
struct HomeCreatorItem: Decodable, Hashable {
|
||||
let creatorId: Int?
|
||||
let creatorNickname: String?
|
||||
let nickname: String?
|
||||
let profileImageUrl: String?
|
||||
let imageUrl: String?
|
||||
let description: String?
|
||||
let followerCount: Int?
|
||||
let cheerCount: Int?
|
||||
let debutDate: String?
|
||||
}
|
||||
|
||||
struct HomeFirstAudioContentItem: Decodable, Hashable {
|
||||
let contentId: Int?
|
||||
let creatorId: Int?
|
||||
let creatorNickname: String?
|
||||
let title: String?
|
||||
let imageUrl: String?
|
||||
let coverImageUrl: String?
|
||||
let releaseDate: String?
|
||||
}
|
||||
|
||||
struct HomeAiCharacterItem: Decodable, Hashable {
|
||||
let characterId: Int?
|
||||
let name: String?
|
||||
let description: String?
|
||||
let profileImageUrl: String?
|
||||
let imageUrl: String?
|
||||
let chatCount: Int?
|
||||
let originalTitle: String?
|
||||
}
|
||||
|
||||
struct HomeGenreCreatorGroupItem: Decodable, Hashable {
|
||||
let genreId: Int?
|
||||
let genreName: String?
|
||||
let title: String?
|
||||
let creators: [HomeCreatorItem]?
|
||||
}
|
||||
|
||||
struct HomePopularCommunityPostItem: Decodable, Hashable {
|
||||
let postId: Int?
|
||||
let creatorId: Int?
|
||||
let creatorNickname: String?
|
||||
let creatorProfileImageUrl: String?
|
||||
let content: String?
|
||||
let imageUrl: String?
|
||||
let price: Int?
|
||||
let existOrdered: Bool?
|
||||
let likeCount: Int?
|
||||
let commentCount: Int?
|
||||
let createdAt: String?
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import Foundation
|
||||
|
||||
enum RecommendedActivityType: Decodable, Hashable {
|
||||
case live
|
||||
case audio
|
||||
case community
|
||||
case unknown(String)
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
let code = try container.decode(String.self)
|
||||
|
||||
switch code {
|
||||
case "LIVE", "LIVE_REPLAY":
|
||||
self = .live
|
||||
case "AUDIO":
|
||||
self = .audio
|
||||
case "COMMUNITY":
|
||||
self = .community
|
||||
default:
|
||||
self = .unknown(code)
|
||||
}
|
||||
}
|
||||
|
||||
var title: String {
|
||||
switch self {
|
||||
case .live:
|
||||
return I18n.HomeRecommendation.activityLive
|
||||
case .audio:
|
||||
return I18n.HomeRecommendation.activityAudio
|
||||
case .community:
|
||||
return I18n.HomeRecommendation.activityCommunity
|
||||
case .unknown:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
47
SodaLive/Sources/V2/Main/Home/Repository/MainHomeApi.swift
Normal file
47
SodaLive/Sources/V2/Main/Home/Repository/MainHomeApi.swift
Normal file
@@ -0,0 +1,47 @@
|
||||
import Foundation
|
||||
import Moya
|
||||
|
||||
enum MainHomeApi {
|
||||
case getRecommendations
|
||||
case followRecommendedCreators(request: FollowRecommendedCreatorsRequest)
|
||||
}
|
||||
|
||||
extension MainHomeApi: TargetType {
|
||||
var baseURL: URL {
|
||||
return URL(string: BASE_URL)!
|
||||
}
|
||||
|
||||
var path: String {
|
||||
switch self {
|
||||
case .getRecommendations:
|
||||
return "/api/v2/home/recommendations"
|
||||
|
||||
case .followRecommendedCreators:
|
||||
return "/api/v2/home/recommendations/creators/follow"
|
||||
}
|
||||
}
|
||||
|
||||
var method: Moya.Method {
|
||||
switch self {
|
||||
case .getRecommendations:
|
||||
return .get
|
||||
|
||||
case .followRecommendedCreators:
|
||||
return .post
|
||||
}
|
||||
}
|
||||
|
||||
var task: Moya.Task {
|
||||
switch self {
|
||||
case .getRecommendations:
|
||||
return .requestPlain
|
||||
|
||||
case .followRecommendedCreators(let request):
|
||||
return .requestJSONEncodable(request)
|
||||
}
|
||||
}
|
||||
|
||||
var headers: [String: String]? {
|
||||
return ["Authorization": "Bearer \(UserDefaults.string(forKey: UserDefaultsKey.token))"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import Foundation
|
||||
import CombineMoya
|
||||
import Combine
|
||||
import Moya
|
||||
|
||||
final class MainHomeRepository {
|
||||
private let api = MoyaProvider<MainHomeApi>()
|
||||
|
||||
func getRecommendations() -> AnyPublisher<Response, MoyaError> {
|
||||
return api.requestPublisher(.getRecommendations)
|
||||
}
|
||||
|
||||
func followRecommendedCreators(request: FollowRecommendedCreatorsRequest) -> AnyPublisher<Response, MoyaError> {
|
||||
return api.requestPublisher(.followRecommendedCreators(request: request))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user