send_filters refactor

Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
William Casarin
2022-05-14 15:35:34 -07:00
parent 040ffdf9f5
commit 8da251dc88
11 changed files with 129 additions and 36 deletions

View File

@@ -37,6 +37,7 @@
4C3BEFDA281DCA1400B3DE84 /* LikeCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3BEFD9281DCA1400B3DE84 /* LikeCounter.swift */; }; 4C3BEFDA281DCA1400B3DE84 /* LikeCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3BEFD9281DCA1400B3DE84 /* LikeCounter.swift */; };
4C3BEFDC281DCE6100B3DE84 /* Liked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3BEFDB281DCE6100B3DE84 /* Liked.swift */; }; 4C3BEFDC281DCE6100B3DE84 /* Liked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3BEFDB281DCE6100B3DE84 /* Liked.swift */; };
4C3BEFE0281DE1ED00B3DE84 /* DamusState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3BEFDF281DE1ED00B3DE84 /* DamusState.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 */; }; 4C75EFA427FA577B0006080F /* PostView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFA327FA577B0006080F /* PostView.swift */; };
4C75EFA627FF87A20006080F /* Nostr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFA527FF87A20006080F /* Nostr.swift */; }; 4C75EFA627FF87A20006080F /* Nostr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFA527FF87A20006080F /* Nostr.swift */; };
4C75EFAD28049CFB0006080F /* PostButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFAC28049CFB0006080F /* PostButton.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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 4C75EFA72804823E0006080F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
@@ -258,6 +260,7 @@
4C363A8328233689006E126D /* Parser.swift */, 4C363A8328233689006E126D /* Parser.swift */,
4C363A8528234FDE006E126D /* ImageCache.swift */, 4C363A8528234FDE006E126D /* ImageCache.swift */,
4C363AA728297703006E126D /* InsertSort.swift */, 4C363AA728297703006E126D /* InsertSort.swift */,
4C477C9D282C3A4800033AA3 /* TipCounter.swift */,
); );
path = Util; path = Util;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -490,6 +493,7 @@
4C363A9828283441006E126D /* TestingPrivate.swift in Sources */, 4C363A9828283441006E126D /* TestingPrivate.swift in Sources */,
4C363A9028247A1D006E126D /* NostrLink.swift in Sources */, 4C363A9028247A1D006E126D /* NostrLink.swift in Sources */,
4C0A3F8C280F5FCA000448DE /* ChatroomView.swift in Sources */, 4C0A3F8C280F5FCA000448DE /* ChatroomView.swift in Sources */,
4C477C9E282C3A4800033AA3 /* TipCounter.swift in Sources */,
4C0A3F91280F6528000448DE /* ChatView.swift in Sources */, 4C0A3F91280F6528000448DE /* ChatView.swift in Sources */,
4C75EFA627FF87A20006080F /* Nostr.swift in Sources */, 4C75EFA627FF87A20006080F /* Nostr.swift in Sources */,
4C75EFB328049D640006080F /* NostrEvent.swift in Sources */, 4C75EFB328049D640006080F /* NostrEvent.swift in Sources */,

View File

@@ -360,6 +360,7 @@ struct ContentView: View {
func connect() { func connect() {
let pool = RelayPool() let pool = RelayPool()
add_relay(pool, "wss://relay.damus.io")
add_relay(pool, "wss://nostr-pub.wellorder.net") add_relay(pool, "wss://nostr-pub.wellorder.net")
add_relay(pool, "wss://nostr.onsats.org") add_relay(pool, "wss://nostr.onsats.org")
add_relay(pool, "wss://nostr.bitcoiner.social") add_relay(pool, "wss://nostr.bitcoiner.social")
@@ -372,6 +373,7 @@ struct ContentView: View {
self.damus = DamusState(pool: pool, pubkey: pubkey, self.damus = DamusState(pool: pool, pubkey: pubkey,
likes: EventCounter(our_pubkey: pubkey), likes: EventCounter(our_pubkey: pubkey),
boosts: EventCounter(our_pubkey: pubkey), boosts: EventCounter(our_pubkey: pubkey),
tips: TipCounter(our_pubkey: pubkey),
image_cache: ImageCache(), image_cache: ImageCache(),
profiles: Profiles() profiles: Profiles()
) )
@@ -393,7 +395,7 @@ struct ContentView: View {
var boost_ev_id = ev.last_refid()?.ref_id var boost_ev_id = ev.last_refid()?.ref_id
// CHECK SIGS ON THESE // CHECK SIGS ON THESE
if var inner_ev = ev.inner_event { if let inner_ev = ev.inner_event {
boost_ev_id = inner_ev.id boost_ev_id = inner_ev.id
if inner_ev.kind == 1 { if inner_ev.kind == 1 {
@@ -461,32 +463,21 @@ struct ContentView: View {
func send_filters(relay_id: String) { func send_filters(relay_id: String) {
// TODO: since times should be based on events from a specific relay // TODO: since times should be based on events from a specific relay
// perhaps we could mark this in the relay pool somehow // 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 text_filter = NostrFilter.filter_kinds([1,5,6,7])
let since = get_since_time(last_event: last_text_event) let profile_filter = NostrFilter.filter_profiles
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
*/
var contacts_filter = NostrFilter.filter_contacts var contacts_filter = NostrFilter.filter_contacts
contacts_filter.authors = [self.pubkey] contacts_filter.authors = [self.pubkey]
let filters = [since_filter, profile_filter, contacts_filter, like_filter] var filters = [text_filter, profile_filter, contacts_filter]
print("connected to \(relay_id), refreshing from \(since)")
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.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"))) //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] { func get_like_pow() -> [String] {
return ["00000"] // 20 bits 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
}
}

View File

@@ -11,14 +11,22 @@ import Foundation
class ActionBarModel: ObservableObject { class ActionBarModel: ObservableObject {
@Published var our_like: NostrEvent? @Published var our_like: NostrEvent?
@Published var our_boost: NostrEvent? @Published var our_boost: NostrEvent?
@Published var our_tip: NostrEvent?
@Published var likes: Int @Published var likes: Int
@Published var boosts: 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.likes = likes
self.boosts = boosts self.boosts = boosts
self.tips = tips
self.our_like = our_like self.our_like = our_like
self.our_boost = our_boost self.our_boost = our_boost
self.our_tip = our_tip
}
var tipped: Bool {
return our_tip != nil
} }
var liked: Bool { var liked: Bool {

View File

@@ -12,6 +12,7 @@ struct DamusState {
let pubkey: String let pubkey: String
let likes: EventCounter let likes: EventCounter
let boosts: EventCounter let boosts: EventCounter
let tips: TipCounter
let image_cache: ImageCache let image_cache: ImageCache
let profiles: Profiles let profiles: Profiles
} }

View File

@@ -36,6 +36,7 @@ class ProfileModel: ObservableObject {
var filter = NostrFilter.filter_authors([pubkey]) var filter = NostrFilter.filter_authors([pubkey])
filter.kinds = kinds filter.kinds = kinds
filter.limit = 500
print("subscribing to profile \(pubkey) with sub_id \(sub_id)") print("subscribing to profile \(pubkey) with sub_id \(sub_id)")
damus.pool.subscribe(sub_id: sub_id, filters: [filter], handler: handle_event) damus.pool.subscribe(sub_id: sub_id, filters: [filter], handler: handle_event)

View File

@@ -13,6 +13,7 @@ class SearchModel: ObservableObject {
let pool: RelayPool let pool: RelayPool
var search: NostrFilter var search: NostrFilter
let sub_id = UUID().description let sub_id = UUID().description
let limit: UInt32 = 500
init(pool: RelayPool, search: NostrFilter) { init(pool: RelayPool, search: NostrFilter) {
self.pool = pool self.pool = pool
@@ -21,7 +22,7 @@ class SearchModel: ObservableObject {
func subscribe() { func subscribe() {
// since 1 month // since 1 month
search.since = Int64(Date.now.timeIntervalSince1970) - 2629800 * 1 search.limit = self.limit
search.kinds = [1,5,7] search.kinds = [1,5,7]
//likes_filter.ids = ref_events.referenced_ids! //likes_filter.ids = ref_events.referenced_ids!

View File

@@ -14,6 +14,7 @@ struct NostrFilter: Codable {
var pubkeys: [String]? var pubkeys: [String]?
var since: Int64? var since: Int64?
var until: Int64? var until: Int64?
var limit: UInt32?
var authors: [String]? var authors: [String]?
var hashtag: [String]? = nil var hashtag: [String]? = nil
@@ -26,6 +27,7 @@ struct NostrFilter: Codable {
case since case since
case until case until
case authors case authors
case limit
} }
public static func copy(from: NostrFilter) -> NostrFilter { public static func copy(from: NostrFilter) -> NostrFilter {

View File

@@ -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
}
}

View File

@@ -113,7 +113,7 @@ struct ChatView: View {
NoteContentView(event: event, profiles: damus.profiles, content: event.content) NoteContentView(event: event, profiles: damus.profiles, content: event.content)
if is_active || next_ev == nil || next_ev!.pubkey != event.pubkey { 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, EventActionBar(event: event,
our_pubkey: damus.pubkey, our_pubkey: damus.pubkey,
profiles: damus.profiles, profiles: damus.profiles,

View File

@@ -37,7 +37,7 @@ struct EventActionBar: View {
EventActionButton(img: "bubble.left", col: nil) { EventActionButton(img: "bubble.left", col: nil) {
notify(.reply, event) notify(.reply, event)
} }
.padding([.trailing], 40) .padding([.trailing], 20)
HStack(alignment: .bottom) { HStack(alignment: .bottom) {
Text("\(bar.likes > 0 ? "\(bar.likes)" : "")") Text("\(bar.likes > 0 ? "\(bar.likes)" : "")")
@@ -52,7 +52,7 @@ struct EventActionBar: View {
} }
} }
} }
.padding([.trailing], 40) .padding([.trailing], 20)
HStack(alignment: .bottom) { HStack(alignment: .bottom) {
Text("\(bar.boosts > 0 ? "\(bar.boosts)" : "")") 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 .onReceive(handle_notify(.liked)) { n in

View File

@@ -99,7 +99,7 @@ struct EventView: View {
Spacer() Spacer()
if has_action_bar { 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) 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 { func make_actionbar_model(ev: NostrEvent, damus: DamusState) -> ActionBarModel {
let likes = like_counter.counts[ev.id] let likes = damus.likes.counts[ev.id]
let boosts = boost_counter.counts[ev.id] let boosts = damus.boosts.counts[ev.id]
let our_like = like_counter.our_events[ev.id] let tips = damus.tips.tips[ev.id]
let our_boost = boost_counter.our_events[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
)
} }