commit 8da251dc88f9846fbce302672435a1c59dfca593
parent 040ffdf9f597da3a83a91a8411a5bd6f7a0356f6
Author: William Casarin <jb55@jb55.com>
Date: Sat, 14 May 2022 15:35:34 -0700
send_filters refactor
Signed-off-by: William Casarin <jb55@jb55.com>
Diffstat:
11 files changed, 129 insertions(+), 36 deletions(-)
diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj
@@ -37,6 +37,7 @@
4C3BEFDA281DCA1400B3DE84 /* LikeCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3BEFD9281DCA1400B3DE84 /* LikeCounter.swift */; };
4C3BEFDC281DCE6100B3DE84 /* Liked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3BEFDB281DCE6100B3DE84 /* Liked.swift */; };
4C3BEFE0281DE1ED00B3DE84 /* DamusState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3BEFDF281DE1ED00B3DE84 /* DamusState.swift */; };
+ 4C477C9E282C3A4800033AA3 /* TipCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C477C9D282C3A4800033AA3 /* TipCounter.swift */; };
4C75EFA427FA577B0006080F /* PostView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFA327FA577B0006080F /* PostView.swift */; };
4C75EFA627FF87A20006080F /* Nostr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFA527FF87A20006080F /* Nostr.swift */; };
4C75EFAD28049CFB0006080F /* PostButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFAC28049CFB0006080F /* PostButton.swift */; };
@@ -120,6 +121,7 @@
4C3BEFD9281DCA1400B3DE84 /* LikeCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LikeCounter.swift; sourceTree = "<group>"; };
4C3BEFDB281DCE6100B3DE84 /* Liked.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Liked.swift; sourceTree = "<group>"; };
4C3BEFDF281DE1ED00B3DE84 /* DamusState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusState.swift; sourceTree = "<group>"; };
+ 4C477C9D282C3A4800033AA3 /* TipCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TipCounter.swift; sourceTree = "<group>"; };
4C75EFA327FA577B0006080F /* PostView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostView.swift; sourceTree = "<group>"; };
4C75EFA527FF87A20006080F /* Nostr.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Nostr.swift; sourceTree = "<group>"; };
4C75EFA72804823E0006080F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
@@ -258,6 +260,7 @@
4C363A8328233689006E126D /* Parser.swift */,
4C363A8528234FDE006E126D /* ImageCache.swift */,
4C363AA728297703006E126D /* InsertSort.swift */,
+ 4C477C9D282C3A4800033AA3 /* TipCounter.swift */,
);
path = Util;
sourceTree = "<group>";
@@ -490,6 +493,7 @@
4C363A9828283441006E126D /* TestingPrivate.swift in Sources */,
4C363A9028247A1D006E126D /* NostrLink.swift in Sources */,
4C0A3F8C280F5FCA000448DE /* ChatroomView.swift in Sources */,
+ 4C477C9E282C3A4800033AA3 /* TipCounter.swift in Sources */,
4C0A3F91280F6528000448DE /* ChatView.swift in Sources */,
4C75EFA627FF87A20006080F /* Nostr.swift in Sources */,
4C75EFB328049D640006080F /* NostrEvent.swift in Sources */,
diff --git a/damus/ContentView.swift b/damus/ContentView.swift
@@ -360,6 +360,7 @@ struct ContentView: View {
func connect() {
let pool = RelayPool()
+ add_relay(pool, "wss://relay.damus.io")
add_relay(pool, "wss://nostr-pub.wellorder.net")
add_relay(pool, "wss://nostr.onsats.org")
add_relay(pool, "wss://nostr.bitcoiner.social")
@@ -372,6 +373,7 @@ struct ContentView: View {
self.damus = DamusState(pool: pool, pubkey: pubkey,
likes: EventCounter(our_pubkey: pubkey),
boosts: EventCounter(our_pubkey: pubkey),
+ tips: TipCounter(our_pubkey: pubkey),
image_cache: ImageCache(),
profiles: Profiles()
)
@@ -393,7 +395,7 @@ struct ContentView: View {
var boost_ev_id = ev.last_refid()?.ref_id
// CHECK SIGS ON THESE
- if var inner_ev = ev.inner_event {
+ if let inner_ev = ev.inner_event {
boost_ev_id = inner_ev.id
if inner_ev.kind == 1 {
@@ -461,32 +463,21 @@ struct ContentView: View {
func send_filters(relay_id: String) {
// TODO: since times should be based on events from a specific relay
// perhaps we could mark this in the relay pool somehow
- let last_text_event = get_last_event_of_kind(relay_id: relay_id, kind: NostrKind.text.rawValue)
- let since = get_since_time(last_event: last_text_event)
- var since_filter = NostrFilter.filter_kinds([1,5,6])
- since_filter.since = since
-
- let last_like_event = get_last_event_of_kind(relay_id: relay_id, kind: 7)
- var like_filter = NostrFilter.filter_kinds([7])
- like_filter.since = get_since_time(last_event: last_like_event)
- //like_filter.ids = get_like_pow()
-
- let last_metadata_event = get_last_event_of_kind(relay_id: relay_id, kind: NostrKind.metadata.rawValue)
- var profile_filter = NostrFilter.filter_profiles
- if let prof_since = get_metadata_since_time(last_metadata_event) {
- profile_filter.since = prof_since
- }
-
- /*
- var notification_filter = NostrFilter.filter_text
- notification_filter.since = since
- */
-
+ let text_filter = NostrFilter.filter_kinds([1,5,6,7])
+ let profile_filter = NostrFilter.filter_profiles
var contacts_filter = NostrFilter.filter_contacts
contacts_filter.authors = [self.pubkey]
- let filters = [since_filter, profile_filter, contacts_filter, like_filter]
- print("connected to \(relay_id), refreshing from \(since)")
+ var filters = [text_filter, profile_filter, contacts_filter]
+
+ filters = update_filters_with_since(last_of_kind: last_event_of_kind[relay_id] ?? [:], filters: filters)
+
+ print("connected to \(relay_id) with filters:")
+ for filter in filters {
+ print(filter)
+ }
+ print("-----")
+
self.damus?.pool.send(.subscribe(.init(filters: filters, sub_id: sub_id)), to: [relay_id])
//self.pool?.send(.subscribe(.init(filters: [notification_filter], sub_id: "notifications")))
}
@@ -734,3 +725,40 @@ func save_last_notified(_ ev: NostrEvent) {
func get_like_pow() -> [String] {
return ["00000"] // 20 bits
}
+
+
+func update_filters_with_since(last_of_kind: [Int: NostrEvent], filters: [NostrFilter]) -> [NostrFilter] {
+ let now = Int64(Date.now.timeIntervalSince1970)
+
+ return filters.map { filter in
+ let kinds = filter.kinds ?? []
+ let initial: Int64? = nil
+ let earliest = kinds.reduce(initial) { earliest, kind in
+ let last = last_of_kind[kind]
+ var since: Int64? = nil
+
+ if kind == 0 {
+ since = get_metadata_since_time(last)
+ } else {
+ since = get_since_time(last_event: last)
+ }
+
+ if earliest == nil {
+ if since == nil {
+ return nil
+ }
+ return since
+ }
+
+ return since! < earliest! ? since! : earliest!
+ }
+
+ if let earliest = earliest {
+ var with_since = NostrFilter.copy(from: filter)
+ with_since.since = earliest
+ return with_since
+ }
+
+ return filter
+ }
+}
diff --git a/damus/Models/ActionBarModel.swift b/damus/Models/ActionBarModel.swift
@@ -11,14 +11,22 @@ import Foundation
class ActionBarModel: ObservableObject {
@Published var our_like: NostrEvent?
@Published var our_boost: NostrEvent?
+ @Published var our_tip: NostrEvent?
@Published var likes: Int
@Published var boosts: Int
+ @Published var tips: Int64
- init(likes: Int, boosts: Int, our_like: NostrEvent?, our_boost: NostrEvent?) {
+ init(likes: Int, boosts: Int, tips: Int64, our_like: NostrEvent?, our_boost: NostrEvent?, our_tip: NostrEvent?) {
self.likes = likes
self.boosts = boosts
+ self.tips = tips
self.our_like = our_like
self.our_boost = our_boost
+ self.our_tip = our_tip
+ }
+
+ var tipped: Bool {
+ return our_tip != nil
}
var liked: Bool {
diff --git a/damus/Models/DamusState.swift b/damus/Models/DamusState.swift
@@ -12,6 +12,7 @@ struct DamusState {
let pubkey: String
let likes: EventCounter
let boosts: EventCounter
+ let tips: TipCounter
let image_cache: ImageCache
let profiles: Profiles
}
diff --git a/damus/Models/ProfileModel.swift b/damus/Models/ProfileModel.swift
@@ -36,6 +36,7 @@ class ProfileModel: ObservableObject {
var filter = NostrFilter.filter_authors([pubkey])
filter.kinds = kinds
+ filter.limit = 500
print("subscribing to profile \(pubkey) with sub_id \(sub_id)")
damus.pool.subscribe(sub_id: sub_id, filters: [filter], handler: handle_event)
diff --git a/damus/Models/SearchModel.swift b/damus/Models/SearchModel.swift
@@ -13,6 +13,7 @@ class SearchModel: ObservableObject {
let pool: RelayPool
var search: NostrFilter
let sub_id = UUID().description
+ let limit: UInt32 = 500
init(pool: RelayPool, search: NostrFilter) {
self.pool = pool
@@ -21,7 +22,7 @@ class SearchModel: ObservableObject {
func subscribe() {
// since 1 month
- search.since = Int64(Date.now.timeIntervalSince1970) - 2629800 * 1
+ search.limit = self.limit
search.kinds = [1,5,7]
//likes_filter.ids = ref_events.referenced_ids!
diff --git a/damus/Nostr/NostrFilter.swift b/damus/Nostr/NostrFilter.swift
@@ -14,6 +14,7 @@ struct NostrFilter: Codable {
var pubkeys: [String]?
var since: Int64?
var until: Int64?
+ var limit: UInt32?
var authors: [String]?
var hashtag: [String]? = nil
@@ -26,6 +27,7 @@ struct NostrFilter: Codable {
case since
case until
case authors
+ case limit
}
public static func copy(from: NostrFilter) -> NostrFilter {
diff --git a/damus/Util/TipCounter.swift b/damus/Util/TipCounter.swift
@@ -0,0 +1,25 @@
+//
+// TipCounter.swift
+// damus
+//
+// Created by William Casarin on 2022-05-11.
+//
+
+import Foundation
+
+class TipCounter {
+ var tips: [String: Int64] = [:]
+ var user_tips: [String: Set<String>] = [:]
+ var our_tips: [String: NostrEvent] = [:]
+ var our_pubkey: String
+
+ enum CountResult {
+ case already_tipped
+ case success(Int64)
+ }
+
+ init (our_pubkey: String) {
+ self.our_pubkey = our_pubkey
+ }
+}
+
diff --git a/damus/Views/ChatView.swift b/damus/Views/ChatView.swift
@@ -113,7 +113,7 @@ struct ChatView: View {
NoteContentView(event: event, profiles: damus.profiles, content: event.content)
if is_active || next_ev == nil || next_ev!.pubkey != event.pubkey {
- let bar = make_actionbar_model(ev: event, like_counter: damus.likes, boost_counter: damus.boosts)
+ let bar = make_actionbar_model(ev: event, damus: damus)
EventActionBar(event: event,
our_pubkey: damus.pubkey,
profiles: damus.profiles,
diff --git a/damus/Views/EventActionBar.swift b/damus/Views/EventActionBar.swift
@@ -37,7 +37,7 @@ struct EventActionBar: View {
EventActionButton(img: "bubble.left", col: nil) {
notify(.reply, event)
}
- .padding([.trailing], 40)
+ .padding([.trailing], 20)
HStack(alignment: .bottom) {
Text("\(bar.likes > 0 ? "\(bar.likes)" : "")")
@@ -52,7 +52,7 @@ struct EventActionBar: View {
}
}
}
- .padding([.trailing], 40)
+ .padding([.trailing], 20)
HStack(alignment: .bottom) {
Text("\(bar.boosts > 0 ? "\(bar.boosts)" : "")")
@@ -67,6 +67,21 @@ struct EventActionBar: View {
}
}
}
+ .padding([.trailing], 20)
+
+ HStack(alignment: .bottom) {
+ Text("\(bar.tips > 0 ? "\(bar.tips)" : "")")
+ .font(.footnote)
+ .foregroundColor(bar.tipped ? Color.orange : Color.gray)
+
+ EventActionButton(img: bar.tipped ? "bitcoinsign.circle.fill" : "bitcoinsign.circle", col: bar.tipped ? Color.orange : nil) {
+ if bar.tipped {
+ notify(.delete, bar.our_tip)
+ } else {
+ notify(.boost, event)
+ }
+ }
+ }
}
.onReceive(handle_notify(.liked)) { n in
diff --git a/damus/Views/EventView.swift b/damus/Views/EventView.swift
@@ -99,7 +99,7 @@ struct EventView: View {
Spacer()
if has_action_bar {
- let bar = make_actionbar_model(ev: event, like_counter: damus.likes, boost_counter: damus.boosts)
+ let bar = make_actionbar_model(ev: event, damus: damus)
EventActionBar(event: event, our_pubkey: damus.pubkey, profiles: damus.profiles, bar: bar)
}
@@ -180,11 +180,19 @@ func reply_others_desc(n: Int, n_pubkeys: Int) -> String {
-func make_actionbar_model(ev: NostrEvent, like_counter: EventCounter, boost_counter: EventCounter) -> ActionBarModel {
- let likes = like_counter.counts[ev.id]
- let boosts = boost_counter.counts[ev.id]
- let our_like = like_counter.our_events[ev.id]
- let our_boost = boost_counter.our_events[ev.id]
+func make_actionbar_model(ev: NostrEvent, damus: DamusState) -> ActionBarModel {
+ let likes = damus.likes.counts[ev.id]
+ let boosts = damus.boosts.counts[ev.id]
+ let tips = damus.tips.tips[ev.id]
+ let our_like = damus.likes.our_events[ev.id]
+ let our_boost = damus.boosts.our_events[ev.id]
+ let our_tip = damus.tips.our_tips[ev.id]
- return ActionBarModel(likes: likes ?? 0, boosts: boosts ?? 0, our_like: our_like, our_boost: our_boost)
+ return ActionBarModel(likes: likes ?? 0,
+ boosts: boosts ?? 0,
+ tips: tips ?? 0,
+ our_like: our_like,
+ our_boost: our_boost,
+ our_tip: our_tip
+ )
}