simplify timestamp logic; remove shape

This commit is contained in:
Levitating Pineapple
2024-08-23 17:15:02 +03:00
parent beefb1ba12
commit 2a20afeda6
3 changed files with 20 additions and 96 deletions
+3 -21
View File
@@ -719,39 +719,21 @@ struct ChatView: View {
struct TimeSeparation {
let isTimestampShown: Bool
let isDateShown: Bool // TODO: Implement UI to show date
let isGapLarge: Bool
init(for chatItem: ChatItem, at index: Int?) {
let im = ItemsModel.shared
if let index, index > 0 && !im.reversedChatItems.isEmpty {
let nextItem = im.reversedChatItems[index - 1]
isTimestampShown = nextItem.chatDir != chatItem.chatDir ||
Self.componentsToMinute(nextItem.meta.createdAt) != Self.componentsToMinute(chatItem.meta.createdAt)
isDateShown =
Self.componentsToDate(nextItem.meta.createdAt) != Self.componentsToDate(chatItem.meta.createdAt)
isGapLarge = nextItem.chatDir != chatItem.chatDir ||
nextItem.meta.createdAt.timeIntervalSince(chatItem.meta.createdAt) > 30
isTimestampShown = isGapLarge ||
formatTimestampText(chatItem.meta.createdAt) != formatTimestampText(nextItem.meta.createdAt)
} else {
isTimestampShown = true
isDateShown = false
isGapLarge = true
}
}
private static func componentsToMinute(_ date: Date) -> DateComponents {
Calendar.current.dateComponents(
[.year, .month, .day, .hour, .minute],
from: date
)
}
private static func componentsToDate(_ date: Date) -> DateComponents {
Calendar.current.dateComponents(
[.year, .month, .day],
from: date
)
}
}
var body: some View {
@@ -934,7 +916,7 @@ struct ChatView: View {
allowMenu: $allowMenu
)
.environment(\.showTimestamp, timeSeparation.isTimestampShown)
.modifier(ChatItemClipped(ci, showsTail: timeSeparation.isGapLarge))
.modifier(ChatItemClipped(ci))
.contextMenu { menu(ci, range, live: composeState.liveMessage != nil) }
.accessibilityLabel("")
if ci.content.msgContent != nil && (ci.meta.itemDeleted == nil || revealed) && ci.reactions.count > 0 {
@@ -9,65 +9,54 @@
import SwiftUI
import SimpleXChat
/// Modifier, which provides clipping mask for ``ChatItemWithMenu`` view
/// Modifier, which provides clipping mask for ``ChatItemWithMenu`` view
/// and it's previews: (drag interaction, context menu, etc.)
/// Supports [Dynamic Type](https://developer.apple.com/documentation/uikit/uifont/scaling_fonts_automatically)
/// by retaining pill shape, even when ``ChatItem``'s height is less that twice its corner radius
struct ChatItemClipped: ViewModifier {
enum TailEdge {
case leading
case trailing
}
struct ClipShape: Shape {
let maxCornerRadius: Double
var tailEdge: TailEdge?
func path(in rect: CGRect) -> Path {
.roundedRectangle(
in: rect,
radius: maxCornerRadius,
bottomLeading: tailEdge == .leading ? 0 : nil,
bottomTrailing: tailEdge == .trailing ? 0 : nil
Path(
roundedRect: rect,
cornerRadius: min((rect.height / 2), maxCornerRadius),
style: .circular
)
}
}
init() {
clipShape = ClipShape(
maxCornerRadius: 18
)
}
init(_ chatItem: ChatItem, showsTail: Bool) {
init(_ chatItem: ChatItem) {
clipShape = ClipShape(
maxCornerRadius: {
switch chatItem.content {
case
.sndMsgContent,
case
.sndMsgContent,
.rcvMsgContent,
.rcvDecryptionError,
.rcvGroupInvitation,
.sndGroupInvitation,
.sndDeleted,
.sndDeleted,
.rcvDeleted,
.rcvIntegrityError,
.sndModerated,
.rcvModerated,
.sndModerated,
.rcvModerated,
.rcvBlocked,
.invalidJSON: 18
default: 8
}
}(),
tailEdge: showsTail
? chatItem.chatDir.sent ? .trailing : .leading
: nil
}()
)
}
private let clipShape: ClipShape
func body(content: Content) -> some View {
content
.contentShape(.dragPreview, clipShape)
@@ -75,50 +64,3 @@ struct ChatItemClipped: ViewModifier {
.clipShape(clipShape)
}
}
extension Path {
static func roundedRectangle(
in rect: CGRect,
radius: CGFloat,
topLeading: CGFloat? = nil,
bottomLeading: CGFloat? = nil,
bottomTrailing: CGFloat? = nil,
topTrailing: CGFloat? = nil
) -> Path {
let maxRadius = min(rect.width, rect.height) / 2
let tl = min(maxRadius, topLeading ?? radius)
let bl = min(maxRadius, bottomLeading ?? radius)
let bt = min(maxRadius, bottomTrailing ?? radius)
let tt = min(maxRadius, topLeading ?? radius)
var path = Path()
path.addArc(
center: CGPoint(x: tl, y: tl),
radius: tl,
startAngle: .degrees(270),
endAngle: .degrees(180),
clockwise: true
)
path.addArc(
center: CGPoint(x: bl, y: rect.height - bl),
radius: bl,
startAngle: .degrees(180),
endAngle: .degrees(90),
clockwise: true
)
path.addArc(
center: CGPoint(x: rect.width - bt, y: rect.height - bt),
radius: bt,
startAngle: .degrees(90),
endAngle: .degrees(0),
clockwise: true
)
path.addArc(
center: CGPoint(x: rect.width - tt, y: tt),
radius: tt,
startAngle: .degrees(0),
endAngle: .degrees(270),
clockwise: true
)
return path
}
}
+1 -1
View File
@@ -2762,7 +2762,7 @@ let msgTimeFormat = Date.FormatStyle.dateTime.hour().minute()
let msgDateFormat = Date.FormatStyle.dateTime.day(.twoDigits).month(.twoDigits)
public func formatTimestampText(_ date: Date) -> Text {
return Text(date, format: recent(date) ? msgTimeFormat : msgDateFormat)
Text(verbatim: date.formatted(recent(date) ? msgTimeFormat : msgDateFormat))
}
private func recent(_ date: Date) -> Bool {