reply.rs (4558B)
1 use crate::draft::Draft; 2 use crate::ui; 3 use crate::ui::note::{PostResponse, PostType}; 4 use enostr::{FilledKeypair, NoteId}; 5 6 use super::contents::NoteContext; 7 use super::NoteOptions; 8 9 pub struct PostReplyView<'a, 'd> { 10 note_context: &'a mut NoteContext<'d>, 11 poster: FilledKeypair<'a>, 12 draft: &'a mut Draft, 13 note: &'a nostrdb::Note<'a>, 14 id_source: Option<egui::Id>, 15 inner_rect: egui::Rect, 16 note_options: NoteOptions, 17 } 18 19 impl<'a, 'd> PostReplyView<'a, 'd> { 20 #[allow(clippy::too_many_arguments)] 21 pub fn new( 22 note_context: &'a mut NoteContext<'d>, 23 poster: FilledKeypair<'a>, 24 draft: &'a mut Draft, 25 note: &'a nostrdb::Note<'a>, 26 inner_rect: egui::Rect, 27 note_options: NoteOptions, 28 ) -> Self { 29 let id_source: Option<egui::Id> = None; 30 PostReplyView { 31 note_context, 32 poster, 33 draft, 34 note, 35 id_source, 36 inner_rect, 37 note_options, 38 } 39 } 40 41 pub fn id_source(mut self, id: egui::Id) -> Self { 42 self.id_source = Some(id); 43 self 44 } 45 46 pub fn id(&self) -> egui::Id { 47 self.id_source 48 .unwrap_or_else(|| egui::Id::new("post-reply-view")) 49 } 50 51 pub fn show(&mut self, ui: &mut egui::Ui) -> PostResponse { 52 ui.vertical(|ui| { 53 let avail_rect = ui.available_rect_before_wrap(); 54 55 // This is the offset of the post view's pfp. We use this 56 // to indent things so that the reply line is aligned 57 let pfp_offset: i8 = ui::PostView::outer_margin() 58 + ui::PostView::inner_margin() 59 + ui::ProfilePic::small_size() / 2; 60 61 let note_offset: i8 = 62 pfp_offset - ui::ProfilePic::medium_size() / 2 - ui::NoteView::expand_size() / 2; 63 64 let selection = egui::Frame::NONE 65 .outer_margin(egui::Margin::same(note_offset)) 66 .show(ui, |ui| { 67 ui::NoteView::new(self.note_context, self.note, self.note_options) 68 .actionbar(false) 69 .medium_pfp(true) 70 .options_button(true) 71 .show(ui) 72 }) 73 .inner 74 .context_selection; 75 76 let id = self.id(); 77 let replying_to = self.note.id(); 78 let rect_before_post = ui.min_rect(); 79 80 let mut post_response = { 81 ui::PostView::new( 82 self.note_context, 83 self.draft, 84 PostType::Reply(NoteId::new(*replying_to)), 85 self.poster, 86 self.inner_rect, 87 self.note_options, 88 ) 89 .id_source(id) 90 .ui(self.note.txn().unwrap(), ui) 91 }; 92 93 post_response.context_selection = selection; 94 95 // 96 // reply line 97 // 98 99 // Position and draw the reply line 100 let mut rect = ui.min_rect(); 101 102 // Position the line right above the poster's profile pic in 103 // the post box. Use the PostView's margin values to 104 // determine this offset. 105 rect.min.x = avail_rect.min.x + pfp_offset as f32; 106 107 // honestly don't know what the fuck I'm doing here. just trying 108 // to get the line under the profile picture 109 rect.min.y = avail_rect.min.y 110 + (ui::ProfilePic::medium_size() as f32 / 2.0 111 + ui::ProfilePic::medium_size() as f32 112 + ui::NoteView::expand_size() as f32 * 2.0) 113 + 1.0; 114 115 // For some reason we need to nudge the reply line's height a 116 // few more pixels? 117 let nudge = if post_response.edit_response.has_focus() { 118 // we nudge by one less pixel if focused, otherwise it 119 // overlaps the focused PostView purple border color 120 2.0 121 } else { 122 // we have to nudge by one more pixel when not focused 123 // otherwise it looks like there's a gap(?) 124 3.0 125 }; 126 127 rect.max.y = rect_before_post.max.y + ui::PostView::outer_margin() as f32 + nudge; 128 129 ui.painter().vline( 130 rect.left(), 131 rect.y_range(), 132 ui.visuals().widgets.noninteractive.bg_stroke, 133 ); 134 135 post_response 136 }) 137 .inner 138 } 139 }