damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | LICENSE

commit cac139fff1b6d05e3f248340ca04ee7f2d527d39
parent 6ac4214be791ecd550205333234eac32260dbab9
Author: William Casarin <jb55@jb55.com>
Date:   Mon,  9 May 2022 11:43:18 -0700

hashtags working

Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mdamus/Models/Mentions.swift | 5++++-
Mdamus/Models/Post.swift | 4++++
Mdamus/Models/PostBlock.swift | 8++++++++
Mdamus/Models/SearchModel.swift | 33+++++++++++++++++++++++++++------
Mdamus/Views/SearchView.swift | 26++++++++++++++++++++------
MdamusTests/damusTests.swift | 15+++++++++++++++
6 files changed, 78 insertions(+), 13 deletions(-)

diff --git a/damus/Models/Mentions.swift b/damus/Models/Mentions.swift @@ -68,7 +68,7 @@ func render_blocks(blocks: [Block]) -> String { case .text(let txt): return str + txt case .hashtag(let htag): - return "#" + htag + return str + "#" + htag } } } @@ -236,6 +236,9 @@ func make_post_tags(post_blocks: [PostBlock], tags: [[String]]) -> PostTags { let block = Block.mention(mention) blocks.append(block) } + case .hashtag(let hashtag): + new_tags.append(["hashtag", hashtag]) + blocks.append(.hashtag(hashtag)) case .text(let txt): blocks.append(Block.text(txt)) } diff --git a/damus/Models/Post.swift b/damus/Models/Post.swift @@ -57,6 +57,10 @@ func parse_post_blocks(content: String) -> [PostBlock] { blocks.append(parse_post_textblock(str: p.str, from: starting_from, to: pre_mention)) blocks.append(.ref(reference)) starting_from = p.pos + } else if let hashtag = parse_hashtag(p) { + blocks.append(parse_post_textblock(str: p.str, from: starting_from, to: pre_mention)) + blocks.append(.hashtag(hashtag)) + starting_from = p.pos } else { p.pos += 1 } diff --git a/damus/Models/PostBlock.swift b/damus/Models/PostBlock.swift @@ -10,6 +10,7 @@ import Foundation enum PostBlock { case text(String) case ref(ReferencedId) + case hashtag(String) var is_text: Bool { if case .text = self { @@ -18,6 +19,13 @@ enum PostBlock { return false } + var is_hashtag: Bool { + if case .hashtag = self { + return true + } + return false + } + var is_ref: Bool { if case .ref = self { return true diff --git a/damus/Models/SearchModel.swift b/damus/Models/SearchModel.swift @@ -11,7 +11,7 @@ import Foundation class SearchModel: ObservableObject { @Published var events: [NostrEvent] = [] let pool: RelayPool - let search: NostrFilter + var search: NostrFilter let sub_id = UUID().description init(pool: RelayPool, search: NostrFilter) { @@ -20,15 +20,15 @@ class SearchModel: ObservableObject { } func subscribe() { - // since 2 month - var filter = NostrFilter.copy(from: search) - filter.since = Int64(Date.now.timeIntervalSince1970) - 2629800 * 2 + // since 1 month + search.since = Int64(Date.now.timeIntervalSince1970) - 2629800 * 1 + search.kinds = [1,5,7] //likes_filter.ids = ref_events.referenced_ids! - print("subscribing to search '\(filter)' with sub_id \(sub_id)") + print("subscribing to search '\(search)' with sub_id \(sub_id)") pool.register_handler(sub_id: sub_id, handler: handle_event) - pool.send(.subscribe(.init(filters: [filter], sub_id: sub_id))) + pool.send(.subscribe(.init(filters: [search], sub_id: sub_id))) } func unsubscribe() { @@ -37,6 +37,10 @@ class SearchModel: ObservableObject { } func add_event(_ ev: NostrEvent) { + if !event_matches_filter(ev, filter: search) { + return + } + if insert_uniq_sorted_event(events: &self.events, new_ev: ev) { objectWillChange.send() } @@ -51,6 +55,23 @@ class SearchModel: ObservableObject { } } +func event_matches_hashtag(_ ev: NostrEvent, hashtags: [String]) -> Bool { + for tag in ev.tags { + if tag.count >= 2 && tag[0] == "hashtag" { + if hashtags.contains(tag[1]) { + return true + } + } + } + return false +} + +func event_matches_filter(_ ev: NostrEvent, filter: NostrFilter) -> Bool { + if let hashtags = filter.hashtag { + return event_matches_hashtag(ev, hashtags: hashtags) + } + return true +} func handle_subid_event(pool: RelayPool, sub_id: String, relay_id: String, ev: NostrConnectionEvent, handle: (NostrEvent) -> ()) { switch ev { diff --git a/damus/Views/SearchView.swift b/damus/Views/SearchView.swift @@ -10,17 +10,31 @@ import SwiftUI struct SearchView: View { let appstate: DamusState @StateObject var search: SearchModel + @Environment(\.dismiss) var dismiss var body: some View { TimelineView(events: $search.events, damus: appstate) - .padding([.leading, .trailing], 6) - .onAppear() { - search.subscribe() - } - .onDisappear() { - search.unsubscribe() + .navigationBarTitle(describe_search(search.search)) + .padding([.leading, .trailing], 6) + .onReceive(handle_notify(.switched_timeline)) { obj in + dismiss() + } + .onAppear() { + search.subscribe() + } + .onDisappear() { + search.unsubscribe() + } + } +} + +func describe_search(_ filter: NostrFilter) -> String { + if let hashtags = filter.hashtag { + if hashtags.count >= 1 { + return "#" + hashtags[0] } } + return "Search" } /* diff --git a/damusTests/damusTests.swift b/damusTests/damusTests.swift @@ -71,6 +71,21 @@ class damusTests: XCTestCase { XCTAssertEqual(parsed.count, 0) } + func testMakeHashtagPost() { + let privkey = "d05f5fcceef3e4529703f62a29222d6ee2d1b7bf1f24729b5e01df7c633cec8a" + let pubkey = "6e59d3b78b1c1490a6489c94405873b57d8ef398a830ae5e39608f4107e9a790" + let post = NostrPost(content: "#damus some content #bitcoin derp", references: []) + let ev = post_to_event(post: post, privkey: privkey, pubkey: pubkey) + + XCTAssertEqual(ev.tags.count, 2) + XCTAssertEqual(ev.content, "#damus some content #bitcoin derp") + XCTAssertEqual(ev.tags[0][0], "hashtag") + XCTAssertEqual(ev.tags[0][1], "damus") + XCTAssertEqual(ev.tags[1][0], "hashtag") + XCTAssertEqual(ev.tags[1][1], "bitcoin") + + } + func testParseHashtag() { let parsed = parse_mentions(content: "some hashtag #bitcoin derp", tags: [])