feat(chat): 대화 날짜 구분선을 연결한다

This commit is contained in:
Yu Sung
2026-10-19 10:12:57 +09:00
parent e765c3c75c
commit 7a6d12e871
5 changed files with 185 additions and 8 deletions
@@ -0,0 +1,26 @@
import SwiftUI
struct UserCreatorChatDateSeparatorView: View {
@Environment(\.locale) private var locale
let title: String
var body: some View {
Text(title)
.font(dateFont)
.foregroundColor(Color.gray400)
.multilineTextAlignment(.center)
.lineLimit(nil)
.fixedSize(horizontal: false, vertical: true)
.frame(maxWidth: .infinity)
.accessibilityElement(children: .ignore)
.accessibilityLabel(Text(title))
}
private var dateFont: SwiftUI.Font {
if let fontName = SodaTypography.caption3.localizedFontName(locale: locale) {
return .custom(fontName, size: SodaTypography.caption3.size, relativeTo: .caption)
}
return .system(.caption, design: .default, weight: SodaTypography.caption3.weight)
}
}
@@ -1,6 +1,26 @@
import Foundation
struct UserCreatorChatDatedMessage: Identifiable {
let message: UserCreatorChatDisplayMessage
let separatorDate: Date?
var id: String { message.id }
}
enum UserCreatorChatDatePresentation {
static func rows(from messages: [UserCreatorChatDisplayMessage], calendar: Calendar, timeZone: TimeZone) -> [UserCreatorChatDatedMessage] {
var calendar = calendar
calendar.timeZone = timeZone
var previousDate: Date?
return messages.filter { $0.messageType == "TEXT" }.map { message in
let date = Date(timeIntervalSince1970: TimeInterval(message.createdAt) / 1000)
let startsDay = previousDate.map { !calendar.isDate($0, inSameDayAs: date) } ?? true
previousDate = date
return UserCreatorChatDatedMessage(message: message, separatorDate: startsDay ? date : nil)
}
}
static func title(for date: Date, locale: Locale, calendar: Calendar, timeZone: TimeZone) -> String {
var calendar = calendar
calendar.timeZone = timeZone
@@ -3,6 +3,8 @@ import UIKit
import Combine
struct UserCreatorChatRoomView: View {
@Environment(\.locale) private var locale
@Environment(\.timeZone) private var timeZone
@StateObject private var viewModel = UserCreatorChatRoomViewModel()
@State private var messageText = ""
@@ -68,7 +70,12 @@ struct UserCreatorChatRoomView: View {
}
private var messageListView: some View {
GeometryReader { geometry in
let textMessages = self.textMessages
var calendar = Calendar.current
calendar.timeZone = timeZone
let rows = UserCreatorChatDatePresentation.rows(from: textMessages, calendar: calendar, timeZone: timeZone)
return GeometryReader { geometry in
ScrollViewReader { proxy in
ScrollView(.vertical, showsIndicators: false) {
LazyVStack(spacing: SodaSpacing.s16) {
@@ -79,14 +86,26 @@ struct UserCreatorChatRoomView: View {
.padding(.vertical, SodaSpacing.s12)
}
ForEach(textMessages) { message in
UserCreatorChatTextMessageItemView(message: message)
.id(message.id)
.onAppear {
if message.id == textMessages.first?.id {
viewModel.loadMore()
}
ForEach(rows) { row in
let message = row.message
VStack(spacing: SodaSpacing.s16) {
if let date = row.separatorDate {
UserCreatorChatDateSeparatorView(title: UserCreatorChatDatePresentation.title(
for: date,
locale: locale,
calendar: calendar,
timeZone: timeZone
))
}
UserCreatorChatTextMessageItemView(message: message)
.id(message.id)
.onAppear {
if message.id == textMessages.first?.id {
viewModel.loadMore()
}
}
}
}
}
.padding(.horizontal, SodaSpacing.s24)