라이브 메인 페이지
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// GetRecommendLiveResponse.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 2023/08/09.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct GetRecommendLiveResponse: Decodable, Hashable {
|
||||
let imageUrl: String
|
||||
let creatorId: Int
|
||||
}
|
56
SodaLive/Sources/Live/Recommend/LiveRecommendApi.swift
Normal file
56
SodaLive/Sources/Live/Recommend/LiveRecommendApi.swift
Normal file
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// LiveRecommendApi.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 2023/08/09.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Moya
|
||||
|
||||
enum LiveRecommendApi {
|
||||
case getFollowedChannelList
|
||||
case getRecommendChannelList
|
||||
case getRecommendLive
|
||||
}
|
||||
|
||||
extension LiveRecommendApi: TargetType {
|
||||
var baseURL: URL {
|
||||
return URL(string: BASE_URL)!
|
||||
}
|
||||
|
||||
var path: String {
|
||||
switch self {
|
||||
case .getFollowedChannelList:
|
||||
return "/live/recommend/following/channel/list"
|
||||
|
||||
case .getRecommendChannelList:
|
||||
return "/live/recommend/channel"
|
||||
|
||||
case .getRecommendLive:
|
||||
return "/live/recommend"
|
||||
}
|
||||
}
|
||||
|
||||
var method: Moya.Method {
|
||||
switch self {
|
||||
case .getFollowedChannelList,
|
||||
.getRecommendChannelList,
|
||||
.getRecommendLive:
|
||||
return .get
|
||||
}
|
||||
}
|
||||
|
||||
var task: Moya.Task {
|
||||
switch self {
|
||||
case .getFollowedChannelList,
|
||||
.getRecommendChannelList,
|
||||
.getRecommendLive:
|
||||
return .requestPlain
|
||||
}
|
||||
}
|
||||
|
||||
var headers: [String : String]? {
|
||||
return ["Authorization": "Bearer \(UserDefaults.string(forKey: UserDefaultsKey.token))"]
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// LiveRecommendRepository.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 2023/08/09.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CombineMoya
|
||||
import Combine
|
||||
import Moya
|
||||
|
||||
final class LiveRecommendRepository {
|
||||
private let api = MoyaProvider<LiveRecommendApi>()
|
||||
|
||||
func getFollowedChannelList() -> AnyPublisher<Response, MoyaError> {
|
||||
return api.requestPublisher(.getFollowedChannelList)
|
||||
}
|
||||
|
||||
func getRecommendChannelList() -> AnyPublisher<Response, MoyaError> {
|
||||
return api.requestPublisher(.getRecommendChannelList)
|
||||
}
|
||||
|
||||
func getRecommendLive() -> AnyPublisher<Response, MoyaError> {
|
||||
return api.requestPublisher(.getRecommendLive)
|
||||
}
|
||||
}
|
114
SodaLive/Sources/Live/Recommend/SectionRecommendLiveView.swift
Normal file
114
SodaLive/Sources/Live/Recommend/SectionRecommendLiveView.swift
Normal file
@@ -0,0 +1,114 @@
|
||||
//
|
||||
// SectionRecommendLiveView.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 2023/08/09.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Kingfisher
|
||||
|
||||
struct SectionRecommendLiveView: View {
|
||||
|
||||
let items: [GetRecommendLiveResponse]
|
||||
@State private var currentIndex = 0
|
||||
@State private var timer = Timer.publish(every: 3, on: .main, in: .common).autoconnect()
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
HStack(spacing: 0) {
|
||||
Text("추천 ")
|
||||
.font(.custom(Font.bold.rawValue, size: 18.3))
|
||||
.foregroundColor(Color(hex: "ff5c49"))
|
||||
|
||||
Text("라이브")
|
||||
.font(.custom(Font.bold.rawValue, size: 18.3))
|
||||
.foregroundColor(Color(hex: "eeeeee"))
|
||||
}
|
||||
.frame(width: screenSize().width - 26.7, alignment: .leading)
|
||||
|
||||
TabView(selection: $currentIndex) {
|
||||
ForEach(0..<items.count, id: \.self) { index in
|
||||
let item = items[index]
|
||||
if let url = item.imageUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
|
||||
KFImage(URL(string: url))
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(
|
||||
width: screenSize().width - 26.7,
|
||||
height: (screenSize().width - 26.7) * 0.53
|
||||
)
|
||||
.onTapGesture {
|
||||
}
|
||||
.cornerRadius(4.7)
|
||||
} else {
|
||||
KFImage(URL(string: item.imageUrl))
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(
|
||||
width: screenSize().width - 26.7,
|
||||
height: (screenSize().width - 26.7) * 0.53
|
||||
)
|
||||
.onTapGesture {
|
||||
}
|
||||
.cornerRadius(4.7)
|
||||
}
|
||||
}
|
||||
}
|
||||
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
|
||||
.frame(
|
||||
width: screenSize().width - 26.7,
|
||||
height: (screenSize().width - 26.7) * 0.53
|
||||
)
|
||||
.padding(.top, 26.7)
|
||||
|
||||
HStack(spacing: 4) {
|
||||
ForEach(0..<items.count, id: \.self) { index in
|
||||
Capsule()
|
||||
.foregroundColor(index == currentIndex ? Color(hex: "9970ff") : Color(hex: "909090"))
|
||||
.frame(
|
||||
width: index == currentIndex ? 18 : 6,
|
||||
height: 6
|
||||
)
|
||||
.tag(index)
|
||||
}
|
||||
}
|
||||
.padding(.top, 13.3)
|
||||
}
|
||||
.frame(width: screenSize().width - 26.7)
|
||||
.onAppear {
|
||||
timer = Timer.publish(every: 3, on: .main, in: .common).autoconnect()
|
||||
}
|
||||
.onDisappear {
|
||||
timer.upstream.connect().cancel()
|
||||
}
|
||||
.onReceive(timer) { _ in
|
||||
DispatchQueue.main.async {
|
||||
withAnimation {
|
||||
if currentIndex == items.count - 1 {
|
||||
currentIndex = 0
|
||||
} else {
|
||||
currentIndex += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SectionRecommendLiveView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
SectionRecommendLiveView(
|
||||
items: [
|
||||
GetRecommendLiveResponse(
|
||||
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
||||
creatorId: 1
|
||||
),
|
||||
GetRecommendLiveResponse(
|
||||
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
|
||||
creatorId: 2
|
||||
)
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user