Fix URL detection and message spacing

- Add URL detection to message formatting with blue color and underline
- Replace List with ScrollView for precise spacing control
- Use minimal vertical padding (1px) between messages
- Remove LazyLinkPreviewView, use LinkPreviewView directly
- URLs now appear highlighted in message text AND show preview below
This commit is contained in:
jack
2025-07-24 12:53:55 +02:00
parent b480a4836c
commit c08fe38c72
2 changed files with 36 additions and 54 deletions
+26 -54
View File
@@ -163,21 +163,22 @@ struct ContentView: View {
private func messagesView(privatePeer: String?) -> some View {
ScrollViewReader { proxy in
List {
let messages: [BitchatMessage] = {
if let privatePeer = privatePeer {
let msgs = viewModel.getPrivateChatMessages(for: privatePeer)
return msgs
} else {
return viewModel.messages
}
}()
// Implement windowing - show last 100 messages for performance
let windowedMessages = messages.suffix(100)
ForEach(Array(windowedMessages), id: \.id) { message in
VStack(alignment: .leading, spacing: 2) {
ScrollView {
VStack(alignment: .leading, spacing: 0) {
let messages: [BitchatMessage] = {
if let privatePeer = privatePeer {
let msgs = viewModel.getPrivateChatMessages(for: privatePeer)
return msgs
} else {
return viewModel.messages
}
}()
// Implement windowing - show last 100 messages for performance
let windowedMessages = messages.suffix(100)
ForEach(Array(windowedMessages), id: \.id) { message in
VStack(alignment: .leading, spacing: 0) {
// Check if current user is mentioned
let _ = message.mentions?.contains(viewModel.nickname) ?? false
@@ -207,12 +208,12 @@ struct ContentView: View {
// Check for plain URLs
let urls = message.content.extractURLs()
ForEach(Array(urls.prefix(3).enumerated()), id: \.offset) { index, urlInfo in
LazyLinkPreviewView(
url: urlInfo.url,
title: nil,
id: "\(message.id)-\(urlInfo.url.absoluteString)"
)
if !urls.isEmpty {
ForEach(Array(urls.prefix(3).enumerated()), id: \.offset) { index, urlInfo in
LinkPreviewView(url: urlInfo.url, title: nil)
.padding(.top, 2)
.id("\(message.id)-\(urlInfo.url.absoluteString)")
}
}
}
}
@@ -227,13 +228,12 @@ struct ContentView: View {
showMessageActions = true
}
}
.listRowInsets(EdgeInsets(top: 0, leading: 12, bottom: 0, trailing: 12))
.listRowSeparator(.hidden)
.listRowBackground(backgroundColor)
.padding(.horizontal, 12)
.padding(.vertical, 1)
}
}
.padding(.vertical, 4)
}
.listStyle(.plain)
.scrollContentBackground(.hidden)
.background(backgroundColor)
.onTapGesture(count: 3) {
// Triple-tap to clear current chat
@@ -938,34 +938,6 @@ struct MessageContentView: View {
}
}
// Lazy loading wrapper for LinkPreviewView
struct LazyLinkPreviewView: View {
let url: URL
let title: String?
let id: String
@State private var shouldLoad = false
var body: some View {
Group {
if shouldLoad {
LinkPreviewView(url: url, title: title)
.padding(.top, 2)
.id(id)
}
}
.onAppear {
// Delay loading to improve scroll performance
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
shouldLoad = true
}
}
.onDisappear {
shouldLoad = false
}
}
}
// Delivery status indicator view
struct DeliveryStatusView: View {
let status: DeliveryStatus