feat: read-shelf auto-expand, stripe removal, pull-reshuffle, BG notifications
- Mark-read now immediately expands the READ shelf so the story is visible - Orange signal stripe is fully removed (not dimmed) when isRead=true - Pull-to-refresh clears seen snapshot → full reshuffle by signal score - BackgroundRefreshManager fires a local notification for the top new high-signal story after each cache refresh; Tech/AI/HomeLab stories get their category in the notification title (≥65 signal threshold) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -272,9 +272,13 @@ struct SignalFeedView: View {
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(Color.black)
|
||||
.animation(.snappy, value: showRead)
|
||||
.animation(.snappy, value: readStories.count)
|
||||
.onAppear { captureSeenSnapshot() }
|
||||
.refreshable {
|
||||
captureSeenSnapshot() // sink what you've already seen
|
||||
// Reshuffle: clear the seen snapshot so all stories re-rank by signal
|
||||
// score, and any stories cached by background refresh float to the top.
|
||||
seenSnapshot = []
|
||||
seenTracker.ids = []
|
||||
await store.loadStories(refresh: true)
|
||||
}
|
||||
}
|
||||
@@ -566,6 +570,7 @@ struct SignalFeedView: View {
|
||||
if existing?.first == nil {
|
||||
modelContext.insert(ReadStory(id: id))
|
||||
try? modelContext.save()
|
||||
withAnimation(.snappy) { showRead = true }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,12 @@ struct StoryRowView: View {
|
||||
|
||||
private var fullBody: some View {
|
||||
HStack(alignment: .top, spacing: 0) {
|
||||
SignalStripe(score: story.signalScore, muted: isRead)
|
||||
if isRead {
|
||||
// No stripe for read stories — remove the orange signal indicator entirely.
|
||||
Color.clear.frame(width: 3)
|
||||
} else {
|
||||
SignalStripe(score: story.signalScore)
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 9) {
|
||||
// Title (+ cached dot)
|
||||
@@ -90,7 +95,6 @@ struct StoryRowView: View {
|
||||
.padding(.trailing, 16)
|
||||
.padding(.top, 16)
|
||||
}
|
||||
.opacity(isRead ? 0.55 : 1)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.background(Color.black)
|
||||
.overlay(alignment: .bottom) {
|
||||
|
||||
Reference in New Issue
Block a user