aboutsummaryrefslogtreecommitdiff
path: root/Hotline/macOS/NewsEditorView.swift
diff options
context:
space:
mode:
authorDustin Mierau <dustin@mierau.me>2024-05-14 13:35:26 -0700
committerDustin Mierau <dustin@mierau.me>2024-05-14 13:35:26 -0700
commit87e979fb48da4a46e64544cea3e7b7d5fc32caa1 (patch)
tree4c10cdba5a88544543bf45ae454f643decf1358c /Hotline/macOS/NewsEditorView.swift
parente9fcf8c3b14e77479a6fb471bb51cd82a008147c (diff)
Newsgroup posting now works. Added reload button to news. More work on server and user icons.
Diffstat (limited to 'Hotline/macOS/NewsEditorView.swift')
-rw-r--r--Hotline/macOS/NewsEditorView.swift189
1 files changed, 122 insertions, 67 deletions
diff --git a/Hotline/macOS/NewsEditorView.swift b/Hotline/macOS/NewsEditorView.swift
index 18c4a0d..ff33281 100644
--- a/Hotline/macOS/NewsEditorView.swift
+++ b/Hotline/macOS/NewsEditorView.swift
@@ -1,5 +1,9 @@
import SwiftUI
-import UniformTypeIdentifiers
+
+private enum FocusFields {
+ case title
+ case body
+}
struct NewsEditorView: View {
@Environment(\.controlActiveState) private var controlActiveState
@@ -7,94 +11,145 @@ struct NewsEditorView: View {
@Environment(\.dismiss) private var dismiss
@Environment(Hotline.self) private var model: Hotline
-// @Binding var article: NewsArticle?
+ let editorTitle: String
+ let isReply: Bool
+ let path: [String]
+ let parentID: UInt32
+
@State var title: String = ""
- @State var text: String = ""
+ @State private var text: String = ""
+ @State private var sending: Bool = false
+
+ @FocusState private var focusedField: FocusFields?
+
+ func sendArticle() async -> Bool {
+ sending = true
+
+ let success = await model.postNewsArticle(title: title, body: text, at: path, parentID: parentID)
+ if success {
+ await model.getNewsList(at: path)
+ }
+
+ sending = false
+
+ return success
+ }
var body: some View {
- NavigationStack {
- VStack(alignment: .leading, spacing: 0) {
- HStack {
- Button {
- dismiss()
- } label: {
- Image(systemName: "xmark.circle.fill")
- .resizable()
- .scaledToFit()
- }
- .buttonStyle(.plain)
- .frame(width: 16, height: 16)
- .padding()
-
- Spacer()
-
+ 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()
+
+ if !isReply {
+ Image("News Category")
+ .resizable()
+ .scaledToFit()
+ .frame(width: 16, height: 16)
+ .padding(.trailing, 6)
+ }
+
+ Text(editorTitle)
+ .fontWeight(.semibold)
+ .lineLimit(1)
+ .truncationMode(.middle)
+
+ Spacer()
+
+ if sending {
+ ProgressView()
+ .controlSize(.small)
+ .frame(width: 22, height: 22)
+ }
+ else {
Button {
+ Task {
+ if await sendArticle() {
+ dismiss()
+ }
+ }
} label: {
- Image(systemName: "paperplane")
+ Image(systemName: "arrow.up.circle.fill")
.resizable()
+ .renderingMode(.template)
.scaledToFit()
+ .foregroundColor((title.isEmpty || text.isEmpty) ? .secondary : .accentColor)
}
.buttonStyle(.plain)
- .frame(width: 16, height: 16)
- .padding()
+ .frame(width: 22, height: 22)
+ .help("Post to Newsgroup")
+ .disabled(title.isEmpty || text.isEmpty)
}
+ }
+ .frame(maxWidth: .infinity)
+ .padding([.leading, .top, .trailing])
+
+ TextField("Title", text: $title, axis: .vertical)
+ .textFieldStyle(.plain)
+ .lineLimit(3)
+ .padding()
+ .focusEffectDisabled()
+ .fontWeight(.semibold)
.frame(maxWidth: .infinity)
- TextField("Title", text: $title, axis: .vertical)
- .textFieldStyle(.plain)
+ .border(Color.pink, width: 0)
+ .background(.tertiary.opacity(0.2))
+ .clipShape(RoundedRectangle(cornerRadius: 8))
+ .padding()
+ .focused($focusedField, equals: .title)
+
+ 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()
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
+ .clipped()
+ .focused($focusedField, equals: .body)
+
+ HStack(alignment: .center) {
+ Spacer()
+
+ Text(String("**bold** _italics_ [link name](url) ![image name](url)"))
+ .foregroundStyle(.secondary)
+ .font(.caption)
+ .fontDesign(.monospaced)
+ .lineLimit(1)
+ .truncationMode(.middle)
.padding()
- .focusEffectDisabled()
- .font(.title)
- .frame(maxWidth: .infinity)
- .border(Color.pink, width: 0)
- Divider()
- TextEditor(text: $text)
- .textEditorStyle(.plain)
- .font(.system(size: 14))
- .lineSpacing(3)
- .padding(16)
- .contentMargins(.top, -16.0, for: .scrollIndicators)
- .contentMargins(.bottom, -16.0, for: .scrollIndicators)
- .contentMargins(.trailing, -16.0, for: .scrollIndicators)
- .scrollClipDisabled()
- .frame(maxWidth: .infinity, maxHeight: .infinity)
+
+ Spacer()
}
+ .frame(maxWidth: .infinity)
+ .background(.tertiary.opacity(0.15))
}
.frame(minWidth: 300, idealWidth: 450, maxWidth: .infinity, minHeight: 300, idealHeight: 500, maxHeight: .infinity)
.background(Color(nsColor: .textBackgroundColor))
.presentationCompactAdaptation(.sheet)
.toolbarTitleDisplayMode(.inlineLarge)
-// .toolbar {
-// ToolbarItem(placement: .navigation) {
-// Button("Post", action: {})
-// }
-// ToolbarItem(placement: .automatic) {
-// Button("Delete", action: {
-// dismiss()
-// })
-// }
-// }
- .task {
-// if let info = info {
-// preview = FilePreview(info: info)
-// preview?.download()
-// }
- }
.onAppear {
-// if info == nil {
-// Task {
-// dismiss()
-// }
-// return
-// }
+ if !title.isEmpty {
+ focusedField = .body
+ }
}
.onDisappear {
-// preview?.cancel()
dismiss()
}
-// .onChange(of: preview?.state) {
-// if preview?.state == .failed {
-// dismiss()
-// }
-// }
}
}