WIP allow a single viewmodel for iPad split screen view
This commit is contained in:
@ -19,23 +19,23 @@ struct FiltersHeader: View {
|
||||
viewModel.searchTerm = ""
|
||||
}.frame(maxWidth: reader.size.width * 0.66)
|
||||
} else {
|
||||
if UIDevice.isIPhone {
|
||||
Menu(
|
||||
content: {
|
||||
ForEach(viewModel.filters) { filter in
|
||||
Button(filter.name, action: {
|
||||
viewModel.appliedFilter = filter
|
||||
})
|
||||
}
|
||||
},
|
||||
label: {
|
||||
TextChipButton.makeMenuButton(
|
||||
title: viewModel.appliedFilter?.name ?? "-",
|
||||
color: .systemGray6
|
||||
)
|
||||
// if UIDevice.isIPhone {
|
||||
Menu(
|
||||
content: {
|
||||
ForEach(viewModel.filters.filter { $0.folder == viewModel.currentFolder }) { filter in
|
||||
Button(filter.name, action: {
|
||||
viewModel.appliedFilter = filter
|
||||
})
|
||||
}
|
||||
).buttonStyle(.plain)
|
||||
}
|
||||
},
|
||||
label: {
|
||||
TextChipButton.makeMenuButton(
|
||||
title: viewModel.appliedFilter?.name ?? "-",
|
||||
color: .systemGray6
|
||||
)
|
||||
}
|
||||
).buttonStyle(.plain)
|
||||
// }
|
||||
}
|
||||
Menu(
|
||||
content: {
|
||||
@ -126,7 +126,7 @@ struct AnimatingCellHeight: AnimatableModifier {
|
||||
|
||||
var showFeatureCards: Bool {
|
||||
isEditMode == .inactive &&
|
||||
viewModel.listConfig.hasFeatureCards &&
|
||||
(viewModel.currentListConfig?.hasFeatureCards ?? false) &&
|
||||
!viewModel.hideFeatureSection &&
|
||||
viewModel.fetcher.items.count > 0 &&
|
||||
viewModel.searchTerm.isEmpty &&
|
||||
@ -298,9 +298,9 @@ struct AnimatingCellHeight: AnimatableModifier {
|
||||
|
||||
Button(
|
||||
action: {
|
||||
if viewModel.folder == "inbox" {
|
||||
if viewModel.currentFolder == "inbox" {
|
||||
showAddLinkView = true
|
||||
} else if viewModel.folder == "following" {
|
||||
} else if viewModel.currentFolder == "following" {
|
||||
showAddFeedView = true
|
||||
}
|
||||
},
|
||||
@ -368,7 +368,7 @@ struct AnimatingCellHeight: AnimatableModifier {
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
if let linkRequest = viewModel.linkRequest, viewModel.listConfig.hasReadNowSection {
|
||||
if let linkRequest = viewModel.linkRequest, viewModel.currentListConfig?.hasReadNowSection ?? false {
|
||||
PresentationLink(
|
||||
transition: PresentationLinkTransition.slide(
|
||||
options: PresentationLinkTransition.SlideTransitionOptions(edge: .trailing,
|
||||
@ -617,7 +617,7 @@ struct AnimatingCellHeight: AnimatableModifier {
|
||||
}
|
||||
|
||||
var emptyState: some View {
|
||||
if viewModel.folder == "following" {
|
||||
if viewModel.currentFolder == "following" {
|
||||
return AnyView(
|
||||
VStack(alignment: .center, spacing: 20) {
|
||||
Text("You don't have any Feed items.")
|
||||
@ -657,7 +657,7 @@ struct AnimatingCellHeight: AnimatableModifier {
|
||||
}
|
||||
|
||||
var listItems: some View {
|
||||
ForEach(viewModel.fetcher.items, id: \.unwrappedID) { item in
|
||||
ForEach(Array(viewModel.fetcher.items.enumerated()), id: \.1.unwrappedID) { idx, item in
|
||||
let horizontalInset = CGFloat(UIDevice.isIPad ? 20 : 10)
|
||||
|
||||
LibraryItemListNavigationLink(
|
||||
@ -681,22 +681,26 @@ struct AnimatingCellHeight: AnimatableModifier {
|
||||
menuItems(for: item)
|
||||
}
|
||||
.swipeActions(edge: .leading, allowsFullSwipe: true) {
|
||||
ForEach(viewModel.listConfig.leadingSwipeActions, id: \.self) { action in
|
||||
swipeActionButton(action: action, item: item)
|
||||
if let listConfig = viewModel.currentListConfig {
|
||||
ForEach(listConfig.leadingSwipeActions, id: \.self) { action in
|
||||
swipeActionButton(action: action, item: item)
|
||||
}
|
||||
}
|
||||
}
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
|
||||
ForEach(viewModel.listConfig.trailingSwipeActions, id: \.self) { action in
|
||||
swipeActionButton(action: action, item: item)
|
||||
if let listConfig = viewModel.currentListConfig {
|
||||
ForEach(listConfig.trailingSwipeActions, id: \.self) { action in
|
||||
swipeActionButton(action: action, item: item)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
if idx >= viewModel.fetcher.items.count - 5 {
|
||||
Task {
|
||||
await viewModel.loadMore(dataService: dataService)
|
||||
}
|
||||
}
|
||||
}
|
||||
// .onAppear {
|
||||
// if idx >= viewModel.fetcher.items.count - 5 {
|
||||
// Task {
|
||||
// await viewModel.loadMore(dataService: dataService)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,9 +6,8 @@ import Utils
|
||||
import Views
|
||||
|
||||
@MainActor final class HomeFeedViewModel: NSObject, ObservableObject {
|
||||
let folder: String
|
||||
let filterKey: String
|
||||
@ObservedObject var fetcher: LibraryItemFetcher
|
||||
let listConfig: LibraryListConfig
|
||||
|
||||
private var fetchedResultsController: NSFetchedResultsController<Models.LibraryItem>?
|
||||
|
||||
@ -40,63 +39,90 @@ import Views
|
||||
@AppStorage(UserDefaultKey.hideFeatureSection.rawValue) var hideFeatureSection = false
|
||||
@AppStorage("LibraryTabView::hideFollowingTab") var hideFollowingTab = false
|
||||
|
||||
@Published var appliedFilter: InternalFilter? {
|
||||
didSet {
|
||||
let filterKey = UserDefaults.standard.string(forKey: "lastSelected-\(folder)-filter") ?? folder
|
||||
UserDefaults.standard.setValue(appliedFilter?.name, forKey: filterKey)
|
||||
}
|
||||
}
|
||||
@Published var appliedFilter: InternalFilter? /* {
|
||||
didSet {
|
||||
if let folder = appliedFilter.folder, let filterKey = UserDefaults.standard.string(forKey: "lastSelected-\(folder))-filter") {
|
||||
UserDefaults.standard.setValue(appliedFilter?.name, forKey: filterKey)
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
private var filterState: FetcherFilterState {
|
||||
FetcherFilterState(folder: folder, searchTerm: searchTerm, selectedLabels: selectedLabels, negatedLabels: negatedLabels, appliedSort: appliedSort, appliedFilter: appliedFilter)
|
||||
}
|
||||
let folderConfigs: [String: LibraryListConfig]
|
||||
|
||||
init(filterKey: String, fetcher: LibraryItemFetcher, folderConfigs: [String: LibraryListConfig]) {
|
||||
self.filterKey = filterKey
|
||||
|
||||
init(folder: String, fetcher: LibraryItemFetcher, listConfig: LibraryListConfig) {
|
||||
self.folder = folder
|
||||
self.fetcher = fetcher
|
||||
self.listConfig = listConfig
|
||||
self.folderConfigs = folderConfigs
|
||||
|
||||
// if let filterKey = UserDefaults.standard.string(forKey: "lastSelected-\(filterKey))-filter") {
|
||||
// UserDefaults.standard.setValue(appliedFilter?.name, forKey: filterKey)
|
||||
// }
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
private var filterState: FetcherFilterState? {
|
||||
if let appliedFilter = appliedFilter {
|
||||
return FetcherFilterState(
|
||||
folder: appliedFilter.folder,
|
||||
searchTerm: searchTerm,
|
||||
selectedLabels: selectedLabels,
|
||||
negatedLabels: negatedLabels,
|
||||
appliedSort: appliedSort,
|
||||
appliedFilter: appliedFilter
|
||||
)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var currentFolder: String? {
|
||||
appliedFilter?.folder
|
||||
}
|
||||
|
||||
var currentListConfig: LibraryListConfig? {
|
||||
if let currentFolder = currentFolder {
|
||||
return folderConfigs[currentFolder]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadFilters(dataService: DataService) async {
|
||||
switch folder {
|
||||
case "following":
|
||||
updateFilters(newFilters: InternalFilter.DefaultFollowingFilters, defaultName: "following")
|
||||
default:
|
||||
var hasLocalResults = false
|
||||
let fetchRequest: NSFetchRequest<Models.Filter> = Filter.fetchRequest()
|
||||
var hasLocalResults = false
|
||||
let fetchRequest: NSFetchRequest<Models.Filter> = Filter.fetchRequest()
|
||||
|
||||
// Load from disk
|
||||
if let results = try? dataService.viewContext.fetch(fetchRequest) {
|
||||
hasLocalResults = true
|
||||
updateFilters(newFilters: InternalFilter.make(from: results), defaultName: "inbox")
|
||||
}
|
||||
// Load from disk
|
||||
if let results = try? dataService.viewContext.fetch(fetchRequest) {
|
||||
hasLocalResults = true
|
||||
updateFilters(newFilters: InternalFilter.make(from: results))
|
||||
}
|
||||
|
||||
let hasResults = hasLocalResults
|
||||
Task.detached {
|
||||
if let downloadedFilters = try? await dataService.filters() {
|
||||
await self.updateFilters(newFilters: downloadedFilters, defaultName: "inbox")
|
||||
} else if !hasResults {
|
||||
await self.updateFilters(newFilters: InternalFilter.DefaultInboxFilters, defaultName: "inbox")
|
||||
}
|
||||
let hasResults = hasLocalResults
|
||||
Task.detached {
|
||||
if let downloadedFilters = try? await dataService.filters() {
|
||||
await self.updateFilters(newFilters: downloadedFilters)
|
||||
} else if !hasResults {
|
||||
await self.updateFilters(newFilters: InternalFilter.DefaultInboxFilters)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loadMore(dataService: DataService, loadCursor: String? = nil) async {
|
||||
if isLoading { return }
|
||||
if let filterState = filterState {
|
||||
if isLoading { return }
|
||||
|
||||
let start = Date.now
|
||||
if let lastMoreFetched, lastMoreFetched.timeIntervalSinceNow > -4 {
|
||||
print("skipping fetching more as last fetch was too recent: ", lastMoreFetched)
|
||||
return
|
||||
let start = Date.now
|
||||
if let lastMoreFetched, lastMoreFetched.timeIntervalSinceNow > -4 {
|
||||
print("skipping fetching more as last fetch was too recent: ", lastMoreFetched)
|
||||
return
|
||||
}
|
||||
|
||||
isLoading = true
|
||||
await fetcher.loadMoreItems(dataService: dataService, filterState: filterState, loadCursor: loadCursor)
|
||||
isLoading = false
|
||||
|
||||
lastMoreFetched = start
|
||||
}
|
||||
|
||||
isLoading = true
|
||||
await fetcher.loadMoreItems(dataService: dataService, filterState: filterState, loadCursor: loadCursor)
|
||||
isLoading = false
|
||||
|
||||
lastMoreFetched = start
|
||||
}
|
||||
|
||||
func pushFeedItem(item _: Models.LibraryItem) {
|
||||
@ -120,24 +146,36 @@ import Views
|
||||
}
|
||||
}
|
||||
|
||||
func updateFilters(newFilters: [InternalFilter], defaultName: String) {
|
||||
let appliedFilterName = UserDefaults.standard.string(forKey: "lastSelected-\(filterState.folder)-filter") ?? defaultName
|
||||
var defaultFilters: [InternalFilter] {
|
||||
[InternalFilter.InboxUnreadFilter,
|
||||
InternalFilter.InboxDeletedFilter,
|
||||
InternalFilter.InboxDownloadedFilter]
|
||||
+ InternalFilter.DefaultFollowingFilters
|
||||
}
|
||||
|
||||
func updateFilters(newFilters: [InternalFilter]) {
|
||||
let availableFolders = folderConfigs.keys
|
||||
let appliedFilterName = UserDefaults.standard.string(forKey: filterKey)
|
||||
|
||||
filters = newFilters
|
||||
.filter { $0.folder == filterState.folder }
|
||||
.filter { availableFolders.contains($0.folder) }
|
||||
.sorted(by: { $0.position < $1.position })
|
||||
+ (folder == "inbox" ? [InternalFilter.UnreadFilter, InternalFilter.DeletedFilter, InternalFilter.DownloadedFilter] : [InternalFilter.DownloadedFilter])
|
||||
+ defaultFilters
|
||||
|
||||
if let newFilter = filters.first(where: { $0.name.lowercased() == appliedFilterName }), newFilter.id != appliedFilter?.id {
|
||||
appliedFilter = newFilter
|
||||
} else {
|
||||
appliedFilter = filters.first(where: { availableFolders.contains($0.folder) })
|
||||
}
|
||||
}
|
||||
|
||||
func loadNewItems(dataService: DataService) async {
|
||||
await fetcher.loadNewItems(
|
||||
dataService: dataService,
|
||||
filterState: filterState
|
||||
)
|
||||
if let filterState = filterState {
|
||||
await fetcher.loadNewItems(
|
||||
dataService: dataService,
|
||||
filterState: filterState
|
||||
)
|
||||
}
|
||||
objectWillChange.send()
|
||||
}
|
||||
|
||||
@ -145,12 +183,14 @@ import Views
|
||||
isLoading = true
|
||||
showLoadingBar = isRefresh
|
||||
|
||||
await fetcher.loadItems(
|
||||
dataService: dataService,
|
||||
filterState: filterState,
|
||||
isRefresh: isRefresh,
|
||||
forceRemote: forceRemote
|
||||
)
|
||||
if let filterState = filterState {
|
||||
await fetcher.loadItems(
|
||||
dataService: dataService,
|
||||
filterState: filterState,
|
||||
isRefresh: isRefresh,
|
||||
forceRemote: forceRemote
|
||||
)
|
||||
}
|
||||
|
||||
isLoading = false
|
||||
showLoadingBar = false
|
||||
|
||||
@ -4,9 +4,7 @@ import Services
|
||||
import SwiftUI
|
||||
|
||||
@MainActor struct LibrarySidebar: View {
|
||||
@ObservedObject var inboxViewModel: HomeFeedViewModel
|
||||
@ObservedObject var followingViewModel: HomeFeedViewModel
|
||||
|
||||
@ObservedObject var viewModel: HomeFeedViewModel
|
||||
@EnvironmentObject var dataService: DataService
|
||||
|
||||
@State private var addLinkPresented = false
|
||||
@ -23,8 +21,8 @@ import SwiftUI
|
||||
|
||||
var innerBody: some View {
|
||||
ZStack {
|
||||
NavigationLink("", destination: HomeView(viewModel: inboxViewModel), isActive: $inboxActive)
|
||||
NavigationLink("", destination: HomeView(viewModel: followingViewModel), isActive: $followingActive)
|
||||
// NavigationLink("", destination: HomeView(viewModel: inboxViewModel), isActive: $inboxActive)
|
||||
// NavigationLink("", destination: HomeView(viewModel: followingViewModel), isActive: $followingActive)
|
||||
|
||||
List {
|
||||
Section {
|
||||
@ -43,9 +41,9 @@ import SwiftUI
|
||||
})
|
||||
|
||||
if inboxMenuState == "open" {
|
||||
ForEach(inboxViewModel.filters, id: \.self) { filter in
|
||||
ForEach(viewModel.filters.filter { $0.folder == "inbox" }, id: \.self) { filter in
|
||||
Button(action: {
|
||||
inboxViewModel.appliedFilter = filter
|
||||
viewModel.appliedFilter = filter
|
||||
selectedFilter = filter
|
||||
followingActive = false
|
||||
inboxActive = true
|
||||
@ -80,9 +78,9 @@ import SwiftUI
|
||||
})
|
||||
|
||||
if followingMenuState == "open" {
|
||||
ForEach(followingViewModel.filters, id: \.self) { filter in
|
||||
ForEach(viewModel.filters.filter { $0.folder == "following" }, id: \.self) { filter in
|
||||
Button(action: {
|
||||
followingViewModel.appliedFilter = filter
|
||||
viewModel.appliedFilter = filter
|
||||
selectedFilter = filter
|
||||
inboxActive = false
|
||||
followingActive = true
|
||||
@ -125,23 +123,18 @@ import SwiftUI
|
||||
}
|
||||
}
|
||||
}.task {
|
||||
await inboxViewModel.loadFilters(dataService: dataService)
|
||||
await followingViewModel.loadFilters(dataService: dataService)
|
||||
await viewModel.loadFilters(dataService: dataService)
|
||||
|
||||
if inboxActive {
|
||||
selectedFilter = inboxViewModel.appliedFilter
|
||||
selectedFilter = viewModel.appliedFilter
|
||||
} else {
|
||||
selectedFilter = followingViewModel.appliedFilter
|
||||
selectedFilter = viewModel.appliedFilter
|
||||
}
|
||||
}.onChange(of: inboxViewModel.appliedFilter) { filter in
|
||||
}.onChange(of: viewModel.appliedFilter) { filter in
|
||||
// When the user uses the dropdown menu to change filter we need to update in the sidebar
|
||||
if inboxActive, filter != selectedFilter {
|
||||
selectedFilter = filter
|
||||
}
|
||||
}.onChange(of: followingViewModel.appliedFilter) { filter in
|
||||
if followingActive, filter != selectedFilter {
|
||||
selectedFilter = filter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7,28 +7,25 @@ import SwiftUI
|
||||
public struct LibrarySplitView: View {
|
||||
@EnvironmentObject var dataService: DataService
|
||||
|
||||
@StateObject private var inboxViewModel = HomeFeedViewModel(
|
||||
folder: "inbox",
|
||||
@StateObject private var viewModel = HomeFeedViewModel(
|
||||
filterKey: "lastSelected",
|
||||
fetcher: LibraryItemFetcher(),
|
||||
listConfig: LibraryListConfig(
|
||||
hasFeatureCards: true,
|
||||
hasReadNowSection: true,
|
||||
leadingSwipeActions: [.pin],
|
||||
trailingSwipeActions: [.archive, .delete],
|
||||
cardStyle: .library
|
||||
)
|
||||
)
|
||||
|
||||
@StateObject private var followingViewModel = HomeFeedViewModel(
|
||||
folder: "following",
|
||||
fetcher: LibraryItemFetcher(),
|
||||
listConfig: LibraryListConfig(
|
||||
hasFeatureCards: false,
|
||||
hasReadNowSection: false,
|
||||
leadingSwipeActions: [.moveToInbox],
|
||||
trailingSwipeActions: [.delete],
|
||||
cardStyle: .library
|
||||
)
|
||||
folderConfigs: [
|
||||
"inbox": LibraryListConfig(
|
||||
hasFeatureCards: true,
|
||||
hasReadNowSection: true,
|
||||
leadingSwipeActions: [.pin],
|
||||
trailingSwipeActions: [.archive, .delete],
|
||||
cardStyle: .library
|
||||
),
|
||||
"following": LibraryListConfig(
|
||||
hasFeatureCards: false,
|
||||
hasReadNowSection: false,
|
||||
leadingSwipeActions: [.moveToInbox],
|
||||
trailingSwipeActions: [.delete],
|
||||
cardStyle: .library
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
private let syncManager = LibrarySyncManager()
|
||||
@ -36,11 +33,11 @@ public struct LibrarySplitView: View {
|
||||
#if os(iOS)
|
||||
public var body: some View {
|
||||
NavigationView {
|
||||
LibrarySidebar(inboxViewModel: inboxViewModel, followingViewModel: followingViewModel)
|
||||
LibrarySidebar(viewModel: viewModel)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.navigationTitle("")
|
||||
|
||||
HomeFeedContainerView(viewModel: inboxViewModel)
|
||||
HomeFeedContainerView(viewModel: viewModel)
|
||||
.navigationViewStyle(.stack)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
}
|
||||
@ -50,27 +47,27 @@ public struct LibrarySplitView: View {
|
||||
$0.preferredPrimaryColumnWidth = 230
|
||||
$0.displayModeButtonVisibility = .always
|
||||
}
|
||||
.onOpenURL { url in
|
||||
inboxViewModel.linkRequest = nil
|
||||
if let deepLink = DeepLink.make(from: url) {
|
||||
switch deepLink {
|
||||
case let .search(query):
|
||||
inboxViewModel.searchTerm = query
|
||||
case let .savedSearch(named):
|
||||
if let filter = inboxViewModel.findFilter(dataService, named: named) {
|
||||
inboxViewModel.appliedFilter = filter
|
||||
}
|
||||
case let .webAppLinkRequest(requestID):
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
|
||||
withoutAnimation {
|
||||
inboxViewModel.linkRequest = LinkRequest(id: UUID(), serverID: requestID)
|
||||
inboxViewModel.presentWebContainer = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// selectedTab = "inbox"
|
||||
}
|
||||
// .onOpenURL { url in
|
||||
// inboxViewModel.linkRequest = nil
|
||||
// if let deepLink = DeepLink.make(from: url) {
|
||||
// switch deepLink {
|
||||
// case let .search(query):
|
||||
// inboxViewModel.searchTerm = query
|
||||
// case let .savedSearch(named):
|
||||
// if let filter = inboxViewModel.findFilter(dataService, named: named) {
|
||||
// inboxViewModel.appliedFilter = filter
|
||||
// }
|
||||
// case let .webAppLinkRequest(requestID):
|
||||
// DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
|
||||
// withoutAnimation {
|
||||
// inboxViewModel.linkRequest = LinkRequest(id: UUID(), serverID: requestID)
|
||||
// inboxViewModel.presentWebContainer = true
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // selectedTab = "inbox"
|
||||
// }
|
||||
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
|
||||
Task {
|
||||
await syncManager.syncUpdates(dataService: dataService)
|
||||
|
||||
@ -32,27 +32,31 @@ struct LibraryTabView: View {
|
||||
}
|
||||
|
||||
@StateObject private var inboxViewModel = HomeFeedViewModel(
|
||||
folder: "inbox",
|
||||
filterKey: "lastSelectedFilter-inbox",
|
||||
fetcher: LibraryItemFetcher(),
|
||||
listConfig: LibraryListConfig(
|
||||
hasFeatureCards: true,
|
||||
hasReadNowSection: true,
|
||||
leadingSwipeActions: [.pin],
|
||||
trailingSwipeActions: [.archive, .delete],
|
||||
cardStyle: .library
|
||||
)
|
||||
folderConfigs: [
|
||||
"inbox": LibraryListConfig(
|
||||
hasFeatureCards: true,
|
||||
hasReadNowSection: true,
|
||||
leadingSwipeActions: [.pin],
|
||||
trailingSwipeActions: [.archive, .delete],
|
||||
cardStyle: .library
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
@StateObject private var followingViewModel = HomeFeedViewModel(
|
||||
folder: "following",
|
||||
filterKey: "lastSelectedFilter-following",
|
||||
fetcher: LibraryItemFetcher(),
|
||||
listConfig: LibraryListConfig(
|
||||
hasFeatureCards: false,
|
||||
hasReadNowSection: false,
|
||||
leadingSwipeActions: [.moveToInbox],
|
||||
trailingSwipeActions: [.delete],
|
||||
cardStyle: .library
|
||||
)
|
||||
folderConfigs: [
|
||||
"following": LibraryListConfig(
|
||||
hasFeatureCards: false,
|
||||
hasReadNowSection: false,
|
||||
leadingSwipeActions: [.moveToInbox],
|
||||
trailingSwipeActions: [.delete],
|
||||
cardStyle: .library
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
var currentViewModel: HomeFeedViewModel? {
|
||||
|
||||
@ -15,9 +15,9 @@ public struct InternalFilter: Encodable, Identifiable, Hashable, Equatable {
|
||||
lhs.id == rhs.id
|
||||
}
|
||||
|
||||
public static var DownloadedFilter: InternalFilter {
|
||||
public static var InboxDownloadedFilter: InternalFilter {
|
||||
InternalFilter(
|
||||
id: "downloaded",
|
||||
id: "inbox-downloaded",
|
||||
name: "Downloaded",
|
||||
folder: "inbox",
|
||||
filter: "",
|
||||
@ -27,9 +27,9 @@ public struct InternalFilter: Encodable, Identifiable, Hashable, Equatable {
|
||||
)
|
||||
}
|
||||
|
||||
public static var DeletedFilter: InternalFilter {
|
||||
public static var InboxDeletedFilter: InternalFilter {
|
||||
InternalFilter(
|
||||
id: "deleted",
|
||||
id: "inbox-deleted",
|
||||
name: "Deleted",
|
||||
folder: "inbox",
|
||||
filter: "in:trash",
|
||||
@ -39,7 +39,43 @@ public struct InternalFilter: Encodable, Identifiable, Hashable, Equatable {
|
||||
)
|
||||
}
|
||||
|
||||
public static var UnreadFilter: InternalFilter {
|
||||
public static var InboxUnreadFilter: InternalFilter {
|
||||
InternalFilter(
|
||||
id: "inbox-unread",
|
||||
name: "Unread",
|
||||
folder: "inbox",
|
||||
filter: "in:inbox is:unread",
|
||||
visible: true,
|
||||
position: -1,
|
||||
defaultFilter: true
|
||||
)
|
||||
}
|
||||
|
||||
public static var FollowingDownloadedFilter: InternalFilter {
|
||||
InternalFilter(
|
||||
id: "following-downloaded",
|
||||
name: "Downloaded",
|
||||
folder: "following",
|
||||
filter: "",
|
||||
visible: true,
|
||||
position: -1,
|
||||
defaultFilter: true
|
||||
)
|
||||
}
|
||||
|
||||
public static var FollowingDeletedFilter: InternalFilter {
|
||||
InternalFilter(
|
||||
id: "following-deleted",
|
||||
name: "Deleted",
|
||||
folder: "following",
|
||||
filter: "in:trash",
|
||||
visible: true,
|
||||
position: -1,
|
||||
defaultFilter: true
|
||||
)
|
||||
}
|
||||
|
||||
public static var FollowingUnreadFilter: InternalFilter {
|
||||
InternalFilter(
|
||||
id: "unread",
|
||||
name: "Unread",
|
||||
|
||||
Reference in New Issue
Block a user