sodalive-ios/SodaLive/Sources/Search/SearchUnifiedView.swift

244 lines
7.5 KiB
Swift

//
// SearchUnifiedView.swift
// SodaLive
//
// Created by klaus on 3/27/25.
//
import SwiftUI
import Kingfisher
struct SearchUnifiedView: View {
let creatorList: [SearchResponseItem]
let contentList: [SearchResponseItem]
let searchList: [SearchResponseItem]
let onTapMoreCreator: () -> Void
let onTapMoreContent: () -> Void
let onTapMoreSeries: () -> Void
var body: some View {
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 30) {
if !creatorList.isEmpty {
SearchUnifiedItemView(
title: "채널",
itemList: creatorList,
onTapMore: onTapMoreCreator
)
.frame(maxWidth: .infinity)
.padding(.horizontal, 13.3)
}
if !contentList.isEmpty {
SearchUnifiedItemView(
title: "콘텐츠",
itemList: contentList,
onTapMore: onTapMoreContent
)
.frame(maxWidth: .infinity)
.padding(.horizontal, 13.3)
}
if !searchList.isEmpty {
SearchUnifiedItemView(
title: "시리즈",
itemList: searchList,
onTapMore: onTapMoreSeries
)
.frame(maxWidth: .infinity)
.padding(.horizontal, 13.3)
}
}
}
}
}
struct SearchUnifiedItemView: View {
let title: String
let itemList: [SearchResponseItem]
let onTapMore: () -> Void
var body: some View {
VStack(alignment: .leading, spacing: 13.3) {
Text(title)
.font(.custom(Font.bold.rawValue, size: 16))
.foregroundColor(.grayee)
ForEach(0..<itemList.count, id: \.self) {
let item = itemList[$0]
switch item.type {
case .CREATOR:
SearchCreatorItemView(item: item)
case .CONTENT:
SearchContentItemView(item: item)
case .SERIES:
SearchSeriesItemView(item: item)
}
}
Text("더보기 >")
.font(.custom(Font.medium.rawValue, size: 13.3))
.foregroundColor(.grayee)
.padding(.vertical, 10)
.frame(maxWidth: .infinity)
.background(Color.gray33.opacity(0.7))
.onTapGesture { onTapMore() }
}
}
}
struct SearchCreatorItemView: View {
let item: SearchResponseItem
var body: some View {
NavigationLink {
UserProfileView(userId: item.id)
} label: {
HStack(spacing: 13.3) {
KFImage(URL(string: item.imageUrl))
.cancelOnDisappear(true)
.downsampling(size: CGSize(width: 60, height: 60))
.resizable()
.frame(width: 60, height: 60)
.clipShape(Circle())
Text(item.nickname)
.font(.custom(Font.medium.rawValue, size: 13.3))
.foregroundColor(Color.grayee)
Spacer()
}
.frame(maxWidth: .infinity)
.contentShape(Rectangle())
}
}
}
struct SearchContentItemView: View {
let item: SearchResponseItem
var body: some View {
NavigationLink {
ContentDetailView(contentId: item.id)
} label: {
HStack(spacing: 13.3) {
KFImage(URL(string: item.imageUrl))
.cancelOnDisappear(true)
.downsampling(size: CGSize(width: 60, height: 60))
.resizable()
.frame(width: 60, height: 60)
.cornerRadius(5.3)
VStack(alignment: .leading, spacing: 6.7) {
Text(item.title)
.font(.custom(Font.medium.rawValue, size: 13.3))
.foregroundColor(Color.grayee)
.multilineTextAlignment(.leading)
.lineLimit(2)
Text(item.nickname)
.font(.custom(Font.medium.rawValue, size: 10))
.foregroundColor(Color.gray77)
}
Spacer()
}
.frame(maxWidth: .infinity)
.contentShape(Rectangle())
}
}
}
struct SearchSeriesItemView: View {
let item: SearchResponseItem
var body: some View {
NavigationLink {
SeriesDetailView(seriesId: item.id)
} label: {
HStack(spacing: 13.3) {
KFImage(URL(string: item.imageUrl))
.cancelOnDisappear(true)
.downsampling(size: CGSize(width: 60, height: 85))
.resizable()
.scaledToFill()
.frame(width: 60, height: 85)
.clipped()
.cornerRadius(5.3)
VStack(alignment: .leading, spacing: 6.7) {
Text(item.title)
.font(.custom(Font.medium.rawValue, size: 13.3))
.foregroundColor(Color.grayee)
.multilineTextAlignment(.leading)
.lineLimit(2)
Text(item.nickname)
.font(.custom(Font.medium.rawValue, size: 10))
.foregroundColor(Color.gray77)
}
Spacer()
}
.frame(maxWidth: .infinity)
.contentShape(Rectangle())
}
}
}
#Preview {
SearchUnifiedView(
creatorList: [
SearchResponseItem(
id: 1,
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
title: "Tester",
nickname: "Tester",
type: .CREATOR
)
],
contentList: [
SearchResponseItem(
id: 1,
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
title: "Title1",
nickname: "Tester",
type: .CONTENT
),
SearchResponseItem(
id: 2,
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
title: "Title2",
nickname: "Tester2",
type: .CONTENT
)
],
searchList: [
SearchResponseItem(
id: 1,
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
title: "Title1",
nickname: "Tester",
type: .SERIES
),
SearchResponseItem(
id: 2,
imageUrl: "https://test-cf.sodalive.net/profile/default-profile.png",
title: "Title2",
nickname: "Tester2",
type: .SERIES
)],
onTapMoreCreator: {},
onTapMoreContent: {},
onTapMoreSeries: {}
)
}