feat(series-all-by-genre): 시리즈 전체보기 장르별 탭 - 장르, 시리즈 UI 추가
This commit is contained in:
@@ -14,6 +14,47 @@ struct SeriesMainByGenreView: View {
|
||||
var body: some View {
|
||||
ZStack {
|
||||
VStack(spacing: 16) {
|
||||
if !viewModel.genreList.isEmpty {
|
||||
SeriesMainGenreView(
|
||||
genreList: viewModel.genreList,
|
||||
selectGenre: viewModel.onTapGenre,
|
||||
selectedGenre: $viewModel.selectedGenre
|
||||
)
|
||||
}
|
||||
|
||||
ScrollView(.vertical, showsIndicators: false) {
|
||||
let horizontalPadding: CGFloat = 24
|
||||
let gridSpacing: CGFloat = 16
|
||||
let width = (screenSize().width - (horizontalPadding * 2) - gridSpacing) / 2
|
||||
|
||||
LazyVGrid(
|
||||
columns: Array(
|
||||
repeating: GridItem(
|
||||
.flexible(),
|
||||
spacing: gridSpacing,
|
||||
alignment: .topLeading
|
||||
),
|
||||
count: 2
|
||||
),
|
||||
alignment: .leading,
|
||||
spacing: gridSpacing
|
||||
) {
|
||||
ForEach(viewModel.seriesList.indices, id: \.self) { index in
|
||||
let item = viewModel.seriesList[index]
|
||||
NavigationLink {
|
||||
SeriesDetailView(seriesId: item.seriesId)
|
||||
} label: {
|
||||
SeriesMainItemView(item: item, width: width, height: width * 227 / 160)
|
||||
.contentShape(Rectangle())
|
||||
.onAppear {
|
||||
if index == viewModel.seriesList.count - 1 {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, horizontalPadding)
|
||||
}
|
||||
}
|
||||
.popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .bottom, autohideIn: 2) {
|
||||
HStack {
|
||||
|
||||
@@ -19,14 +19,16 @@ final class SeriesMainByGenreViewModel: ObservableObject {
|
||||
@Published var genreList: [GetSeriesGenreListResponse] = []
|
||||
@Published var seriesList: [SeriesListItem] = []
|
||||
|
||||
@Published var selectedGenre: GetSeriesGenreListResponse = GetSeriesGenreListResponse(id: 0, genre: "")
|
||||
|
||||
private var page = 1
|
||||
private var isLast = false
|
||||
private let pageSize = 20
|
||||
|
||||
func onTapGenre(genreId: Int) {
|
||||
func onTapGenre() {
|
||||
page = 1
|
||||
isLast = false
|
||||
getSeriesListByGenre(genreId: genreId)
|
||||
getSeriesListByGenre()
|
||||
}
|
||||
|
||||
func getGenreList() {
|
||||
@@ -54,7 +56,8 @@ final class SeriesMainByGenreViewModel: ObservableObject {
|
||||
|
||||
if let data = decoded.data, decoded.success {
|
||||
self.genreList = data
|
||||
self.getSeriesListByGenre(genreId: genreList[0].id)
|
||||
self.selectedGenre = data[0]
|
||||
self.getSeriesListByGenre()
|
||||
} else {
|
||||
if let message = decoded.message {
|
||||
self.errorMessage = message
|
||||
@@ -72,11 +75,11 @@ final class SeriesMainByGenreViewModel: ObservableObject {
|
||||
.store(in: &subscription)
|
||||
}
|
||||
|
||||
func getSeriesListByGenre(genreId: Int) {
|
||||
func getSeriesListByGenre() {
|
||||
if !isLast && !isLoading {
|
||||
isLoading = true
|
||||
|
||||
repository.getSeriesListByGenre(genreId: genreId, page: page, size: pageSize)
|
||||
repository.getSeriesListByGenre(genreId: selectedGenre.id, page: page, size: pageSize)
|
||||
.sink { result in
|
||||
switch result {
|
||||
case .finished:
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// SeriesMainGenreView.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 11/15/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct SeriesMainGenreView: View {
|
||||
let genreList: [GetSeriesGenreListResponse]
|
||||
let selectGenre: () -> Void
|
||||
|
||||
@Binding var selectedGenre: GetSeriesGenreListResponse
|
||||
|
||||
var body: some View {
|
||||
ScrollView(.horizontal, showsIndicators: false) {
|
||||
HStack(alignment: .top, spacing: 16) {
|
||||
ForEach(0..<genreList.count, id: \.self) { index in
|
||||
let genre = genreList[index]
|
||||
Text(genre.genre)
|
||||
.font(
|
||||
.custom(
|
||||
selectedGenre.genre == genre.genre ? Font.preBold.rawValue : Font.preRegular.rawValue,
|
||||
size: 16
|
||||
)
|
||||
)
|
||||
.foregroundColor(.white)
|
||||
.padding(.horizontal, 24)
|
||||
.padding(.vertical, 12)
|
||||
.background(
|
||||
selectedGenre.genre == genre.genre ? Color.button : Color(hex: "263238")
|
||||
)
|
||||
.cornerRadius(999)
|
||||
.onTapGesture {
|
||||
if selectedGenre.genre != genre.genre {
|
||||
selectedGenre = genre
|
||||
selectGenre()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 24)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
SeriesMainGenreView(
|
||||
genreList: [
|
||||
GetSeriesGenreListResponse(id: 1, genre: "test"),
|
||||
GetSeriesGenreListResponse(id: 2, genre: "test2"),
|
||||
GetSeriesGenreListResponse(id: 3, genre: "test3")
|
||||
],
|
||||
selectGenre: { },
|
||||
selectedGenre: .constant(GetSeriesGenreListResponse(id: 1, genre: "test"))
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user