feat(home): 팔로잉 탭 API 상태를 추가한다

This commit is contained in:
Yu Sung
2026-06-30 22:04:40 +09:00
parent e2d46614bd
commit ae09776c9b
9 changed files with 423 additions and 10 deletions

View File

@@ -0,0 +1,154 @@
import Foundation
struct HomeFollowingTabResponse: Decodable {
let isLoginRequired: Bool
let followingCreators: [FollowingCreatorResponse]
let onAirLives: [FollowingLiveResponse]
let recentChats: [ChatRoomListItemResponse]
let monthlySchedules: [FollowingScheduleResponse]
let recentNews: [FollowingNewsResponse]
}
struct FollowingCreatorResponse: Decodable, Identifiable {
let creatorId: Int
let creatorNickname: String
let creatorProfileImageUrl: String
var id: Int { creatorId }
}
struct FollowingLiveResponse: Decodable, Identifiable {
let liveId: Int
let creatorProfileImageUrl: String
let creatorNickname: String
let title: String
let startedAtUtc: String
var id: Int { liveId }
}
struct ChatRoomListItemResponse: Decodable, Identifiable {
let roomId: Int
let chatType: String
let targetName: String
let targetImageUrl: String
let lastMessage: String
let lastMessageAt: String
var id: Int { roomId }
}
struct FollowingScheduleResponse: Decodable, Identifiable {
let scheduleId: String
let creatorId: Int
let creatorProfileImageUrl: String
let creatorNickname: String
let title: String
let type: CreatorActivityType
let targetId: Int
let scheduledAtUtc: String
let isOnAir: Bool
var id: String { scheduleId }
}
enum CreatorActivityType: Decodable, Hashable {
case live
case audio
case community
case liveReplay
case unknown(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let code = try container.decode(String.self)
switch code {
case "LIVE":
self = .live
case "AUDIO":
self = .audio
case "COMMUNITY":
self = .community
case "LIVE_REPLAY":
self = .liveReplay
default:
self = .unknown(code)
}
}
}
struct FollowingNewsResponse: Decodable, Identifiable {
let newsId: String
let type: FollowingNewsType
let visibleFromAtUtc: String
let creatorRanking: FollowingCreatorRankingNewsResponse?
let audioContent: FollowingContentNewsResponse?
let photoContent: FollowingContentNewsResponse?
let contentRanking: FollowingContentRankingNewsResponse?
let communityPost: FollowingCommunityPostNewsResponse?
var id: String { newsId }
}
struct FollowingCreatorRankingNewsResponse: Decodable {
let rank: Int
let creatorId: Int
let nickname: String
let profileImageUrl: String
}
struct FollowingContentNewsResponse: Decodable {
let contentId: Int
let contentImageUrl: String?
let title: String
let creatorProfileImageUrl: String
let creatorNickname: String
}
struct FollowingContentRankingNewsResponse: Decodable {
let rank: Int
let contentId: Int
let contentImageUrl: String?
let title: String
}
struct FollowingCommunityPostNewsResponse: Decodable {
let postId: Int
let creatorProfileImage: String
let creatorNickname: String
let imageUrl: String?
let content: String
let createdAt: String
let likeCount: Int
let commentCount: Int
}
enum FollowingNewsType: Decodable, Hashable {
case creatorRanking
case contentRanking
case communityPost
case audioContent
case photoContent
case unknown(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let code = try container.decode(String.self)
switch code {
case "CREATOR_RANKING":
self = .creatorRanking
case "CONTENT_RANKING":
self = .contentRanking
case "COMMUNITY_POST":
self = .communityPost
case "AUDIO_CONTENT":
self = .audioContent
case "PHOTO_CONTENT":
self = .photoContent
default:
self = .unknown(code)
}
}
}