diff --git a/src/app.rs b/src/app.rs index 1e92dc2..e93d272 100644 --- a/src/app.rs +++ b/src/app.rs @@ -903,7 +903,7 @@ fn render_damus_mobile(ctx: &egui::Context, app: &mut Damus) { main_panel(&ctx.style(), ui::is_narrow(ctx)).show(ctx, |ui| { if !app.columns.columns().is_empty() { - nav::render_nav(false, 0, app, ui); + nav::render_nav(0, app, ui); } }); } @@ -986,24 +986,10 @@ fn timelines_view(ui: &mut egui::Ui, sizes: Size, app: &mut Damus, columns: usiz }); let n_cols = app.columns.columns().len(); - let mut first = true; for column_ind in 0..n_cols { strip.cell(|ui| { let rect = ui.available_rect_before_wrap(); - let show_postbox = first - && app - .columns - .column(column_ind) - .router() - .routes() - .iter() - .find_map(|r| r.timeline_id()) - .is_some(); - if show_postbox { - first = false - } - - nav::render_nav(show_postbox, column_ind, app, ui); + nav::render_nav(column_ind, app, ui); // vertical line ui.painter().vline( diff --git a/src/nav.rs b/src/nav.rs index d278400..dadde3c 100644 --- a/src/nav.rs +++ b/src/nav.rs @@ -1,16 +1,17 @@ use crate::{ account_manager::render_accounts_route, + post_action_executor::PostActionExecutor, relay_pool_manager::RelayPoolManager, route::Route, thread::thread_unsubscribe, timeline::route::{render_timeline_route, TimelineRoute, TimelineRouteResponse}, - ui::{note::PostAction, RelayView, View}, + ui::{self, note::PostAction, RelayView, View}, Damus, }; use egui_nav::{Nav, NavAction}; -pub fn render_nav(show_postbox: bool, col: usize, app: &mut Damus, ui: &mut egui::Ui) { +pub fn render_nav(col: usize, app: &mut Damus, ui: &mut egui::Ui) { // TODO(jb55): clean up this router_mut mess by using Router in egui-nav directly let nav_response = Nav::new(app.columns().column(col).router().routes().clone()) .navigating(app.columns_mut().column_mut(col).router_mut().navigating) @@ -28,7 +29,6 @@ pub fn render_nav(show_postbox: bool, col: usize, app: &mut Damus, ui: &mut egui &mut app.accounts, *tlr, col, - show_postbox, app.textmode, ui, ), @@ -50,6 +50,29 @@ pub fn render_nav(show_postbox: bool, col: usize, app: &mut Damus, ui: &mut egui RelayView::new(manager).ui(ui); None } + Route::ComposeNote => { + let kp = app.accounts.selected_or_first_nsec()?; + let draft = app.drafts.compose_mut(); + + let txn = nostrdb::Transaction::new(&app.ndb).expect("txn"); + let post_response = ui::PostView::new( + &app.ndb, + draft, + crate::draft::DraftSource::Compose, + &mut app.img_cache, + &mut app.note_cache, + kp, + ) + .ui(&txn, ui); + + if let Some(action) = post_response.action { + PostActionExecutor::execute(kp, &action, &mut app.pool, draft, |np, seckey| { + np.to_note(seckey) + }); + } + + None + } }); if let Some(reply_response) = nav_response.inner { diff --git a/src/route.rs b/src/route.rs index 33acb34..f9c3736 100644 --- a/src/route.rs +++ b/src/route.rs @@ -12,6 +12,7 @@ pub enum Route { Timeline(TimelineRoute), Accounts(AccountsRoute), Relays, + ComposeNote, } impl Route { @@ -123,6 +124,7 @@ impl fmt::Display for Route { AccountsRoute::Accounts => write!(f, "Accounts"), AccountsRoute::AddAccount => write!(f, "Add Account"), }, + Route::ComposeNote => write!(f, "Compose Note"), } } } diff --git a/src/timeline/route.rs b/src/timeline/route.rs index a7c5a83..0ec381f 100644 --- a/src/timeline/route.rs +++ b/src/timeline/route.rs @@ -46,25 +46,11 @@ pub fn render_timeline_route( accounts: &mut AccountManager, route: TimelineRoute, col: usize, - show_postbox: bool, textmode: bool, ui: &mut egui::Ui, ) -> Option { match route { TimelineRoute::Timeline(timeline_id) => { - if show_postbox { - let kp = accounts.selected_or_first_nsec()?; - let draft = drafts.compose_mut(); - let response = - ui::timeline::postbox_view(ndb, kp, draft, img_cache, note_cache, ui); - - if let Some(action) = response.action { - PostActionExecutor::execute(kp, &action, pool, draft, |np, seckey| { - np.to_note(seckey) - }); - } - } - if let Some(bar_action) = ui::TimelineView::new(timeline_id, columns, ndb, note_cache, img_cache, textmode) .ui(ui) diff --git a/src/ui/side_panel.rs b/src/ui/side_panel.rs index 8a890d2..9d1cbe1 100644 --- a/src/ui/side_panel.rs +++ b/src/ui/side_panel.rs @@ -1,4 +1,4 @@ -use egui::{Button, Layout, SidePanel, Vec2, Widget}; +use egui::{Button, InnerResponse, Layout, RichText, SidePanel, Vec2, Widget}; use crate::{ account_manager::AccountsRoute, @@ -26,6 +26,7 @@ pub enum SidePanelAction { Account, Settings, Columns, + ComposeNote, } pub struct SidePanelResponse { @@ -55,18 +56,56 @@ impl<'a> DesktopSidePanel<'a> { let spacing_amt = 16.0; let inner = ui - .with_layout(Layout::bottom_up(egui::Align::Center), |ui| { - ui.spacing_mut().item_spacing.y = spacing_amt; - let pfp_resp = self.pfp_button(ui); - let settings_resp = ui.add(settings_button(dark_mode)); - let column_resp = ui.add(add_column_button(dark_mode)); + .vertical(|ui| { + let top_resp = ui + .with_layout(Layout::top_down(egui::Align::Center), |ui| { + let compose_resp = ui.add(compose_note_button()); - if pfp_resp.clicked() { - egui::InnerResponse::new(SidePanelAction::Account, pfp_resp) - } else if settings_resp.clicked() || settings_resp.hovered() { - egui::InnerResponse::new(SidePanelAction::Settings, settings_resp) - } else if column_resp.clicked() || column_resp.hovered() { - egui::InnerResponse::new(SidePanelAction::Columns, column_resp) + if compose_resp.clicked() { + Some(InnerResponse::new( + SidePanelAction::ComposeNote, + compose_resp, + )) + } else { + None + } + }) + .inner; + + let (pfp_resp, bottom_resp) = ui + .with_layout(Layout::bottom_up(egui::Align::Center), |ui| { + ui.spacing_mut().item_spacing.y = spacing_amt; + let pfp_resp = self.pfp_button(ui); + let settings_resp = ui.add(settings_button(dark_mode)); + let column_resp = ui.add(add_column_button(dark_mode)); + + let optional_inner = if pfp_resp.clicked() { + Some(egui::InnerResponse::new( + SidePanelAction::Account, + pfp_resp.clone(), + )) + } else if settings_resp.clicked() || settings_resp.hovered() { + Some(egui::InnerResponse::new( + SidePanelAction::Settings, + settings_resp, + )) + } else if column_resp.clicked() || column_resp.hovered() { + Some(egui::InnerResponse::new( + SidePanelAction::Columns, + column_resp, + )) + } else { + None + }; + + (pfp_resp, optional_inner) + }) + .inner; + + if let Some(bottom_inner) = bottom_resp { + bottom_inner + } else if let Some(top_inner) = top_resp { + top_inner } else { egui::InnerResponse::new(SidePanelAction::Panel, pfp_resp) } @@ -110,6 +149,13 @@ impl<'a> DesktopSidePanel<'a> { } } SidePanelAction::Columns => (), // TODO + SidePanelAction::ComposeNote => { + if router.routes().iter().any(|&r| r == Route::ComposeNote) { + router.go_back(); + } else { + router.route_to(Route::ComposeNote); + } + } } } } @@ -145,6 +191,10 @@ fn add_column_button(dark_mode: bool) -> egui::Button<'static> { egui::Button::image(egui::Image::new(img_data).max_width(32.0)).frame(false) } +fn compose_note_button() -> Button<'static> { + Button::new(RichText::new("+").size(32.0)).frame(false) +} + mod preview { use egui_extras::{Size, StripBuilder}; diff --git a/src/ui/timeline.rs b/src/ui/timeline.rs index bc1e02b..00e8973 100644 --- a/src/ui/timeline.rs +++ b/src/ui/timeline.rs @@ -1,4 +1,3 @@ -use crate::draft::Draft; use crate::{ actionbar::BarAction, column::Columns, imgcache::ImageCache, notecache::NoteCache, timeline::TimelineId, ui, @@ -6,12 +5,9 @@ use crate::{ use egui::containers::scroll_area::ScrollBarVisibility; use egui::{Direction, Layout}; use egui_tabs::TabColor; -use enostr::FilledKeypair; use nostrdb::{Ndb, Transaction}; use tracing::{debug, error, warn}; -use super::note::PostResponse; - pub struct TimelineView<'a> { timeline_id: TimelineId, columns: &'a mut Columns, @@ -170,27 +166,6 @@ fn timeline_ui( bar_action } -pub fn postbox_view<'a>( - ndb: &'a Ndb, - key: FilledKeypair<'a>, - draft: &'a mut Draft, - img_cache: &'a mut ImageCache, - note_cache: &'a mut NoteCache, - ui: &'a mut egui::Ui, -) -> PostResponse { - // show a postbox in the first timeline - let txn = Transaction::new(ndb).expect("txn"); - ui::PostView::new( - ndb, - draft, - crate::draft::DraftSource::Compose, - img_cache, - note_cache, - key, - ) - .ui(&txn, ui) -} - fn tabs_ui(ui: &mut egui::Ui) -> i32 { ui.spacing_mut().item_spacing.y = 0.0;