feat(chat): 대화 날짜 구분선을 연결한다
This commit is contained in:
+26
@@ -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)
|
||||
}
|
||||
}
|
||||
+20
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user