Extract TextMessageView into a separate file (#759)

* Extract `TextMessageView` into a separate file

* Remove dead code
This commit is contained in:
Islam
2025-10-06 17:42:06 +02:00
committed by GitHub
parent 8c368233c4
commit 81c90b2924
4 changed files with 166 additions and 61 deletions
+1 -61
View File
@@ -308,54 +308,7 @@ struct ContentView: View {
.fixedSize(horizontal: false, vertical: true)
.frame(maxWidth: .infinity, alignment: .leading)
} else {
// Regular messages with natural text wrapping
VStack(alignment: .leading, spacing: 0) {
// Precompute heavy token scans once per row
let cashuLinks = message.content.extractCashuLinks()
let lightningLinks = message.content.extractLightningLinks()
HStack(alignment: .top, spacing: 0) {
let isLong = (message.content.count > TransportConfig.uiLongMessageLengthThreshold || message.content.hasVeryLongToken(threshold: TransportConfig.uiVeryLongTokenThreshold)) && cashuLinks.isEmpty
let isExpanded = expandedMessageIDs.contains(message.id)
Text(viewModel.formatMessageAsText(message, colorScheme: colorScheme))
.fixedSize(horizontal: false, vertical: true)
.lineLimit(isLong && !isExpanded ? TransportConfig.uiLongMessageLineLimit : nil)
.frame(maxWidth: .infinity, alignment: .leading)
// Delivery status indicator for private messages
if message.isPrivate && message.sender == viewModel.nickname,
let status = message.deliveryStatus {
DeliveryStatusView(status: status)
.padding(.leading, 4)
}
}
// Expand/Collapse for very long messages
if (message.content.count > TransportConfig.uiLongMessageLengthThreshold || message.content.hasVeryLongToken(threshold: TransportConfig.uiVeryLongTokenThreshold)) && cashuLinks.isEmpty {
let isExpanded = expandedMessageIDs.contains(message.id)
let labelKey = isExpanded ? LocalizedStringKey("content.message.show_less") : LocalizedStringKey("content.message.show_more")
Button(labelKey) {
if isExpanded { expandedMessageIDs.remove(message.id) }
else { expandedMessageIDs.insert(message.id) }
}
.font(.bitchatSystem(size: 11, weight: .medium, design: .monospaced))
.foregroundColor(Color.blue)
.padding(.top, 4)
}
// Render payment chips (Lightning / Cashu) with rounded background
if !lightningLinks.isEmpty || !cashuLinks.isEmpty {
HStack(spacing: 8) {
ForEach(lightningLinks, id: \.self) { link in
PaymentChipView(paymentType: .lightning(link))
}
ForEach(cashuLinks, id: \.self) { link in
PaymentChipView(paymentType: .cashu(link))
}
}
.padding(.top, 6)
.padding(.leading, 2)
}
}
TextMessageView(message: message, expandedMessageIDs: $expandedMessageIDs)
}
}
.id(item.uiID)
@@ -1038,19 +991,6 @@ struct ContentView: View {
.foregroundColor(textColor)
}
}
// Split a name into base and a '#abcd' suffix if present
private func splitNameSuffix(_ name: String) -> (base: String, suffix: String) {
guard name.count >= 5 else { return (name, "") }
let suffix = String(name.suffix(5))
if suffix.first == "#", suffix.dropFirst().allSatisfy({ c in
("0"..."9").contains(String(c)) || ("a"..."f").contains(String(c)) || ("A"..."F").contains(String(c))
}) {
let base = String(name.dropLast(5))
return (base, suffix)
}
return (name, "")
}
// Compute channel-aware people count and color for toolbar (cross-platform)
private func channelPeopleCountAndColor() -> (Int, Color) {