diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift
index 9b1c8c40b..f01eab5ac 100644
--- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift
+++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift
@@ -53,7 +53,8 @@ struct AnimatingCellHeight: AnimatableModifier {
}
var showFeatureCards: Bool {
- viewModel.listConfig.hasFeatureCards &&
+ isEditMode == .inactive &&
+ viewModel.listConfig.hasFeatureCards &&
!viewModel.hideFeatureSection &&
viewModel.fetcher.items.count > 0 &&
viewModel.searchTerm.isEmpty &&
@@ -204,14 +205,6 @@ struct AnimatingCellHeight: AnimatableModifier {
}
.frame(maxWidth: .infinity, alignment: .bottomLeading)
}
-
- ToolbarItem(placement: .barTrailing) {
- if UIDevice.isIPad, viewModel.folder == "inbox" {
- Button(action: { addLinkPresented = true }, label: {
- Label("Add Link", systemImage: "plus")
- })
- }
- }
ToolbarItem(placement: UIDevice.isIPhone ? .barLeading : .barTrailing) {
if enableGrid {
Button(
@@ -226,26 +219,31 @@ struct AnimatingCellHeight: AnimatableModifier {
Button(
action: { searchPresented = true },
label: {
- Image(systemName: "magnifyingglass")
+ Image.magnifyingGlass
.foregroundColor(Color.appGrayTextContrast)
}
)
}
ToolbarItem(placement: .barTrailing) {
- if UIDevice.isIPhone {
- Menu(content: {
- Button(action: {
- isEditMode = isEditMode == .inactive ? .active : .inactive
- }, label: {
- Text(isEditMode == .inactive ? "Select Multiple" : "End Multiselect")
- })
- Button(action: { addLinkPresented = true }, label: {
- Label("Add Link", systemImage: "plus.circle")
- })
- }, label: {
- Image.utilityMenu
- })
- .foregroundColor(.appGrayTextContrast)
+ Button(
+ action: { isEditMode = isEditMode == .active ? .inactive : .active },
+ label: {
+ Image.selectMultiple
+ .foregroundColor(Color.appGrayTextContrast)
+ }
+ )
+ }
+ ToolbarItem(placement: .barTrailing) {
+ if viewModel.folder == "inbox" {
+ Button(
+ action: { addLinkPresented = true },
+ label: {
+ Image.addLink
+ .foregroundColor(Color.appGrayTextContrast)
+ }
+ )
+ } else {
+ EmptyView()
}
}
ToolbarItemGroup(placement: .bottomBar) {
@@ -594,8 +592,45 @@ struct AnimatingCellHeight: AnimatableModifier {
}
}
+ var listItems: some View {
+ ForEach(Array(viewModel.fetcher.items.enumerated()), id: \.1.unwrappedID) { _, item in
+ let horizontalInset = CGFloat(UIDevice.isIPad ? 20 : 10)
+
+ FeedCardNavigationLink(
+ item: item,
+ isInMultiSelectMode: viewModel.isInMultiSelectMode,
+ viewModel: viewModel
+ )
+ .background(GeometryReader { geometry in
+ Color.clear
+ .preference(key: ScrollOffsetPreferenceKey.self, value: geometry.frame(in: .named("scroll")).origin)
+ })
+ .onPreferenceChange(ScrollOffsetPreferenceKey.self) { value in
+ if value.y < 100, value.y > 0 {
+ if item.savedAt != nil, topItem != item {
+ setTopItem(item)
+ }
+ }
+ }
+ .listRowSeparatorTint(Color.thBorderColor)
+ .listRowInsets(.init(top: 0, leading: horizontalInset, bottom: 10, trailing: horizontalInset))
+ .contextMenu {
+ menuItems(for: item)
+ }
+ .swipeActions(edge: .leading, allowsFullSwipe: true) {
+ ForEach(viewModel.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)
+ }
+ }
+ }
+ }
+
var body: some View {
- let horizontalInset = CGFloat(UIDevice.isIPad ? 20 : 10)
VStack(spacing: 0) {
Color.systemBackground.frame(height: 1)
ScrollViewReader { reader in
@@ -634,38 +669,14 @@ struct AnimatingCellHeight: AnimatableModifier {
}
}
- ForEach(Array(viewModel.fetcher.items.enumerated()), id: \.1.unwrappedID) { _, item in
- FeedCardNavigationLink(
- item: item,
- isInMultiSelectMode: viewModel.isInMultiSelectMode,
- viewModel: viewModel
- )
- .background(GeometryReader { geometry in
- Color.clear
- .preference(key: ScrollOffsetPreferenceKey.self, value: geometry.frame(in: .named("scroll")).origin)
- })
- .onPreferenceChange(ScrollOffsetPreferenceKey.self) { value in
- if value.y < 100, value.y > 0 {
- if item.savedAt != nil, topItem != item {
- setTopItem(item)
- }
- }
- }
- .listRowSeparatorTint(Color.thBorderColor)
- .listRowInsets(.init(top: 0, leading: horizontalInset, bottom: 10, trailing: horizontalInset))
- .contextMenu {
- menuItems(for: item)
- }
- .swipeActions(edge: .leading, allowsFullSwipe: true) {
- ForEach(viewModel.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 viewModel.showLoadingBar {
+ HStack(alignment: .center, spacing: 10) {
+ ProgressView()
}
+ .frame(height: 100)
+ .listRowSeparator(.hidden)
+ } else {
+ listItems
}
}
}, header: {
diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift
index 03f63bd66..96e4f2b81 100644
--- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift
+++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift
@@ -152,10 +152,9 @@ import Views
func loadItems(dataService: DataService, isRefresh: Bool) async {
isLoading = true
- showLoadingBar = true
+ showLoadingBar = isRefresh
await fetcher.loadItems(dataService: dataService, filterState: filterState, isRefresh: isRefresh)
-
updateFeatureFilter(context: dataService.viewContext, filter: FeaturedItemFilter(rawValue: featureFilter))
isLoading = false
@@ -164,12 +163,10 @@ import Views
func loadMoreItems(dataService: DataService, filterState: FetcherFilterState, isRefresh: Bool) async {
isLoading = true
- showLoadingBar = true
await fetcher.loadMoreItems(dataService: dataService, filterState: filterState, isRefresh: isRefresh)
isLoading = false
- showLoadingBar = false
}
func loadFeatureItems(context: NSManagedObjectContext, predicate: NSPredicate, sort: NSSortDescriptor) async -> [Models.LibraryItem] {
diff --git a/apple/OmnivoreKit/Sources/Utils/FirstFewWords.swift b/apple/OmnivoreKit/Sources/Utils/FirstFewWords.swift
new file mode 100644
index 000000000..4d752dc4e
--- /dev/null
+++ b/apple/OmnivoreKit/Sources/Utils/FirstFewWords.swift
@@ -0,0 +1,31 @@
+//
+// File.swift
+//
+//
+// Created by Jackson Harper on 12/8/23.
+//
+
+import Foundation
+import NaturalLanguage
+
+public func extractFirstFewWords(_ title: String) -> String {
+ let languageRecognizer = NLLanguageRecognizer()
+
+ languageRecognizer.processString(title)
+ let language = languageRecognizer.dominantLanguage ?? NLLanguage.english
+
+ let tokenizer = NLTokenizer(unit: .word)
+ tokenizer.setLanguage(language)
+ tokenizer.string = title
+
+ var words: [String] = []
+ tokenizer.enumerateTokens(in: title.startIndex ..< title.endIndex) { range, _ in
+ let word = String(title[range])
+ words.append(word)
+ return true
+ }
+
+ print("WORDS: ", words)
+ let truncatedTitle = words.prefix(2).joined(separator: " ")
+ return truncatedTitle
+}
diff --git a/apple/OmnivoreKit/Sources/Views/Images/Images.swift b/apple/OmnivoreKit/Sources/Views/Images/Images.swift
index d66deb6f1..eb8817b63 100644
--- a/apple/OmnivoreKit/Sources/Views/Images/Images.swift
+++ b/apple/OmnivoreKit/Sources/Views/Images/Images.swift
@@ -21,6 +21,10 @@ public extension Image {
static var readerSettings: Image { Image("reader-settings", bundle: .module) }
static var utilityMenu: Image { Image("utility-menu", bundle: .module) }
+ static var addLink: Image { Image("add-link", bundle: .module) }
+ static var selectMultiple: Image { Image("select-multiple", bundle: .module) }
+ static var magnifyingGlass: Image { Image("magnifying-glass", bundle: .module) }
+
static var archive: Image { Image("archive", bundle: .module) }
static var unarchive: Image { Image("unarchive", bundle: .module) }
static var remove: Image { Image("remove", bundle: .module) }
diff --git a/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/add-link.imageset/Contents.json b/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/add-link.imageset/Contents.json
new file mode 100644
index 000000000..e343db9c2
--- /dev/null
+++ b/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/add-link.imageset/Contents.json
@@ -0,0 +1,24 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "add-link.svg",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/add-link.imageset/add-link.svg b/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/add-link.imageset/add-link.svg
new file mode 100644
index 000000000..b4d8e3edc
--- /dev/null
+++ b/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/add-link.imageset/add-link.svg
@@ -0,0 +1,11 @@
+
diff --git a/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/magnifying-glass.imageset/Contents.json b/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/magnifying-glass.imageset/Contents.json
new file mode 100644
index 000000000..1da65d1a1
--- /dev/null
+++ b/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/magnifying-glass.imageset/Contents.json
@@ -0,0 +1,24 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "magnifying-glass.svg",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/magnifying-glass.imageset/magnifying-glass.svg b/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/magnifying-glass.imageset/magnifying-glass.svg
new file mode 100644
index 000000000..65cf1cce7
--- /dev/null
+++ b/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/magnifying-glass.imageset/magnifying-glass.svg
@@ -0,0 +1,11 @@
+
diff --git a/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/select-multiple.imageset/Contents.json b/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/select-multiple.imageset/Contents.json
new file mode 100644
index 000000000..fe3fde928
--- /dev/null
+++ b/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/select-multiple.imageset/Contents.json
@@ -0,0 +1,24 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "multiple-select.svg",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/select-multiple.imageset/multiple-select.svg b/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/select-multiple.imageset/multiple-select.svg
new file mode 100644
index 000000000..66cf30494
--- /dev/null
+++ b/apple/OmnivoreKit/Sources/Views/Images/Images.xcassets/select-multiple.imageset/multiple-select.svg
@@ -0,0 +1,11 @@
+