Files
damus/damus/Views/Events/SelectedEventView.swift
T
ericholguin 6376c61bad Highlights
This patch adds highlights (NIP-84) to Damus.

Kind 9802 are handled by all the necessary models.
We show highlighted events, longform events, and url references.
Url references also leverage text fragments to take the user to the highlighted text.

Testing
——
iPhone 15 Pro Max (17.0) Dark Mode:
https://v.nostr.build/oM6DW.mp4

iPhone 15 Pro Max (17.0) Light Mode:
https://v.nostr.build/BRrmP.mp4

iPhone SE (3rd generation) (16.4) Light Mode:
https://v.nostr.build/6GzKa.mp4
——

Closes: https://github.com/damus-io/damus/issues/2172
Closes: https://github.com/damus-io/damus/issues/1772
Closes: https://github.com/damus-io/damus/issues/1773
Closes: https://github.com/damus-io/damus/issues/2173
Closes: https://github.com/damus-io/damus/issues/2175
Changelog-Added: Highlights (NIP-84)

PATCH CHANGELOG:
V1 -> V2: addressed review comments highlights are now truncated and highlight label shown in Thread view
V2 -> V3: handle case where highlight context is smaller than the highlight content

Signed-off-by: ericholguin <ericholguin@apache.org>
2024-06-21 12:00:44 -07:00

109 lines
3.5 KiB
Swift

//
// SelectedEventView.swift
// damus
//
// Created by William Casarin on 2023-01-23.
//
import SwiftUI
struct SelectedEventView: View {
let damus: DamusState
let event: NostrEvent
let size: EventViewKind
var pubkey: Pubkey {
event.pubkey
}
@StateObject var bar: ActionBarModel
init(damus: DamusState, event: NostrEvent, size: EventViewKind) {
self.damus = damus
self.event = event
self.size = size
self._bar = StateObject(wrappedValue: make_actionbar_model(ev: event.id, damus: damus))
}
var body: some View {
HStack(alignment: .top) {
VStack(alignment: .leading) {
HStack {
EventProfile(damus_state: damus, pubkey: pubkey, size: .normal)
Spacer()
EventMenuContext(damus: damus, event: event)
.padding([.bottom], 4)
}
.padding(.horizontal)
.minimumScaleFactor(0.75)
.lineLimit(1)
if let reply_ref = event.thread_reply()?.reply {
let replying_to = damus.events.lookup(reply_ref.note_id)
if event.known_kind == .highlight {
HighlightDescription(event: event, highlighted_event: replying_to, ndb: damus.ndb)
.padding(.horizontal)
} else {
ReplyDescription(event: event, replying_to: replying_to, ndb: damus.ndb)
.padding(.horizontal)
}
} else if event.known_kind == .highlight {
HighlightDescription(event: event, highlighted_event: nil, ndb: damus.ndb)
.padding(.horizontal)
}
ProxyView(event: event)
.padding(.top, 5)
.padding(.horizontal)
EventBody(damus_state: damus, event: event, size: size, options: [.wide])
Mention
Text(verbatim: "\(format_date(created_at: event.created_at))")
.padding([.top, .leading, .trailing])
.font(.footnote)
.foregroundColor(.gray)
Divider()
.padding([.bottom], 4)
if !bar.is_empty {
EventDetailBar(state: damus, target: event.id, target_pk: event.pubkey)
.padding(.horizontal)
Divider()
}
EventActionBar(damus_state: damus, event: event)
.padding([.top], 4)
.padding(.horizontal)
Divider()
.padding([.top], 4)
}
.onReceive(handle_notify(.update_stats)) { target in
guard target == self.event.id else { return }
self.bar.update(damus: self.damus, evid: target)
}
.compositingGroup()
}
}
var Mention: some View {
Group {
if let mention = first_eref_mention(ev: event, keypair: damus.keypair) {
MentionView(damus_state: damus, mention: mention)
.padding(.horizontal)
}
}
}
}
struct SelectedEventView_Previews: PreviewProvider {
static var previews: some View {
SelectedEventView(damus: test_damus_state, event: test_note, size: .selected)
}
}