Empty state handling for feature section

This commit is contained in:
Jackson Harper
2023-04-05 10:40:08 +08:00
parent 95a48f8752
commit de524736e2
5 changed files with 41 additions and 17 deletions

View File

@ -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 {

View File

@ -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))
} }

View File

@ -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) {

View File

@ -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)

View File

@ -30,4 +30,5 @@ public enum UserDefaultKey: String {
case deviceTokenID case deviceTokenID
case shouldPromptCommunityModal case shouldPromptCommunityModal
case userWordsPerMinute case userWordsPerMinute
case hideFeatureSection
} }