diff options
Diffstat (limited to 'Hotline/macOS/ChatView.swift')
| -rw-r--r-- | Hotline/macOS/ChatView.swift | 161 |
1 files changed, 81 insertions, 80 deletions
diff --git a/Hotline/macOS/ChatView.swift b/Hotline/macOS/ChatView.swift index cd84369..33a43b1 100644 --- a/Hotline/macOS/ChatView.swift +++ b/Hotline/macOS/ChatView.swift @@ -8,34 +8,34 @@ struct ChatView: View { @Environment(Hotline.self) private var model: Hotline @Environment(\.colorScheme) var colorScheme @Environment(\.dismiss) var dismiss - + @State var input: String = "" @State private var scrollPos: Int? @State private var contentHeight: CGFloat = 0 - + @FocusState private var focusedField: FocusedField? - + @Namespace var bottomID - + @State private var showingExporter: Bool = false - + @State private var chatDocument: TextFile = TextFile() - + var body: some View { NavigationStack { ScrollViewReader { reader in VStack(alignment: .leading, spacing: 0) { - + // MARK: Scroll View GeometryReader { gm in ScrollView(.vertical) { LazyVStack(alignment: .leading) { - + ForEach(model.chat) { msg in - + // MARK: Agreement if msg.type == .agreement { -#if os(iOS) + #if os(iOS) if let bannerImage = self.model.bannerImage { Image(uiImage: bannerImage) .resizable() @@ -43,9 +43,9 @@ struct ChatView: View { .frame(maxWidth: 468.0) .clipShape(RoundedRectangle(cornerRadius: 3)) } -#endif + #endif ServerAgreementView(text: msg.text) - .padding(.bottom, 16) + .padding(.bottom, 16) } // MARK: Server Message else if msg.type == .server { @@ -64,50 +64,51 @@ struct ChatView: View { Spacer() } .padding(EdgeInsets(top: 2, leading: 0, bottom: 2, trailing: 0)) - } - else { + } else { HStack(alignment: .firstTextBaseline) { if let username = msg.username { -// if msg.text.isImageURL() { -// HStack(alignment: .bottom) { -// Text("**\(username):** ") -// -// let imageURL = URL(string: msg.text)! -// AsyncImage(url: imageURL) { phase in -// switch phase { -// case .failure: -// Text(LocalizedStringKey(msg.text.convertLinksToMarkdown())) -// .lineSpacing(4) -// .multilineTextAlignment(.leading) -// .textSelection(.enabled) -// .tint(Color("Link Color")) -// case .success(let img): -// Link(destination: imageURL) { -// img -// .resizable() -// .scaledToFit() -// .frame(maxWidth: 250, maxHeight: 150, alignment: .leading) -// .onAppear { -// reader.scrollTo(bottomID, anchor: .bottom) -// } -// } -// default: -// ProgressView().controlSize(.small) -// } -// } -// -// Spacer() -// } -// } -// else { - Text(LocalizedStringKey("**\(username):** \(msg.text)".convertingLinksToMarkdown())) - .lineSpacing(4) - .multilineTextAlignment(.leading) - .textSelection(.enabled) - .tint(Color("Link Color")) -// } - } - else { + // if msg.text.isImageURL() { + // HStack(alignment: .bottom) { + // Text("**\(username):** ") + // + // let imageURL = URL(string: msg.text)! + // AsyncImage(url: imageURL) { phase in + // switch phase { + // case .failure: + // Text(LocalizedStringKey(msg.text.convertLinksToMarkdown())) + // .lineSpacing(4) + // .multilineTextAlignment(.leading) + // .textSelection(.enabled) + // .tint(Color("Link Color")) + // case .success(let img): + // Link(destination: imageURL) { + // img + // .resizable() + // .scaledToFit() + // .frame(maxWidth: 250, maxHeight: 150, alignment: .leading) + // .onAppear { + // reader.scrollTo(bottomID, anchor: .bottom) + // } + // } + // default: + // ProgressView().controlSize(.small) + // } + // } + // + // Spacer() + // } + // } + // else { + Text( + LocalizedStringKey( + "**\(username):** \(msg.text)".convertingLinksToMarkdown()) + ) + .lineSpacing(4) + .multilineTextAlignment(.leading) + .textSelection(.enabled) + .tint(Color("Link Color")) + // } + } else { Text(msg.text) .lineSpacing(4) .multilineTextAlignment(.leading) @@ -137,10 +138,10 @@ struct ChatView: View { reader.scrollTo(bottomID, anchor: .bottom) } } - + // MARK: Input Divider Divider() - + // MARK: Input Bar HStack(alignment: .lastTextBaseline, spacing: 0) { TextField("", text: $input, axis: .vertical) @@ -178,59 +179,59 @@ struct ChatView: View { } } .background(Color(nsColor: .textBackgroundColor)) -// .toolbar { -// ToolbarItem(placement: .primaryAction) { -// Button { -// if prepareChatDocument() { -// showingExporter = true -// } -// } label: { -// Image(systemName: "square.and.arrow.up") -// }.help("Save Chat...") -// } -// } - .fileExporter(isPresented: $showingExporter, document: self.chatDocument, contentType: .utf8PlainText, defaultFilename: "\(self.model.serverTitle) Chat.txt") { result in + // .toolbar { + // ToolbarItem(placement: .primaryAction) { + // Button { + // if prepareChatDocument() { + // showingExporter = true + // } + // } label: { + // Image(systemName: "square.and.arrow.up") + // }.help("Save Chat...") + // } + // } + .fileExporter( + isPresented: $showingExporter, document: self.chatDocument, contentType: .utf8PlainText, + defaultFilename: "\(self.model.serverTitle) Chat.txt" + ) { result in switch result { case .success(let url): print("Saved to \(url)") - + case .failure(let error): print(error.localizedDescription) } self.chatDocument.text = "" } } - + private func prepareChatDocument() -> Bool { var text: String = String() - + self.chatDocument.text = "" for msg in model.chat { if msg.type == .agreement { text.append(msg.text) text.append("\n\n") - } - else if msg.type == .message { + } else if msg.type == .message { if let username = msg.username { text.append("\(username): \(msg.text)") - } - else { + } else { text.append(msg.text) } text.append("\n") - } - else if msg.type == .status { + } else if msg.type == .status { text.append(msg.text) text.append("\n") } } - + if text.isEmpty { return false } - + self.chatDocument.text = text - + return true } } |