fix crash when removing non-last columns

Fixes: https://github.com/damus-io/notedeck/issues/445
This commit is contained in:
William Casarin
2024-11-17 17:12:59 -08:00
parent a678e647a4
commit de8029d60f
2 changed files with 37 additions and 14 deletions

View File

@@ -729,8 +729,10 @@ fn render_damus_mobile(ctx: &egui::Context, app: &mut Damus) {
//let routes = app.timelines[0].routes.clone(); //let routes = app.timelines[0].routes.clone();
main_panel(&ctx.style(), ui::is_narrow(ctx)).show(ctx, |ui| { main_panel(&ctx.style(), ui::is_narrow(ctx)).show(ctx, |ui| {
if !app.columns.columns().is_empty() && nav::render_nav(0, app, ui) { if !app.columns.columns().is_empty() {
storage::save_columns(&app.path, app.columns.as_serializable_columns()); if let Some(r) = nav::render_nav(0, app, ui) {
r.process_nav_response(&app.path, &mut app.columns)
}
} }
}); });
} }
@@ -807,12 +809,12 @@ fn timelines_view(ui: &mut egui::Ui, sizes: Size, app: &mut Damus) {
); );
}); });
let mut columns_changed = false; let mut nav_resp: Option<nav::RenderNavResponse> = None;
for col_index in 0..app.columns.num_columns() { for col_index in 0..app.columns.num_columns() {
strip.cell(|ui| { strip.cell(|ui| {
let rect = ui.available_rect_before_wrap(); let rect = ui.available_rect_before_wrap();
if nav::render_nav(col_index, app, ui) { if let Some(r) = nav::render_nav(col_index, app, ui) {
columns_changed = true; nav_resp = Some(r);
} }
// vertical line // vertical line
@@ -826,8 +828,8 @@ fn timelines_view(ui: &mut egui::Ui, sizes: Size, app: &mut Damus) {
//strip.cell(|ui| timeline::timeline_view(ui, app, timeline_ind)); //strip.cell(|ui| timeline::timeline_view(ui, app, timeline_ind));
} }
if columns_changed { if let Some(r) = nav_resp {
storage::save_columns(&app.path, app.columns.as_serializable_columns()); r.process_nav_response(&app.path, &mut app.columns);
} }
}); });
} }

View File

@@ -1,11 +1,13 @@
use crate::{ use crate::{
account_manager::render_accounts_route, account_manager::render_accounts_route,
app_style::{get_font_size, NotedeckTextStyle}, app_style::{get_font_size, NotedeckTextStyle},
column::Columns,
fonts::NamedFontFamily, fonts::NamedFontFamily,
notes_holder::NotesHolder, notes_holder::NotesHolder,
profile::Profile, profile::Profile,
relay_pool_manager::RelayPoolManager, relay_pool_manager::RelayPoolManager,
route::Route, route::Route,
storage::{self, DataPath},
thread::Thread, thread::Thread,
timeline::{ timeline::{
route::{render_profile_route, render_timeline_route, AfterRouteExecution, TimelineRoute}, route::{render_profile_route, render_timeline_route, AfterRouteExecution, TimelineRoute},
@@ -27,8 +29,28 @@ use egui_nav::{Nav, NavAction, TitleBarResponse};
use nostrdb::{Ndb, Transaction}; use nostrdb::{Ndb, Transaction};
use tracing::{error, info}; use tracing::{error, info};
pub fn render_nav(col: usize, app: &mut Damus, ui: &mut egui::Ui) -> bool { pub enum RenderNavResponse {
let mut col_changed = false; ColumnChanged,
RemoveColumn(usize),
}
impl RenderNavResponse {
pub fn process_nav_response(&self, path: &DataPath, columns: &mut Columns) {
match self {
RenderNavResponse::ColumnChanged => {
storage::save_columns(path, columns.as_serializable_columns());
}
RenderNavResponse::RemoveColumn(col) => {
columns.delete_column(*col);
storage::save_columns(path, columns.as_serializable_columns());
}
}
}
}
pub fn render_nav(col: usize, app: &mut Damus, ui: &mut egui::Ui) -> Option<RenderNavResponse> {
let mut resp: Option<RenderNavResponse> = None;
let col_id = app.columns.get_column_id_at_index(col); let col_id = app.columns.get_column_id_at_index(col);
// TODO(jb55): clean up this router_mut mess by using Router<R> in egui-nav directly // TODO(jb55): clean up this router_mut mess by using Router<R> in egui-nav directly
let routes = app let routes = app
@@ -193,14 +215,14 @@ pub fn render_nav(col: usize, app: &mut Damus, ui: &mut egui::Ui) -> bool {
pubkey.bytes(), pubkey.bytes(),
); );
} }
col_changed = true; resp = Some(RenderNavResponse::ColumnChanged)
} else if let Some(NavAction::Navigated) = nav_response.action { } else if let Some(NavAction::Navigated) = nav_response.action {
let cur_router = app.columns_mut().column_mut(col).router_mut(); let cur_router = app.columns_mut().column_mut(col).router_mut();
cur_router.navigating = false; cur_router.navigating = false;
if cur_router.is_replacing() { if cur_router.is_replacing() {
cur_router.remove_previous_routes(); cur_router.remove_previous_routes();
} }
col_changed = true; resp = Some(RenderNavResponse::ColumnChanged)
} }
if let Some(title_response) = nav_response.title_response { if let Some(title_response) = nav_response.title_response {
@@ -210,13 +232,12 @@ pub fn render_nav(col: usize, app: &mut Damus, ui: &mut egui::Ui) -> bool {
if let Some(timeline) = tl { if let Some(timeline) = tl {
unsubscribe_timeline(app.ndb(), timeline); unsubscribe_timeline(app.ndb(), timeline);
} }
app.columns_mut().delete_column(col); resp = Some(RenderNavResponse::RemoveColumn(col))
col_changed = true;
} }
} }
} }
col_changed resp
} }
fn unsubscribe_timeline(ndb: &Ndb, timeline: &Timeline) { fn unsubscribe_timeline(ndb: &Ndb, timeline: &Timeline) {