Compare commits
2 Commits
hidden-lin
...
tyiu/dm-ti
| Author | SHA1 | Date | |
|---|---|---|---|
|
60bff81ff8
|
|||
|
467ce4c801
|
@@ -128,7 +128,7 @@ struct TranslateView: View {
|
|||||||
if let translated = translated_note {
|
if let translated = translated_note {
|
||||||
// Render translated note.
|
// Render translated note.
|
||||||
let translatedBlocks = event.get_blocks(content: translated)
|
let translatedBlocks = event.get_blocks(content: translated)
|
||||||
translated_artifacts = render_blocks(blocks: translatedBlocks, profiles: damus_state.profiles, privkey: damus_state.keypair.privkey)
|
translated_artifacts = render_blocks(blocks: translatedBlocks, profiles: damus_state.profiles, privkey: damus_state.keypair.privkey, ev: event)
|
||||||
}
|
}
|
||||||
|
|
||||||
checkingTranslationStatus = false
|
checkingTranslationStatus = false
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ struct ChatView: View {
|
|||||||
event: event,
|
event: event,
|
||||||
show_images: show_images,
|
show_images: show_images,
|
||||||
size: .normal,
|
size: .normal,
|
||||||
|
show_time: false,
|
||||||
artifacts: .just_content(event.content))
|
artifacts: .just_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 {
|
||||||
|
|||||||
@@ -12,14 +12,42 @@ struct DMChatView: View {
|
|||||||
let pubkey: String
|
let pubkey: String
|
||||||
@EnvironmentObject var dms: DirectMessageModel
|
@EnvironmentObject var dms: DirectMessageModel
|
||||||
@State var showPrivateKeyWarning: Bool = false
|
@State var showPrivateKeyWarning: Bool = false
|
||||||
|
@State var eventsInView = Set<NostrEvent>()
|
||||||
|
@State var minDate: String = ""
|
||||||
|
|
||||||
|
func fillColor() -> Color {
|
||||||
|
colorScheme == .light ? Color("DamusLightGrey") : Color("DamusDarkGrey")
|
||||||
|
}
|
||||||
|
|
||||||
|
func foregroundColor() -> Color {
|
||||||
|
colorScheme == .light ? Color("DamusBlack") : Color("DamusWhite")
|
||||||
|
}
|
||||||
|
|
||||||
var Messages: some View {
|
var Messages: some View {
|
||||||
ScrollViewReader { scroller in
|
ScrollViewReader { scroller in
|
||||||
ScrollView {
|
ScrollView {
|
||||||
VStack(alignment: .leading) {
|
LazyVStack() {
|
||||||
|
var dates = Set<Date>()
|
||||||
ForEach(Array(zip(dms.events, dms.events.indices)), id: \.0.id) { (ev, ind) in
|
ForEach(Array(zip(dms.events, dms.events.indices)), id: \.0.id) { (ev, ind) in
|
||||||
DMView(event: dms.events[ind], damus_state: damus_state)
|
if let date = Calendar.current.startOfDay(for: Date.init(timeIntervalSince1970: Double(ev.created_at))), dates.insert(date).inserted {
|
||||||
|
Text(date.formatted(date: .abbreviated, time: .omitted))
|
||||||
|
.padding([.leading, .trailing], 6.0)
|
||||||
|
.padding([.top, .bottom], 2.0)
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
.background {
|
||||||
|
RoundedRectangle(cornerRadius: 5.0)
|
||||||
|
.foregroundColor(fillColor())
|
||||||
|
}
|
||||||
|
.font(.callout)
|
||||||
|
}
|
||||||
|
DMView(event: ev, damus_state: damus_state)
|
||||||
.event_context_menu(ev, keypair: damus_state.keypair, target_pubkey: ev.pubkey)
|
.event_context_menu(ev, keypair: damus_state.keypair, target_pubkey: ev.pubkey)
|
||||||
|
.onAppear {
|
||||||
|
eventsInView.insert(ev)
|
||||||
|
}
|
||||||
|
.onDisappear {
|
||||||
|
eventsInView.remove(ev)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EndBlock(height: 80)
|
EndBlock(height: 80)
|
||||||
}
|
}
|
||||||
@@ -31,6 +59,12 @@ struct DMChatView: View {
|
|||||||
withAnimation {
|
withAnimation {
|
||||||
scroller.scrollTo("endblock")
|
scroller.scrollTo("endblock")
|
||||||
}
|
}
|
||||||
|
}.onChange(of: eventsInView) { _ in
|
||||||
|
let timestamps = eventsInView.map { $0.created_at }
|
||||||
|
guard let minTimestamp = timestamps.min() else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
minDate = Date.init(timeIntervalSince1970: Double(minTimestamp)).formatted(date: .abbreviated, time: .omitted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,6 +176,16 @@ struct DMChatView: View {
|
|||||||
.dismissKeyboardOnTap()
|
.dismissKeyboardOnTap()
|
||||||
|
|
||||||
VStack {
|
VStack {
|
||||||
|
Text(minDate)
|
||||||
|
.padding([.leading, .trailing], 6.0)
|
||||||
|
.padding([.top, .bottom], 2.0)
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
.background {
|
||||||
|
RoundedRectangle(cornerRadius: 5.0)
|
||||||
|
.foregroundColor(fillColor())
|
||||||
|
}
|
||||||
|
.font(.callout)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
Footer
|
Footer
|
||||||
|
|||||||
@@ -23,12 +23,14 @@ struct DMView: View {
|
|||||||
|
|
||||||
let should_show_img = should_show_images(contacts: damus_state.contacts, ev: event, our_pubkey: damus_state.pubkey)
|
let should_show_img = should_show_images(contacts: damus_state.contacts, ev: event, our_pubkey: damus_state.pubkey)
|
||||||
|
|
||||||
NoteContentView(damus_state: damus_state, event: event, show_images: should_show_img, size: .normal, artifacts: .just_content(event.get_content(damus_state.keypair.privkey)))
|
NoteContentView(damus_state: damus_state, event: event, show_images: should_show_img, size: .normal, show_time: true, artifacts: .just_content(event.get_content(damus_state.keypair.privkey)))
|
||||||
.foregroundColor(is_ours ? Color.white : Color.primary)
|
.foregroundColor(is_ours ? Color.white : Color.primary)
|
||||||
.padding(10)
|
.padding(10)
|
||||||
.background(is_ours ? Color.accentColor : Color.secondary.opacity(0.15))
|
.background(is_ours ? Color.accentColor : Color.secondary.opacity(0.15))
|
||||||
.cornerRadius(8.0)
|
.cornerRadius(8.0)
|
||||||
.tint(is_ours ? Color.white : Color.accentColor)
|
.tint(is_ours ? Color.white : Color.accentColor)
|
||||||
|
.frame(maxWidth: .infinity, alignment: is_ours ? .trailing : .leading)
|
||||||
|
|
||||||
if !is_ours {
|
if !is_ours {
|
||||||
Spacer(minLength: UIScreen.main.bounds.width * 0.2)
|
Spacer(minLength: UIScreen.main.bounds.width * 0.2)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ struct EventBody: View {
|
|||||||
|
|
||||||
let should_show_img = should_show_images(contacts: damus_state.contacts, ev: event, our_pubkey: damus_state.pubkey, booster_pubkey: nil)
|
let should_show_img = should_show_images(contacts: damus_state.contacts, ev: event, our_pubkey: damus_state.pubkey, booster_pubkey: nil)
|
||||||
|
|
||||||
NoteContentView(damus_state: damus_state, event: event, show_images: should_show_img, size: size, artifacts: .just_content(content))
|
NoteContentView(damus_state: damus_state, event: event, show_images: should_show_img, size: size, show_time: false, artifacts: .just_content(content))
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ struct NoteContentView: View {
|
|||||||
let event: NostrEvent
|
let event: NostrEvent
|
||||||
let show_images: Bool
|
let show_images: Bool
|
||||||
let size: EventViewKind
|
let size: EventViewKind
|
||||||
|
let show_time: Bool
|
||||||
|
|
||||||
@State var artifacts: NoteArtifacts
|
@State var artifacts: NoteArtifacts
|
||||||
@State var preview: LinkViewRepresentable? = nil
|
@State var preview: LinkViewRepresentable? = nil
|
||||||
@@ -67,6 +68,14 @@ struct NoteContentView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if show_time {
|
||||||
|
Text(verbatim: Date.init(timeIntervalSince1970: Double(event.created_at)).formatted(date: .omitted, time: .shortened))
|
||||||
|
.font(.footnote)
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
.frame(alignment: .trailing)
|
||||||
|
.padding([.top], 2)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,37 +138,54 @@ struct NoteContentView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func hashtag_str(_ htag: String) -> AttributedString {
|
func hashtag_str(_ htag: String, ev: NostrEvent) -> AttributedString {
|
||||||
var attributedString = AttributedString(stringLiteral: "#\(htag)")
|
var attributedString = AttributedString(stringLiteral: "#\(htag)")
|
||||||
attributedString.link = URL(string: "nostr:t:\(htag)")
|
attributedString.link = URL(string: "nostr:t:\(htag)")
|
||||||
attributedString.foregroundColor = .purple
|
|
||||||
return attributedString
|
if ev.known_kind == .dm {
|
||||||
}
|
attributedString.underlineStyle = .single
|
||||||
|
} else {
|
||||||
|
attributedString.foregroundColor = .purple
|
||||||
|
}
|
||||||
|
|
||||||
func url_str(_ url: URL) -> AttributedString {
|
|
||||||
var attributedString = AttributedString(stringLiteral: url.absoluteString)
|
|
||||||
attributedString.link = url
|
|
||||||
attributedString.foregroundColor = .purple
|
|
||||||
return attributedString
|
return attributedString
|
||||||
}
|
}
|
||||||
|
|
||||||
func mention_str(_ m: Mention, profiles: Profiles) -> AttributedString {
|
func url_str(_ url: URL, ev: NostrEvent) -> AttributedString {
|
||||||
|
var attributedString = AttributedString(stringLiteral: url.absoluteString)
|
||||||
|
attributedString.link = url
|
||||||
|
|
||||||
|
if ev.known_kind == .dm {
|
||||||
|
attributedString.underlineStyle = .single
|
||||||
|
} else {
|
||||||
|
attributedString.foregroundColor = .purple
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributedString
|
||||||
|
}
|
||||||
|
|
||||||
|
func mention_str(_ m: Mention, profiles: Profiles, ev: NostrEvent) -> AttributedString {
|
||||||
|
var attributedString: AttributedString
|
||||||
switch m.type {
|
switch m.type {
|
||||||
case .pubkey:
|
case .pubkey:
|
||||||
let pk = m.ref.ref_id
|
let pk = m.ref.ref_id
|
||||||
let profile = profiles.lookup(id: pk)
|
let profile = profiles.lookup(id: pk)
|
||||||
let disp = Profile.displayName(profile: profile, pubkey: pk)
|
let disp = Profile.displayName(profile: profile, pubkey: pk)
|
||||||
var attributedString = AttributedString(stringLiteral: "@\(disp)")
|
attributedString = AttributedString(stringLiteral: "@\(disp)")
|
||||||
attributedString.link = URL(string: "nostr:\(encode_pubkey_uri(m.ref))")
|
attributedString.link = URL(string: "nostr:\(encode_pubkey_uri(m.ref))")
|
||||||
attributedString.foregroundColor = .purple
|
|
||||||
return attributedString
|
|
||||||
case .event:
|
case .event:
|
||||||
let bevid = bech32_note_id(m.ref.ref_id) ?? m.ref.ref_id
|
let bevid = bech32_note_id(m.ref.ref_id) ?? m.ref.ref_id
|
||||||
var attributedString = AttributedString(stringLiteral: "@\(abbrev_pubkey(bevid))")
|
attributedString = AttributedString(stringLiteral: "@\(abbrev_pubkey(bevid))")
|
||||||
attributedString.link = URL(string: "nostr:\(encode_event_id_uri(m.ref))")
|
attributedString.link = URL(string: "nostr:\(encode_event_id_uri(m.ref))")
|
||||||
attributedString.foregroundColor = .purple
|
|
||||||
return attributedString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ev.known_kind == .dm {
|
||||||
|
attributedString.underlineStyle = .single
|
||||||
|
} else {
|
||||||
|
attributedString.foregroundColor = .purple
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributedString
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NoteContentView_Previews: PreviewProvider {
|
struct NoteContentView_Previews: PreviewProvider {
|
||||||
@@ -167,11 +193,10 @@ struct NoteContentView_Previews: PreviewProvider {
|
|||||||
let state = test_damus_state()
|
let state = test_damus_state()
|
||||||
let content = "hi there ¯\\_(ツ)_/¯ https://jb55.com/s/Oct12-150217.png 5739a762ef6124dd.jpg"
|
let content = "hi there ¯\\_(ツ)_/¯ https://jb55.com/s/Oct12-150217.png 5739a762ef6124dd.jpg"
|
||||||
let artifacts = NoteArtifacts(content: AttributedString(stringLiteral: content), images: [], invoices: [], links: [])
|
let artifacts = NoteArtifacts(content: AttributedString(stringLiteral: content), images: [], invoices: [], links: [])
|
||||||
NoteContentView(damus_state: state, event: NostrEvent(content: content, pubkey: "pk"), show_images: true, size: .normal, artifacts: artifacts)
|
NoteContentView(damus_state: state, event: NostrEvent(content: content, pubkey: "pk"), show_images: true, size: .normal, show_time: false, artifacts: artifacts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extension View {
|
extension View {
|
||||||
func translate_button_style() -> some View {
|
func translate_button_style() -> some View {
|
||||||
return self
|
return self
|
||||||
@@ -194,21 +219,21 @@ struct NoteArtifacts {
|
|||||||
|
|
||||||
func render_note_content(ev: NostrEvent, profiles: Profiles, privkey: String?) -> NoteArtifacts {
|
func render_note_content(ev: NostrEvent, profiles: Profiles, privkey: String?) -> NoteArtifacts {
|
||||||
let blocks = ev.blocks(privkey)
|
let blocks = ev.blocks(privkey)
|
||||||
return render_blocks(blocks: blocks, profiles: profiles, privkey: privkey)
|
return render_blocks(blocks: blocks, profiles: profiles, privkey: privkey, ev: ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
func render_blocks(blocks: [Block], profiles: Profiles, privkey: String?) -> NoteArtifacts {
|
func render_blocks(blocks: [Block], profiles: Profiles, privkey: String?, ev: NostrEvent) -> NoteArtifacts {
|
||||||
var invoices: [Invoice] = []
|
var invoices: [Invoice] = []
|
||||||
var img_urls: [URL] = []
|
var img_urls: [URL] = []
|
||||||
var link_urls: [URL] = []
|
var link_urls: [URL] = []
|
||||||
let txt: AttributedString = blocks.reduce("") { str, block in
|
let txt: AttributedString = blocks.reduce("") { str, block in
|
||||||
switch block {
|
switch block {
|
||||||
case .mention(let m):
|
case .mention(let m):
|
||||||
return str + mention_str(m, profiles: profiles)
|
return str + mention_str(m, profiles: profiles, ev: ev)
|
||||||
case .text(let txt):
|
case .text(let txt):
|
||||||
return str + AttributedString(stringLiteral: txt)
|
return str + AttributedString(stringLiteral: txt)
|
||||||
case .hashtag(let htag):
|
case .hashtag(let htag):
|
||||||
return str + hashtag_str(htag)
|
return str + hashtag_str(htag, ev: ev)
|
||||||
case .invoice(let invoice):
|
case .invoice(let invoice):
|
||||||
invoices.append(invoice)
|
invoices.append(invoice)
|
||||||
return str
|
return str
|
||||||
@@ -220,7 +245,7 @@ func render_blocks(blocks: [Block], profiles: Profiles, privkey: String?) -> Not
|
|||||||
return str
|
return str
|
||||||
} else {
|
} else {
|
||||||
link_urls.append(url)
|
link_urls.append(url)
|
||||||
return str + url_str(url)
|
return str + url_str(url, ev: ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user