diff options
Diffstat (limited to 'Hotline/macOS/NewsView.swift')
| -rw-r--r-- | Hotline/macOS/NewsView.swift | 96 |
1 files changed, 52 insertions, 44 deletions
diff --git a/Hotline/macOS/NewsView.swift b/Hotline/macOS/NewsView.swift index 91bf2fe..d710c62 100644 --- a/Hotline/macOS/NewsView.swift +++ b/Hotline/macOS/NewsView.swift @@ -1,20 +1,21 @@ -import SwiftUI import MarkdownUI import SplitView +import SwiftUI struct NewsView: View { @Environment(Hotline.self) private var model: Hotline @Environment(\.openWindow) private var openWindow @Environment(\.colorScheme) private var colorScheme - + @State private var selection: NewsInfo? @State private var articleText: String? @State private var splitHidden = SideHolder(.bottom) - @State private var splitFraction = FractionHolder.usingUserDefaults(0.25, key: "News Split Fraction") + @State private var splitFraction = FractionHolder.usingUserDefaults( + 0.25, key: "News Split Fraction") @State private var editorOpen: Bool = false @State private var replyOpen: Bool = false @State private var loading: Bool = false - + var body: some View { Group { if model.serverVersion < 151 { @@ -28,15 +29,13 @@ struct NewsView: View { .font(.system(size: 13)) } .padding() - } - else { + } else { NavigationStack { VSplit( top: { if !model.newsLoaded { loadingIndicator - } - else if model.news.isEmpty { + } else if model.news.isEmpty { ZStack(alignment: .center) { Text("No News") .font(.title) @@ -45,8 +44,7 @@ struct NewsView: View { .padding() } .frame(maxWidth: .infinity) - } - else { + } else { newsBrowser } }, @@ -57,7 +55,10 @@ struct NewsView: View { .fraction(splitFraction) .constraints(minPFraction: 0.1, minSFraction: 0.3) .hide(splitHidden) - .styling(color: colorScheme == .dark ? .black : Splitter.defaultColor, inset: 0, visibleThickness: 0.5, invisibleThickness: 5, hideSplitter: true) + .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)) } @@ -75,21 +76,24 @@ struct NewsView: View { if let selection = selection { switch selection.type { case .article, .category: - NewsEditorView(editorTitle: selection.path.last ?? "New Post", isReply: false, path: selection.path, parentID: 0) + NewsEditorView( + editorTitle: selection.path.last ?? "New Post", isReply: false, path: selection.path, + parentID: 0) default: EmptyView() } - } - else { + } else { EmptyView() } } .sheet(isPresented: $replyOpen) { } content: { if let selection = selection, selection.type == .article { - NewsEditorView(editorTitle: "Reply to \(selection.articleUsername ?? "Post")", isReply: true, path: selection.path, parentID: UInt32(selection.articleID!), title: selection.name.replyToString()) - } - else { + NewsEditorView( + editorTitle: "Reply to \(selection.articleUsername ?? "Post")", isReply: true, + path: selection.path, parentID: UInt32(selection.articleID!), + title: selection.name.replyToString()) + } else { EmptyView() } } @@ -105,7 +109,7 @@ struct NewsView: View { .help("New Post") .disabled(selection?.type != .category && selection?.type != .article) } - + ToolbarItem(placement: .primaryAction) { Button { if selection?.type == .article { @@ -117,7 +121,7 @@ struct NewsView: View { .help("Reply to Post") .disabled(selection?.type != .article) } - + ToolbarItem(placement: .primaryAction) { Button { loading = true @@ -126,8 +130,7 @@ struct NewsView: View { await model.getNewsList(at: selectionPath) loading = false } - } - else { + } else { Task { await model.getNewsList() loading = false @@ -141,7 +144,7 @@ struct NewsView: View { } } } - + var newsBrowser: some View { List(model.news, id: \.self, selection: $selection) { newsItem in NewsItemView(news: newsItem, depth: 0).tag(newsItem.id) @@ -152,23 +155,27 @@ struct NewsView: View { .alternatingRowBackgrounds(.enabled) .contextMenu(forSelectionType: NewsInfo.self) { items in let selectedItem = items.first - + Button { if selectedItem?.type == .article { replyOpen = true } } label: { - Label("Reply to \(selectedItem?.articleUsername ?? "Post")", systemImage: "arrowshape.turn.up.left") + Label( + "Reply to \(selectedItem?.articleUsername ?? "Post")", + systemImage: "arrowshape.turn.up.left") } .disabled(selectedItem == nil || selectedItem?.type != .article) - + } primaryAction: { items in guard let clickedNews = items.first else { return } - + self.selection = clickedNews - if clickedNews.type == .bundle || clickedNews.type == .category || clickedNews.children.count > 0 { + if clickedNews.type == .bundle || clickedNews.type == .category + || clickedNews.children.count > 0 + { clickedNews.expanded.toggle() } } @@ -177,9 +184,12 @@ struct NewsView: View { if let article = selection, article.type == .article { article.read = true if let articleFlavor = article.articleFlavors?.first, - let articleID = article.articleID { + let articleID = article.articleID + { Task { - if let articleText = await self.model.getNewsArticle(id: articleID, at: article.path, flavor: articleFlavor) { + if let articleText = await self.model.getNewsArticle( + id: articleID, at: article.path, flavor: articleFlavor) + { self.articleText = articleText } } @@ -188,10 +198,9 @@ struct NewsView: View { self.splitHidden.side = nil } } - + } - } - else { + } else { if self.splitHidden.side != .bottom { withAnimation(.easeOut(duration: 0.25)) { self.splitHidden.side = .bottom @@ -214,7 +223,7 @@ struct NewsView: View { return .ignored } } - + var loadingIndicator: some View { VStack { HStack { @@ -226,7 +235,7 @@ struct NewsView: View { } .frame(maxWidth: .infinity) } - + var articleViewer: some View { ScrollView { VStack(alignment: .leading, spacing: 0) { @@ -248,14 +257,14 @@ struct NewsView: View { .padding(.bottom, 16) } } - + Divider() - + Text(selection.name).font(.title) .textSelection(.enabled) .padding(.bottom, 8) .padding(.top, 16) - + if let newsText = self.articleText { Markdown(newsText) .markdownTheme(.basic) @@ -263,16 +272,15 @@ struct NewsView: View { .lineSpacing(6) .padding(.top, 16) } - } - else { + } else { HStack(alignment: .center) { Spacer() HStack(alignment: .center, spacing: 8) { -// Image(systemName: "doc.append") -// .resizable() -// .scaledToFit() -// .foregroundStyle(.tertiary) -// .frame(width: 16, height: 16) + // Image(systemName: "doc.append") + // .resizable() + // .scaledToFit() + // .foregroundStyle(.tertiary) + // .frame(width: 16, height: 16) Text("Select a news post to read") .foregroundStyle(.tertiary) .font(.system(size: 13)) |