Empty state handling for feature section
This commit is contained in:
@ -72,7 +72,7 @@ struct HighlightListItemParams: Identifiable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func loadHighlights(item: LinkedItem) {
|
private func loadHighlights(item: LinkedItem) {
|
||||||
let unsortedHighlights = item.highlights.asArray(of: Highlight.self)
|
let unsortedHighlights = item.highlights.asArray(of: Highlight.self).filter { $0.type == "HIGHLIGHT" }
|
||||||
|
|
||||||
let highlights = unsortedHighlights.sorted { left, right in
|
let highlights = unsortedHighlights.sorted { left, right in
|
||||||
if left.positionPercent > 0, right.positionPercent > 0 {
|
if left.positionPercent > 0, right.positionPercent > 0 {
|
||||||
|
|||||||
@ -358,22 +358,24 @@ import Views
|
|||||||
VStack(alignment: .leading, spacing: 20) {
|
VStack(alignment: .leading, spacing: 20) {
|
||||||
Menu(content: {
|
Menu(content: {
|
||||||
Button(action: {
|
Button(action: {
|
||||||
viewModel.featureFilter = .continueReading
|
viewModel.updateFeatureFilter(.continueReading)
|
||||||
}, label: {
|
}, label: {
|
||||||
Text("Continue Reading")
|
Text("Continue Reading")
|
||||||
})
|
})
|
||||||
Button(action: {
|
Button(action: {
|
||||||
viewModel.featureFilter = .recommended
|
viewModel.updateFeatureFilter(.recommended)
|
||||||
}, label: {
|
}, label: {
|
||||||
Text("Recommended")
|
Text("Recommended")
|
||||||
// Label("Recommended", systemImage: "x.circle")
|
|
||||||
})
|
})
|
||||||
Button(action: {
|
Button(action: {
|
||||||
viewModel.featureFilter = .newsletters
|
viewModel.updateFeatureFilter(.newsletters)
|
||||||
}, label: {
|
}, label: {
|
||||||
Text("Newsletters")
|
Text("Newsletters")
|
||||||
|
})
|
||||||
// Label("Newsletters", systemImage: "x.circle")
|
Button(action: {
|
||||||
|
// viewModel.updateFeatureFilter(.newsletters)
|
||||||
|
}, label: {
|
||||||
|
Text("Hide Feature Section")
|
||||||
})
|
})
|
||||||
}, label: {
|
}, label: {
|
||||||
HStack(alignment: .center) {
|
HStack(alignment: .center) {
|
||||||
@ -385,14 +387,18 @@ import Views
|
|||||||
.padding(.top, 20)
|
.padding(.top, 20)
|
||||||
.padding(.bottom, 0)
|
.padding(.bottom, 0)
|
||||||
|
|
||||||
ScrollView(.horizontal, showsIndicators: false) {
|
if viewModel.featureItems.count > 0 {
|
||||||
LazyHStack(alignment: .top, spacing: 20) {
|
ScrollView(.horizontal, showsIndicators: false) {
|
||||||
ForEach(viewModel.featureItems) { item in
|
LazyHStack(alignment: .top, spacing: 20) {
|
||||||
LibraryFeatureCardNavigationLink(item: item, viewModel: viewModel)
|
ForEach(viewModel.featureItems) { item in
|
||||||
}
|
LibraryFeatureCardNavigationLink(item: item, viewModel: viewModel)
|
||||||
}.padding(0)
|
}
|
||||||
|
}.padding(0)
|
||||||
|
}
|
||||||
|
.padding(.top, 0)
|
||||||
|
} else {
|
||||||
|
Text(viewModel.featureFilter.emptyMessage)
|
||||||
}
|
}
|
||||||
.padding(.top, 0)
|
|
||||||
|
|
||||||
Text((LinkedItemFilter(rawValue: viewModel.appliedFilter)?.displayName ?? "Inbox").uppercased())
|
Text((LinkedItemFilter(rawValue: viewModel.appliedFilter)?.displayName ?? "Inbox").uppercased())
|
||||||
.font(Font.system(size: 14, weight: .medium))
|
.font(Font.system(size: 14, weight: .medium))
|
||||||
@ -419,7 +425,8 @@ import Views
|
|||||||
filtersHeader
|
filtersHeader
|
||||||
.listRowInsets(.init(top: 0, leading: 10, bottom: 10, trailing: 10))
|
.listRowInsets(.init(top: 0, leading: 10, bottom: 10, trailing: 10))
|
||||||
|
|
||||||
if viewModel.featureItems.count > 0 {
|
// Only show the feature card section if we have items loaded
|
||||||
|
if viewModel.items.count > 0 {
|
||||||
featureCard
|
featureCard
|
||||||
.listRowInsets(.init(top: 0, leading: 10, bottom: 10, trailing: 10))
|
.listRowInsets(.init(top: 0, leading: 10, bottom: 10, trailing: 10))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,17 +45,22 @@ import Views
|
|||||||
|
|
||||||
var syncCursor: String?
|
var syncCursor: String?
|
||||||
|
|
||||||
|
@AppStorage(UserDefaultKey.hideFeatureSection.rawValue) var hideFeatureSection = false
|
||||||
@AppStorage(UserDefaultKey.lastSelectedLinkedItemFilter.rawValue) var appliedFilter = LinkedItemFilter.inbox.rawValue
|
@AppStorage(UserDefaultKey.lastSelectedLinkedItemFilter.rawValue) var appliedFilter = LinkedItemFilter.inbox.rawValue
|
||||||
|
|
||||||
func setItems(_ items: [LinkedItem]) {
|
func setItems(_ items: [LinkedItem]) {
|
||||||
self.items = items
|
self.items = items
|
||||||
|
updateFeatureFilter(featureFilter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateFeatureFilter(_ filter: FeaturedItemFilter) {
|
||||||
// now try to update the continue reading items:
|
// now try to update the continue reading items:
|
||||||
featureItems = (items.filter { item in
|
featureItems = (items.filter { item in
|
||||||
featureFilter.predicate.evaluate(with: item)
|
filter.predicate.evaluate(with: item)
|
||||||
} as NSArray)
|
} as NSArray)
|
||||||
.sortedArray(using: [featureFilter.sortDescriptor])
|
.sortedArray(using: [filter.sortDescriptor])
|
||||||
.compactMap { $0 as? LinkedItem }
|
.compactMap { $0 as? LinkedItem }
|
||||||
|
featureFilter = filter
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleReaderItemNotification(objectID: NSManagedObjectID, dataService: DataService) {
|
func handleReaderItemNotification(objectID: NSManagedObjectID, dataService: DataService) {
|
||||||
|
|||||||
@ -106,6 +106,17 @@ public extension FeaturedItemFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var emptyMessage: String {
|
||||||
|
switch self {
|
||||||
|
case .continueReading:
|
||||||
|
return "Your recently read items will appear here."
|
||||||
|
case .recommended:
|
||||||
|
return "Reads recommended in your Clubs will appear here."
|
||||||
|
case .newsletters:
|
||||||
|
return "All your Newsletters will appear here."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var predicate: NSPredicate {
|
var predicate: NSPredicate {
|
||||||
let undeletedPredicate = NSPredicate(
|
let undeletedPredicate = NSPredicate(
|
||||||
format: "%K != %i", #keyPath(LinkedItem.serverSyncStatus), Int64(ServerSyncStatus.needsDeletion.rawValue)
|
format: "%K != %i", #keyPath(LinkedItem.serverSyncStatus), Int64(ServerSyncStatus.needsDeletion.rawValue)
|
||||||
|
|||||||
@ -30,4 +30,5 @@ public enum UserDefaultKey: String {
|
|||||||
case deviceTokenID
|
case deviceTokenID
|
||||||
case shouldPromptCommunityModal
|
case shouldPromptCommunityModal
|
||||||
case userWordsPerMinute
|
case userWordsPerMinute
|
||||||
|
case hideFeatureSection
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user