diff options
Diffstat (limited to 'Hotline/Views/NewsView.swift')
| -rw-r--r-- | Hotline/Views/NewsView.swift | 188 |
1 files changed, 132 insertions, 56 deletions
diff --git a/Hotline/Views/NewsView.swift b/Hotline/Views/NewsView.swift index ad7904e..bd3ae1c 100644 --- a/Hotline/Views/NewsView.swift +++ b/Hotline/Views/NewsView.swift @@ -1,58 +1,142 @@ import SwiftUI +import UniformTypeIdentifiers -struct NewsView: View { + + +struct NewsItemView: View { @Environment(Hotline.self) private var model: Hotline - @Environment(\.colorScheme) var colorScheme + @Environment(NewsItemSelection.self) private var selectedArticle: NewsItemSelection - @State private var fetched = false - @State private var selectedCategory: NewsCategory? = nil - @State private var topListHeight: CGFloat = 200 - @State private var dividerHeight: CGFloat = 30 + let news: NewsInfo - var articleList: some View { - - // Your list content goes here - List { - ForEach(model.news, id: \.self) { category in - DisclosureGroup { - ProgressView(value: 0.4) - .task { - print("EXPANDED?", category.name) -// hotline.sendGetNewsArticles(path: [cat.name]) { -// print("OK") -// } - } - } label: { - Text(category.name) + @State var expanded = false + + var body: some View { + if news.count > 0 { + DisclosureGroup(isExpanded: $expanded) { + ForEach(news.children) { childNews in + NewsItemView(news: childNews) + .environment(self.selectedArticle) + .frame(height: 38) + } + } label: { + HStack { + if news.type == .bundle { + Text(Image(systemName: "tray.2.fill")) + } + else { + Text(Image(systemName: "tray.full.fill")) + } + Text(news.name) .fontWeight(.medium) .lineLimit(1) .truncationMode(.tail) + Spacer() + if news.count > 0 { + Text("\(news.count)") + .foregroundStyle(.secondary) + } + } + } + .onChange(of: expanded) { + if !expanded { + return + } + + Task { + await model.getNewsList(at: news.path) } } } - .scrollBounceBehavior(.basedOnSize) -// .listStyle(.plain) - } - - var readerView: some View { - // Your list content goes here - ScrollView(.vertical) { - HStack(alignment: .top, spacing: 0) { - Text("HELLO") - .multilineTextAlignment(.leading) + else { + HStack { + Text(Image(systemName: "doc.text")) + Text(news.name) + .fontWeight(.medium) + .lineLimit(1) + .truncationMode(.tail) Spacer() + if news.count > 0 { + Text("\(news.count)") + .foregroundStyle(.secondary) + } + } + .onTapGesture { + if news.type == .article { + print("SELECTED", news.name) + selectedArticle.selectedArticle = news + } } - .padding() } - .scrollBounceBehavior(.basedOnSize) - .background(colorScheme == .dark ? Color(white: 0.1) : Color(uiColor: UIColor.systemBackground)) } +} + +@Observable +class NewsItemSelection: Equatable { + var selectedArticle: NewsInfo? = nil + static func == (lhs: NewsItemSelection, rhs: NewsItemSelection) -> Bool { + return lhs.selectedArticle == rhs.selectedArticle + } +} + +struct NewsView: View { + @Environment(Hotline.self) private var model: Hotline + @Environment(\.colorScheme) var colorScheme + + @State private var fetched = false + @State private var selectedCategory: NewsInfo? = nil + @State private var topListHeight: CGFloat = 200 + @State private var dividerHeight: CGFloat = 30 + + @State private var articleSelection = NewsItemSelection() + @State private var articleText = "" +// @State private var selectedArticleID: UInt? + + var articleList: some View { + VStack(spacing: 0) { + if model.news.count == 0 { + Text("No News Available") + .font(.headline) + .opacity(0.3) + } + else { + List(model.news) { category in + NewsItemView(news: category) + .environment(self.articleSelection) + .frame(height: 38) + } + .scrollBounceBehavior(.basedOnSize) + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color(uiColor: .systemGroupedBackground)) + + // .listStyle(.plain) + } + var body: some View { NavigationStack { VStack(spacing: 0) { articleList .frame(height: topListHeight) + .frame(minHeight: topListHeight) + .onChange(of: self.articleSelection.selectedArticle) { + self.articleText = "" + if + let article = self.articleSelection.selectedArticle, + let articleFlavor = article.articleFlavors?.first, + let articleID = article.articleID { + Task { + if let articleText = await self.model.getNewsArticle(id: articleID, at: article.path, flavor: articleFlavor) { + self.articleText = articleText + } + } + } +// print("SELECTED ARTICLE", articleSelection.selectedArticle?.name) + } + + // Movable Divider VStack(alignment: .center) { Divider() Spacer() @@ -72,28 +156,31 @@ struct NewsView: View { .onChanged { gesture in let delta = gesture.translation.height topListHeight = max(min(topListHeight + delta, 500), 50) - // bottomListHeight = max(min(bottomListHeight - delta, 400), 0) } ) - readerView + + // Reader View + ScrollView(.vertical) { + HStack(alignment: .top, spacing: 0) { + Text(self.articleText) + .multilineTextAlignment(.leading) + Spacer() + } + .padding() + } + .scrollBounceBehavior(.basedOnSize) + .background(colorScheme == .dark ? Color(white: 0.1) : Color(uiColor: UIColor.systemBackground)) } .task { if !fetched { - let _ = await model.getNewsCategories() + let _ = await model.getNewsList() fetched = true - - // hotline.sendGetNewsArticles(path: ["News"]) { - // print("GOT ARTICLES?") - // } } } - // .refreshable { - // hotline.sendGetNewsCategories() - // } .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .principal) { - Text(model.server?.name ?? "") + Text(model.serverTitle) .font(.headline) } ToolbarItem(placement: .navigationBarLeading) { @@ -106,19 +193,8 @@ struct NewsView: View { .foregroundColor(.secondary) } } -// ToolbarItem(placement: .navigationBarTrailing) { -// Button { -// -// } label: { -// Image(systemName: "square.and.pencil") -// // .symbolRenderingMode(.hierarchical) -// // .foregroundColor(.secondary) -// } -// -// } } } - } } |