diff options
| author | Dustin Mierau <dustin@mierau.me> | 2024-05-02 11:52:55 -0700 |
|---|---|---|
| committer | Dustin Mierau <dustin@mierau.me> | 2024-05-02 11:52:55 -0700 |
| commit | 480500a3e7cfe1e2aa8ff261ca6f9e522c3aaf4c (patch) | |
| tree | 0a90a527da1ae9d2664277948328fba5d58de55f /Hotline | |
| parent | 91569dd83bfe1e17b8f3b31334814132707de5a1 (diff) | |
Link highlighting in chat (with basic markdown support for bold, italtics, strikethrough, monospace/code). Remove some source files from iOS build.
Diffstat (limited to 'Hotline')
| -rw-r--r-- | Hotline/Assets.xcassets/Agreement Background.colorset/Contents.json | 38 | ||||
| -rw-r--r-- | Hotline/Assets.xcassets/Link Color.colorset/Contents.json | 38 | ||||
| -rw-r--r-- | Hotline/Utility/FoundationExtensions.swift | 21 | ||||
| -rw-r--r-- | Hotline/macOS/ChatView.swift | 35 | ||||
| -rw-r--r-- | Hotline/macOS/MessageBoardView.swift | 11 |
5 files changed, 117 insertions, 26 deletions
diff --git a/Hotline/Assets.xcassets/Agreement Background.colorset/Contents.json b/Hotline/Assets.xcassets/Agreement Background.colorset/Contents.json new file mode 100644 index 0000000..7da34fe --- /dev/null +++ b/Hotline/Assets.xcassets/Agreement Background.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF5", + "green" : "0xF5", + "red" : "0xF5" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.500", + "blue" : "0x00", + "green" : "0x00", + "red" : "0x00" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Hotline/Assets.xcassets/Link Color.colorset/Contents.json b/Hotline/Assets.xcassets/Link Color.colorset/Contents.json new file mode 100644 index 0000000..4373edf --- /dev/null +++ b/Hotline/Assets.xcassets/Link Color.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF1", + "green" : "0x61", + "red" : "0x39" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xA3", + "red" : "0x8A" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Hotline/Utility/FoundationExtensions.swift b/Hotline/Utility/FoundationExtensions.swift index a1df815..f2cd39c 100644 --- a/Hotline/Utility/FoundationExtensions.swift +++ b/Hotline/Utility/FoundationExtensions.swift @@ -5,6 +5,27 @@ enum Endianness { case little } +extension String { + func isImageURL() -> Bool { + guard let url = URL(string: self) else { + return false + } + + let validImageExtensions = ["jpg", "jpeg", "png", "gif", "bmp", "tiff", "webp"] + return validImageExtensions.contains(url.pathExtension.lowercased()) + } + + func convertLinksToMarkdown() -> String { + let urlPattern = #"https?://[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?"# + + guard let regex = try? NSRegularExpression(pattern: urlPattern, options: .caseInsensitive) else { + return self + } + + return regex.stringByReplacingMatches(in: self, range: NSRange(location: 0, length: self.count), withTemplate: "[$0]($0)") + } +} + extension Array where Element == UInt8 { init(_ val: UInt8) { self.init() diff --git a/Hotline/macOS/ChatView.swift b/Hotline/macOS/ChatView.swift index 1b82e02..57814e2 100644 --- a/Hotline/macOS/ChatView.swift +++ b/Hotline/macOS/ChatView.swift @@ -37,16 +37,8 @@ struct ChatView: View { // MARK: Agreement if msg.type == .agreement { VStack(alignment: .center, spacing: 16) { - #if os(iOS) if let bannerImage = self.model.bannerImage { -// #if os(macOS) -// Image(nsImage: bannerImage) -// .resizable() -// .scaledToFit() -// .frame(maxWidth: 468.0) -// .clipShape(RoundedRectangle(cornerRadius: 3)) -// #elseif os(iOS) Image(uiImage: bannerImage) .resizable() .scaledToFit() @@ -54,24 +46,31 @@ struct ChatView: View { .clipShape(RoundedRectangle(cornerRadius: 3)) } #endif - - VStack(spacing: 0) { + HStack(spacing: 0) { + Spacer() + ScrollView(.vertical) { HStack { - Text(msg.text) + Text(LocalizedStringKey(msg.text.convertLinksToMarkdown())) .font(.system(size: 12)) .fontDesign(.monospaced) .textSelection(.enabled) + .tint(Color("Link Color")) Spacer() } .padding(16) } .scrollBounceBehavior(.basedOnSize) - .frame(maxHeight: 375) + .frame(maxWidth: 468, maxHeight: 375) + + Spacer() } - .background(Color(white: colorScheme == .light ? 0.0 : 1.0).opacity(0.05)) - .frame(maxWidth: 468.0) - .clipShape(RoundedRectangle(cornerRadius: 3)) + #if os(iOS) + .background(Color("Agreement Background")) + #elseif os(macOS) + .background(VisualEffectView(material: .titlebar, blendingMode: .withinWindow)) + #endif + .clipShape(RoundedRectangle(cornerRadius: 8)) } .frame(maxWidth: .infinity) .padding() @@ -92,16 +91,18 @@ struct ChatView: View { else { HStack(alignment: .firstTextBaseline) { if let username = msg.username { - Text("**\(username):** \(msg.text)") + Text(LocalizedStringKey("**\(username):** \(msg.text)".convertLinksToMarkdown())) .lineSpacing(4) .multilineTextAlignment(.leading) .textSelection(.enabled) + .tint(Color("Link Color")) } else { - Text(msg.text) + Text(LocalizedStringKey(msg.text.convertLinksToMarkdown())) .lineSpacing(4) .multilineTextAlignment(.leading) .textSelection(.enabled) + .tint(Color("Link Color")) } Spacer() } diff --git a/Hotline/macOS/MessageBoardView.swift b/Hotline/macOS/MessageBoardView.swift index 27b4be7..660ca05 100644 --- a/Hotline/macOS/MessageBoardView.swift +++ b/Hotline/macOS/MessageBoardView.swift @@ -13,7 +13,8 @@ struct MessageBoardView: View { ScrollView { LazyVStack(alignment: .leading) { ForEach(model.messageBoard, id: \.self) { - Text($0) + Text(LocalizedStringKey($0.convertLinksToMarkdown())) + .tint(Color("Link Color")) .lineLimit(100) .lineSpacing(4) .padding() @@ -51,9 +52,6 @@ struct MessageBoardView: View { } .padding() } - - - } .sheet(isPresented: $composerDisplayed) { TextEditor(text: $composerText) @@ -82,11 +80,6 @@ struct MessageBoardView: View { } } } -// .alert("Hello", isPresented: $showPermissionAlert) { -// Button("OK") { -// showPermissionAlert.toggle() -// } -// } message: { Text("WHAT") } .toolbar { ToolbarItem(placement:.primaryAction) { Button { |