commit 26c4d90be38f5b12f34d76d591a0a256d5eb100a
parent a6856867a992e3ecbffb8d1224405a0382e2cb31
Author: William Casarin <jb55@jb55.com>
Date: Tue, 25 Jun 2024 13:16:13 -0500
initial postbox for testing
not sure if we want to put this here yet, but it matches the design
and will be useful for testing
Fixes: https://github.com/damus-io/notedeck/issues/110
Suggested-by: Rob
Diffstat:
4 files changed, 97 insertions(+), 58 deletions(-)
diff --git a/src/app.rs b/src/app.rs
@@ -1,7 +1,7 @@
use crate::account_manager::AccountManager;
use crate::app_creation::setup_cc;
use crate::app_style::user_requested_visuals_change;
-use crate::draft::Draft;
+use crate::draft::{DraftSource, Drafts};
use crate::error::Error;
use crate::frame_history::FrameHistory;
use crate::imgcache::ImageCache;
@@ -16,7 +16,6 @@ use crate::Result;
use egui_nav::{Nav, NavAction};
use enostr::RelayPool;
use std::cell::RefCell;
-use std::collections::HashMap;
use std::rc::Rc;
use egui::{Context, Frame, Style};
@@ -48,10 +47,10 @@ pub struct Damus {
/// global navigation for account management popups, etc.
pub global_nav: Vec<Route>,
pub textmode: bool,
- pub drafts: HashMap<enostr::NoteId, Draft>,
pub timelines: Vec<Timeline>,
pub selected_timeline: i32,
+ pub drafts: Drafts,
pub img_cache: ImageCache,
pub ndb: Ndb,
@@ -711,7 +710,7 @@ impl Damus {
Self {
is_mobile,
- drafts: HashMap::new(),
+ drafts: Drafts::default(),
state: DamusState::Initializing,
pool: RelayPool::new(),
img_cache: ImageCache::new(imgcache_dir),
@@ -746,7 +745,7 @@ impl Damus {
config.set_ingester_threads(2);
Self {
is_mobile,
- drafts: HashMap::new(),
+ drafts: Drafts::default(),
state: DamusState::Initializing,
pool: RelayPool::new(),
img_cache: ImageCache::new(imgcache_dir),
@@ -891,53 +890,68 @@ fn render_nav(routes: Vec<Route>, timeline_ind: usize, app: &mut Damus, ui: &mut
let navigating = app.timelines[timeline_ind].navigating;
let app_ctx = Rc::new(RefCell::new(app));
- let nav_response =
- Nav::new(routes)
- .navigating(navigating)
- .show(ui, |ui, nav| match nav.top() {
- Route::Timeline(_n) => {
- timeline::timeline_view(ui, &mut app_ctx.borrow_mut(), timeline_ind);
- }
+ let nav_response = Nav::new(routes)
+ .navigating(navigating)
+ .title(false)
+ .show(ui, |ui, nav| match nav.top() {
+ Route::Timeline(_n) => {
+ let app = &mut app_ctx.borrow_mut();
- Route::ManageAccount => {
- ui.label("account management view");
- }
+ if timeline_ind == 0 {
+ // show a postbox in the first timeline
- Route::Thread(_key) => {
- ui.label("thread view");
- }
+ // TODO: don't show the post box if we have no accounts
+ let poster = app
+ .account_manager
+ .get_selected_account_index()
+ .unwrap_or(0);
- Route::Relays => {
- let pool = &mut app_ctx.borrow_mut().pool;
- let manager = RelayPoolManager::new(pool);
- RelayView::new(manager).ui(ui);
+ if let Ok(txn) = Transaction::new(&app.ndb) {
+ ui::PostView::new(app, DraftSource::Compose, poster).ui(&txn, ui);
+ }
}
+ timeline::timeline_view(ui, app, timeline_ind);
+ }
- Route::Reply(id) => {
- let mut app = app_ctx.borrow_mut();
+ Route::ManageAccount => {
+ ui.label("account management view");
+ }
- let txn = if let Ok(txn) = Transaction::new(&app.ndb) {
- txn
- } else {
- ui.label("Reply to unknown note");
- return;
- };
+ Route::Thread(_key) => {
+ ui.label("thread view");
+ }
- let note = if let Ok(note) = app.ndb.get_note_by_id(&txn, id.bytes()) {
- note
- } else {
- ui.label("Reply to unknown note");
- return;
- };
+ Route::Relays => {
+ let pool = &mut app_ctx.borrow_mut().pool;
+ let manager = RelayPoolManager::new(pool);
+ RelayView::new(manager).ui(ui);
+ }
- let id = egui::Id::new(("post", timeline_ind, note.key().unwrap()));
- egui::ScrollArea::vertical().show(ui, |ui| {
- ui::PostReplyView::new(&mut app, ¬e)
- .id_source(id)
- .show(ui);
- });
- }
- });
+ Route::Reply(id) => {
+ let mut app = app_ctx.borrow_mut();
+
+ let txn = if let Ok(txn) = Transaction::new(&app.ndb) {
+ txn
+ } else {
+ ui.label("Reply to unknown note");
+ return;
+ };
+
+ let note = if let Ok(note) = app.ndb.get_note_by_id(&txn, id.bytes()) {
+ note
+ } else {
+ ui.label("Reply to unknown note");
+ return;
+ };
+
+ let id = egui::Id::new(("post", timeline_ind, note.key().unwrap()));
+ egui::ScrollArea::vertical().show(ui, |ui| {
+ ui::PostReplyView::new(&mut app, ¬e)
+ .id_source(id)
+ .show(ui);
+ });
+ }
+ });
if let Some(NavAction::Returned) = nav_response.action {
app_ctx.borrow_mut().timelines[timeline_ind].routes.pop();
diff --git a/src/draft.rs b/src/draft.rs
@@ -1,8 +1,30 @@
+use std::collections::HashMap;
+
#[derive(Default)]
pub struct Draft {
pub buffer: String,
}
+#[derive(Default)]
+pub struct Drafts {
+ pub replies: HashMap<[u8; 32], Draft>,
+ pub compose: Draft,
+}
+
+pub enum DraftSource<'a> {
+ Compose,
+ Reply(&'a [u8; 32]), // note id
+}
+
+impl<'a> DraftSource<'a> {
+ pub fn draft(&self, drafts: &'a mut Drafts) -> &'a mut Draft {
+ match self {
+ DraftSource::Compose => &mut drafts.compose,
+ DraftSource::Reply(id) => drafts.replies.entry(**id).or_default(),
+ }
+ }
+}
+
impl Draft {
pub fn new() -> Self {
Draft::default()
diff --git a/src/ui/note/post.rs b/src/ui/note/post.rs
@@ -1,16 +1,16 @@
use crate::app::Damus;
-use crate::draft::Draft;
+use crate::draft::{Draft, DraftSource};
use crate::ui;
use crate::ui::{Preview, PreviewConfig, View};
use egui::widgets::text_edit::TextEdit;
use nostrdb::Transaction;
-pub struct PostView<'app, 'p> {
+pub struct PostView<'app, 'd> {
app: &'app mut Damus,
/// account index
poster: usize,
+ draft_source: DraftSource<'d>,
id_source: Option<egui::Id>,
- replying_to: &'p [u8; 32],
}
pub struct NewPost {
@@ -27,14 +27,14 @@ pub struct PostResponse {
pub edit_response: egui::Response,
}
-impl<'app, 'p> PostView<'app, 'p> {
- pub fn new(app: &'app mut Damus, poster: usize, replying_to: &'p [u8; 32]) -> Self {
+impl<'app, 'd> PostView<'app, 'd> {
+ pub fn new(app: &'app mut Damus, draft_source: DraftSource<'d>, poster: usize) -> Self {
let id_source: Option<egui::Id> = None;
PostView {
id_source,
app,
poster,
- replying_to,
+ draft_source,
}
}
@@ -44,10 +44,7 @@ impl<'app, 'p> PostView<'app, 'p> {
}
fn draft(&mut self) -> &mut Draft {
- self.app
- .drafts
- .entry(enostr::NoteId::new(*self.replying_to))
- .or_default()
+ self.draft_source.draft(&mut self.app.drafts)
}
fn editbox(&mut self, txn: &nostrdb::Transaction, ui: &mut egui::Ui) -> egui::Response {
@@ -82,7 +79,12 @@ impl<'app, 'p> PostView<'app, 'p> {
);
}
- let response = ui.add(TextEdit::multiline(&mut self.draft().buffer).frame(false));
+ let buffer = &mut self.draft_source.draft(&mut self.app.drafts).buffer;
+ let response = ui.add(
+ TextEdit::multiline(buffer)
+ .hint_text(egui::RichText::new("Write a banger note here...").weak())
+ .frame(false),
+ );
let focused = response.has_focus();
@@ -183,9 +185,8 @@ mod preview {
impl View for PostPreview {
fn ui(&mut self, ui: &mut egui::Ui) {
- let test_note_id = test_data::test_pubkey();
let txn = Transaction::new(&self.app.ndb).unwrap();
- PostView::new(&mut self.app, 0, test_note_id).ui(&txn, ui);
+ PostView::new(&mut self.app, DraftSource::Compose, 0).ui(&txn, ui);
}
}
diff --git a/src/ui/note/reply.rs b/src/ui/note/reply.rs
@@ -1,3 +1,4 @@
+use crate::draft::DraftSource;
use crate::{ui, Damus};
pub struct PostReplyView<'a> {
@@ -58,7 +59,8 @@ impl<'a> PostReplyView<'a> {
let rect_before_post = ui.min_rect();
let id = self.id();
- let post_response = ui::PostView::new(self.app, poster, replying_to)
+ let draft_source = DraftSource::Reply(replying_to);
+ let post_response = ui::PostView::new(self.app, draft_source, poster)
.id_source(id)
.ui(self.note.txn().unwrap(), ui);