Reactions View
Changelog-Added: Added Reactions View
This commit is contained in:
@@ -116,8 +116,12 @@
|
|||||||
4CB55EF3295E5D59007FD187 /* RecommendedRelayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB55EF2295E5D59007FD187 /* RecommendedRelayView.swift */; };
|
4CB55EF3295E5D59007FD187 /* RecommendedRelayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB55EF2295E5D59007FD187 /* RecommendedRelayView.swift */; };
|
||||||
4CB55EF5295E679D007FD187 /* UserRelaysView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB55EF4295E679D007FD187 /* UserRelaysView.swift */; };
|
4CB55EF5295E679D007FD187 /* UserRelaysView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB55EF4295E679D007FD187 /* UserRelaysView.swift */; };
|
||||||
4CB8838629656C8B00DC99E7 /* NIP05.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB8838529656C8B00DC99E7 /* NIP05.swift */; };
|
4CB8838629656C8B00DC99E7 /* NIP05.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB8838529656C8B00DC99E7 /* NIP05.swift */; };
|
||||||
|
4CB88389296AF99A00DC99E7 /* EventDetailBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB88388296AF99A00DC99E7 /* EventDetailBar.swift */; };
|
||||||
4CB8838B296F6E1E00DC99E7 /* NIP05Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB8838A296F6E1E00DC99E7 /* NIP05Badge.swift */; };
|
4CB8838B296F6E1E00DC99E7 /* NIP05Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB8838A296F6E1E00DC99E7 /* NIP05Badge.swift */; };
|
||||||
4CB8838D296F710400DC99E7 /* Reposted.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB8838C296F710400DC99E7 /* Reposted.swift */; };
|
4CB8838D296F710400DC99E7 /* Reposted.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB8838C296F710400DC99E7 /* Reposted.swift */; };
|
||||||
|
4CB8838F296F781C00DC99E7 /* ReactionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB8838E296F781C00DC99E7 /* ReactionsView.swift */; };
|
||||||
|
4CB88393296F798300DC99E7 /* ReactionsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB88392296F798300DC99E7 /* ReactionsModel.swift */; };
|
||||||
|
4CB88396296F7F8B00DC99E7 /* ReactionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB88395296F7F8B00DC99E7 /* ReactionView.swift */; };
|
||||||
4CD7641B28A1641400B6928F /* EndBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CD7641A28A1641400B6928F /* EndBlock.swift */; };
|
4CD7641B28A1641400B6928F /* EndBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CD7641A28A1641400B6928F /* EndBlock.swift */; };
|
||||||
4CE4F8CD281352B30009DFBB /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F8CC281352B30009DFBB /* Notifications.swift */; };
|
4CE4F8CD281352B30009DFBB /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F8CC281352B30009DFBB /* Notifications.swift */; };
|
||||||
4CE4F9DE2852768D00C00DD9 /* ConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */; };
|
4CE4F9DE2852768D00C00DD9 /* ConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */; };
|
||||||
@@ -310,8 +314,12 @@
|
|||||||
4CB55EF2295E5D59007FD187 /* RecommendedRelayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendedRelayView.swift; sourceTree = "<group>"; };
|
4CB55EF2295E5D59007FD187 /* RecommendedRelayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendedRelayView.swift; sourceTree = "<group>"; };
|
||||||
4CB55EF4295E679D007FD187 /* UserRelaysView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserRelaysView.swift; sourceTree = "<group>"; };
|
4CB55EF4295E679D007FD187 /* UserRelaysView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserRelaysView.swift; sourceTree = "<group>"; };
|
||||||
4CB8838529656C8B00DC99E7 /* NIP05.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NIP05.swift; sourceTree = "<group>"; };
|
4CB8838529656C8B00DC99E7 /* NIP05.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NIP05.swift; sourceTree = "<group>"; };
|
||||||
|
4CB88388296AF99A00DC99E7 /* EventDetailBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventDetailBar.swift; sourceTree = "<group>"; };
|
||||||
4CB8838A296F6E1E00DC99E7 /* NIP05Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NIP05Badge.swift; sourceTree = "<group>"; };
|
4CB8838A296F6E1E00DC99E7 /* NIP05Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NIP05Badge.swift; sourceTree = "<group>"; };
|
||||||
4CB8838C296F710400DC99E7 /* Reposted.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reposted.swift; sourceTree = "<group>"; };
|
4CB8838C296F710400DC99E7 /* Reposted.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reposted.swift; sourceTree = "<group>"; };
|
||||||
|
4CB8838E296F781C00DC99E7 /* ReactionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactionsView.swift; sourceTree = "<group>"; };
|
||||||
|
4CB88392296F798300DC99E7 /* ReactionsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactionsModel.swift; sourceTree = "<group>"; };
|
||||||
|
4CB88395296F7F8B00DC99E7 /* ReactionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactionView.swift; sourceTree = "<group>"; };
|
||||||
4CD7641A28A1641400B6928F /* EndBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EndBlock.swift; sourceTree = "<group>"; };
|
4CD7641A28A1641400B6928F /* EndBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EndBlock.swift; sourceTree = "<group>"; };
|
||||||
4CE4F8CC281352B30009DFBB /* Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; };
|
4CE4F8CC281352B30009DFBB /* Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; };
|
||||||
4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigView.swift; sourceTree = "<group>"; };
|
4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigView.swift; sourceTree = "<group>"; };
|
||||||
@@ -469,6 +477,7 @@
|
|||||||
4C99737A28C92A9200E53835 /* ChatroomMetadata.swift */,
|
4C99737A28C92A9200E53835 /* ChatroomMetadata.swift */,
|
||||||
BA693073295D649800ADDB87 /* UserSettingsStore.swift */,
|
BA693073295D649800ADDB87 /* UserSettingsStore.swift */,
|
||||||
4FE60CDC295E1C5E00105A1F /* Wallet.swift */,
|
4FE60CDC295E1C5E00105A1F /* Wallet.swift */,
|
||||||
|
4CB88392296F798300DC99E7 /* ReactionsModel.swift */,
|
||||||
);
|
);
|
||||||
path = Models;
|
path = Models;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -476,6 +485,8 @@
|
|||||||
4C75EFA227FA576C0006080F /* Views */ = {
|
4C75EFA227FA576C0006080F /* Views */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
4CB88394296F7F8100DC99E7 /* Reactions */,
|
||||||
|
4CB88387296AF97C00DC99E7 /* ActionBar */,
|
||||||
4CE4F9E228528C5200C00DD9 /* AddRelayView.swift */,
|
4CE4F9E228528C5200C00DD9 /* AddRelayView.swift */,
|
||||||
4C363A8728236948006E126D /* BlocksView.swift */,
|
4C363A8728236948006E126D /* BlocksView.swift */,
|
||||||
4C285C8128385570008A31F1 /* CarouselView.swift */,
|
4C285C8128385570008A31F1 /* CarouselView.swift */,
|
||||||
@@ -488,7 +499,6 @@
|
|||||||
4C216F33286F5ACD00040376 /* DMView.swift */,
|
4C216F33286F5ACD00040376 /* DMView.swift */,
|
||||||
E990020E2955F837003BBC5A /* EditMetadataView.swift */,
|
E990020E2955F837003BBC5A /* EditMetadataView.swift */,
|
||||||
3169CAE4294E699400EE4006 /* Empty Views */,
|
3169CAE4294E699400EE4006 /* Empty Views */,
|
||||||
4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */,
|
|
||||||
4CEE2AF0280B216B00AB5EEF /* EventDetailView.swift */,
|
4CEE2AF0280B216B00AB5EEF /* EventDetailView.swift */,
|
||||||
4C75EFB82804A2740006080F /* EventView.swift */,
|
4C75EFB82804A2740006080F /* EventView.swift */,
|
||||||
4C3AC79E2833115300E1F516 /* FollowButtonView.swift */,
|
4C3AC79E2833115300E1F516 /* FollowButtonView.swift */,
|
||||||
@@ -520,6 +530,7 @@
|
|||||||
4CA2EF9F280E37AC0044ACD8 /* TimelineView.swift */,
|
4CA2EF9F280E37AC0044ACD8 /* TimelineView.swift */,
|
||||||
4CB55EF4295E679D007FD187 /* UserRelaysView.swift */,
|
4CB55EF4295E679D007FD187 /* UserRelaysView.swift */,
|
||||||
647D9A8C2968520300A295DE /* SideMenuView.swift */,
|
647D9A8C2968520300A295DE /* SideMenuView.swift */,
|
||||||
|
4CB8838E296F781C00DC99E7 /* ReactionsView.swift */,
|
||||||
);
|
);
|
||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -565,6 +576,23 @@
|
|||||||
path = Util;
|
path = Util;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
4CB88387296AF97C00DC99E7 /* ActionBar */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */,
|
||||||
|
4CB88388296AF99A00DC99E7 /* EventDetailBar.swift */,
|
||||||
|
);
|
||||||
|
path = ActionBar;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
4CB88394296F7F8100DC99E7 /* Reactions */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4CB88395296F7F8B00DC99E7 /* ReactionView.swift */,
|
||||||
|
);
|
||||||
|
path = Reactions;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
4CE4F9DF285287A000C00DD9 /* Components */ = {
|
4CE4F9DF285287A000C00DD9 /* Components */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -840,6 +868,7 @@
|
|||||||
4C75EFA627FF87A20006080F /* Nostr.swift in Sources */,
|
4C75EFA627FF87A20006080F /* Nostr.swift in Sources */,
|
||||||
4CE4F9DE2852768D00C00DD9 /* ConfigView.swift in Sources */,
|
4CE4F9DE2852768D00C00DD9 /* ConfigView.swift in Sources */,
|
||||||
4C285C8E28399BFE008A31F1 /* SaveKeysView.swift in Sources */,
|
4C285C8E28399BFE008A31F1 /* SaveKeysView.swift in Sources */,
|
||||||
|
4CB8838F296F781C00DC99E7 /* ReactionsView.swift in Sources */,
|
||||||
4C649844285A952100EAE2B3 /* LocalUserConfig.swift in Sources */,
|
4C649844285A952100EAE2B3 /* LocalUserConfig.swift in Sources */,
|
||||||
4C75EFB328049D640006080F /* NostrEvent.swift in Sources */,
|
4C75EFB328049D640006080F /* NostrEvent.swift in Sources */,
|
||||||
4CA2EFA0280E37AC0044ACD8 /* TimelineView.swift in Sources */,
|
4CA2EFA0280E37AC0044ACD8 /* TimelineView.swift in Sources */,
|
||||||
@@ -888,6 +917,8 @@
|
|||||||
4C3EA66528FF5F6800C48A62 /* mem.c in Sources */,
|
4C3EA66528FF5F6800C48A62 /* mem.c in Sources */,
|
||||||
4C3EA64128FF553900C48A62 /* hash_u5.c in Sources */,
|
4C3EA64128FF553900C48A62 /* hash_u5.c in Sources */,
|
||||||
4C3EA64F28FF59F200C48A62 /* tal.c in Sources */,
|
4C3EA64F28FF59F200C48A62 /* tal.c in Sources */,
|
||||||
|
4CB88393296F798300DC99E7 /* ReactionsModel.swift in Sources */,
|
||||||
|
4CB88396296F7F8B00DC99E7 /* ReactionView.swift in Sources */,
|
||||||
4C8682872814DE470026224F /* ProfileView.swift in Sources */,
|
4C8682872814DE470026224F /* ProfileView.swift in Sources */,
|
||||||
4C5F9114283D694D0052CD1C /* FollowTarget.swift in Sources */,
|
4C5F9114283D694D0052CD1C /* FollowTarget.swift in Sources */,
|
||||||
4CB8838629656C8B00DC99E7 /* NIP05.swift in Sources */,
|
4CB8838629656C8B00DC99E7 /* NIP05.swift in Sources */,
|
||||||
@@ -910,6 +941,7 @@
|
|||||||
4C363A922825FCF2006E126D /* ProfileUpdate.swift in Sources */,
|
4C363A922825FCF2006E126D /* ProfileUpdate.swift in Sources */,
|
||||||
4C0A3F95280F6C78000448DE /* ReplyQuoteView.swift in Sources */,
|
4C0A3F95280F6C78000448DE /* ReplyQuoteView.swift in Sources */,
|
||||||
4C3BEFDA281DCA1400B3DE84 /* LikeCounter.swift in Sources */,
|
4C3BEFDA281DCA1400B3DE84 /* LikeCounter.swift in Sources */,
|
||||||
|
4CB88389296AF99A00DC99E7 /* EventDetailBar.swift in Sources */,
|
||||||
4C3AC79B28306D7B00E1F516 /* Contacts.swift in Sources */,
|
4C3AC79B28306D7B00E1F516 /* Contacts.swift in Sources */,
|
||||||
4C3EA63D28FF52D600C48A62 /* bolt11.c in Sources */,
|
4C3EA63D28FF52D600C48A62 /* bolt11.c in Sources */,
|
||||||
4CB55EF3295E5D59007FD187 /* RecommendedRelayView.swift in Sources */,
|
4CB55EF3295E5D59007FD187 /* RecommendedRelayView.swift in Sources */,
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ struct ContentView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
if let damus = self.damus_state {
|
if let damus = self.damus_state {
|
||||||
@@ -229,9 +229,6 @@ struct ContentView: View {
|
|||||||
Button {
|
Button {
|
||||||
isSideBarOpened.toggle()
|
isSideBarOpened.toggle()
|
||||||
} label: {
|
} label: {
|
||||||
let profile_model = ProfileModel(pubkey: damus_state!.pubkey, damus: damus_state!)
|
|
||||||
let followers_model = FollowersModel(damus_state: damus_state!, target: damus_state!.pubkey)
|
|
||||||
|
|
||||||
if let picture = damus_state?.profiles.lookup(id: pubkey)?.picture {
|
if let picture = damus_state?.profiles.lookup(id: pubkey)?.picture {
|
||||||
ProfilePicView(pubkey: damus_state!.pubkey, size: 32, highlight: .none, profiles: damus_state!.profiles, picture: picture)
|
ProfilePicView(pubkey: damus_state!.pubkey, size: 32, highlight: .none, profiles: damus_state!.profiles, picture: picture)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ class ActionBarModel: ObservableObject {
|
|||||||
@Published var boosts: Int
|
@Published var boosts: Int
|
||||||
@Published var tips: Int64
|
@Published var tips: Int64
|
||||||
|
|
||||||
|
static func empty() -> ActionBarModel {
|
||||||
|
return ActionBarModel(likes: 0, boosts: 0, tips: 0, our_like: nil, our_boost: nil, our_tip: nil)
|
||||||
|
}
|
||||||
|
|
||||||
init(likes: Int, boosts: Int, tips: Int64, our_like: NostrEvent?, our_boost: NostrEvent?, our_tip: 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
|
||||||
|
|||||||
@@ -73,31 +73,30 @@ class FollowersModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handle_event(relay_id: String, ev: NostrConnectionEvent) {
|
func handle_event(relay_id: String, ev: NostrConnectionEvent) {
|
||||||
switch ev {
|
guard case .nostr_event(let nev) = ev else {
|
||||||
case .ws_event:
|
return
|
||||||
break
|
}
|
||||||
case .nostr_event(let nev):
|
|
||||||
switch nev {
|
switch nev {
|
||||||
case .event(let sub_id, let ev):
|
case .event(let sub_id, let ev):
|
||||||
guard sub_id == self.sub_id || sub_id == self.profiles_id else {
|
guard sub_id == self.sub_id || sub_id == self.profiles_id else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if ev.known_kind == .contacts {
|
if ev.known_kind == .contacts {
|
||||||
handle_contact_event(ev)
|
handle_contact_event(ev)
|
||||||
} else if ev.known_kind == .metadata {
|
} else if ev.known_kind == .metadata {
|
||||||
process_metadata_event(profiles: damus_state.profiles, ev: ev)
|
process_metadata_event(profiles: damus_state.profiles, ev: ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
case .notice(let msg):
|
case .notice(let msg):
|
||||||
print("followingmodel notice: \(msg)")
|
print("followingmodel notice: \(msg)")
|
||||||
|
|
||||||
case .eose(let sub_id):
|
case .eose(let sub_id):
|
||||||
if sub_id == self.sub_id {
|
if sub_id == self.sub_id {
|
||||||
load_profiles(relay_id: relay_id)
|
load_profiles(relay_id: relay_id)
|
||||||
} else if sub_id == self.profiles_id {
|
} else if sub_id == self.profiles_id {
|
||||||
damus_state.pool.unsubscribe(sub_id: profiles_id, to: [relay_id])
|
damus_state.pool.unsubscribe(sub_id: profiles_id, to: [relay_id])
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
75
damus/Models/ReactionsModel.swift
Normal file
75
damus/Models/ReactionsModel.swift
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
//
|
||||||
|
// LikesModel.swift
|
||||||
|
// damus
|
||||||
|
//
|
||||||
|
// Created by William Casarin on 2023-01-11.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
class ReactionsModel: ObservableObject {
|
||||||
|
let state: DamusState
|
||||||
|
let target: String
|
||||||
|
let sub_id: String
|
||||||
|
@Published var reactions: [NostrEvent]
|
||||||
|
|
||||||
|
init (state: DamusState, target: String) {
|
||||||
|
self.state = state
|
||||||
|
self.target = target
|
||||||
|
self.sub_id = UUID().description
|
||||||
|
self.reactions = []
|
||||||
|
}
|
||||||
|
|
||||||
|
func get_filter() -> NostrFilter {
|
||||||
|
var filter = NostrFilter.filter_kinds([7])
|
||||||
|
filter.referenced_ids = [target]
|
||||||
|
filter.limit = 500
|
||||||
|
return filter
|
||||||
|
}
|
||||||
|
|
||||||
|
func subscribe() {
|
||||||
|
let filter = get_filter()
|
||||||
|
let filters = [filter]
|
||||||
|
self.state.pool.subscribe(sub_id: sub_id, filters: filters, handler: handle_nostr_event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func unsubscribe() {
|
||||||
|
self.state.pool.unsubscribe(sub_id: sub_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handle_event(relay_id: String, ev: NostrEvent) {
|
||||||
|
guard ev.kind == 7 else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let reacted_to = last_etag(tags: ev.tags) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard reacted_to == self.target else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if insert_uniq_sorted_event(events: &self.reactions, new_ev: ev, cmp: { a, b in a.created_at < b.created_at } ) {
|
||||||
|
objectWillChange.send()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handle_nostr_event(relay_id: String, ev: NostrConnectionEvent) {
|
||||||
|
guard case .nostr_event(let nev) = ev else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch nev {
|
||||||
|
case .event(_, let ev):
|
||||||
|
handle_event(relay_id: relay_id, ev: ev)
|
||||||
|
|
||||||
|
case .notice(_):
|
||||||
|
break
|
||||||
|
case .eose(_):
|
||||||
|
load_profiles(profiles_subid: UUID().description, relay_id: relay_id, events: reactions, damus_state: state)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -772,6 +772,15 @@ func validate_event(ev: NostrEvent) -> ValidationResult {
|
|||||||
return ok ? .ok : .bad_sig
|
return ok ? .ok : .bad_sig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func last_etag(tags: [[String]]) -> String? {
|
||||||
|
var e: String? = nil
|
||||||
|
for tag in tags {
|
||||||
|
if tag.count >= 2 && tag[0] == "e" {
|
||||||
|
e = tag[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
func inner_event_or_self(ev: NostrEvent) -> NostrEvent {
|
func inner_event_or_self(ev: NostrEvent) -> NostrEvent {
|
||||||
guard let inner_ev = ev.inner_event else {
|
guard let inner_ev = ev.inner_event else {
|
||||||
|
|||||||
@@ -29,14 +29,6 @@ struct EventActionBar: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack {
|
HStack {
|
||||||
/*
|
|
||||||
EventActionButton(img: "square.and.arrow.up") {
|
|
||||||
print("share")
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer()
|
|
||||||
|
|
||||||
*/
|
|
||||||
if damus_state.keypair.privkey != nil {
|
if damus_state.keypair.privkey != nil {
|
||||||
EventActionButton(img: "bubble.left", col: nil) {
|
EventActionButton(img: "bubble.left", col: nil) {
|
||||||
notify(.reply, event)
|
notify(.reply, event)
|
||||||
39
damus/Views/ActionBar/EventDetailBar.swift
Normal file
39
damus/Views/ActionBar/EventDetailBar.swift
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// EventDetailBar.swift
|
||||||
|
// damus
|
||||||
|
//
|
||||||
|
// Created by William Casarin on 2023-01-08.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct EventDetailBar: View {
|
||||||
|
let state: DamusState
|
||||||
|
let target: String
|
||||||
|
@StateObject var bar: ActionBarModel
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack {
|
||||||
|
Text("\(bar.boosts)")
|
||||||
|
.font(.body.bold())
|
||||||
|
Text("Reposts")
|
||||||
|
|
||||||
|
NavigationLink(destination: ReactionsView(damus_state: state, model: ReactionsModel(state: state, target: target))) {
|
||||||
|
Text("\(bar.likes)")
|
||||||
|
.font(.body.bold())
|
||||||
|
Text("Reactions")
|
||||||
|
}
|
||||||
|
.buttonStyle(PlainButtonStyle())
|
||||||
|
|
||||||
|
Text("\(bar.tips)")
|
||||||
|
.font(.body.bold())
|
||||||
|
Text("Tips")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct EventDetailBar_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
EventDetailBar(state: test_damus_state(), target: "", bar: ActionBarModel.empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -251,6 +251,13 @@ struct EventView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let bar = make_actionbar_model(ev: event, damus: damus)
|
let bar = make_actionbar_model(ev: event, damus: damus)
|
||||||
|
|
||||||
|
if size == .selected {
|
||||||
|
EventDetailBar(state: damus, target: event.id, bar: bar)
|
||||||
|
Divider()
|
||||||
|
.padding([.bottom], 4)
|
||||||
|
}
|
||||||
|
|
||||||
EventActionBar(damus_state: damus, event: event, bar: bar)
|
EventActionBar(damus_state: damus, event: event, bar: bar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
36
damus/Views/Reactions/ReactionView.swift
Normal file
36
damus/Views/Reactions/ReactionView.swift
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// ReactionView.swift
|
||||||
|
// damus
|
||||||
|
//
|
||||||
|
// Created by William Casarin on 2023-01-11.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ReactionView: View {
|
||||||
|
let damus_state: DamusState
|
||||||
|
let reaction: NostrEvent
|
||||||
|
|
||||||
|
var content: String {
|
||||||
|
if reaction.content == "" || reaction.content == "+" {
|
||||||
|
return "❤️"
|
||||||
|
}
|
||||||
|
return reaction.content
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack {
|
||||||
|
Text(content)
|
||||||
|
.font(Font.headline)
|
||||||
|
.frame(width: 50, height: 50)
|
||||||
|
|
||||||
|
FollowUserView(target: .pubkey(reaction.pubkey), damus_state: damus_state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ReactionView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
ReactionView(damus_state: test_damus_state(), reaction: NostrEvent(id: "", content: "🤙🏼", pubkey: ""))
|
||||||
|
}
|
||||||
|
}
|
||||||
38
damus/Views/ReactionsView.swift
Normal file
38
damus/Views/ReactionsView.swift
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// ReactionsView.swift
|
||||||
|
// damus
|
||||||
|
//
|
||||||
|
// Created by William Casarin on 2023-01-11.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ReactionsView: View {
|
||||||
|
let damus_state: DamusState
|
||||||
|
@StateObject var model: ReactionsModel
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ScrollView {
|
||||||
|
LazyVStack {
|
||||||
|
ForEach(model.reactions, id: \.id) { ev in
|
||||||
|
ReactionView(damus_state: damus_state, reaction: ev)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
.navigationBarTitle("Reactions")
|
||||||
|
.onAppear {
|
||||||
|
model.subscribe()
|
||||||
|
}
|
||||||
|
.onDisappear {
|
||||||
|
model.unsubscribe()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ReactionsView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
let state = test_damus_state()
|
||||||
|
ReactionsView(damus_state: state, model: ReactionsModel(state: state, target: "pubkey"))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,6 +42,7 @@ struct SearchView_Previews: PreviewProvider {
|
|||||||
let test_state = test_damus_state()
|
let test_state = test_damus_state()
|
||||||
let filter = NostrFilter.filter_hashtag(["bitcoin"])
|
let filter = NostrFilter.filter_hashtag(["bitcoin"])
|
||||||
let pool = test_state.pool
|
let pool = test_state.pool
|
||||||
|
|
||||||
let model = SearchModel(pool: pool, search: filter)
|
let model = SearchModel(pool: pool, search: filter)
|
||||||
|
|
||||||
SearchView(appstate: test_state, search: model)
|
SearchView(appstate: test_state, search: model)
|
||||||
|
|||||||
Reference in New Issue
Block a user