commit 3540290f0ab6e78c2af0b66ad9210beef7969a36
parent 2533448180d0a501e03aac3547051ee5d2dc4021
Author: kernelkind <kernelkind@gmail.com>
Date: Mon, 22 Sep 2025 15:15:40 -0400
make update return AppResponse instead of Option<AppAction>
Signed-off-by: kernelkind <kernelkind@gmail.com>
Diffstat:
15 files changed, 92 insertions(+), 58 deletions(-)
diff --git a/crates/notedeck/src/app.rs b/crates/notedeck/src/app.rs
@@ -31,7 +31,31 @@ pub enum AppAction {
}
pub trait App {
- fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> Option<AppAction>;
+ fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> AppResponse;
+}
+
+#[derive(Default)]
+pub struct AppResponse {
+ pub action: Option<AppAction>,
+ pub can_take_drag_from: Vec<egui::Id>,
+}
+
+impl AppResponse {
+ pub fn none() -> Self {
+ Self::default()
+ }
+
+ pub fn action(action: Option<AppAction>) -> Self {
+ Self {
+ action,
+ can_take_drag_from: Vec::new(),
+ }
+ }
+
+ pub fn drag(mut self, can_take_drag_from: Vec<egui::Id>) -> Self {
+ self.can_take_drag_from.extend(can_take_drag_from);
+ self
+ }
}
/// Main notedeck app framework
diff --git a/crates/notedeck/src/lib.rs b/crates/notedeck/src/lib.rs
@@ -44,7 +44,7 @@ pub use account::accounts::{AccountData, AccountSubs, Accounts};
pub use account::contacts::{ContactState, IsFollowing};
pub use account::relay::RelayAction;
pub use account::FALLBACK_PUBKEY;
-pub use app::{App, AppAction, Notedeck};
+pub use app::{App, AppAction, AppResponse, Notedeck};
pub use args::Args;
pub use context::{AppContext, SoftKeyboardContext};
pub use error::{show_one_error_message, Error, FilterError, ZapError};
diff --git a/crates/notedeck_chrome/src/app.rs b/crates/notedeck_chrome/src/app.rs
@@ -1,4 +1,4 @@
-use notedeck::{AppAction, AppContext};
+use notedeck::{AppContext, AppResponse};
use notedeck_clndash::ClnDash;
use notedeck_columns::Damus;
use notedeck_dave::Dave;
@@ -14,7 +14,7 @@ pub enum NotedeckApp {
}
impl notedeck::App for NotedeckApp {
- fn update(&mut self, ctx: &mut AppContext, ui: &mut egui::Ui) -> Option<AppAction> {
+ fn update(&mut self, ctx: &mut AppContext, ui: &mut egui::Ui) -> AppResponse {
match self {
NotedeckApp::Dave(dave) => dave.update(ctx, ui),
NotedeckApp::Columns(columns) => columns.update(ctx, ui),
diff --git a/crates/notedeck_chrome/src/chrome.rs b/crates/notedeck_chrome/src/chrome.rs
@@ -8,6 +8,7 @@ use eframe::CreationContext;
use egui::{vec2, Button, Color32, Label, Layout, Rect, RichText, ThemePreference, Widget};
use egui_extras::{Size, StripBuilder};
use nostrdb::{ProfileRecord, Transaction};
+use notedeck::AppResponse;
use notedeck::Error;
use notedeck::SoftKeyboardContext;
use notedeck::{
@@ -255,7 +256,8 @@ impl Chrome {
);
*/
- if let Some(action) = self.apps[self.active as usize].update(app_ctx, ui) {
+ let resp = self.apps[self.active as usize].update(app_ctx, ui);
+ if let Some(action) = resp.action {
chrome_handle_app_action(self, app_ctx, action, ui);
}
});
@@ -378,12 +380,12 @@ impl Chrome {
}
impl notedeck::App for Chrome {
- fn update(&mut self, ctx: &mut notedeck::AppContext, ui: &mut egui::Ui) -> Option<AppAction> {
+ fn update(&mut self, ctx: &mut notedeck::AppContext, ui: &mut egui::Ui) -> AppResponse {
if let Some(action) = self.show(ctx, ui) {
action.process(ctx, self, ui);
}
// TODO: unify this constant with the columns side panel width. ui crate?
- None
+ AppResponse::none()
}
}
diff --git a/crates/notedeck_clndash/src/lib.rs b/crates/notedeck_clndash/src/lib.rs
@@ -13,7 +13,8 @@ use crate::watch::fetch_paid_invoices;
use lnsocket::bitcoin::secp256k1::{PublicKey, SecretKey, rand};
use lnsocket::{CommandoClient, LNSocket};
use nostrdb::Ndb;
-use notedeck::{AppAction, AppContext};
+use notedeck::AppContext;
+use notedeck::AppResponse;
use serde_json::json;
use std::collections::HashMap;
use std::str::FromStr;
@@ -59,7 +60,7 @@ struct CommChannel {
}
impl notedeck::App for ClnDash {
- fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> Option<AppAction> {
+ fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> AppResponse {
if !self.initialized {
self.connection_state = ConnectionState::Connecting;
@@ -71,7 +72,7 @@ impl notedeck::App for ClnDash {
self.show(ui, ctx);
- None
+ AppResponse::none()
}
}
diff --git a/crates/notedeck_columns/src/app.rs b/crates/notedeck_columns/src/app.rs
@@ -20,8 +20,8 @@ use egui_extras::{Size, StripBuilder};
use enostr::{ClientMessage, PoolRelay, Pubkey, RelayEvent, RelayMessage, RelayPool};
use nostrdb::Transaction;
use notedeck::{
- tr, ui::is_narrow, Accounts, AppAction, AppContext, DataPath, DataPathType, FilterState,
- Images, JobsCache, Localization, NotedeckOptions, SettingsHandler, UnknownIds,
+ tr, ui::is_narrow, Accounts, AppAction, AppContext, AppResponse, DataPath, DataPathType,
+ FilterState, Images, JobsCache, Localization, NotedeckOptions, SettingsHandler, UnknownIds,
};
use notedeck_ui::{
media::{MediaViewer, MediaViewerFlags, MediaViewerState},
@@ -375,16 +375,12 @@ fn process_message(damus: &mut Damus, ctx: &mut AppContext<'_>, relay: &str, msg
}
}
-fn render_damus(
- damus: &mut Damus,
- app_ctx: &mut AppContext<'_>,
- ui: &mut egui::Ui,
-) -> Option<AppAction> {
+fn render_damus(damus: &mut Damus, app_ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> AppResponse {
damus
.note_options
.set(NoteOptions::Wide, is_narrow(ui.ctx()));
- let app_action = if notedeck::ui::is_narrow(ui.ctx()) {
+ let app_resp = if notedeck::ui::is_narrow(ui.ctx()) {
render_damus_mobile(damus, app_ctx, ui)
} else {
render_damus_desktop(damus, app_ctx, ui)
@@ -395,7 +391,7 @@ fn render_damus(
// We use this for keeping timestamps and things up to date
//ui.ctx().request_repaint_after(Duration::from_secs(5));
- app_action
+ app_resp
}
/// Present a fullscreen media viewer if the FullscreenMedia AppOptions flag is set. This is
@@ -641,9 +637,10 @@ fn render_damus_mobile(
app: &mut Damus,
app_ctx: &mut AppContext<'_>,
ui: &mut egui::Ui,
-) -> Option<AppAction> {
+) -> AppResponse {
//let routes = app.timelines[0].routes.clone();
+ let mut can_take_drag_from = Vec::new();
let active_col = app.columns_mut(app_ctx.i18n, app_ctx.accounts).selected as usize;
let mut app_action: Option<AppAction> = None;
// don't show toolbar if soft keyboard is open
@@ -664,14 +661,17 @@ fn render_damus_mobile(
strip.cell(|ui| {
let rect = ui.available_rect_before_wrap();
if !app.columns(app_ctx.accounts).columns().is_empty() {
- let r = nav::render_nav(
+ let resp = nav::render_nav(
active_col,
ui.available_rect_before_wrap(),
app,
app_ctx,
ui,
- )
- .process_render_nav_response(app, app_ctx, ui);
+ );
+
+ can_take_drag_from.extend(resp.can_take_drag_from());
+
+ let r = resp.process_render_nav_response(app, app_ctx, ui);
if let Some(r) = &r {
match r {
ProcessNavResult::SwitchOccurred => {
@@ -710,7 +710,7 @@ fn render_damus_mobile(
});
});
- app_action
+ AppResponse::action(app_action).drag(can_take_drag_from)
}
fn hovering_post_button(
@@ -794,7 +794,7 @@ fn render_damus_desktop(
app: &mut Damus,
app_ctx: &mut AppContext<'_>,
ui: &mut egui::Ui,
-) -> Option<AppAction> {
+) -> AppResponse {
let screen_size = ui.ctx().screen_rect().width();
let calc_panel_width = (screen_size
/ get_active_columns(app_ctx.accounts, &app.decks_cache).num_columns() as f32)
@@ -823,11 +823,13 @@ fn timelines_view(
sizes: Size,
app: &mut Damus,
ctx: &mut AppContext<'_>,
-) -> Option<AppAction> {
+) -> AppResponse {
let num_cols = get_active_columns(ctx.accounts, &app.decks_cache).num_columns();
let mut side_panel_action: Option<nav::SwitchingAction> = None;
let mut responses = Vec::with_capacity(num_cols);
+ let mut can_take_drag_from = Vec::new();
+
StripBuilder::new(ui)
.size(Size::exact(ui::side_panel::SIDE_PANEL_WIDTH))
.sizes(sizes, num_cols)
@@ -883,7 +885,9 @@ fn timelines_view(
inner.set_right(rect.right() - v_line_stroke.width);
inner
};
- responses.push(nav::render_nav(col_index, inner_rect, app, ctx, ui));
+ let resp = nav::render_nav(col_index, inner_rect, app, ctx, ui);
+ can_take_drag_from.extend(resp.can_take_drag_from());
+ responses.push(resp);
// vertical line
ui.painter()
@@ -937,11 +941,11 @@ fn timelines_view(
storage::save_decks_cache(ctx.path, &app.decks_cache);
}
- app_action
+ AppResponse::action(app_action).drag(can_take_drag_from)
}
impl notedeck::App for Damus {
- fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> Option<AppAction> {
+ fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> AppResponse {
/*
self.app
.frame_history
diff --git a/crates/notedeck_columns/src/nav.rs b/crates/notedeck_columns/src/nav.rs
@@ -200,6 +200,13 @@ impl RenderNavResponse {
RenderNavResponse { column, response }
}
+ pub fn can_take_drag_from(&self) -> Vec<egui::Id> {
+ match &self.response {
+ NotedeckNavResponse::Popup(_) => Vec::new(), // TODO(kernelkind): upgrade once popup supports drag ids
+ NotedeckNavResponse::Nav(nav_response) => nav_response.can_take_drag_from.clone(),
+ }
+ }
+
#[must_use = "Make sure to save columns if result is true"]
pub fn process_render_nav_response(
self,
diff --git a/crates/notedeck_columns/src/ui/account_login_view.rs b/crates/notedeck_columns/src/ui/account_login_view.rs
@@ -6,7 +6,7 @@ use egui::{
};
use egui_winit::clipboard::Clipboard;
use enostr::Keypair;
-use notedeck::{fonts::get_font_size, tr, AppAction, Localization, NotedeckTextStyle};
+use notedeck::{fonts::get_font_size, tr, Localization, NotedeckTextStyle};
use notedeck_ui::{
app_images,
context_menu::{input_context, PasteBehavior},
@@ -173,17 +173,17 @@ pub fn eye_button(ui: &mut egui::Ui, is_visible: bool) -> egui::Response {
mod preview {
use super::*;
- use notedeck::{App, AppContext};
+ use notedeck::{App, AppContext, AppResponse};
pub struct AccountLoginPreview {
manager: AcquireKeyState,
}
impl App for AccountLoginPreview {
- fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> Option<AppAction> {
+ fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> AppResponse {
AccountLoginView::new(&mut self.manager, ctx.clipboard, ctx.i18n).ui(ui);
- None
+ AppResponse::none()
}
}
diff --git a/crates/notedeck_columns/src/ui/configure_deck.rs b/crates/notedeck_columns/src/ui/configure_deck.rs
@@ -326,7 +326,7 @@ mod preview {
};
use super::ConfigureDeckView;
- use notedeck::{App, AppAction, AppContext};
+ use notedeck::{App, AppContext, AppResponse};
pub struct ConfigureDeckPreview {
state: DeckState,
@@ -341,10 +341,10 @@ mod preview {
}
impl App for ConfigureDeckPreview {
- fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> Option<AppAction> {
+ fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> AppResponse {
ConfigureDeckView::new(&mut self.state, ctx.i18n).ui(ui);
- None
+ AppResponse::none()
}
}
diff --git a/crates/notedeck_columns/src/ui/edit_deck.rs b/crates/notedeck_columns/src/ui/edit_deck.rs
@@ -60,7 +60,7 @@ mod preview {
};
use super::EditDeckView;
- use notedeck::{App, AppAction, AppContext};
+ use notedeck::{App, AppContext, AppResponse};
pub struct EditDeckPreview {
state: DeckState,
@@ -75,9 +75,9 @@ mod preview {
}
impl App for EditDeckPreview {
- fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> Option<AppAction> {
+ fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> AppResponse {
EditDeckView::new(&mut self.state, ctx.i18n).ui(ui);
- None
+ AppResponse::none()
}
}
diff --git a/crates/notedeck_columns/src/ui/note/post.rs b/crates/notedeck_columns/src/ui/note/post.rs
@@ -825,7 +825,7 @@ mod preview {
use crate::media_upload::Nip94Event;
use super::*;
- use notedeck::{App, AppAction, AppContext};
+ use notedeck::{App, AppContext, AppResponse};
pub struct PostPreview {
draft: Draft,
@@ -866,7 +866,7 @@ mod preview {
}
impl App for PostPreview {
- fn update(&mut self, app: &mut AppContext<'_>, ui: &mut egui::Ui) -> Option<AppAction> {
+ fn update(&mut self, app: &mut AppContext<'_>, ui: &mut egui::Ui) -> AppResponse {
let txn = Transaction::new(app.ndb).expect("txn");
let mut note_context = NoteContext {
ndb: app.ndb,
@@ -893,7 +893,7 @@ mod preview {
)
.ui(&txn, ui);
- None
+ AppResponse::none()
}
}
diff --git a/crates/notedeck_columns/src/ui/preview.rs b/crates/notedeck_columns/src/ui/preview.rs
@@ -1,4 +1,4 @@
-use notedeck::AppAction;
+use notedeck::AppResponse;
pub struct PreviewConfig {
pub is_mobile: bool,
@@ -22,12 +22,8 @@ impl PreviewApp {
}
impl notedeck::App for PreviewApp {
- fn update(
- &mut self,
- app_ctx: &mut notedeck::AppContext<'_>,
- ui: &mut egui::Ui,
- ) -> Option<AppAction> {
+ fn update(&mut self, app_ctx: &mut notedeck::AppContext<'_>, ui: &mut egui::Ui) -> AppResponse {
self.view.update(app_ctx, ui);
- None
+ AppResponse::none()
}
}
diff --git a/crates/notedeck_columns/src/ui/relay.rs b/crates/notedeck_columns/src/ui/relay.rs
@@ -292,7 +292,7 @@ fn get_relay_infos(pool: &RelayPool) -> Vec<RelayInfo<'_>> {
mod preview {
use super::*;
use crate::test_data::sample_pool;
- use notedeck::{App, AppAction, AppContext};
+ use notedeck::{App, AppContext, AppResponse};
pub struct RelayViewPreview {
pool: RelayPool,
@@ -307,11 +307,11 @@ mod preview {
}
impl App for RelayViewPreview {
- fn update(&mut self, app: &mut AppContext<'_>, ui: &mut egui::Ui) -> Option<AppAction> {
+ fn update(&mut self, app: &mut AppContext<'_>, ui: &mut egui::Ui) -> AppResponse {
self.pool.try_recv();
let mut id_string_map = HashMap::new();
RelayView::new(app.pool, &mut id_string_map, app.i18n).ui(ui);
- None
+ AppResponse::none()
}
}
diff --git a/crates/notedeck_dave/src/lib.rs b/crates/notedeck_dave/src/lib.rs
@@ -8,7 +8,7 @@ use egui_wgpu::RenderState;
use enostr::KeypairUnowned;
use futures::StreamExt;
use nostrdb::Transaction;
-use notedeck::{AppAction, AppContext, JobsCache};
+use notedeck::{AppAction, AppContext, AppResponse, JobsCache};
use std::collections::HashMap;
use std::string::ToString;
use std::sync::mpsc::{self, Receiver};
@@ -343,7 +343,7 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr
}
impl notedeck::App for Dave {
- fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> Option<AppAction> {
+ fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> AppResponse {
let mut app_action: Option<AppAction> = None;
// always insert system prompt if we have no context
@@ -374,6 +374,6 @@ impl notedeck::App for Dave {
self.send_user_message(ctx, ui.ctx());
}
- app_action
+ AppResponse::action(app_action)
}
}
diff --git a/crates/notedeck_notebook/src/lib.rs b/crates/notedeck_notebook/src/lib.rs
@@ -1,7 +1,7 @@
use crate::ui::{edge_ui, node_ui};
use egui::{Pos2, Rect};
use jsoncanvas::JsonCanvas;
-use notedeck::{AppAction, AppContext};
+use notedeck::{AppContext, AppResponse};
mod ui;
@@ -28,7 +28,7 @@ impl Default for Notebook {
}
impl notedeck::App for Notebook {
- fn update(&mut self, _ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> Option<AppAction> {
+ fn update(&mut self, _ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> AppResponse {
//let app_action: Option<AppAction> = None;
if !self.loaded {
@@ -48,7 +48,7 @@ impl notedeck::App for Notebook {
}
});
- None
+ AppResponse::none()
}
}