@@ -1,3 +1,4 @@
|
|||||||
|
use egui::text::LayoutJob;
|
||||||
use poll_promise::Promise;
|
use poll_promise::Promise;
|
||||||
|
|
||||||
use crate::{media_upload::Nip94Event, post::PostBuffer, ui::note::PostType, Error};
|
use crate::{media_upload::Nip94Event, post::PostBuffer, ui::note::PostType, Error};
|
||||||
@@ -6,6 +7,7 @@ use std::collections::HashMap;
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Draft {
|
pub struct Draft {
|
||||||
pub buffer: PostBuffer,
|
pub buffer: PostBuffer,
|
||||||
|
pub cur_layout: Option<(String, LayoutJob)>, // `PostBuffer::text_buffer` to current `LayoutJob`
|
||||||
pub cur_mention_hint: Option<MentionHint>,
|
pub cur_mention_hint: Option<MentionHint>,
|
||||||
pub uploaded_media: Vec<Nip94Event>, // media uploads to include
|
pub uploaded_media: Vec<Nip94Event>, // media uploads to include
|
||||||
pub uploading_media: Vec<Promise<Result<Nip94Event, Error>>>, // promises that aren't ready yet
|
pub uploading_media: Vec<Promise<Result<Nip94Event, Error>>>, // promises that aren't ready yet
|
||||||
|
|||||||
@@ -247,6 +247,7 @@ pub struct PostBuffer {
|
|||||||
pub mention_indicator: char,
|
pub mention_indicator: char,
|
||||||
pub mentions: HashMap<MentionKey, MentionInfo>,
|
pub mentions: HashMap<MentionKey, MentionInfo>,
|
||||||
mentions_key: MentionKey,
|
mentions_key: MentionKey,
|
||||||
|
pub selected_mention: bool,
|
||||||
|
|
||||||
// the start index of a mention is inclusive
|
// the start index of a mention is inclusive
|
||||||
pub mention_starts: BTreeMap<usize, MentionKey>, // maps the mention start index with the correct `MentionKey`
|
pub mention_starts: BTreeMap<usize, MentionKey>, // maps the mention start index with the correct `MentionKey`
|
||||||
@@ -260,6 +261,7 @@ impl Default for PostBuffer {
|
|||||||
Self {
|
Self {
|
||||||
mention_indicator: '@',
|
mention_indicator: '@',
|
||||||
mentions_key: 0,
|
mentions_key: 0,
|
||||||
|
selected_mention: false,
|
||||||
text_buffer: Default::default(),
|
text_buffer: Default::default(),
|
||||||
mentions: Default::default(),
|
mentions: Default::default(),
|
||||||
mention_starts: Default::default(),
|
mention_starts: Default::default(),
|
||||||
@@ -306,6 +308,7 @@ impl PostBuffer {
|
|||||||
pub fn select_full_mention(&mut self, mention_key: usize, pk: Pubkey) {
|
pub fn select_full_mention(&mut self, mention_key: usize, pk: Pubkey) {
|
||||||
if let Some(info) = self.mentions.get_mut(&mention_key) {
|
if let Some(info) = self.mentions.get_mut(&mention_key) {
|
||||||
info.mention_type = MentionType::Finalized(pk);
|
info.mention_type = MentionType::Finalized(pk);
|
||||||
|
self.selected_mention = true;
|
||||||
} else {
|
} else {
|
||||||
error!("Error selecting mention for index: {mention_key}. Have the following mentions: {:?}", self.mentions);
|
error!("Error selecting mention for index: {mention_key}. Have the following mentions: {:?}", self.mentions);
|
||||||
}
|
}
|
||||||
@@ -402,6 +405,18 @@ impl PostBuffer {
|
|||||||
|
|
||||||
job
|
job
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn need_new_layout(&self, cache: Option<&(String, LayoutJob)>) -> bool {
|
||||||
|
if let Some((text, _)) = cache {
|
||||||
|
if self.selected_mention {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.text_buffer != *text
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn char_indices_to_byte(text: &str, char_range: Range<usize>) -> Option<Range<usize>> {
|
fn char_indices_to_byte(text: &str, char_range: Range<usize>) -> Option<Range<usize>> {
|
||||||
|
|||||||
@@ -130,13 +130,28 @@ impl<'a> PostView<'a> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut updated_layout = false;
|
||||||
let mut layouter = |ui: &egui::Ui, buf: &dyn TextBuffer, wrap_width: f32| {
|
let mut layouter = |ui: &egui::Ui, buf: &dyn TextBuffer, wrap_width: f32| {
|
||||||
let mut layout_job = if let Some(post_buffer) = downcast_post_buffer(buf) {
|
if let Some(post_buffer) = downcast_post_buffer(buf) {
|
||||||
post_buffer.to_layout_job(ui)
|
let maybe_job = if post_buffer.need_new_layout(self.draft.cur_layout.as_ref()) {
|
||||||
|
Some(post_buffer.to_layout_job(ui))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(job) = maybe_job {
|
||||||
|
self.draft.cur_layout = Some((post_buffer.text_buffer.clone(), job));
|
||||||
|
updated_layout = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut layout_job = if let Some((_, job)) = &self.draft.cur_layout {
|
||||||
|
job.clone()
|
||||||
} else {
|
} else {
|
||||||
error!("Failed to get custom mentions layouter");
|
error!("Failed to get custom mentions layouter");
|
||||||
text_edit_default_layout(ui, buf.as_str().to_owned(), wrap_width)
|
text_edit_default_layout(ui, buf.as_str().to_owned(), wrap_width)
|
||||||
};
|
};
|
||||||
|
|
||||||
layout_job.wrap.max_width = wrap_width;
|
layout_job.wrap.max_width = wrap_width;
|
||||||
ui.fonts(|f| f.layout_job(layout_job))
|
ui.fonts(|f| f.layout_job(layout_job))
|
||||||
};
|
};
|
||||||
@@ -149,6 +164,10 @@ impl<'a> PostView<'a> {
|
|||||||
|
|
||||||
let out = textedit.show(ui);
|
let out = textedit.show(ui);
|
||||||
|
|
||||||
|
if updated_layout {
|
||||||
|
self.draft.buffer.selected_mention = false;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(cursor_index) = get_cursor_index(&out.state.cursor.char_range()) {
|
if let Some(cursor_index) = get_cursor_index(&out.state.cursor.char_range()) {
|
||||||
self.show_mention_hints(txn, ui, cursor_index, &out);
|
self.show_mention_hints(txn, ui, cursor_index, &out);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user