fix: remove broken mark-as-read on scroll entirely
onDisappear fires when scrolling in BOTH directions and when navigating, making it impossible to reliably detect scroll direction. Reverted to simple behavior: articles only mark as read when you tap into them (handled in ArticleView). Will revisit mark-on-scroll with a proper ScrollViewReader approach later. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,12 +3,11 @@ import SwiftUI
|
|||||||
struct EntryListView: View {
|
struct EntryListView: View {
|
||||||
@Bindable var vm: ReaderViewModel
|
@Bindable var vm: ReaderViewModel
|
||||||
var isCardView: Bool = true
|
var isCardView: Bool = true
|
||||||
@State private var visibleEntryIDs: Set<Int> = []
|
|
||||||
@State private var readByScrollIDs: Set<Int> = []
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if vm.isLoading && vm.entries.isEmpty {
|
if vm.isLoading && vm.entries.isEmpty {
|
||||||
LoadingView()
|
LoadingView()
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
} else if vm.entries.isEmpty {
|
} else if vm.entries.isEmpty {
|
||||||
EmptyStateView(
|
EmptyStateView(
|
||||||
icon: "newspaper",
|
icon: "newspaper",
|
||||||
@@ -17,6 +16,7 @@ struct EntryListView: View {
|
|||||||
? "Star articles to save them here"
|
? "Star articles to save them here"
|
||||||
: "All caught up!"
|
: "All caught up!"
|
||||||
)
|
)
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
} else {
|
} else {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
if isCardView {
|
if isCardView {
|
||||||
@@ -44,8 +44,6 @@ struct EntryListView: View {
|
|||||||
}
|
}
|
||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
.onAppear { visibleEntryIDs.insert(entry.id) }
|
|
||||||
.onDisappear { markReadIfScrolled(entry) }
|
|
||||||
.contextMenu {
|
.contextMenu {
|
||||||
entryContextMenu(entry: entry, vm: vm)
|
entryContextMenu(entry: entry, vm: vm)
|
||||||
}
|
}
|
||||||
@@ -69,8 +67,6 @@ struct EntryListView: View {
|
|||||||
}
|
}
|
||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
.onAppear { visibleEntryIDs.insert(entry.id) }
|
|
||||||
.onDisappear { markReadIfScrolled(entry) }
|
|
||||||
.contextMenu {
|
.contextMenu {
|
||||||
entryContextMenu(entry: entry, vm: vm)
|
entryContextMenu(entry: entry, vm: vm)
|
||||||
}
|
}
|
||||||
@@ -85,24 +81,6 @@ struct EntryListView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Mark as read on scroll
|
|
||||||
|
|
||||||
/// Only mark as read if the entry was visible before AND has scrolled off
|
|
||||||
/// while other entries are still visible (i.e. user is scrolling, not navigating away)
|
|
||||||
private func markReadIfScrolled(_ entry: ReaderEntry) {
|
|
||||||
// Remove from visible set
|
|
||||||
visibleEntryIDs.remove(entry.id)
|
|
||||||
|
|
||||||
// If there are still visible entries, user is scrolling (not navigating)
|
|
||||||
// and this entry scrolled off → mark as read
|
|
||||||
guard !visibleEntryIDs.isEmpty else { return }
|
|
||||||
guard !entry.isRead else { return }
|
|
||||||
guard !readByScrollIDs.contains(entry.id) else { return }
|
|
||||||
|
|
||||||
readByScrollIDs.insert(entry.id)
|
|
||||||
Task { await vm.markAsRead(entry) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private var loadMoreTrigger: some View {
|
private var loadMoreTrigger: some View {
|
||||||
Group {
|
Group {
|
||||||
if vm.isLoadingMore {
|
if vm.isLoadingMore {
|
||||||
|
|||||||
Reference in New Issue
Block a user