feat(creator): 공지 섹션을 연결한다
This commit is contained in:
@@ -31,6 +31,9 @@
|
|||||||
CC0101162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift */; };
|
CC0101162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift */; };
|
||||||
CC0102162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift */; };
|
CC0102162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift */; };
|
||||||
CC0103162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift */; };
|
CC0103162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift */; };
|
||||||
|
CC0101172FF0100000A5BBA3 /* CreatorChannelNoticeSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100172FF0100000A5BBA3 /* CreatorChannelNoticeSection.swift */; };
|
||||||
|
CC0102172FF0100000A5BBA3 /* CreatorChannelNoticeSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100172FF0100000A5BBA3 /* CreatorChannelNoticeSection.swift */; };
|
||||||
|
CC0103172FF0100000A5BBA3 /* CreatorChannelNoticeSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0100172FF0100000A5BBA3 /* CreatorChannelNoticeSection.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 */; };
|
||||||
@@ -1758,6 +1761,7 @@
|
|||||||
CC0100142FF0100000A5BBA3 /* CreatorChannelCurrentLiveSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelCurrentLiveSection.swift; sourceTree = "<group>"; };
|
CC0100142FF0100000A5BBA3 /* CreatorChannelCurrentLiveSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelCurrentLiveSection.swift; sourceTree = "<group>"; };
|
||||||
CC0100152FF0100000A5BBA3 /* CreatorChannelLatestAudioSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelLatestAudioSection.swift; sourceTree = "<group>"; };
|
CC0100152FF0100000A5BBA3 /* CreatorChannelLatestAudioSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelLatestAudioSection.swift; sourceTree = "<group>"; };
|
||||||
CC0100162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelDonationSection.swift; sourceTree = "<group>"; };
|
CC0100162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelDonationSection.swift; sourceTree = "<group>"; };
|
||||||
|
CC0100172FF0100000A5BBA3 /* CreatorChannelNoticeSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelNoticeSection.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>"; };
|
||||||
@@ -2680,6 +2684,7 @@
|
|||||||
CC0100142FF0100000A5BBA3 /* CreatorChannelCurrentLiveSection.swift */,
|
CC0100142FF0100000A5BBA3 /* CreatorChannelCurrentLiveSection.swift */,
|
||||||
CC0100152FF0100000A5BBA3 /* CreatorChannelLatestAudioSection.swift */,
|
CC0100152FF0100000A5BBA3 /* CreatorChannelLatestAudioSection.swift */,
|
||||||
CC0100162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift */,
|
CC0100162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift */,
|
||||||
|
CC0100172FF0100000A5BBA3 /* CreatorChannelNoticeSection.swift */,
|
||||||
);
|
);
|
||||||
path = Components;
|
path = Components;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -5617,6 +5622,7 @@
|
|||||||
CC0101142FF0100000A5BBA3 /* CreatorChannelCurrentLiveSection.swift in Sources */,
|
CC0101142FF0100000A5BBA3 /* CreatorChannelCurrentLiveSection.swift in Sources */,
|
||||||
CC0101152FF0100000A5BBA3 /* CreatorChannelLatestAudioSection.swift in Sources */,
|
CC0101152FF0100000A5BBA3 /* CreatorChannelLatestAudioSection.swift in Sources */,
|
||||||
CC0101162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift in Sources */,
|
CC0101162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift in Sources */,
|
||||||
|
CC0101172FF0100000A5BBA3 /* CreatorChannelNoticeSection.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 */,
|
||||||
@@ -6417,6 +6423,7 @@
|
|||||||
CC0102142FF0100000A5BBA3 /* CreatorChannelCurrentLiveSection.swift in Sources */,
|
CC0102142FF0100000A5BBA3 /* CreatorChannelCurrentLiveSection.swift in Sources */,
|
||||||
CC0102152FF0100000A5BBA3 /* CreatorChannelLatestAudioSection.swift in Sources */,
|
CC0102152FF0100000A5BBA3 /* CreatorChannelLatestAudioSection.swift in Sources */,
|
||||||
CC0102162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift in Sources */,
|
CC0102162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift in Sources */,
|
||||||
|
CC0102172FF0100000A5BBA3 /* CreatorChannelNoticeSection.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 */,
|
||||||
@@ -7233,6 +7240,7 @@
|
|||||||
CC0103142FF0100000A5BBA3 /* CreatorChannelCurrentLiveSection.swift in Sources */,
|
CC0103142FF0100000A5BBA3 /* CreatorChannelCurrentLiveSection.swift in Sources */,
|
||||||
CC0103152FF0100000A5BBA3 /* CreatorChannelLatestAudioSection.swift in Sources */,
|
CC0103152FF0100000A5BBA3 /* CreatorChannelLatestAudioSection.swift in Sources */,
|
||||||
CC0103162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift in Sources */,
|
CC0103162FF0100000A5BBA3 /* CreatorChannelDonationSection.swift in Sources */,
|
||||||
|
CC0103172FF0100000A5BBA3 /* CreatorChannelNoticeSection.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 */,
|
||||||
|
|||||||
@@ -0,0 +1,290 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct CreatorChannelNoticeSection: View {
|
||||||
|
let notices: [CreatorChannelCommunityPostResponse]
|
||||||
|
let onTapNotice: (Int) -> Void
|
||||||
|
let onTapComment: (Int) -> Void
|
||||||
|
let onTapPurchase: (CreatorChannelCommunityPostResponse) -> Void
|
||||||
|
|
||||||
|
init(
|
||||||
|
notices: [CreatorChannelCommunityPostResponse],
|
||||||
|
onTapNotice: @escaping (Int) -> Void = { _ in },
|
||||||
|
onTapComment: @escaping (Int) -> Void = { _ in },
|
||||||
|
onTapPurchase: @escaping (CreatorChannelCommunityPostResponse) -> Void = { _ in }
|
||||||
|
) {
|
||||||
|
self.notices = notices
|
||||||
|
self.onTapNotice = onTapNotice
|
||||||
|
self.onTapComment = onTapComment
|
||||||
|
self.onTapPurchase = onTapPurchase
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
if !notices.isEmpty {
|
||||||
|
VStack(alignment: .leading, spacing: SodaSpacing.s14) {
|
||||||
|
SectionTitle(title: I18n.CreatorChannelHome.notice)
|
||||||
|
|
||||||
|
ScrollView(.horizontal, showsIndicators: false) {
|
||||||
|
HStack(alignment: .top, spacing: SodaSpacing.s4) {
|
||||||
|
ForEach(notices) { notice in
|
||||||
|
CreatorChannelNoticeCard(
|
||||||
|
notice: notice,
|
||||||
|
onTapNotice: {
|
||||||
|
onTapNotice(notice.postId)
|
||||||
|
},
|
||||||
|
onTapComment: {
|
||||||
|
onTapComment(notice.postId)
|
||||||
|
},
|
||||||
|
onTapPurchase: {
|
||||||
|
onTapPurchase(notice)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.frame(width: 374)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.horizontal, SodaSpacing.s14)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.top, SodaSpacing.s20)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct CreatorChannelNoticeCard: View {
|
||||||
|
let notice: CreatorChannelCommunityPostResponse
|
||||||
|
let onTapNotice: () -> Void
|
||||||
|
let onTapComment: () -> Void
|
||||||
|
let onTapPurchase: () -> Void
|
||||||
|
|
||||||
|
@StateObject private var playManager = CreatorCommunityMediaPlayerManager.shared
|
||||||
|
@StateObject private var contentPlayManager = ContentPlayManager.shared
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(alignment: .leading, spacing: SodaSpacing.s14) {
|
||||||
|
noticeLabel
|
||||||
|
header
|
||||||
|
bodyContent
|
||||||
|
reactionBar
|
||||||
|
}
|
||||||
|
.padding(SodaSpacing.s14)
|
||||||
|
.background(Color.gray900)
|
||||||
|
.clipShape(RoundedRectangle(cornerRadius: SodaSpacing.s14, style: .continuous))
|
||||||
|
.contentShape(Rectangle())
|
||||||
|
.onTapGesture(perform: onTapNotice)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var noticeLabel: some View {
|
||||||
|
HStack(spacing: 2) {
|
||||||
|
Image("ic_pin")
|
||||||
|
.resizable()
|
||||||
|
.renderingMode(.template)
|
||||||
|
.foregroundColor(Color(hex: "73FF01"))
|
||||||
|
.scaledToFit()
|
||||||
|
.frame(width: 18, height: 18)
|
||||||
|
|
||||||
|
Text("Notice")
|
||||||
|
.appFont(size: 14, weight: .medium)
|
||||||
|
.foregroundColor(Color(hex: "73FF01"))
|
||||||
|
.lineLimit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var header: some View {
|
||||||
|
HStack(spacing: SodaSpacing.s8) {
|
||||||
|
DownsampledKFImage(
|
||||||
|
url: URL(string: notice.creatorProfileUrl),
|
||||||
|
size: CGSize(width: 42, height: 42)
|
||||||
|
)
|
||||||
|
.background(Color.white.opacity(0.6))
|
||||||
|
.clipShape(Circle())
|
||||||
|
|
||||||
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
|
Text(notice.creatorNickname)
|
||||||
|
.appFont(size: 14, weight: .medium)
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.lineLimit(1)
|
||||||
|
.truncationMode(.tail)
|
||||||
|
|
||||||
|
Text(notice.relativeTimeText())
|
||||||
|
.appFont(size: 14, weight: .regular)
|
||||||
|
.foregroundColor(Color.gray500)
|
||||||
|
.lineLimit(1)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var bodyContent: some View {
|
||||||
|
HStack(alignment: .center, spacing: SodaSpacing.s8) {
|
||||||
|
Text(notice.content)
|
||||||
|
.appFont(size: 16, weight: .regular)
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.lineLimit(4)
|
||||||
|
.truncationMode(.tail)
|
||||||
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
|
||||||
|
if notice.hasImage {
|
||||||
|
thumbnail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(minHeight: 92, alignment: .center)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var thumbnail: some View {
|
||||||
|
ZStack {
|
||||||
|
DownsampledKFImage(
|
||||||
|
url: URL(string: notice.imageUrl ?? ""),
|
||||||
|
size: CGSize(width: 92, height: 92)
|
||||||
|
)
|
||||||
|
.background(Color.gray800)
|
||||||
|
.frame(width: 92, height: 92)
|
||||||
|
.clipShape(RoundedRectangle(cornerRadius: SodaSpacing.s14, style: .continuous))
|
||||||
|
.blur(radius: notice.isLocked ? 12 : 0)
|
||||||
|
|
||||||
|
if notice.isLocked {
|
||||||
|
paidLockOverlay
|
||||||
|
} else if notice.hasAudio {
|
||||||
|
audioPlayButton
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var audioPlayButton: some View {
|
||||||
|
Button {
|
||||||
|
guard let audioUrl = notice.audioUrl, !audioUrl.isEmpty else { return }
|
||||||
|
|
||||||
|
contentPlayManager.pauseAudio()
|
||||||
|
playManager.toggleContent(item: CreatorCommunityContentItem(contentId: notice.postId, url: audioUrl))
|
||||||
|
} label: {
|
||||||
|
Image(playManager.isPlaying && playManager.currentPlayingContentId == notice.postId ? "btn_audio_content_pause" : "btn_audio_content_play")
|
||||||
|
.resizable()
|
||||||
|
.frame(width: 48, height: 48)
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var paidLockOverlay: some View {
|
||||||
|
Button(action: onTapPurchase) {
|
||||||
|
ZStack {
|
||||||
|
Color.gray700.opacity(0.35)
|
||||||
|
|
||||||
|
VStack(spacing: SodaSpacing.s4) {
|
||||||
|
Image("ic_new_community_lock")
|
||||||
|
.resizable()
|
||||||
|
.renderingMode(.template)
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.frame(width: 24, height: 24)
|
||||||
|
|
||||||
|
HStack(spacing: SodaSpacing.s6) {
|
||||||
|
Image("ic_bar_cash")
|
||||||
|
.resizable()
|
||||||
|
.frame(width: 20, height: 20)
|
||||||
|
|
||||||
|
Text("\(notice.price)")
|
||||||
|
.appFont(.body2)
|
||||||
|
.foregroundColor(.black)
|
||||||
|
}
|
||||||
|
.padding(SodaSpacing.s8)
|
||||||
|
.background(Color.white)
|
||||||
|
.clipShape(Capsule())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
.frame(width: 92, height: 92)
|
||||||
|
.clipShape(RoundedRectangle(cornerRadius: SodaSpacing.s14, style: .continuous))
|
||||||
|
}
|
||||||
|
|
||||||
|
private var reactionBar: some View {
|
||||||
|
HStack(spacing: 15) {
|
||||||
|
Button(action: onTapComment) {
|
||||||
|
HStack(spacing: SodaSpacing.s4) {
|
||||||
|
Image("ic_feed_community_reply")
|
||||||
|
.resizable()
|
||||||
|
.frame(width: 18, height: 18)
|
||||||
|
|
||||||
|
Text("\(notice.commentCount)")
|
||||||
|
.appFont(.body2)
|
||||||
|
.foregroundColor(Color.gray400)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
|
||||||
|
HStack(spacing: SodaSpacing.s4) {
|
||||||
|
Image(notice.isLiked ? "ic_feed_community_heart_fill" : "ic_feed_community_heart")
|
||||||
|
.resizable()
|
||||||
|
.frame(width: 18, height: 18)
|
||||||
|
|
||||||
|
Text("\(notice.likeCount)")
|
||||||
|
.appFont(.body2)
|
||||||
|
.foregroundColor(Color.gray400)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(height: 24)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension CreatorChannelCommunityPostResponse {
|
||||||
|
func relativeTimeText(now: Date = Date()) -> String {
|
||||||
|
DateParser.relativeTimeText(fromUTC: dateUtc, fallback: dateUtc, now: now)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasImage: Bool {
|
||||||
|
!(imageUrl ?? "").isEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasAudio: Bool {
|
||||||
|
!(audioUrl ?? "").isEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
var isLocked: Bool {
|
||||||
|
price > 0 && !existOrdered
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CreatorChannelNoticeSection_Previews: PreviewProvider {
|
||||||
|
private static let previewImageUrl = "https://picsum.photos/300/300"
|
||||||
|
|
||||||
|
static var previews: some View {
|
||||||
|
VStack(spacing: SodaSpacing.s20) {
|
||||||
|
CreatorChannelNoticeSection(notices: [])
|
||||||
|
|
||||||
|
CreatorChannelNoticeSection(
|
||||||
|
notices: [
|
||||||
|
CreatorChannelCommunityPostResponse(
|
||||||
|
postId: 1,
|
||||||
|
creatorId: 10,
|
||||||
|
creatorNickname: "크리에이터 이름",
|
||||||
|
creatorProfileUrl: previewImageUrl,
|
||||||
|
imageUrl: previewImageUrl,
|
||||||
|
audioUrl: nil,
|
||||||
|
content: "크리에이터가 커뮤니티에 올린 글이 보이는 부분 크리에이터가 커뮤니티에 올린 글이 보이는 부분크리에이터가 커뮤니티에 올린 글이 보이는 부분 말줄임...",
|
||||||
|
price: 0,
|
||||||
|
dateUtc: "2026-07-03T03:44:00Z",
|
||||||
|
existOrdered: true,
|
||||||
|
likeCount: 5,
|
||||||
|
commentCount: 2,
|
||||||
|
isLiked: false
|
||||||
|
),
|
||||||
|
CreatorChannelCommunityPostResponse(
|
||||||
|
postId: 2,
|
||||||
|
creatorId: 10,
|
||||||
|
creatorNickname: "크리에이터 이름",
|
||||||
|
creatorProfileUrl: previewImageUrl,
|
||||||
|
imageUrl: nil,
|
||||||
|
audioUrl: nil,
|
||||||
|
content: "크리에이터가 커뮤니티에 올린 글이 보이는 부분 크리에이터가 커뮤니티에 올린 글이 보이는 부분 크리에이터가 커뮤니티에 올린 글이 보이는 부분",
|
||||||
|
price: 10,
|
||||||
|
dateUtc: "2026-07-03T03:42:00Z",
|
||||||
|
existOrdered: false,
|
||||||
|
likeCount: 3,
|
||||||
|
commentCount: 1,
|
||||||
|
isLiked: false
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.background(Color.black)
|
||||||
|
.previewLayout(.sizeThatFits)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,6 +38,8 @@ struct CreatorChannelHomeView: View {
|
|||||||
onSelectTab: onSelectTab,
|
onSelectTab: onSelectTab,
|
||||||
onTapDonate: onTapDonate
|
onTapDonate: onTapDonate
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CreatorChannelNoticeSection(notices: response.notices)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
.background(Color.black)
|
.background(Color.black)
|
||||||
|
|||||||
@@ -400,7 +400,7 @@
|
|||||||
|
|
||||||
### Phase 8: 공지 섹션
|
### Phase 8: 공지 섹션
|
||||||
|
|
||||||
- [ ] **Task 8.1: 공지 섹션 구현**
|
- [x] **Task 8.1: 공지 섹션 구현**
|
||||||
- 대상 파일:
|
- 대상 파일:
|
||||||
- 생성: `SodaLive/Sources/V2/CreatorChannel/Home/Components/CreatorChannelNoticeSection.swift`
|
- 생성: `SodaLive/Sources/V2/CreatorChannel/Home/Components/CreatorChannelNoticeSection.swift`
|
||||||
- 수정: `SodaLive/Sources/V2/CreatorChannel/Home/CreatorChannelHomeView.swift`
|
- 수정: `SodaLive/Sources/V2/CreatorChannel/Home/CreatorChannelHomeView.swift`
|
||||||
|
|||||||
Reference in New Issue
Block a user