From b898d225fd7d30dc0c30c81008af71de2543ac41 Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Tue, 1 Apr 2025 22:30:26 +0900 Subject: [PATCH] =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20-=20=EC=9D=B4=EC=A0=84=ED=99=94/=EB=8B=A4=EC=9D=8C?= =?UTF-8?q?=ED=99=94=20=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...tDetailPreviousNextContentButtonView.swift | 112 ++++++++++++++++++ .../Content/Detail/ContentDetailView.swift | 9 ++ .../GetAudioContentDetailResponse.swift | 2 + 3 files changed, 123 insertions(+) create mode 100644 SodaLive/Sources/Content/Detail/ContentDetailPreviousNextContentButtonView.swift diff --git a/SodaLive/Sources/Content/Detail/ContentDetailPreviousNextContentButtonView.swift b/SodaLive/Sources/Content/Detail/ContentDetailPreviousNextContentButtonView.swift new file mode 100644 index 0000000..9fa1aa2 --- /dev/null +++ b/SodaLive/Sources/Content/Detail/ContentDetailPreviousNextContentButtonView.swift @@ -0,0 +1,112 @@ +// +// ContentDetailPreviousNextContentButtonView.swift +// SodaLive +// +// Created by klaus on 4/1/25. +// + +import SwiftUI +import Kingfisher + +struct ContentDetailPreviousNextContentButtonView: View { + + let previousContent: OtherContentResponse? + let nextContent: OtherContentResponse? + let onClickButton: (Int) -> Void + + var body: some View { + HStack(spacing: 8) { + VStack { + if let previousContent = previousContent { + HStack(alignment: .top, spacing: 5.3) { + KFImage(URL(string: previousContent.coverUrl)) + .resizable() + .frame(width: 33.3, height: 33.3) + .cornerRadius(5.3) + + VStack(alignment: .leading, spacing: 5.3) { + Text(previousContent.title) + .font(.custom(Font.medium.rawValue, size: 11)) + .foregroundColor(.grayd2) + .multilineTextAlignment(.leading) + .lineLimit(2) + + Text("이전화") + .font(.custom(Font.medium.rawValue, size: 13.3)) + .foregroundColor(.button) + .multilineTextAlignment(.leading) + .lineLimit(2) + } + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(5.3) + .background(Color.gray22) + .overlay( + RoundedRectangle(cornerRadius: 5.3) + .strokeBorder(lineWidth: 1) + .foregroundColor(Color.gray55) + ) + .contentShape(Rectangle()) + .onTapGesture { + onClickButton(previousContent.contentId) + } + } + } + .frame(maxWidth: .infinity) + + VStack { + if let nextContent = nextContent { + HStack(alignment: .top, spacing: 5.3) { + KFImage(URL(string: nextContent.coverUrl)) + .resizable() + .frame(width: 33.3, height: 33.3) + .cornerRadius(5.3) + + VStack(alignment: .leading, spacing: 5.3) { + Text(nextContent.title) + .font(.custom(Font.medium.rawValue, size: 11)) + .foregroundColor(.grayd2) + .multilineTextAlignment(.leading) + .lineLimit(2) + + Text("다음화") + .font(.custom(Font.medium.rawValue, size: 13.3)) + .foregroundColor(.button) + .multilineTextAlignment(.leading) + .lineLimit(2) + } + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(5.3) + .background(Color.gray22) + .overlay( + RoundedRectangle(cornerRadius: 5.3) + .strokeBorder(lineWidth: 1) + .foregroundColor(Color.gray55) + ) + .contentShape(Rectangle()) + .onTapGesture { + onClickButton(nextContent.contentId) + } + } + } + .frame(maxWidth: .infinity) + } + } +} + +#Preview { + ContentDetailPreviousNextContentButtonView( + previousContent: OtherContentResponse( + contentId: 1, + title: "1화\n남편은 분명 성기사였다", + coverUrl: "https://test-cf.sodalive.net/profile/default-profile.png" + ), + nextContent: OtherContentResponse( + contentId: 3, + title: "3화\n남편은 분명 성기사였다", + coverUrl: "https://test-cf.sodalive.net/profile/default-profile.png" + ), + onClickButton: { _ in } + ) +} diff --git a/SodaLive/Sources/Content/Detail/ContentDetailView.swift b/SodaLive/Sources/Content/Detail/ContentDetailView.swift index c12c6ef..fc0066a 100644 --- a/SodaLive/Sources/Content/Detail/ContentDetailView.swift +++ b/SodaLive/Sources/Content/Detail/ContentDetailView.swift @@ -83,6 +83,15 @@ struct ContentDetailView: View { isShowPreviewAlert: $viewModel.isShowPreviewAlert ) + ContentDetailPreviousNextContentButtonView( + previousContent: audioContent.previousContent, + nextContent: audioContent.nextContent + ) { + viewModel.contentId = $0 + } + .padding(.top, 13.3) + .padding(.horizontal, 13.3) + ContentDetailInfoView( isExpandDescription: $viewModel.isExpandDescription, isShowPreviewAlert: $viewModel.isShowPreviewAlert, diff --git a/SodaLive/Sources/Content/Detail/GetAudioContentDetailResponse.swift b/SodaLive/Sources/Content/Detail/GetAudioContentDetailResponse.swift index 7a87de2..abb85de 100644 --- a/SodaLive/Sources/Content/Detail/GetAudioContentDetailResponse.swift +++ b/SodaLive/Sources/Content/Detail/GetAudioContentDetailResponse.swift @@ -38,6 +38,8 @@ struct GetAudioContentDetailResponse: Decodable { let isPin: Bool let isAvailablePin: Bool let creator: AudioContentCreator + let previousContent: OtherContentResponse? + let nextContent: OtherContentResponse? } enum OrderType: String, Codable {