From 54a5c99666c446ae7b4ef43a94975f8d3b7b80b1 Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Sat, 15 Nov 2025 06:03:54 +0900 Subject: [PATCH] =?UTF-8?q?feat(series-all-by-genre):=20=EC=8B=9C=EB=A6=AC?= =?UTF-8?q?=EC=A6=88=20=EC=A0=84=EC=B2=B4=EB=B3=B4=EA=B8=B0=20=EC=9E=A5?= =?UTF-8?q?=EB=A5=B4=EB=B3=84=20=ED=83=AD=20-=20=EC=9E=A5=EB=A5=B4,=20?= =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=20UI=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Main/ByGenre/SeriesMainByGenreView.swift | 41 +++++++++++++ .../ByGenre/SeriesMainByGenreViewModel.swift | 13 +++-- .../Main/ByGenre/SeriesMainGenreView.swift | 58 +++++++++++++++++++ 3 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 SodaLive/Sources/Content/Series/Main/ByGenre/SeriesMainGenreView.swift diff --git a/SodaLive/Sources/Content/Series/Main/ByGenre/SeriesMainByGenreView.swift b/SodaLive/Sources/Content/Series/Main/ByGenre/SeriesMainByGenreView.swift index 4ade3c5..a895c2c 100644 --- a/SodaLive/Sources/Content/Series/Main/ByGenre/SeriesMainByGenreView.swift +++ b/SodaLive/Sources/Content/Series/Main/ByGenre/SeriesMainByGenreView.swift @@ -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 { diff --git a/SodaLive/Sources/Content/Series/Main/ByGenre/SeriesMainByGenreViewModel.swift b/SodaLive/Sources/Content/Series/Main/ByGenre/SeriesMainByGenreViewModel.swift index 98ee0ed..d71d869 100644 --- a/SodaLive/Sources/Content/Series/Main/ByGenre/SeriesMainByGenreViewModel.swift +++ b/SodaLive/Sources/Content/Series/Main/ByGenre/SeriesMainByGenreViewModel.swift @@ -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: diff --git a/SodaLive/Sources/Content/Series/Main/ByGenre/SeriesMainGenreView.swift b/SodaLive/Sources/Content/Series/Main/ByGenre/SeriesMainGenreView.swift new file mode 100644 index 0000000..2db2a2d --- /dev/null +++ b/SodaLive/Sources/Content/Series/Main/ByGenre/SeriesMainGenreView.swift @@ -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..