Skip to content

Commit

Permalink
Merge pull request #1314 from planetary-social/revert-home-feed-filter
Browse files Browse the repository at this point in the history
Revert home feed filter #1291
  • Loading branch information
mplorentz authored Jul 18, 2024
2 parents 02b7653 + 1e1244c commit c5da9cd
Show file tree
Hide file tree
Showing 15 changed files with 189 additions and 412 deletions.
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

- Add impersonation flag category and better NIP-56 mapping.
- Added a filter button to the Home tab that lets you browse all notes on a specific relay.
- Add a Tap to Refresh button in empty profiles.
- Update the reply count shown below each Note in a Feed.
- Removed follower count from profile screen.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,5 +216,5 @@
}
}
],
"version" : 2
"version": 2
}
47 changes: 12 additions & 35 deletions Nos/Assets/Localization/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -433,17 +433,6 @@
}
}
},
"accountsIFollow" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Accounts I Follow"
}
}
}
},
"activity" : {
"extractionState" : "manual",
"localizations" : {
Expand Down Expand Up @@ -4327,18 +4316,6 @@
}
}
},
"filter" : {
"comment" : "verb for filtering your feed in various ways",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "filter"
}
}
}
},
"flagUser" : {
"extractionState" : "manual",
"localizations" : {
Expand Down Expand Up @@ -7174,73 +7151,73 @@
"localizations" : {
"ar" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "لا يوجد ملاحظات (بعد)! اطلع على علامة التصفح واتبع بعض الأشخاص للبدء."
}
},
"de" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "(Noch) keine Notizen! Durchsuche das Tab \\\"Entdecken\\\" und folge einigen Leuten, um loszulegen."
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "No notes (yet), but we'll keep looking!"
"value" : "No notes (yet)! Browse the Discover tab and follow some people to get started."
}
},
"es" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "¡No hay notas (aún)! Navega a la pestaña de Descubrir y sigue a algunas personas para empezar."
}
},
"fa" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "(هنوز) هیچ یادداشتی نیست! برای شروع سربرگ یافتن را بگردید و چند نفر را دنبال کنید."
}
},
"fr" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "Aucune note (pour l'instant) ! Allez sur l'onglet \\\"Découvrir\\\" et suivez des gens pour commencer."
}
},
"ja" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "メモはまだありません!ディスカバー / 検索 タブをタップして、何人かのユーザーをフォローして始めましょう。"
}
},
"nl" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "Nog geen notes! Blader de Ontdek tab en volg enkele accounts om te beginnen."
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "Sem notas (ainda)! Navegue na guia \"Descobrir\" e siga algumas pessoas para começar."
}
},
"sv" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "Inga anteckningar (ännu)! Bläddra i fliken Upptäck och följ några personer för att komma igång."
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "(还)没有笔记!浏览发现选项卡并关注一些帐户以开始操作。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "(還)沒有筆記!瀏覽發現選項卡並關注一些帳戶以開始操作。"
}
}
Expand Down
31 changes: 6 additions & 25 deletions Nos/Controller/PagedNoteDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ class PagedNoteDataSource<Header: View, EmptyPlaceholder: View>: NSObject, UICol
var collectionView: UICollectionView

@Dependency(\.relayService) private var relayService: RelayService
private(set) var databaseFilter: NSFetchRequest<Event>
private(set) var relayFilter: Filter
private(set) var relay: Relay?
private var relayFilter: Filter
private var pager: PagedRelaySubscription?
private var context: NSManagedObjectContext
private var header: () -> Header
Expand All @@ -29,14 +27,12 @@ class PagedNoteDataSource<Header: View, EmptyPlaceholder: View>: NSObject, UICol
init(
databaseFilter: NSFetchRequest<Event>,
relayFilter: Filter,
relay: Relay?,
collectionView: UICollectionView,
context: NSManagedObjectContext,
@ViewBuilder header: @escaping () -> Header,
@ViewBuilder emptyPlaceholder: @escaping (@escaping () -> Void) -> EmptyPlaceholder,
onRefresh: @escaping () -> NSFetchRequest<Event>
) {
self.databaseFilter = databaseFilter
self.fetchedResultsController = NSFetchedResultsController<Event>(
fetchRequest: databaseFilter,
managedObjectContext: context,
Expand All @@ -46,7 +42,6 @@ class PagedNoteDataSource<Header: View, EmptyPlaceholder: View>: NSObject, UICol
self.collectionView = collectionView
self.context = context
self.relayFilter = relayFilter
self.relay = relay
self.header = header
self.emptyPlaceholder = emptyPlaceholder
self.onRefresh = onRefresh
Expand Down Expand Up @@ -74,23 +69,15 @@ class PagedNoteDataSource<Header: View, EmptyPlaceholder: View>: NSObject, UICol
Log.error(error)
}

subscribeToEvents(matching: relayFilter, from: relay)
}

func subscribeToEvents(matching filter: Filter, from relay: Relay?) {
self.relayFilter = filter
self.relay = relay

Task {
var limitedFilter = filter
Task {
var limitedFilter = relayFilter
limitedFilter.limit = pageSize
self.pager = await relayService.subscribeToPagedEvents(matching: limitedFilter, from: relay?.addressURL)
self.pager = await relayService.subscribeToPagedEvents(matching: limitedFilter)
loadMoreIfNeeded(for: IndexPath(row: 0, section: 0))
}
}

func updateFetchRequest(_ fetchRequest: NSFetchRequest<Event>) {
self.databaseFilter = fetchRequest
self.fetchedResultsController = NSFetchedResultsController<Event>(
fetchRequest: fetchRequest,
managedObjectContext: context,
Expand All @@ -100,8 +87,6 @@ class PagedNoteDataSource<Header: View, EmptyPlaceholder: View>: NSObject, UICol
self.fetchedResultsController.delegate = self
try? self.fetchedResultsController.performFetch()
loadMoreIfNeeded(for: IndexPath(row: 0, section: 0))
collectionView.reloadData()
collectionView.setContentOffset(.zero, animated: false)
}

// MARK: - UICollectionViewDataSource
Expand Down Expand Up @@ -224,9 +209,7 @@ class PagedNoteDataSource<Header: View, EmptyPlaceholder: View>: NSObject, UICol
startAggressivePaging()
return
} else if indexPath.row.isMultiple(of: pageSize / 2) {
Task {
await pager?.loadMore()
}
pager?.loadMore()
}
}

Expand Down Expand Up @@ -259,9 +242,7 @@ class PagedNoteDataSource<Header: View, EmptyPlaceholder: View>: NSObject, UICol

if self.largestLoadedRowIndex > lastPageStartIndex {
// we are still on the last page of results, keep loading
Task {
await self.pager?.loadMore()
}
self.pager?.loadMore()
} else {
// we've loaded enough, go back to normal paging
self.stopAggressivePaging()
Expand Down
33 changes: 11 additions & 22 deletions Nos/Models/CoreData/Event+CoreDataClass.swift
Original file line number Diff line number Diff line change
Expand Up @@ -480,32 +480,21 @@ public class Event: NosManagedObject, VerifiableEvent {
return fetchRequest
}

@nonobjc public class func homeFeedPredicate(
for user: Author,
before: Date,
seenOn relay: Relay? = nil
) -> NSPredicate {
// swiftlint:disable:next line_length
var queryString = "((kind = 1 AND SUBQUERY(eventReferences, $reference, $reference.marker = 'root' OR $reference.marker = 'reply' OR $reference.marker = nil).@count = 0) OR kind = 6 OR kind = 30023) AND author.muted = 0 AND createdAt <= %@ AND deletedOn.@count = 0"
var arguments: [CVarArg] = [before as CVarArg]
if let relay {
queryString.append(" AND ANY seenOnRelays = %@")
arguments.append(relay)
} else {
queryString.append(" AND (ANY author.followers.source = %@ OR author = %@)")
arguments += [user, user]
}
return NSPredicate(format: queryString, argumentArray: arguments)
@nonobjc public class func homeFeedPredicate(for user: Author, before: Date) -> NSPredicate {
NSPredicate(
// swiftlint:disable line_length
format: "((kind = 1 AND SUBQUERY(eventReferences, $reference, $reference.marker = 'root' OR $reference.marker = 'reply' OR $reference.marker = nil).@count = 0) OR kind = 6 OR kind = 30023) AND (ANY author.followers.source = %@ OR author = %@) AND author.muted = 0 AND createdAt <= %@ AND deletedOn.@count = 0",
// swiftlint:enable line_length
user,
user,
before as CVarArg
)
}

@nonobjc public class func homeFeed(
for user: Author,
before: Date,
seenOn relay: Relay? = nil
) -> NSFetchRequest<Event> {
@nonobjc public class func homeFeed(for user: Author, before: Date) -> NSFetchRequest<Event> {
let fetchRequest = NSFetchRequest<Event>(entityName: "Event")
fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \Event.createdAt, ascending: false)]
fetchRequest.predicate = homeFeedPredicate(for: user, before: before, seenOn: relay)
fetchRequest.predicate = homeFeedPredicate(for: user, before: before)
return fetchRequest
}

Expand Down
29 changes: 6 additions & 23 deletions Nos/Models/RelaySubscription.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import Foundation
import Logger
import Combine

/// Models a request to a relay for Nostr Events.
class RelaySubscription: Identifiable, Hashable {
struct RelaySubscription: Identifiable, Hashable {

var id: String

Expand All @@ -15,16 +14,16 @@ class RelaySubscription: Identifiable, Hashable {
/// The date this Filter was opened as a subscription on relays. Used to close stale subscriptions
var subscriptionStartDate: Date?

/// The oldest creation date on an event processed by this filter. Used for pagination.
var oldestEventCreationDate: Date?

/// The number of events that have been returned for this subscription
var receivedEventCount = 0

/// The number of objects using this filter. This is incremented and decremented by the RelayService to determine
/// when a filter can be closed.
var referenceCount: Int = 0

/// An observable stream of events that should emit every event downloaded on this subscription
let events: PassthroughSubject<JSONEvent, Never> = PassthroughSubject<JSONEvent, Never>()

var isActive: Bool {
subscriptionStartDate != nil
}
Expand All @@ -39,31 +38,15 @@ class RelaySubscription: Identifiable, Hashable {
filter: Filter,
relayAddress: URL,
subscriptionStartDate: Date? = nil,
oldestEventCreationDate: Date? = nil,
referenceCount: Int = 0
) {
self.filter = filter
self.relayAddress = relayAddress
// Compute a unique ID but predictable ID. The sha256 cuts the length down to an acceptable size.
self.id = (filter.id + "-" + relayAddress.absoluteString).data(using: .utf8)?.sha256 ?? "error"
self.subscriptionStartDate = subscriptionStartDate
self.oldestEventCreationDate = oldestEventCreationDate
self.referenceCount = referenceCount
}

static func == (lhs: RelaySubscription, rhs: RelaySubscription) -> Bool {
lhs.id == rhs.id &&
lhs.filter == rhs.filter &&
lhs.relayAddress == rhs.relayAddress &&
lhs.subscriptionStartDate == rhs.subscriptionStartDate &&
lhs.referenceCount == rhs.referenceCount &&
lhs.isActive == rhs.isActive
}

func hash(into hasher: inout Hasher) {
hasher.combine(id)
hasher.combine(filter)
hasher.combine(relayAddress)
hasher.combine(subscriptionStartDate)
hasher.combine(referenceCount)
hasher.combine(isActive)
}
}
4 changes: 2 additions & 2 deletions Nos/Service/MockRelaySubscriptionManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ class MockRelaySubscriptionManager: RelaySubscriptionManager {
}

var queueSubscriptionFilter: Filter?
func queueSubscription(with filter: Filter, to relayAddress: URL) async -> RelaySubscription {
func queueSubscription(with filter: Filter, to relayAddress: URL) async -> RelaySubscription.ID {
queueSubscriptionFilter = filter
return RelaySubscription(filter: filter, relayAddress: relayAddress)
return RelaySubscription.ID()
}

func remove(_ socket: any WebSocketClient) async {
Expand Down
6 changes: 3 additions & 3 deletions Nos/Service/Relay/Filter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import Foundation
struct Filter: Hashable, Identifiable {

/// List of author identifiers the Filter should be constrained to.
var authorKeys: [RawAuthorID]
let authorKeys: [RawAuthorID]

/// List of event identifiers the Filter should be constrained to.
let eventIDs: [RawEventID]

/// List of Note kinds to filter
var kinds: [EventKind]
let kinds: [EventKind]

/// Ask the relay to return events mentioned in the `tags` field.
let eTags: [RawEventID]
Expand Down Expand Up @@ -69,7 +69,7 @@ struct Filter: Hashable, Identifiable {
until: Date? = nil,
keepSubscriptionOpen: Bool = false
) {
self.authorKeys = authorKeys.sorted()
self.authorKeys = authorKeys.sorted(by: { $0 > $1 })
self.eventIDs = eventIDs
self.kinds = kinds.sorted(by: { $0.rawValue > $1.rawValue })
self.eTags = eTags
Expand Down
Loading

0 comments on commit c5da9cd

Please sign in to comment.