diff --git a/SodaLive/Sources/V2/CreatorChannel/FanTalk/Components/CreatorChannelFanTalkListItem.swift b/SodaLive/Sources/V2/CreatorChannel/FanTalk/Components/CreatorChannelFanTalkListItem.swift index 414b6a7d..8da86db8 100644 --- a/SodaLive/Sources/V2/CreatorChannel/FanTalk/Components/CreatorChannelFanTalkListItem.swift +++ b/SodaLive/Sources/V2/CreatorChannel/FanTalk/Components/CreatorChannelFanTalkListItem.swift @@ -18,6 +18,15 @@ struct CreatorChannelFanTalkListItem: View { .fixedSize(horizontal: false, vertical: true) .frame(maxWidth: .infinity, alignment: .leading) .padding(.leading, 50) + .background(alignment: .topLeading) { + if fanTalk.creatorReplies.isEmpty == false { + GeometryReader { proxy in + CreatorChannelFanTalkReplyConnector() + .stroke(Color.gray800, style: StrokeStyle(lineWidth: 2, lineCap: .round, lineJoin: .round)) + .frame(height: proxy.size.height + SodaSpacing.s12 + SodaSpacing.s20) + } + } + } if fanTalk.creatorReplies.isEmpty == false { replies @@ -84,13 +93,7 @@ struct CreatorChannelFanTalkListItem: View { private var replies: some View { VStack(alignment: .leading, spacing: SodaSpacing.s8) { ForEach(fanTalk.creatorReplies) { reply in - HStack(alignment: .top, spacing: SodaSpacing.s8) { - Rectangle() - .fill(Color.gray800) - .frame(width: 2) - - replyCard(reply) - } + replyCard(reply) } } } @@ -129,6 +132,27 @@ struct CreatorChannelFanTalkListItem: View { } } +private struct CreatorChannelFanTalkReplyConnector: Shape { + func path(in rect: CGRect) -> Path { + var path = Path() + let avatarCenterX: CGFloat = 21 + let replyCardStartX: CGFloat = 50 + let connectorGap: CGFloat = 14 + let connectorEndX = replyCardStartX - connectorGap + let startY: CGFloat = 0 + let endY = rect.height - 8 + let bendY = max(startY, endY - 14) + + path.move(to: CGPoint(x: avatarCenterX, y: startY)) + path.addLine(to: CGPoint(x: avatarCenterX, y: bendY)) + path.addQuadCurve( + to: CGPoint(x: connectorEndX, y: endY), + control: CGPoint(x: avatarCenterX, y: endY) + ) + return path + } +} + extension CreatorChannelFanTalkItemResponse { func relativeTimeText(now: Date = Date()) -> String { DateParser.relativeTimeText(fromUTC: createdAtUtc, fallback: createdAtUtc, now: now)