Improve labels loading for iOS17, bump version
This commit is contained in:
@ -1400,7 +1400,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||||
MARKETING_VERSION = 1.29.0;
|
MARKETING_VERSION = 1.30.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.app;
|
PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.app;
|
||||||
@ -1435,7 +1435,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||||
MARKETING_VERSION = 1.29.0;
|
MARKETING_VERSION = 1.30.0;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.app;
|
PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.app;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
@ -1490,7 +1490,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.29.0;
|
MARKETING_VERSION = 1.30.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.app;
|
PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.app;
|
||||||
PRODUCT_NAME = Omnivore;
|
PRODUCT_NAME = Omnivore;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -1831,7 +1831,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.29.0;
|
MARKETING_VERSION = 1.30.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.app;
|
PRODUCT_BUNDLE_IDENTIFIER = app.omnivore.app;
|
||||||
PRODUCT_NAME = Omnivore;
|
PRODUCT_NAME = Omnivore;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
|||||||
@ -20,7 +20,31 @@ struct FilterByLabelsView: View {
|
|||||||
viewModel.selectedLabels.contains(where: { $0.id == label.id })
|
viewModel.selectedLabels.contains(where: { $0.id == label.id })
|
||||||
}
|
}
|
||||||
|
|
||||||
var innerBody: some View {
|
func loadLabelsAsync() {
|
||||||
|
Task {
|
||||||
|
await viewModel.loadLabels(
|
||||||
|
dataService: dataService,
|
||||||
|
initiallySelectedLabels: initiallySelected,
|
||||||
|
initiallyNegatedLabels: initiallyNegated
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var navBody: some View {
|
||||||
|
if let errorMessage = viewModel.errorMessage {
|
||||||
|
AnyView(
|
||||||
|
VStack {
|
||||||
|
Text(errorMessage)
|
||||||
|
Button("Retry", action: loadLabelsAsync)
|
||||||
|
})
|
||||||
|
} else if viewModel.labels.isEmpty, viewModel.isLoading {
|
||||||
|
AnyView(ProgressView())
|
||||||
|
} else {
|
||||||
|
AnyView(labelsList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var labelsList: some View {
|
||||||
List {
|
List {
|
||||||
ForEach(viewModel.labels.applySearchFilter(viewModel.labelSearchFilter), id: \.self) { label in
|
ForEach(viewModel.labels.applySearchFilter(viewModel.labelSearchFilter), id: \.self) { label in
|
||||||
Button(
|
Button(
|
||||||
@ -48,7 +72,18 @@ struct FilterByLabelsView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.listStyle(PlainListStyle())
|
.listStyle(PlainListStyle())
|
||||||
.navigationTitle("Filter by Label")
|
}
|
||||||
|
|
||||||
|
var innerBody: some View {
|
||||||
|
navBody
|
||||||
|
.navigationTitle("Filter by Label")
|
||||||
|
.refreshable {
|
||||||
|
await viewModel.loadLabels(
|
||||||
|
dataService: dataService,
|
||||||
|
initiallySelectedLabels: initiallySelected,
|
||||||
|
initiallyNegatedLabels: initiallyNegated
|
||||||
|
)
|
||||||
|
}
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
@ -73,20 +108,16 @@ struct FilterByLabelsView: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
if viewModel.isLoading {
|
#if os(iOS)
|
||||||
EmptyView()
|
innerBody
|
||||||
} else {
|
.searchable(
|
||||||
#if os(iOS)
|
text: $viewModel.labelSearchFilter,
|
||||||
innerBody
|
placement: .navigationBarDrawer(displayMode: .always),
|
||||||
.searchable(
|
prompt: "Filter Labels"
|
||||||
text: $viewModel.labelSearchFilter,
|
)
|
||||||
placement: .navigationBarDrawer(displayMode: .always),
|
#else
|
||||||
prompt: "Filter Labels"
|
innerBody
|
||||||
)
|
#endif
|
||||||
#else
|
|
||||||
innerBody
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.task {
|
.task {
|
||||||
await viewModel.loadLabels(
|
await viewModel.loadLabels(
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import Views
|
|||||||
|
|
||||||
@MainActor final class FilterByLabelsViewModel: ObservableObject {
|
@MainActor final class FilterByLabelsViewModel: ObservableObject {
|
||||||
@Published var isLoading = false
|
@Published var isLoading = false
|
||||||
|
@Published var errorMessage: String? = nil
|
||||||
@Published var labels = [LinkedItemLabel]()
|
@Published var labels = [LinkedItemLabel]()
|
||||||
@Published var selectedLabels = [LinkedItemLabel]()
|
@Published var selectedLabels = [LinkedItemLabel]()
|
||||||
@Published var negatedLabels = [LinkedItemLabel]()
|
@Published var negatedLabels = [LinkedItemLabel]()
|
||||||
@ -26,7 +27,7 @@ import Views
|
|||||||
initiallyNegatedLabels: [LinkedItemLabel]
|
initiallyNegatedLabels: [LinkedItemLabel]
|
||||||
) async {
|
) async {
|
||||||
isLoading = true
|
isLoading = true
|
||||||
|
errorMessage = nil
|
||||||
await loadLabelsFromStore(dataService: dataService)
|
await loadLabelsFromStore(dataService: dataService)
|
||||||
for label in labels {
|
for label in labels {
|
||||||
if initiallySelectedLabels.contains(label) {
|
if initiallySelectedLabels.contains(label) {
|
||||||
@ -37,6 +38,11 @@ import Views
|
|||||||
unselectedLabels.append(label)
|
unselectedLabels.append(label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
isLoading = false
|
||||||
|
|
||||||
|
if labels.isEmpty {
|
||||||
|
isLoading = true
|
||||||
|
}
|
||||||
|
|
||||||
Task.detached(priority: .userInitiated) {
|
Task.detached(priority: .userInitiated) {
|
||||||
if let labelIDs = try? await dataService.labels() {
|
if let labelIDs = try? await dataService.labels() {
|
||||||
@ -53,11 +59,14 @@ import Views
|
|||||||
self.unselectedLabels.append(label)
|
self.unselectedLabels.append(label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.isLoading = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.errorMessage = "Error loading labels"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isLoading = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadLabelsFromStore(dataService: DataService) async {
|
func loadLabelsFromStore(dataService: DataService) async {
|
||||||
|
|||||||
@ -416,7 +416,7 @@
|
|||||||
let currentReadIndex = currentItem.index(currentItem.startIndex, offsetBy: min(currentItemOffset, currentItem.count))
|
let currentReadIndex = currentItem.index(currentItem.startIndex, offsetBy: min(currentItemOffset, currentItem.count))
|
||||||
let lastItem = String(currentItem[..<currentReadIndex])
|
let lastItem = String(currentItem[..<currentReadIndex])
|
||||||
let lastItemAfter = String(currentItem[currentReadIndex...])
|
let lastItemAfter = String(currentItem[currentReadIndex...])
|
||||||
|
|
||||||
readText = lastItem
|
readText = lastItem
|
||||||
unreadText = lastItemAfter
|
unreadText = lastItemAfter
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user