mirror of
https://github.com/kiwix/kiwix-apple.git
synced 2025-09-24 04:03:03 -04:00
Apply LaunchViewModel on BrowserTab
This commit is contained in:
parent
7ad164d178
commit
d94c862110
@ -228,8 +228,6 @@ private struct Content<LaunchModel>: View where LaunchModel: LaunchProtocol {
|
||||
sortDescriptors: [NSSortDescriptor(keyPath: \ZimFile.size, ascending: false)],
|
||||
predicate: ZimFile.openedPredicate
|
||||
) private var zimFiles: FetchedResults<ZimFile>
|
||||
@State var isInitialLoad: Bool = true
|
||||
|
||||
/// this is still hacky a bit, as the change from here re-validates the view
|
||||
/// which triggers the model to be revalidated
|
||||
@Default(.hasSeenCategories) private var hasSeenCategories
|
||||
@ -300,11 +298,6 @@ private struct Content<LaunchModel>: View where LaunchModel: LaunchProtocol {
|
||||
browser.refreshVideoState()
|
||||
}
|
||||
}
|
||||
.onChange(of: browser.isLoading) { isLoading in
|
||||
if isLoading == false { // wait for the first full webpage load
|
||||
isInitialLoad = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -141,7 +141,7 @@ final class SplitViewController: UISplitViewController {
|
||||
let controller = UIHostingController(rootView: Settings())
|
||||
setViewController(UINavigationController(rootViewController: controller), for: .secondary)
|
||||
case .loading:
|
||||
let controller = UIHostingController(rootView: LoadingView())
|
||||
let controller = UIHostingController(rootView: LoadingDataView())
|
||||
setViewController(UINavigationController(rootViewController: controller), for: .secondary)
|
||||
default:
|
||||
let controller = UIHostingController(rootView: Text("vc-not-implemented"))
|
||||
|
@ -14,18 +14,25 @@
|
||||
// along with Kiwix; If not, see https://www.gnu.org/licenses/.
|
||||
|
||||
import SwiftUI
|
||||
import Defaults
|
||||
|
||||
/// This is macOS and iPad only specific, not used on iPhone
|
||||
struct BrowserTab: View {
|
||||
@Environment(\.scenePhase) private var scenePhase
|
||||
@EnvironmentObject private var browser: BrowserViewModel
|
||||
@EnvironmentObject private var library: LibraryViewModel
|
||||
@StateObject private var search = SearchViewModel()
|
||||
|
||||
var body: some View {
|
||||
Content().toolbar {
|
||||
#if os(macOS)
|
||||
let model = if FeatureFlags.hasLibrary {
|
||||
CatalogLaunchViewModel(library: library, browser: browser)
|
||||
} else {
|
||||
NoCatalogLaunchViewModel(browser: browser)
|
||||
}
|
||||
Content(model: model).toolbar {
|
||||
#if os(macOS)
|
||||
ToolbarItemGroup(placement: .navigation) { NavigationButtons() }
|
||||
#elseif os(iOS)
|
||||
#elseif os(iOS)
|
||||
ToolbarItemGroup(placement: .navigationBarLeading) {
|
||||
if #unavailable(iOS 16) {
|
||||
Button {
|
||||
@ -36,17 +43,17 @@ struct BrowserTab: View {
|
||||
}
|
||||
NavigationButtons()
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
ToolbarItemGroup(placement: .primaryAction) {
|
||||
OutlineButton()
|
||||
ExportButton()
|
||||
#if os(macOS)
|
||||
#if os(macOS)
|
||||
PrintButton()
|
||||
#endif
|
||||
#endif
|
||||
BookmarkButton()
|
||||
#if os(iOS)
|
||||
#if os(iOS)
|
||||
ContentSearchButton()
|
||||
#endif
|
||||
#endif
|
||||
ArticleShortcutButtons(displayMode: .mainAndRandomArticle)
|
||||
}
|
||||
}
|
||||
@ -62,12 +69,12 @@ struct BrowserTab: View {
|
||||
}
|
||||
}
|
||||
.modify { view in
|
||||
#if os(macOS)
|
||||
#if os(macOS)
|
||||
view.navigationTitle(browser.articleTitle.isEmpty ? Brand.appName : browser.articleTitle)
|
||||
.navigationSubtitle(browser.zimFileName)
|
||||
#elseif os(iOS)
|
||||
#elseif os(iOS)
|
||||
view
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
.onAppear {
|
||||
browser.updateLastOpened()
|
||||
@ -78,11 +85,23 @@ struct BrowserTab: View {
|
||||
}
|
||||
}
|
||||
|
||||
struct Content: View {
|
||||
private struct Content<LaunchModel>: View where LaunchModel: LaunchProtocol {
|
||||
@Environment(\.isSearching) private var isSearching
|
||||
@EnvironmentObject private var browser: BrowserViewModel
|
||||
@FetchRequest(
|
||||
sortDescriptors: [NSSortDescriptor(keyPath: \ZimFile.size, ascending: false)],
|
||||
predicate: ZimFile.openedPredicate
|
||||
) private var zimFiles: FetchedResults<ZimFile>
|
||||
/// this is still hacky a bit, as the change from here re-validates the view
|
||||
/// which triggers the model to be revalidated
|
||||
@Default(.hasSeenCategories) private var hasSeenCategories
|
||||
@ObservedObject var model: LaunchModel
|
||||
|
||||
|
||||
var body: some View {
|
||||
let _ = model.updateWith(hasZimFiles: !zimFiles.isEmpty,
|
||||
hasSeenCategories: hasSeenCategories)
|
||||
let _ = debugPrint("model.state: \(model.state)")
|
||||
GeometryReader { proxy in
|
||||
Group {
|
||||
if isSearching {
|
||||
@ -92,17 +111,32 @@ struct BrowserTab: View {
|
||||
#elseif os(iOS)
|
||||
.environment(\.horizontalSizeClass, proxy.size.width > 750 ? .regular : .compact)
|
||||
#endif
|
||||
} else if browser.url == nil && FeatureFlags.hasLibrary {
|
||||
Welcome(showLibrary: nil)
|
||||
} else {
|
||||
WebView().ignoresSafeArea()
|
||||
#if os(macOS)
|
||||
.overlay(alignment: .bottomTrailing) {
|
||||
ContentSearchBar(
|
||||
model: ContentSearchViewModel(findInWebPage: browser.webView.find(_:configuration:))
|
||||
)
|
||||
}
|
||||
#endif
|
||||
switch model.state {
|
||||
case .loadingData:
|
||||
LoadingDataView()
|
||||
case .webPage(let isLoading):
|
||||
WebView()
|
||||
.ignoresSafeArea()
|
||||
.overlay {
|
||||
if isLoading {
|
||||
LoadingProgressView()
|
||||
}
|
||||
}
|
||||
#if os(macOS)
|
||||
.overlay(alignment: .bottomTrailing) {
|
||||
ContentSearchBar(
|
||||
model: ContentSearchViewModel(findInWebPage: browser.webView.find(_:configuration:))
|
||||
)
|
||||
}
|
||||
#endif
|
||||
case .catalog(.fetching):
|
||||
FetchingCatalogView()
|
||||
case .catalog(.list):
|
||||
LocalLibraryList()
|
||||
case .catalog(.welcome(let welcomeViewState)):
|
||||
WelcomeCatalog(viewState: welcomeViewState, showLibrary: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
67
Views/LocalLibraryList.swift
Normal file
67
Views/LocalLibraryList.swift
Normal file
@ -0,0 +1,67 @@
|
||||
// This file is part of Kiwix for iOS & macOS.
|
||||
//
|
||||
// Kiwix is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kiwix is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kiwix; If not, see https://www.gnu.org/licenses/.
|
||||
|
||||
import SwiftUI
|
||||
import Combine
|
||||
import Defaults
|
||||
|
||||
struct LocalLibraryList: View {
|
||||
@EnvironmentObject private var browser: BrowserViewModel
|
||||
@FetchRequest(
|
||||
sortDescriptors: [NSSortDescriptor(keyPath: \Bookmark.created, ascending: false)],
|
||||
animation: .easeInOut
|
||||
) private var bookmarks: FetchedResults<Bookmark>
|
||||
@FetchRequest(
|
||||
sortDescriptors: [NSSortDescriptor(keyPath: \ZimFile.size, ascending: false)],
|
||||
predicate: ZimFile.openedPredicate,
|
||||
animation: .easeInOut
|
||||
) private var zimFiles: FetchedResults<ZimFile>
|
||||
|
||||
var body: some View {
|
||||
LazyVGrid(
|
||||
columns: ([GridItem(.adaptive(minimum: 250, maximum: 500), spacing: 12)]),
|
||||
alignment: .leading,
|
||||
spacing: 12
|
||||
) {
|
||||
GridSection(title: "welcome.main_page.title".localized) {
|
||||
ForEach(zimFiles) { zimFile in
|
||||
AsyncButtonView {
|
||||
guard let url = await ZimFileService.shared
|
||||
.getMainPageURL(zimFileID: zimFile.fileID) else { return }
|
||||
browser.load(url: url)
|
||||
} label: {
|
||||
ZimFileCell(zimFile, prominent: .name)
|
||||
} loading: {
|
||||
ZimFileCell(zimFile, prominent: .name, isLoading: true)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
}
|
||||
if !bookmarks.isEmpty {
|
||||
GridSection(title: "welcome.grid.bookmarks.title".localized) {
|
||||
ForEach(bookmarks.prefix(6)) { bookmark in
|
||||
Button {
|
||||
browser.load(url: bookmark.articleURL)
|
||||
} label: {
|
||||
ArticleCell(bookmark: bookmark)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.modifier(BookmarkContextMenu(bookmark: bookmark))
|
||||
}
|
||||
}
|
||||
}
|
||||
}.modifier(GridCommon(edges: .all))
|
||||
}
|
||||
}
|
@ -17,56 +17,6 @@ import SwiftUI
|
||||
import Combine
|
||||
import Defaults
|
||||
|
||||
|
||||
struct LocalLibraryList: View {
|
||||
@EnvironmentObject private var browser: BrowserViewModel
|
||||
@FetchRequest(
|
||||
sortDescriptors: [NSSortDescriptor(keyPath: \Bookmark.created, ascending: false)],
|
||||
animation: .easeInOut
|
||||
) private var bookmarks: FetchedResults<Bookmark>
|
||||
@FetchRequest(
|
||||
sortDescriptors: [NSSortDescriptor(keyPath: \ZimFile.size, ascending: false)],
|
||||
predicate: ZimFile.openedPredicate,
|
||||
animation: .easeInOut
|
||||
) private var zimFiles: FetchedResults<ZimFile>
|
||||
|
||||
var body: some View {
|
||||
LazyVGrid(
|
||||
columns: ([GridItem(.adaptive(minimum: 250, maximum: 500), spacing: 12)]),
|
||||
alignment: .leading,
|
||||
spacing: 12
|
||||
) {
|
||||
GridSection(title: "welcome.main_page.title".localized) {
|
||||
ForEach(zimFiles) { zimFile in
|
||||
AsyncButtonView {
|
||||
guard let url = await ZimFileService.shared
|
||||
.getMainPageURL(zimFileID: zimFile.fileID) else { return }
|
||||
browser.load(url: url)
|
||||
} label: {
|
||||
ZimFileCell(zimFile, prominent: .name)
|
||||
} loading: {
|
||||
ZimFileCell(zimFile, prominent: .name, isLoading: true)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
}
|
||||
if !bookmarks.isEmpty {
|
||||
GridSection(title: "welcome.grid.bookmarks.title".localized) {
|
||||
ForEach(bookmarks.prefix(6)) { bookmark in
|
||||
Button {
|
||||
browser.load(url: bookmark.articleURL)
|
||||
} label: {
|
||||
ArticleCell(bookmark: bookmark)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.modifier(BookmarkContextMenu(bookmark: bookmark))
|
||||
}
|
||||
}
|
||||
}
|
||||
}.modifier(GridCommon(edges: .all))
|
||||
}
|
||||
}
|
||||
|
||||
struct WelcomeCatalog: View {
|
||||
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
||||
@Environment(\.verticalSizeClass) private var verticalSizeClass
|
Loading…
x
Reference in New Issue
Block a user