feat(creator): 소개, 활동, SNS 섹션을 연결한다
This commit is contained in:
@@ -52,6 +52,15 @@
|
|||||||
CC01011D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC01001D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift */; };
|
CC01011D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC01001D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift */; };
|
||||||
CC01021D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC01001D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift */; };
|
CC01021D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC01001D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift */; };
|
||||||
CC01031D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC01001D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift */; };
|
CC01031D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC01001D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift */; };
|
||||||
|
CC01011E2FF0100000A5BBA3 /* CreatorChannelIntroduceSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC01001E2FF0100000A5BBA3 /* CreatorChannelIntroduceSection.swift */; };
|
||||||
|
CC01021E2FF0100000A5BBA3 /* CreatorChannelIntroduceSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC01001E2FF0100000A5BBA3 /* CreatorChannelIntroduceSection.swift */; };
|
||||||
|
CC01031E2FF0100000A5BBA3 /* CreatorChannelIntroduceSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC01001E2FF0100000A5BBA3 /* CreatorChannelIntroduceSection.swift */; };
|
||||||
|
CC01011F2FF0100000A5BBA3 /* CreatorChannelActivitySection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC01001F2FF0100000A5BBA3 /* CreatorChannelActivitySection.swift */; };
|
||||||
|
CC01021F2FF0100000A5BBA3 /* CreatorChannelActivitySection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC01001F2FF0100000A5BBA3 /* CreatorChannelActivitySection.swift */; };
|
||||||
|
CC01031F2FF0100000A5BBA3 /* CreatorChannelActivitySection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC01001F2FF0100000A5BBA3 /* CreatorChannelActivitySection.swift */; };
|
||||||
|
CC0101272FF0100000A5BBA3 /* CreatorChannelSnsSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100272FF0100000A5BBA3 /* CreatorChannelSnsSection.swift */; };
|
||||||
|
CC0102272FF0100000A5BBA3 /* CreatorChannelSnsSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100272FF0100000A5BBA3 /* CreatorChannelSnsSection.swift */; };
|
||||||
|
CC0103272FF0100000A5BBA3 /* CreatorChannelSnsSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100272FF0100000A5BBA3 /* CreatorChannelSnsSection.swift */; };
|
||||||
CC0101082FF0100000A5BBA3 /* CreatorChannelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100082FF0100000A5BBA3 /* CreatorChannelView.swift */; };
|
CC0101082FF0100000A5BBA3 /* CreatorChannelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100082FF0100000A5BBA3 /* CreatorChannelView.swift */; };
|
||||||
CC0102082FF0100000A5BBA3 /* CreatorChannelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100082FF0100000A5BBA3 /* CreatorChannelView.swift */; };
|
CC0102082FF0100000A5BBA3 /* CreatorChannelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100082FF0100000A5BBA3 /* CreatorChannelView.swift */; };
|
||||||
CC0103082FF0100000A5BBA3 /* CreatorChannelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100082FF0100000A5BBA3 /* CreatorChannelView.swift */; };
|
CC0103082FF0100000A5BBA3 /* CreatorChannelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100082FF0100000A5BBA3 /* CreatorChannelView.swift */; };
|
||||||
@@ -1786,6 +1795,9 @@
|
|||||||
CC01001B2FF0100000A5BBA3 /* CreatorChannelSeriesSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelSeriesSection.swift; sourceTree = "<group>"; };
|
CC01001B2FF0100000A5BBA3 /* CreatorChannelSeriesSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelSeriesSection.swift; sourceTree = "<group>"; };
|
||||||
CC01001C2FF0100000A5BBA3 /* CreatorChannelCommunitySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelCommunitySection.swift; sourceTree = "<group>"; };
|
CC01001C2FF0100000A5BBA3 /* CreatorChannelCommunitySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelCommunitySection.swift; sourceTree = "<group>"; };
|
||||||
CC01001D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelFanTalkSection.swift; sourceTree = "<group>"; };
|
CC01001D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelFanTalkSection.swift; sourceTree = "<group>"; };
|
||||||
|
CC01001E2FF0100000A5BBA3 /* CreatorChannelIntroduceSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelIntroduceSection.swift; sourceTree = "<group>"; };
|
||||||
|
CC01001F2FF0100000A5BBA3 /* CreatorChannelActivitySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelActivitySection.swift; sourceTree = "<group>"; };
|
||||||
|
CC0100272FF0100000A5BBA3 /* CreatorChannelSnsSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelSnsSection.swift; sourceTree = "<group>"; };
|
||||||
0BBDC3ECBBE049EAA4057D3A /* PostChannelDonationRequest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PostChannelDonationRequest.swift; sourceTree = "<group>"; };
|
0BBDC3ECBBE049EAA4057D3A /* PostChannelDonationRequest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PostChannelDonationRequest.swift; sourceTree = "<group>"; };
|
||||||
0EC05859619BDC03056911E7 /* MainTab.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MainTab.swift; sourceTree = "<group>"; };
|
0EC05859619BDC03056911E7 /* MainTab.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MainTab.swift; sourceTree = "<group>"; };
|
||||||
189350EA101CF12EEBA6EC1D /* MainTabBarView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MainTabBarView.swift; sourceTree = "<group>"; };
|
189350EA101CF12EEBA6EC1D /* MainTabBarView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = MainTabBarView.swift; sourceTree = "<group>"; };
|
||||||
@@ -2715,6 +2727,9 @@
|
|||||||
CC01001B2FF0100000A5BBA3 /* CreatorChannelSeriesSection.swift */,
|
CC01001B2FF0100000A5BBA3 /* CreatorChannelSeriesSection.swift */,
|
||||||
CC01001C2FF0100000A5BBA3 /* CreatorChannelCommunitySection.swift */,
|
CC01001C2FF0100000A5BBA3 /* CreatorChannelCommunitySection.swift */,
|
||||||
CC01001D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift */,
|
CC01001D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift */,
|
||||||
|
CC01001E2FF0100000A5BBA3 /* CreatorChannelIntroduceSection.swift */,
|
||||||
|
CC01001F2FF0100000A5BBA3 /* CreatorChannelActivitySection.swift */,
|
||||||
|
CC0100272FF0100000A5BBA3 /* CreatorChannelSnsSection.swift */,
|
||||||
);
|
);
|
||||||
path = Components;
|
path = Components;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -5659,6 +5674,9 @@
|
|||||||
CC01011B2FF0100000A5BBA3 /* CreatorChannelSeriesSection.swift in Sources */,
|
CC01011B2FF0100000A5BBA3 /* CreatorChannelSeriesSection.swift in Sources */,
|
||||||
CC01011C2FF0100000A5BBA3 /* CreatorChannelCommunitySection.swift in Sources */,
|
CC01011C2FF0100000A5BBA3 /* CreatorChannelCommunitySection.swift in Sources */,
|
||||||
CC01011D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift in Sources */,
|
CC01011D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift in Sources */,
|
||||||
|
CC01011E2FF0100000A5BBA3 /* CreatorChannelIntroduceSection.swift in Sources */,
|
||||||
|
CC01011F2FF0100000A5BBA3 /* CreatorChannelActivitySection.swift in Sources */,
|
||||||
|
CC0101272FF0100000A5BBA3 /* CreatorChannelSnsSection.swift in Sources */,
|
||||||
CC0101082FF0100000A5BBA3 /* CreatorChannelView.swift in Sources */,
|
CC0101082FF0100000A5BBA3 /* CreatorChannelView.swift in Sources */,
|
||||||
CC0101112FF0100000A5BBA3 /* CreatorChannelTitleBar.swift in Sources */,
|
CC0101112FF0100000A5BBA3 /* CreatorChannelTitleBar.swift in Sources */,
|
||||||
CC0101122FF0100000A5BBA3 /* CreatorChannelHeaderSection.swift in Sources */,
|
CC0101122FF0100000A5BBA3 /* CreatorChannelHeaderSection.swift in Sources */,
|
||||||
@@ -6466,6 +6484,9 @@
|
|||||||
CC01021B2FF0100000A5BBA3 /* CreatorChannelSeriesSection.swift in Sources */,
|
CC01021B2FF0100000A5BBA3 /* CreatorChannelSeriesSection.swift in Sources */,
|
||||||
CC01021C2FF0100000A5BBA3 /* CreatorChannelCommunitySection.swift in Sources */,
|
CC01021C2FF0100000A5BBA3 /* CreatorChannelCommunitySection.swift in Sources */,
|
||||||
CC01021D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift in Sources */,
|
CC01021D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift in Sources */,
|
||||||
|
CC01021E2FF0100000A5BBA3 /* CreatorChannelIntroduceSection.swift in Sources */,
|
||||||
|
CC01021F2FF0100000A5BBA3 /* CreatorChannelActivitySection.swift in Sources */,
|
||||||
|
CC0102272FF0100000A5BBA3 /* CreatorChannelSnsSection.swift in Sources */,
|
||||||
CC0102082FF0100000A5BBA3 /* CreatorChannelView.swift in Sources */,
|
CC0102082FF0100000A5BBA3 /* CreatorChannelView.swift in Sources */,
|
||||||
CC0102112FF0100000A5BBA3 /* CreatorChannelTitleBar.swift in Sources */,
|
CC0102112FF0100000A5BBA3 /* CreatorChannelTitleBar.swift in Sources */,
|
||||||
CC0102122FF0100000A5BBA3 /* CreatorChannelHeaderSection.swift in Sources */,
|
CC0102122FF0100000A5BBA3 /* CreatorChannelHeaderSection.swift in Sources */,
|
||||||
@@ -7289,6 +7310,9 @@
|
|||||||
CC01031B2FF0100000A5BBA3 /* CreatorChannelSeriesSection.swift in Sources */,
|
CC01031B2FF0100000A5BBA3 /* CreatorChannelSeriesSection.swift in Sources */,
|
||||||
CC01031C2FF0100000A5BBA3 /* CreatorChannelCommunitySection.swift in Sources */,
|
CC01031C2FF0100000A5BBA3 /* CreatorChannelCommunitySection.swift in Sources */,
|
||||||
CC01031D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift in Sources */,
|
CC01031D2FF0100000A5BBA3 /* CreatorChannelFanTalkSection.swift in Sources */,
|
||||||
|
CC01031E2FF0100000A5BBA3 /* CreatorChannelIntroduceSection.swift in Sources */,
|
||||||
|
CC01031F2FF0100000A5BBA3 /* CreatorChannelActivitySection.swift in Sources */,
|
||||||
|
CC0103272FF0100000A5BBA3 /* CreatorChannelSnsSection.swift in Sources */,
|
||||||
CC0103082FF0100000A5BBA3 /* CreatorChannelView.swift in Sources */,
|
CC0103082FF0100000A5BBA3 /* CreatorChannelView.swift in Sources */,
|
||||||
CC0103112FF0100000A5BBA3 /* CreatorChannelTitleBar.swift in Sources */,
|
CC0103112FF0100000A5BBA3 /* CreatorChannelTitleBar.swift in Sources */,
|
||||||
CC0103122FF0100000A5BBA3 /* CreatorChannelHeaderSection.swift in Sources */,
|
CC0103122FF0100000A5BBA3 /* CreatorChannelHeaderSection.swift in Sources */,
|
||||||
|
|||||||
@@ -3196,6 +3196,26 @@ If you block this user, the following features will be restricted.
|
|||||||
static func followerCount(_ count: String) -> String {
|
static func followerCount(_ count: String) -> String {
|
||||||
pick(ko: "팔로워 \(count)명", en: "\(count) followers", ja: "フォロワー\(count)人")
|
pick(ko: "팔로워 \(count)명", en: "\(count) followers", ja: "フォロワー\(count)人")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func liveCountValue(_ count: String) -> String {
|
||||||
|
pick(ko: "\(count)회", en: "\(count)", ja: "\(count)回")
|
||||||
|
}
|
||||||
|
|
||||||
|
static func liveDurationHoursValue(_ count: String) -> String {
|
||||||
|
pick(ko: "\(count)시간", en: "\(count) hours", ja: "\(count)時間")
|
||||||
|
}
|
||||||
|
|
||||||
|
static func liveContributorCountValue(_ count: String) -> String {
|
||||||
|
pick(ko: "\(count)명", en: "\(count) people", ja: "\(count)人")
|
||||||
|
}
|
||||||
|
|
||||||
|
static func audioContentCountValue(_ count: String) -> String {
|
||||||
|
pick(ko: "\(count)개", en: "\(count)", ja: "\(count)件")
|
||||||
|
}
|
||||||
|
|
||||||
|
static func seriesCountValue(_ count: String) -> String {
|
||||||
|
pick(ko: "\(count)개", en: "\(count)", ja: "\(count)件")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum HomeRecommendation {
|
enum HomeRecommendation {
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct CreatorChannelActivitySection: View {
|
||||||
|
let activity: CreatorChannelActivityResponse
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(alignment: .leading, spacing: SodaSpacing.s14) {
|
||||||
|
SectionTitle(title: I18n.CreatorChannelHome.activity)
|
||||||
|
|
||||||
|
VStack(alignment: .leading, spacing: SodaSpacing.s8) {
|
||||||
|
activityRow(title: I18n.CreatorChannelHome.debut, value: activity.debutText)
|
||||||
|
activityRow(title: I18n.CreatorChannelHome.liveCount, value: I18n.CreatorChannelHome.liveCountValue(activity.liveCount.comma()))
|
||||||
|
activityRow(title: I18n.CreatorChannelHome.liveDurationHours, value: I18n.CreatorChannelHome.liveDurationHoursValue(activity.liveDurationHours.comma()))
|
||||||
|
activityRow(title: I18n.CreatorChannelHome.liveContributorCount, value: I18n.CreatorChannelHome.liveContributorCountValue(activity.liveContributorCount.comma()))
|
||||||
|
activityRow(title: I18n.CreatorChannelHome.audioContentCount, value: I18n.CreatorChannelHome.audioContentCountValue(activity.audioContentCount.comma()))
|
||||||
|
activityRow(title: I18n.CreatorChannelHome.seriesCount, value: I18n.CreatorChannelHome.seriesCountValue(activity.seriesCount.comma()))
|
||||||
|
}
|
||||||
|
.padding(.horizontal, SodaSpacing.s20)
|
||||||
|
}
|
||||||
|
.padding(.top, SodaSpacing.s20)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func activityRow(title: String, value: String) -> some View {
|
||||||
|
HStack(alignment: .top, spacing: SodaSpacing.s8) {
|
||||||
|
Text(title)
|
||||||
|
.appFont(size: 16, weight: .medium)
|
||||||
|
.foregroundColor(Color.gray500)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
|
||||||
|
Text(value)
|
||||||
|
.appFont(size: 16, weight: .medium)
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.lineLimit(1)
|
||||||
|
.multilineTextAlignment(.trailing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension CreatorChannelActivityResponse {
|
||||||
|
var debutText: String {
|
||||||
|
let dDayText = dday.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
|
||||||
|
guard let debutDateUtc,
|
||||||
|
let debutDate = DateParser.parse(debutDateUtc),
|
||||||
|
!dDayText.isEmpty else {
|
||||||
|
return dDayText
|
||||||
|
}
|
||||||
|
|
||||||
|
return "\(debutDate.convertDateFormat(dateFormat: "yyyy.MM.dd"))(\(dDayText))"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CreatorChannelActivitySection_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
CreatorChannelActivitySection(
|
||||||
|
activity: CreatorChannelActivityResponse(
|
||||||
|
debutDateUtc: "2026-06-11T00:00:00Z",
|
||||||
|
dday: "D+1",
|
||||||
|
liveCount: 719,
|
||||||
|
liveDurationHours: 1839,
|
||||||
|
liveContributorCount: 2189,
|
||||||
|
audioContentCount: 281,
|
||||||
|
seriesCount: 8
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.background(Color.black)
|
||||||
|
.previewLayout(.sizeThatFits)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct CreatorChannelIntroduceSection: View {
|
||||||
|
let introduce: String
|
||||||
|
|
||||||
|
private var trimmedIntroduce: String {
|
||||||
|
introduce.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
if !trimmedIntroduce.isEmpty {
|
||||||
|
VStack(alignment: .leading, spacing: SodaSpacing.s14) {
|
||||||
|
SectionTitle(title: I18n.CreatorChannelHome.introduce)
|
||||||
|
|
||||||
|
Text(trimmedIntroduce)
|
||||||
|
.appFont(size: 16, weight: .regular)
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.lineSpacing(4)
|
||||||
|
.lineLimit(nil)
|
||||||
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
.padding(.horizontal, SodaSpacing.s20)
|
||||||
|
}
|
||||||
|
.padding(.top, SodaSpacing.s20)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CreatorChannelIntroduceSection_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
CreatorChannelIntroduceSection(
|
||||||
|
introduce: "크리에이터가 커뮤니티에 올린 글이 보이는 부분 크리에이터가 커뮤니티에 올린 글이 보이는 부분 크리에이터가 커뮤니티에 올린 글이 보이는 부분"
|
||||||
|
)
|
||||||
|
.background(Color.black)
|
||||||
|
.previewLayout(.sizeThatFits)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct CreatorChannelSnsSection: View {
|
||||||
|
let sns: CreatorChannelSnsResponse
|
||||||
|
|
||||||
|
@Environment(\.openURL) private var openURL
|
||||||
|
|
||||||
|
private var snsItems: [CreatorChannelSnsItem] {
|
||||||
|
[
|
||||||
|
CreatorChannelSnsItem(iconName: "ic_sns_instagram", url: sns.instagramUrl),
|
||||||
|
CreatorChannelSnsItem(iconName: "ic_sns_youtube", url: sns.youtubeUrl),
|
||||||
|
CreatorChannelSnsItem(iconName: "ic_sns_x", url: sns.xurl),
|
||||||
|
CreatorChannelSnsItem(iconName: "ic_sns_kakao", url: sns.kakaoOpenChatUrl),
|
||||||
|
CreatorChannelSnsItem(iconName: "ic_sns_fancimm", url: sns.fancimmUrl)
|
||||||
|
]
|
||||||
|
.compactMap { item in
|
||||||
|
guard normalizedUrl(item.url) != nil else { return nil }
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
if !snsItems.isEmpty {
|
||||||
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
|
SectionTitle(title: I18n.CreatorChannelHome.sns)
|
||||||
|
|
||||||
|
HStack(alignment: .center, spacing: SodaSpacing.s16) {
|
||||||
|
ForEach(snsItems) { item in
|
||||||
|
Button {
|
||||||
|
if let url = normalizedUrl(item.url) {
|
||||||
|
openURL(url)
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
Image(item.iconName)
|
||||||
|
.resizable()
|
||||||
|
.scaledToFill()
|
||||||
|
.frame(width: 52, height: 52)
|
||||||
|
.clipShape(Circle())
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.horizontal, SodaSpacing.s20)
|
||||||
|
}
|
||||||
|
.padding(.top, SodaSpacing.s20)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func normalizedUrl(_ urlString: String) -> URL? {
|
||||||
|
let trimmed = urlString.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
|
||||||
|
guard !trimmed.isEmpty else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if trimmed.hasPrefix("http://") || trimmed.hasPrefix("https://") {
|
||||||
|
return URL(string: trimmed)
|
||||||
|
}
|
||||||
|
|
||||||
|
return URL(string: "https://\(trimmed)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct CreatorChannelSnsItem: Identifiable {
|
||||||
|
let iconName: String
|
||||||
|
let url: String
|
||||||
|
|
||||||
|
var id: String { iconName }
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CreatorChannelSnsSection_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
CreatorChannelSnsSection(
|
||||||
|
sns: CreatorChannelSnsResponse(
|
||||||
|
instagramUrl: "https://instagram.com/voiceon",
|
||||||
|
fancimmUrl: "https://fancimm.com",
|
||||||
|
xurl: "https://x.com/voiceon",
|
||||||
|
youtubeUrl: "https://youtube.com",
|
||||||
|
kakaoOpenChatUrl: "https://open.kakao.com"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.background(Color.black)
|
||||||
|
.previewLayout(.sizeThatFits)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -77,6 +77,12 @@ struct CreatorChannelHomeView: View {
|
|||||||
fanTalk: response.fanTalk,
|
fanTalk: response.fanTalk,
|
||||||
onSelectTab: onSelectTab
|
onSelectTab: onSelectTab
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CreatorChannelIntroduceSection(introduce: response.introduce)
|
||||||
|
|
||||||
|
CreatorChannelActivitySection(activity: response.activity)
|
||||||
|
|
||||||
|
CreatorChannelSnsSection(sns: response.sns)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
.background(Color.black)
|
.background(Color.black)
|
||||||
|
|||||||
@@ -496,7 +496,7 @@
|
|||||||
|
|
||||||
### Phase 14: 소개 섹션
|
### Phase 14: 소개 섹션
|
||||||
|
|
||||||
- [ ] **Task 14.1: 소개 섹션 구현**
|
- [x] **Task 14.1: 소개 섹션 구현**
|
||||||
- 대상 파일:
|
- 대상 파일:
|
||||||
- 생성: `SodaLive/Sources/V2/CreatorChannel/Home/Components/CreatorChannelIntroduceSection.swift`
|
- 생성: `SodaLive/Sources/V2/CreatorChannel/Home/Components/CreatorChannelIntroduceSection.swift`
|
||||||
- 수정: `SodaLive/Sources/V2/CreatorChannel/Home/CreatorChannelHomeView.swift`
|
- 수정: `SodaLive/Sources/V2/CreatorChannel/Home/CreatorChannelHomeView.swift`
|
||||||
@@ -509,7 +509,7 @@
|
|||||||
|
|
||||||
### Phase 15: 활동 섹션
|
### Phase 15: 활동 섹션
|
||||||
|
|
||||||
- [ ] **Task 15.1: 활동 섹션 구현**
|
- [x] **Task 15.1: 활동 섹션 구현**
|
||||||
- 대상 파일:
|
- 대상 파일:
|
||||||
- 생성: `SodaLive/Sources/V2/CreatorChannel/Home/Components/CreatorChannelActivitySection.swift`
|
- 생성: `SodaLive/Sources/V2/CreatorChannel/Home/Components/CreatorChannelActivitySection.swift`
|
||||||
- 수정: `SodaLive/Sources/V2/CreatorChannel/Home/CreatorChannelHomeView.swift`
|
- 수정: `SodaLive/Sources/V2/CreatorChannel/Home/CreatorChannelHomeView.swift`
|
||||||
@@ -524,7 +524,7 @@
|
|||||||
|
|
||||||
### Phase 16: SNS 섹션
|
### Phase 16: SNS 섹션
|
||||||
|
|
||||||
- [ ] **Task 16.1: SNS 섹션 구현**
|
- [x] **Task 16.1: SNS 섹션 구현**
|
||||||
- 대상 파일:
|
- 대상 파일:
|
||||||
- 생성: `SodaLive/Sources/V2/CreatorChannel/Home/Components/CreatorChannelSnsSection.swift`
|
- 생성: `SodaLive/Sources/V2/CreatorChannel/Home/Components/CreatorChannelSnsSection.swift`
|
||||||
- 수정: `SodaLive/Sources/V2/CreatorChannel/Home/CreatorChannelHomeView.swift`
|
- 수정: `SodaLive/Sources/V2/CreatorChannel/Home/CreatorChannelHomeView.swift`
|
||||||
|
|||||||
Reference in New Issue
Block a user