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 {