aboutsummaryrefslogtreecommitdiff
path: root/Hotline/macOS
diff options
context:
space:
mode:
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)
}