aboutsummaryrefslogtreecommitdiff
path: root/Hotline/macOS
diff options
context:
space:
mode:
authorDustin Mierau <dustin@mierau.me>2024-05-22 11:40:53 -0700
committerDustin Mierau <dustin@mierau.me>2024-05-22 11:40:53 -0700
commitc7a2970c7f17a1b19a76d9cb6addda8fb877a63a (patch)
tree20f52495dd9e599d7b3942ba8357c79bc394822d /Hotline/macOS
parent39255f49250e3b0ccbd42661614a7c8a3e0d4fb7 (diff)
Redesign of Message Board post sheet. Tweaks to NewsEditor. Disable smart quotes in message board and news editor text view. Hide news section on older servers.
Diffstat (limited to 'Hotline/macOS')
-rw-r--r--Hotline/macOS/MessageBoardEditorView.swift117
-rw-r--r--Hotline/macOS/MessageBoardView.swift58
-rw-r--r--Hotline/macOS/NewsEditorView.swift18
-rw-r--r--Hotline/macOS/NewsView.swift2
-rw-r--r--Hotline/macOS/ServerView.swift9
5 files changed, 165 insertions, 39 deletions
diff --git a/Hotline/macOS/MessageBoardEditorView.swift b/Hotline/macOS/MessageBoardEditorView.swift
new file mode 100644
index 0000000..1b49f4e
--- /dev/null
+++ b/Hotline/macOS/MessageBoardEditorView.swift
@@ -0,0 +1,117 @@
+import SwiftUI
+
+private enum FocusFields {
+ case body
+}
+
+struct MessageBoardEditorView: View {
+ @Environment(\.controlActiveState) private var controlActiveState
+ @Environment(\.colorScheme) private var colorScheme
+ @Environment(\.dismiss) private var dismiss
+ @Environment(Hotline.self) private var model: Hotline
+
+ @State private var text: String = ""
+ @State private var sending: Bool = false
+
+ @FocusState private var focusedField: FocusFields?
+
+ func sendPost() async {
+ sending = true
+
+ let cleanedText = text.trimmingCharacters(in: .whitespacesAndNewlines)
+
+ await model.postToMessageBoard(text: cleanedText)
+ let _ = await model.getMessageBoard()
+
+// let success = await model.postNewsArticle(title: title, body: text, at: path, parentID: parentID)
+// if success {
+// await model.getNewsList(at: path)
+// }
+
+ sending = false
+ }
+
+ var body: some View {
+ VStack(alignment: .leading, spacing: 0) {
+ HStack(alignment: .center, spacing: 0) {
+ Button {
+ dismiss()
+ } label: {
+ Image(systemName: "xmark")
+ .resizable()
+ .scaledToFit()
+ .frame(width: 14, height: 14)
+ .opacity(0.5)
+ }
+ .buttonStyle(.plain)
+ .frame(width: 16, height: 16)
+
+ Spacer()
+
+ Image("Message Board Post")
+ .resizable()
+ .scaledToFit()
+ .frame(width: 16, height: 16)
+ .padding(.trailing, 6)
+
+ Text("New Post")
+ .fontWeight(.semibold)
+ .lineLimit(1)
+ .truncationMode(.middle)
+
+ Spacer()
+
+ if sending {
+ ProgressView()
+ .controlSize(.small)
+ .frame(width: 22, height: 22)
+ }
+ else {
+ Button {
+ sending = true
+ model.postToMessageBoard(text: text)
+ Task {
+ let _ = await model.getMessageBoard()
+ Task { @MainActor in
+ sending = false
+ dismiss()
+ }
+ }
+ } label: {
+ Image(systemName: "arrow.up.circle.fill")
+ .resizable()
+ .renderingMode(.template)
+ .scaledToFit()
+ .foregroundColor(text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ? .secondary : .accentColor)
+ }
+ .buttonStyle(.plain)
+ .frame(width: 22, height: 22)
+ .help("Post to Message Board")
+ .disabled(text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
+ }
+ }
+ .frame(maxWidth: .infinity)
+ .padding()
+
+ Divider()
+
+ BetterTextEditor(text: $text)
+ .betterEditorFont(NSFont.systemFont(ofSize: 14.0))
+ .betterEditorAutomaticSpellingCorrection(true)
+ .betterEditorTextInset(.init(width: 16, height: 18))
+ .lineSpacing(20)
+ .background(Color(nsColor: .textBackgroundColor))
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
+ .focused($focusedField, equals: .body)
+ }
+ .frame(minWidth: 300, idealWidth: 450, maxWidth: .infinity, minHeight: 300, idealHeight: 500, maxHeight: .infinity)
+ .background(Color(nsColor: .textBackgroundColor))
+ .presentationCompactAdaptation(.sheet)
+ .onAppear {
+ focusedField = .body
+ }
+ .onDisappear {
+ dismiss()
+ }
+ }
+}
diff --git a/Hotline/macOS/MessageBoardView.swift b/Hotline/macOS/MessageBoardView.swift
index 2bd3713..ba9968b 100644
--- a/Hotline/macOS/MessageBoardView.swift
+++ b/Hotline/macOS/MessageBoardView.swift
@@ -3,9 +3,8 @@ import SwiftUI
struct MessageBoardView: View {
@Environment(Hotline.self) private var model: Hotline
- @State private var initialLoadComplete = false
- @State private var composerDisplayed = false
- @State private var composerText = ""
+ @State private var composerDisplayed: Bool = false
+ @State private var composerText: String = ""
var body: some View {
NavigationStack {
@@ -54,31 +53,36 @@ struct MessageBoardView: View {
}
}
.sheet(isPresented: $composerDisplayed) {
- TextEditor(text: $composerText)
- .padding()
- .font(.system(size: 13))
- .lineSpacing(4)
- .background(Color(nsColor: .textBackgroundColor))
+ MessageBoardEditorView()
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
.frame(idealWidth: 450, idealHeight: 350)
- .toolbar {
- ToolbarItem(placement: .cancellationAction) {
- Button("Cancel") {
- composerDisplayed.toggle()
- }
- }
-
- ToolbarItem(placement: .primaryAction) {
- Button("Post") {
- composerDisplayed.toggle()
- let text = composerText
- composerText = ""
- model.postToMessageBoard(text: text)
- Task {
- await model.getMessageBoard()
- }
- }
- }
- }
+// RichTextEditor(text: $composerText)
+// .richEditorFont(NSFont.systemFont(ofSize: 16.0))
+// .richEditorAutomaticDashSubstitution(false)
+// .richEditorAutomaticQuoteSubstitution(false)
+// .richEditorAutomaticSpellingCorrection(false)
+// .background(Color(nsColor: .textBackgroundColor))
+// .frame(maxWidth: .infinity, maxHeight: .infinity)
+// .frame(idealWidth: 450, idealHeight: 350)
+// .toolbar {
+// ToolbarItem(placement: .cancellationAction) {
+// Button("Cancel") {
+// composerDisplayed.toggle()
+// }
+// }
+//
+// ToolbarItem(placement: .primaryAction) {
+// Button("Post") {
+// composerDisplayed.toggle()
+// let text = composerText
+// composerText = ""
+// model.postToMessageBoard(text: text)
+// Task {
+// await model.getMessageBoard()
+// }
+// }
+// }
+// }
}
.toolbar {
ToolbarItem(placement:.primaryAction) {
diff --git a/Hotline/macOS/NewsEditorView.swift b/Hotline/macOS/NewsEditorView.swift
index ff33281..a6f72ec 100644
--- a/Hotline/macOS/NewsEditorView.swift
+++ b/Hotline/macOS/NewsEditorView.swift
@@ -110,17 +110,12 @@ struct NewsEditorView: View {
Divider()
- TextEditor(text: $text)
- .textEditorStyle(.plain)
- .font(.system(size: 14, design: .monospaced))
- .lineSpacing(3)
- .padding(16)
- .contentMargins(.top, -16.0, for: .scrollIndicators)
- .contentMargins(.bottom, -16.0, for: .scrollIndicators)
- .contentMargins(.trailing, -16.0, for: .scrollIndicators)
- .scrollClipDisabled()
+ BetterTextEditor(text: $text)
+ .betterEditorFont(NSFont.monospacedSystemFont(ofSize: 14.0, weight: .regular))
+ .betterEditorAutomaticSpellingCorrection(true)
+ .betterEditorTextInset(.init(width: 16, height: 18))
+ .background(Color(nsColor: .textBackgroundColor))
.frame(maxWidth: .infinity, maxHeight: .infinity)
- .clipped()
.focused($focusedField, equals: .body)
HStack(alignment: .center) {
@@ -147,6 +142,9 @@ struct NewsEditorView: View {
if !title.isEmpty {
focusedField = .body
}
+ else {
+ focusedField = .title
+ }
}
.onDisappear {
dismiss()
diff --git a/Hotline/macOS/NewsView.swift b/Hotline/macOS/NewsView.swift
index 8e10b19..4469585 100644
--- a/Hotline/macOS/NewsView.swift
+++ b/Hotline/macOS/NewsView.swift
@@ -58,7 +58,7 @@ struct NewsView: View {
)
.fraction(splitFraction)
.constraints(minPFraction: 0.1, minSFraction: 0.3)
-// .hide(splitHidden)
+ .hide(splitHidden)
.styling(color: colorScheme == .dark ? .black : Splitter.defaultColor, inset: 0, visibleThickness: 0.5, invisibleThickness: 5, hideSplitter: true)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(nsColor: .textBackgroundColor))
diff --git a/Hotline/macOS/ServerView.swift b/Hotline/macOS/ServerView.swift
index e3f0596..e342f73 100644
--- a/Hotline/macOS/ServerView.swift
+++ b/Hotline/macOS/ServerView.swift
@@ -151,6 +151,12 @@ struct ServerView: View {
ServerMenuItem(type: .files, name: "Files", image: "folder"),
]
+ static var classicMenuItems: [ServerMenuItem] = [
+ ServerMenuItem(type: .chat, name: "Chat", image: "bubble"),
+ ServerMenuItem(type: .board, name: "Board", image: "pin"),
+ ServerMenuItem(type: .files, name: "Files", image: "folder"),
+ ]
+
enum FocusFields {
case address
case login
@@ -347,7 +353,8 @@ struct ServerView: View {
var navigationList: some View {
List(selection: $state.selection) {
- ForEach(ServerView.menuItems) { menuItem in
+ // Don't show news on older servers.
+ ForEach(model.serverVersion < 151 ? ServerView.classicMenuItems : ServerView.menuItems) { menuItem in
if menuItem.type == .chat {
ListItemView(icon: menuItem.image, title: menuItem.name, unread: model.unreadPublicChat).tag(menuItem.type)
}