refactor: unify note, post and nav actions
There was a bunch of redundant responses. Let's unify them under the RenderNavAction enum. We unify all action processing under this type. This also centralizes all of our side effects into a single function instead of scattering them everywhere
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
column::Columns,
|
||||||
note::NoteRef,
|
note::NoteRef,
|
||||||
notecache::NoteCache,
|
notecache::NoteCache,
|
||||||
notes_holder::{NotesHolder, NotesHolderStorage},
|
notes_holder::{NotesHolder, NotesHolderStorage},
|
||||||
|
profile::Profile,
|
||||||
route::{Route, Router},
|
route::{Route, Router},
|
||||||
thread::Thread,
|
thread::Thread,
|
||||||
};
|
};
|
||||||
@@ -9,16 +11,11 @@ use enostr::{NoteId, Pubkey, RelayPool};
|
|||||||
use nostrdb::{Ndb, Transaction};
|
use nostrdb::{Ndb, Transaction};
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||||
pub enum BarAction {
|
pub enum NoteAction {
|
||||||
Reply(NoteId),
|
Reply(NoteId),
|
||||||
Quote(NoteId),
|
Quote(NoteId),
|
||||||
OpenThread(NoteId),
|
OpenThread(NoteId),
|
||||||
}
|
OpenProfile(Pubkey),
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct NoteActionResponse {
|
|
||||||
pub bar_action: Option<BarAction>,
|
|
||||||
pub open_profile: Option<Pubkey>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NewNotes {
|
pub struct NewNotes {
|
||||||
@@ -50,47 +47,55 @@ fn open_thread(
|
|||||||
Thread::open(ndb, note_cache, txn, pool, threads, root_id)
|
Thread::open(ndb, note_cache, txn, pool, threads, root_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BarAction {
|
impl NoteAction {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn execute(
|
pub fn execute(
|
||||||
self,
|
self,
|
||||||
ndb: &Ndb,
|
ndb: &Ndb,
|
||||||
router: &mut Router<Route>,
|
router: &mut Router<Route>,
|
||||||
threads: &mut NotesHolderStorage<Thread>,
|
threads: &mut NotesHolderStorage<Thread>,
|
||||||
|
profiles: &mut NotesHolderStorage<Profile>,
|
||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
pool: &mut RelayPool,
|
pool: &mut RelayPool,
|
||||||
txn: &Transaction,
|
txn: &Transaction,
|
||||||
) -> Option<NotesHolderResult> {
|
) -> Option<NotesHolderResult> {
|
||||||
match self {
|
match self {
|
||||||
BarAction::Reply(note_id) => {
|
NoteAction::Reply(note_id) => {
|
||||||
router.route_to(Route::reply(note_id));
|
router.route_to(Route::reply(note_id));
|
||||||
router.navigating = true;
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
BarAction::OpenThread(note_id) => {
|
NoteAction::OpenThread(note_id) => {
|
||||||
open_thread(ndb, txn, router, note_cache, pool, threads, note_id.bytes())
|
open_thread(ndb, txn, router, note_cache, pool, threads, note_id.bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
BarAction::Quote(note_id) => {
|
NoteAction::OpenProfile(pubkey) => {
|
||||||
|
router.route_to(Route::profile(pubkey));
|
||||||
|
Profile::open(ndb, note_cache, txn, pool, profiles, pubkey.bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
NoteAction::Quote(note_id) => {
|
||||||
router.route_to(Route::quote(note_id));
|
router.route_to(Route::quote(note_id));
|
||||||
router.navigating = true;
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute the BarAction and process the BarResult
|
/// Execute the NoteAction and process the NotesHolderResult
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn execute_and_process_result(
|
pub fn execute_and_process_result(
|
||||||
self,
|
self,
|
||||||
ndb: &Ndb,
|
ndb: &Ndb,
|
||||||
router: &mut Router<Route>,
|
columns: &mut Columns,
|
||||||
|
col: usize,
|
||||||
threads: &mut NotesHolderStorage<Thread>,
|
threads: &mut NotesHolderStorage<Thread>,
|
||||||
|
profiles: &mut NotesHolderStorage<Profile>,
|
||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
pool: &mut RelayPool,
|
pool: &mut RelayPool,
|
||||||
txn: &Transaction,
|
txn: &Transaction,
|
||||||
) {
|
) {
|
||||||
if let Some(br) = self.execute(ndb, router, threads, note_cache, pool, txn) {
|
let router = columns.column_mut(col).router_mut();
|
||||||
|
if let Some(br) = self.execute(ndb, router, threads, profiles, note_cache, pool, txn) {
|
||||||
br.process(ndb, note_cache, txn, threads);
|
br.process(ndb, note_cache, txn, threads);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/app.rs
14
src/app.rs
@@ -745,9 +745,7 @@ fn render_damus_mobile(ctx: &egui::Context, app: &mut Damus) {
|
|||||||
|
|
||||||
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() {
|
if !app.columns.columns().is_empty() {
|
||||||
if let Some(r) = nav::render_nav(0, app, ui) {
|
nav::render_nav(0, app, ui).process_render_nav_response(app);
|
||||||
r.process_nav_response(&app.path, &mut app.columns)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -824,13 +822,11 @@ fn timelines_view(ui: &mut egui::Ui, sizes: Size, app: &mut Damus) {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut nav_resp: Option<nav::RenderNavResponse> = None;
|
let mut responses = Vec::with_capacity(app.columns.num_columns());
|
||||||
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 let Some(r) = nav::render_nav(col_index, app, ui) {
|
responses.push(nav::render_nav(col_index, app, ui));
|
||||||
nav_resp = Some(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
// vertical line
|
// vertical line
|
||||||
ui.painter().vline(
|
ui.painter().vline(
|
||||||
@@ -843,8 +839,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 let Some(r) = nav_resp {
|
for response in responses {
|
||||||
r.process_nav_response(&app.path, &mut app.columns);
|
response.process_render_nav_response(app);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -261,9 +261,6 @@ impl SerializableColumns {
|
|||||||
Route::Timeline(TimelineRoute::Thread(_thread)) => {
|
Route::Timeline(TimelineRoute::Thread(_thread)) => {
|
||||||
// TODO: open thread before pushing route
|
// TODO: open thread before pushing route
|
||||||
}
|
}
|
||||||
Route::Profile(_profile) => {
|
|
||||||
// TODO: open profile before pushing route
|
|
||||||
}
|
|
||||||
_ => routes.push(*route),
|
_ => routes.push(*route),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
26
src/draft.rs
26
src/draft.rs
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::ui::note::PostType;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@@ -17,6 +18,14 @@ impl Drafts {
|
|||||||
&mut self.compose
|
&mut self.compose
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_from_post_type(&mut self, post_type: &PostType) -> &mut Draft {
|
||||||
|
match post_type {
|
||||||
|
PostType::New => self.compose_mut(),
|
||||||
|
PostType::Quote(note_id) => self.quote_mut(note_id.bytes()),
|
||||||
|
PostType::Reply(note_id) => self.reply_mut(note_id.bytes()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reply_mut(&mut self, id: &[u8; 32]) -> &mut Draft {
|
pub fn reply_mut(&mut self, id: &[u8; 32]) -> &mut Draft {
|
||||||
self.replies.entry(*id).or_default()
|
self.replies.entry(*id).or_default()
|
||||||
}
|
}
|
||||||
@@ -26,23 +35,6 @@ impl Drafts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum DraftSource<'a> {
|
|
||||||
Compose,
|
|
||||||
Reply(&'a [u8; 32]), // note id
|
|
||||||
Quote(&'a [u8; 32]), // note id
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
impl<'a> DraftSource<'a> {
|
|
||||||
pub fn draft(&self, drafts: &'a mut Drafts) -> &'a mut Draft {
|
|
||||||
match self {
|
|
||||||
DraftSource::Compose => drafts.compose_mut(),
|
|
||||||
DraftSource::Reply(id) => drafts.reply_mut(id),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
impl Draft {
|
impl Draft {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Draft::default()
|
Draft::default()
|
||||||
|
|||||||
357
src/nav.rs
357
src/nav.rs
@@ -1,23 +1,23 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
accounts::render_accounts_route,
|
accounts::render_accounts_route,
|
||||||
|
actionbar::NoteAction,
|
||||||
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},
|
storage::{self},
|
||||||
thread::Thread,
|
thread::Thread,
|
||||||
timeline::{
|
timeline::{
|
||||||
route::{render_profile_route, render_timeline_route, AfterRouteExecution, TimelineRoute},
|
route::{render_timeline_route, TimelineRoute},
|
||||||
Timeline,
|
Timeline,
|
||||||
},
|
},
|
||||||
ui::{
|
ui::{
|
||||||
self,
|
self,
|
||||||
add_column::render_add_column_routes,
|
add_column::render_add_column_routes,
|
||||||
anim::{AnimationHelper, ICON_EXPANSION_MULTIPLE},
|
anim::{AnimationHelper, ICON_EXPANSION_MULTIPLE},
|
||||||
note::PostAction,
|
note::{PostAction, PostType},
|
||||||
support::SupportView,
|
support::SupportView,
|
||||||
RelayView, View,
|
RelayView, View,
|
||||||
},
|
},
|
||||||
@@ -25,32 +25,135 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use egui::{pos2, Color32, InnerResponse, Stroke};
|
use egui::{pos2, Color32, InnerResponse, Stroke};
|
||||||
use egui_nav::{Nav, NavAction, TitleBarResponse};
|
use egui_nav::{Nav, NavAction, NavResponse, TitleBarResponse};
|
||||||
use nostrdb::{Ndb, Transaction};
|
use nostrdb::{Ndb, Transaction};
|
||||||
use tracing::{error, info};
|
use tracing::{error, info};
|
||||||
|
|
||||||
pub enum RenderNavResponse {
|
pub enum RenderNavAction {
|
||||||
ColumnChanged,
|
PostAction(PostAction),
|
||||||
RemoveColumn(usize),
|
NoteAction(NoteAction),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<PostAction> for RenderNavAction {
|
||||||
|
fn from(post_action: PostAction) -> Self {
|
||||||
|
Self::PostAction(post_action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<NoteAction> for RenderNavAction {
|
||||||
|
fn from(note_action: NoteAction) -> RenderNavAction {
|
||||||
|
Self::NoteAction(note_action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RenderNavResponse {
|
||||||
|
column: usize,
|
||||||
|
response: NavResponse<Option<RenderNavAction>, TitleResponse>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderNavResponse {
|
impl RenderNavResponse {
|
||||||
pub fn process_nav_response(&self, path: &DataPath, columns: &mut Columns) {
|
#[allow(private_interfaces)]
|
||||||
match self {
|
pub fn new(
|
||||||
RenderNavResponse::ColumnChanged => {
|
column: usize,
|
||||||
storage::save_columns(path, columns.as_serializable_columns());
|
response: NavResponse<Option<RenderNavAction>, TitleResponse>,
|
||||||
|
) -> Self {
|
||||||
|
RenderNavResponse { column, response }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_render_nav_response(&self, app: &mut Damus) {
|
||||||
|
let mut col_changed: bool = false;
|
||||||
|
let col = self.column;
|
||||||
|
|
||||||
|
if let Some(action) = &self.response.inner {
|
||||||
|
// start returning when we're finished posting
|
||||||
|
match action {
|
||||||
|
RenderNavAction::PostAction(post_action) => {
|
||||||
|
let txn = Transaction::new(&app.ndb).expect("txn");
|
||||||
|
let _ = post_action.execute(&app.ndb, &txn, &mut app.pool, &mut app.drafts);
|
||||||
|
app.columns_mut().column_mut(col).router_mut().go_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderNavAction::NoteAction(note_action) => {
|
||||||
|
let txn = Transaction::new(&app.ndb).expect("txn");
|
||||||
|
|
||||||
|
note_action.execute_and_process_result(
|
||||||
|
&app.ndb,
|
||||||
|
&mut app.columns,
|
||||||
|
col,
|
||||||
|
&mut app.threads,
|
||||||
|
&mut app.profiles,
|
||||||
|
&mut app.note_cache,
|
||||||
|
&mut app.pool,
|
||||||
|
&txn,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(NavAction::Returned) = self.response.action {
|
||||||
|
let r = app.columns_mut().column_mut(col).router_mut().pop();
|
||||||
|
let txn = Transaction::new(&app.ndb).expect("txn");
|
||||||
|
if let Some(Route::Timeline(TimelineRoute::Thread(id))) = r {
|
||||||
|
let root_id = {
|
||||||
|
crate::note::root_note_id_from_selected_id(
|
||||||
|
&app.ndb,
|
||||||
|
&mut app.note_cache,
|
||||||
|
&txn,
|
||||||
|
id.bytes(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
Thread::unsubscribe_locally(
|
||||||
|
&txn,
|
||||||
|
&app.ndb,
|
||||||
|
&mut app.note_cache,
|
||||||
|
&mut app.threads,
|
||||||
|
&mut app.pool,
|
||||||
|
root_id,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderNavResponse::RemoveColumn(col) => {
|
if let Some(Route::Timeline(TimelineRoute::Profile(pubkey))) = r {
|
||||||
columns.delete_column(*col);
|
Profile::unsubscribe_locally(
|
||||||
storage::save_columns(path, columns.as_serializable_columns());
|
&txn,
|
||||||
|
&app.ndb,
|
||||||
|
&mut app.note_cache,
|
||||||
|
&mut app.profiles,
|
||||||
|
&mut app.pool,
|
||||||
|
pubkey.bytes(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
col_changed = true;
|
||||||
|
} else if let Some(NavAction::Navigated) = self.response.action {
|
||||||
|
let cur_router = app.columns_mut().column_mut(col).router_mut();
|
||||||
|
cur_router.navigating = false;
|
||||||
|
if cur_router.is_replacing() {
|
||||||
|
cur_router.remove_previous_routes();
|
||||||
|
}
|
||||||
|
col_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(title_response) = &self.response.title_response {
|
||||||
|
match title_response {
|
||||||
|
TitleResponse::RemoveColumn => {
|
||||||
|
let tl = app.columns().find_timeline_for_column_index(col);
|
||||||
|
if let Some(timeline) = tl {
|
||||||
|
unsubscribe_timeline(app.ndb(), timeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
app.columns_mut().delete_column(col);
|
||||||
|
col_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if col_changed {
|
||||||
|
storage::save_columns(&app.path, app.columns().as_serializable_columns());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_nav(col: usize, app: &mut Damus, ui: &mut egui::Ui) -> Option<RenderNavResponse> {
|
#[must_use = "RenderNavResponse must be handled by calling .process_render_nav_response(..)"]
|
||||||
let mut resp: Option<RenderNavResponse> = None;
|
pub fn render_nav(col: usize, app: &mut Damus, ui: &mut egui::Ui) -> RenderNavResponse {
|
||||||
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
|
||||||
@@ -61,186 +164,78 @@ pub fn render_nav(col: usize, app: &mut Damus, ui: &mut egui::Ui) -> Option<Rend
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|r| r.get_titled_route(&app.columns, &app.ndb))
|
.map(|r| r.get_titled_route(&app.columns, &app.ndb))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let nav_response = Nav::new(routes)
|
let nav_response = Nav::new(routes)
|
||||||
.navigating(app.columns_mut().column_mut(col).router_mut().navigating)
|
.navigating(app.columns_mut().column_mut(col).router_mut().navigating)
|
||||||
.returning(app.columns_mut().column_mut(col).router_mut().returning)
|
.returning(app.columns_mut().column_mut(col).router_mut().returning)
|
||||||
.id_source(egui::Id::new(col_id))
|
.id_source(egui::Id::new(col_id))
|
||||||
.title(48.0, title_bar)
|
.title(48.0, title_bar)
|
||||||
.show_mut(ui, |ui, nav| {
|
.show_mut(ui, |ui, nav| match &nav.top().route {
|
||||||
let column = app.columns.column_mut(col);
|
Route::Timeline(tlr) => render_timeline_route(
|
||||||
match &nav.top().route {
|
&app.ndb,
|
||||||
Route::Timeline(tlr) => render_timeline_route(
|
&mut app.columns,
|
||||||
|
&mut app.drafts,
|
||||||
|
&mut app.img_cache,
|
||||||
|
&mut app.unknown_ids,
|
||||||
|
&mut app.note_cache,
|
||||||
|
&mut app.threads,
|
||||||
|
&mut app.profiles,
|
||||||
|
&mut app.accounts,
|
||||||
|
*tlr,
|
||||||
|
col,
|
||||||
|
app.textmode,
|
||||||
|
ui,
|
||||||
|
),
|
||||||
|
Route::Accounts(amr) => {
|
||||||
|
let action = render_accounts_route(
|
||||||
|
ui,
|
||||||
&app.ndb,
|
&app.ndb,
|
||||||
|
col,
|
||||||
&mut app.columns,
|
&mut app.columns,
|
||||||
&mut app.pool,
|
|
||||||
&mut app.drafts,
|
|
||||||
&mut app.img_cache,
|
&mut app.img_cache,
|
||||||
&mut app.unknown_ids,
|
|
||||||
&mut app.note_cache,
|
|
||||||
&mut app.threads,
|
|
||||||
&mut app.accounts,
|
&mut app.accounts,
|
||||||
*tlr,
|
&mut app.view_state.login,
|
||||||
col,
|
*amr,
|
||||||
app.textmode,
|
);
|
||||||
ui,
|
let txn = Transaction::new(&app.ndb).expect("txn");
|
||||||
),
|
action.process_action(&mut app.unknown_ids, &app.ndb, &txn);
|
||||||
Route::Accounts(amr) => {
|
None
|
||||||
let action = render_accounts_route(
|
}
|
||||||
ui,
|
Route::Relays => {
|
||||||
&app.ndb,
|
let manager = RelayPoolManager::new(app.pool_mut());
|
||||||
col,
|
RelayView::new(manager).ui(ui);
|
||||||
&mut app.columns,
|
None
|
||||||
&mut app.img_cache,
|
}
|
||||||
&mut app.accounts,
|
Route::ComposeNote => {
|
||||||
&mut app.view_state.login,
|
let kp = app.accounts.selected_or_first_nsec()?;
|
||||||
*amr,
|
let draft = app.drafts.compose_mut();
|
||||||
);
|
|
||||||
let txn = Transaction::new(&app.ndb).expect("txn");
|
|
||||||
action.process_action(&mut app.unknown_ids, &app.ndb, &txn);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
Route::Relays => {
|
|
||||||
let manager = RelayPoolManager::new(app.pool_mut());
|
|
||||||
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 txn = nostrdb::Transaction::new(&app.ndb).expect("txn");
|
||||||
let post_response = ui::PostView::new(
|
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 {
|
|
||||||
PostAction::execute(kp, &action, &mut app.pool, draft, |np, seckey| {
|
|
||||||
np.to_note(seckey)
|
|
||||||
});
|
|
||||||
column.router_mut().go_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
Route::AddColumn(route) => {
|
|
||||||
render_add_column_routes(ui, app, col, route);
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
Route::Profile(pubkey) => render_profile_route(
|
|
||||||
pubkey,
|
|
||||||
&app.ndb,
|
&app.ndb,
|
||||||
&mut app.columns,
|
draft,
|
||||||
&mut app.profiles,
|
PostType::New,
|
||||||
&mut app.pool,
|
|
||||||
&mut app.img_cache,
|
&mut app.img_cache,
|
||||||
&mut app.note_cache,
|
&mut app.note_cache,
|
||||||
&mut app.threads,
|
kp,
|
||||||
col,
|
)
|
||||||
ui,
|
.ui(&txn, ui);
|
||||||
),
|
|
||||||
Route::Support => {
|
post_response.action.map(Into::into)
|
||||||
SupportView::new(&mut app.support).show(ui);
|
}
|
||||||
None
|
Route::AddColumn(route) => {
|
||||||
}
|
render_add_column_routes(ui, app, col, route);
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
Route::Support => {
|
||||||
|
SupportView::new(&mut app.support).show(ui);
|
||||||
|
None
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(after_route_execution) = nav_response.inner {
|
RenderNavResponse::new(col, nav_response)
|
||||||
// start returning when we're finished posting
|
|
||||||
match after_route_execution {
|
|
||||||
AfterRouteExecution::Post(resp) => {
|
|
||||||
if let Some(action) = resp.action {
|
|
||||||
match action {
|
|
||||||
PostAction::Post(_) => {
|
|
||||||
app.columns_mut().column_mut(col).router_mut().returning = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AfterRouteExecution::OpenProfile(pubkey) => {
|
|
||||||
app.columns
|
|
||||||
.column_mut(col)
|
|
||||||
.router_mut()
|
|
||||||
.route_to(Route::Profile(pubkey));
|
|
||||||
let txn = Transaction::new(&app.ndb).expect("txn");
|
|
||||||
if let Some(res) = Profile::open(
|
|
||||||
&app.ndb,
|
|
||||||
&mut app.note_cache,
|
|
||||||
&txn,
|
|
||||||
&mut app.pool,
|
|
||||||
&mut app.profiles,
|
|
||||||
pubkey.bytes(),
|
|
||||||
) {
|
|
||||||
res.process(&app.ndb, &mut app.note_cache, &txn, &mut app.profiles);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(NavAction::Returned) = nav_response.action {
|
|
||||||
let r = app.columns_mut().column_mut(col).router_mut().pop();
|
|
||||||
let txn = Transaction::new(&app.ndb).expect("txn");
|
|
||||||
if let Some(Route::Timeline(TimelineRoute::Thread(id))) = r {
|
|
||||||
let root_id = {
|
|
||||||
crate::note::root_note_id_from_selected_id(
|
|
||||||
&app.ndb,
|
|
||||||
&mut app.note_cache,
|
|
||||||
&txn,
|
|
||||||
id.bytes(),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
Thread::unsubscribe_locally(
|
|
||||||
&txn,
|
|
||||||
&app.ndb,
|
|
||||||
&mut app.note_cache,
|
|
||||||
&mut app.threads,
|
|
||||||
&mut app.pool,
|
|
||||||
root_id,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(Route::Profile(pubkey)) = r {
|
|
||||||
Profile::unsubscribe_locally(
|
|
||||||
&txn,
|
|
||||||
&app.ndb,
|
|
||||||
&mut app.note_cache,
|
|
||||||
&mut app.profiles,
|
|
||||||
&mut app.pool,
|
|
||||||
pubkey.bytes(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
resp = Some(RenderNavResponse::ColumnChanged)
|
|
||||||
} else if let Some(NavAction::Navigated) = nav_response.action {
|
|
||||||
let cur_router = app.columns_mut().column_mut(col).router_mut();
|
|
||||||
cur_router.navigating = false;
|
|
||||||
if cur_router.is_replacing() {
|
|
||||||
cur_router.remove_previous_routes();
|
|
||||||
}
|
|
||||||
resp = Some(RenderNavResponse::ColumnChanged)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(title_response) = nav_response.title_response {
|
|
||||||
match title_response {
|
|
||||||
TitleResponse::RemoveColumn => {
|
|
||||||
let tl = app.columns().find_timeline_for_column_index(col);
|
|
||||||
if let Some(timeline) = tl {
|
|
||||||
unsubscribe_timeline(app.ndb(), timeline);
|
|
||||||
}
|
|
||||||
resp = Some(RenderNavResponse::RemoveColumn(col))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unsubscribe_timeline(ndb: &Ndb, timeline: &Timeline) {
|
fn unsubscribe_timeline(ndb: &Ndb, timeline: &Timeline) {
|
||||||
|
|||||||
13
src/route.rs
13
src/route.rs
@@ -21,7 +21,6 @@ pub enum Route {
|
|||||||
Relays,
|
Relays,
|
||||||
ComposeNote,
|
ComposeNote,
|
||||||
AddColumn(AddColumnRoute),
|
AddColumn(AddColumnRoute),
|
||||||
Profile(Pubkey),
|
|
||||||
Support,
|
Support,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,6 +57,10 @@ impl Route {
|
|||||||
Route::Timeline(TimelineRoute::Thread(thread_root))
|
Route::Timeline(TimelineRoute::Thread(thread_root))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn profile(pubkey: Pubkey) -> Self {
|
||||||
|
Route::Timeline(TimelineRoute::Profile(pubkey))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reply(replying_to: NoteId) -> Self {
|
pub fn reply(replying_to: NoteId) -> Self {
|
||||||
Route::Timeline(TimelineRoute::Reply(replying_to))
|
Route::Timeline(TimelineRoute::Reply(replying_to))
|
||||||
}
|
}
|
||||||
@@ -92,6 +95,9 @@ impl Route {
|
|||||||
TimelineRoute::Quote(id) => {
|
TimelineRoute::Quote(id) => {
|
||||||
format!("{}'s Quote", get_note_users_displayname_string(ndb, id))
|
format!("{}'s Quote", get_note_users_displayname_string(ndb, id))
|
||||||
}
|
}
|
||||||
|
TimelineRoute::Profile(pubkey) => {
|
||||||
|
format!("{}'s Profile", get_profile_displayname_string(ndb, pubkey))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
Route::Relays => "Relays".to_owned(),
|
Route::Relays => "Relays".to_owned(),
|
||||||
@@ -108,9 +114,6 @@ impl Route {
|
|||||||
"Add External Notifications Column".to_owned()
|
"Add External Notifications Column".to_owned()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Route::Profile(pubkey) => {
|
|
||||||
format!("{}'s Profile", get_profile_displayname_string(ndb, pubkey))
|
|
||||||
}
|
|
||||||
Route::Support => "Damus Support".to_owned(),
|
Route::Support => "Damus Support".to_owned(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -207,6 +210,7 @@ impl fmt::Display for Route {
|
|||||||
Route::Timeline(tlr) => match tlr {
|
Route::Timeline(tlr) => match tlr {
|
||||||
TimelineRoute::Timeline(name) => write!(f, "{}", name),
|
TimelineRoute::Timeline(name) => write!(f, "{}", name),
|
||||||
TimelineRoute::Thread(_id) => write!(f, "Thread"),
|
TimelineRoute::Thread(_id) => write!(f, "Thread"),
|
||||||
|
TimelineRoute::Profile(_id) => write!(f, "Profile"),
|
||||||
TimelineRoute::Reply(_id) => write!(f, "Reply"),
|
TimelineRoute::Reply(_id) => write!(f, "Reply"),
|
||||||
TimelineRoute::Quote(_id) => write!(f, "Quote"),
|
TimelineRoute::Quote(_id) => write!(f, "Quote"),
|
||||||
},
|
},
|
||||||
@@ -220,7 +224,6 @@ impl fmt::Display for Route {
|
|||||||
Route::ComposeNote => write!(f, "Compose Note"),
|
Route::ComposeNote => write!(f, "Compose Note"),
|
||||||
|
|
||||||
Route::AddColumn(_) => write!(f, "Add Column"),
|
Route::AddColumn(_) => write!(f, "Add Column"),
|
||||||
Route::Profile(_) => write!(f, "Profile"),
|
|
||||||
Route::Support => write!(f, "Support"),
|
Route::Support => write!(f, "Support"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use crate::{
|
|||||||
column::Columns,
|
column::Columns,
|
||||||
draft::Drafts,
|
draft::Drafts,
|
||||||
imgcache::ImageCache,
|
imgcache::ImageCache,
|
||||||
|
nav::RenderNavAction,
|
||||||
notecache::NoteCache,
|
notecache::NoteCache,
|
||||||
notes_holder::NotesHolderStorage,
|
notes_holder::NotesHolderStorage,
|
||||||
profile::Profile,
|
profile::Profile,
|
||||||
@@ -10,53 +11,40 @@ use crate::{
|
|||||||
timeline::{TimelineId, TimelineKind},
|
timeline::{TimelineId, TimelineKind},
|
||||||
ui::{
|
ui::{
|
||||||
self,
|
self,
|
||||||
note::{
|
note::{NoteOptions, QuoteRepostView},
|
||||||
post::{PostAction, PostResponse},
|
|
||||||
NoteOptions, QuoteRepostView,
|
|
||||||
},
|
|
||||||
profile::ProfileView,
|
profile::ProfileView,
|
||||||
},
|
},
|
||||||
unknowns::UnknownIds,
|
unknowns::UnknownIds,
|
||||||
};
|
};
|
||||||
|
|
||||||
use enostr::{NoteId, Pubkey, RelayPool};
|
use enostr::{NoteId, Pubkey};
|
||||||
use nostrdb::{Ndb, Transaction};
|
use nostrdb::{Ndb, Transaction};
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone, Copy, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Eq, PartialEq, Clone, Copy, serde::Serialize, serde::Deserialize)]
|
||||||
pub enum TimelineRoute {
|
pub enum TimelineRoute {
|
||||||
Timeline(TimelineId),
|
Timeline(TimelineId),
|
||||||
Thread(NoteId),
|
Thread(NoteId),
|
||||||
|
Profile(Pubkey),
|
||||||
Reply(NoteId),
|
Reply(NoteId),
|
||||||
Quote(NoteId),
|
Quote(NoteId),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum AfterRouteExecution {
|
|
||||||
Post(PostResponse),
|
|
||||||
OpenProfile(Pubkey),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AfterRouteExecution {
|
|
||||||
pub fn post(post: PostResponse) -> Self {
|
|
||||||
AfterRouteExecution::Post(post)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn render_timeline_route(
|
pub fn render_timeline_route(
|
||||||
ndb: &Ndb,
|
ndb: &Ndb,
|
||||||
columns: &mut Columns,
|
columns: &mut Columns,
|
||||||
pool: &mut RelayPool,
|
|
||||||
drafts: &mut Drafts,
|
drafts: &mut Drafts,
|
||||||
img_cache: &mut ImageCache,
|
img_cache: &mut ImageCache,
|
||||||
unknown_ids: &mut UnknownIds,
|
unknown_ids: &mut UnknownIds,
|
||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
threads: &mut NotesHolderStorage<Thread>,
|
threads: &mut NotesHolderStorage<Thread>,
|
||||||
|
profiles: &mut NotesHolderStorage<Profile>,
|
||||||
accounts: &mut Accounts,
|
accounts: &mut Accounts,
|
||||||
route: TimelineRoute,
|
route: TimelineRoute,
|
||||||
col: usize,
|
col: usize,
|
||||||
textmode: bool,
|
textmode: bool,
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
) -> Option<AfterRouteExecution> {
|
) -> Option<RenderNavAction> {
|
||||||
match route {
|
match route {
|
||||||
TimelineRoute::Timeline(timeline_id) => {
|
TimelineRoute::Timeline(timeline_id) => {
|
||||||
let note_options = {
|
let note_options = {
|
||||||
@@ -71,7 +59,7 @@ pub fn render_timeline_route(
|
|||||||
options
|
options
|
||||||
};
|
};
|
||||||
|
|
||||||
let timeline_response = ui::TimelineView::new(
|
let note_action = ui::TimelineView::new(
|
||||||
timeline_id,
|
timeline_id,
|
||||||
columns,
|
columns,
|
||||||
ndb,
|
ndb,
|
||||||
@@ -81,42 +69,21 @@ pub fn render_timeline_route(
|
|||||||
)
|
)
|
||||||
.ui(ui);
|
.ui(ui);
|
||||||
|
|
||||||
if let Some(bar_action) = timeline_response.bar_action {
|
note_action.map(RenderNavAction::NoteAction)
|
||||||
let txn = Transaction::new(ndb).expect("txn");
|
|
||||||
let mut cur_column = columns.columns_mut();
|
|
||||||
let router = cur_column[col].router_mut();
|
|
||||||
|
|
||||||
bar_action.execute_and_process_result(ndb, router, threads, note_cache, pool, &txn);
|
|
||||||
}
|
|
||||||
|
|
||||||
timeline_response
|
|
||||||
.open_profile
|
|
||||||
.map(AfterRouteExecution::OpenProfile)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TimelineRoute::Thread(id) => {
|
TimelineRoute::Thread(id) => ui::ThreadView::new(
|
||||||
let timeline_response = ui::ThreadView::new(
|
threads,
|
||||||
threads,
|
ndb,
|
||||||
ndb,
|
note_cache,
|
||||||
note_cache,
|
unknown_ids,
|
||||||
unknown_ids,
|
img_cache,
|
||||||
img_cache,
|
id.bytes(),
|
||||||
id.bytes(),
|
textmode,
|
||||||
textmode,
|
)
|
||||||
)
|
.id_source(egui::Id::new(("threadscroll", col)))
|
||||||
.id_source(egui::Id::new(("threadscroll", col)))
|
.ui(ui)
|
||||||
.ui(ui);
|
.map(Into::into),
|
||||||
if let Some(bar_action) = timeline_response.bar_action {
|
|
||||||
let txn = Transaction::new(ndb).expect("txn");
|
|
||||||
let mut cur_column = columns.columns_mut();
|
|
||||||
let router = cur_column[col].router_mut();
|
|
||||||
bar_action.execute_and_process_result(ndb, router, threads, note_cache, pool, &txn);
|
|
||||||
}
|
|
||||||
|
|
||||||
timeline_response
|
|
||||||
.open_profile
|
|
||||||
.map(AfterRouteExecution::OpenProfile)
|
|
||||||
}
|
|
||||||
|
|
||||||
TimelineRoute::Reply(id) => {
|
TimelineRoute::Reply(id) => {
|
||||||
let txn = if let Ok(txn) = Transaction::new(ndb) {
|
let txn = if let Ok(txn) = Transaction::new(ndb) {
|
||||||
@@ -135,21 +102,24 @@ pub fn render_timeline_route(
|
|||||||
|
|
||||||
let id = egui::Id::new(("post", col, note.key().unwrap()));
|
let id = egui::Id::new(("post", col, note.key().unwrap()));
|
||||||
let poster = accounts.selected_or_first_nsec()?;
|
let poster = accounts.selected_or_first_nsec()?;
|
||||||
let draft = drafts.reply_mut(note.id());
|
|
||||||
|
|
||||||
let response = egui::ScrollArea::vertical().show(ui, |ui| {
|
let action = {
|
||||||
ui::PostReplyView::new(ndb, poster, draft, note_cache, img_cache, ¬e)
|
let draft = drafts.reply_mut(note.id());
|
||||||
.id_source(id)
|
|
||||||
.show(ui)
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(action) = &response.inner.action {
|
let response = egui::ScrollArea::vertical().show(ui, |ui| {
|
||||||
PostAction::execute(poster, action, pool, draft, |np, seckey| {
|
ui::PostReplyView::new(ndb, poster, draft, note_cache, img_cache, ¬e)
|
||||||
np.to_reply(seckey, ¬e)
|
.id_source(id)
|
||||||
|
.show(ui)
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
Some(AfterRouteExecution::post(response.inner))
|
response.inner.action
|
||||||
|
};
|
||||||
|
|
||||||
|
action.map(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
TimelineRoute::Profile(pubkey) => {
|
||||||
|
render_profile_route(&pubkey, ndb, profiles, img_cache, note_cache, col, ui)
|
||||||
}
|
}
|
||||||
|
|
||||||
TimelineRoute::Quote(id) => {
|
TimelineRoute::Quote(id) => {
|
||||||
@@ -173,12 +143,7 @@ pub fn render_timeline_route(
|
|||||||
.show(ui)
|
.show(ui)
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(action) = &response.inner.action {
|
response.inner.action.map(Into::into)
|
||||||
PostAction::execute(poster, action, pool, draft, |np, seckey| {
|
|
||||||
np.to_quote(seckey, ¬e)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Some(AfterRouteExecution::post(response.inner))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,16 +152,13 @@ pub fn render_timeline_route(
|
|||||||
pub fn render_profile_route(
|
pub fn render_profile_route(
|
||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
ndb: &Ndb,
|
ndb: &Ndb,
|
||||||
columns: &mut Columns,
|
|
||||||
profiles: &mut NotesHolderStorage<Profile>,
|
profiles: &mut NotesHolderStorage<Profile>,
|
||||||
pool: &mut RelayPool,
|
|
||||||
img_cache: &mut ImageCache,
|
img_cache: &mut ImageCache,
|
||||||
note_cache: &mut NoteCache,
|
note_cache: &mut NoteCache,
|
||||||
threads: &mut NotesHolderStorage<Thread>,
|
|
||||||
col: usize,
|
col: usize,
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
) -> Option<AfterRouteExecution> {
|
) -> Option<RenderNavAction> {
|
||||||
let timeline_response = ProfileView::new(
|
let note_action = ProfileView::new(
|
||||||
pubkey,
|
pubkey,
|
||||||
col,
|
col,
|
||||||
profiles,
|
profiles,
|
||||||
@@ -206,15 +168,6 @@ pub fn render_profile_route(
|
|||||||
NoteOptions::default(),
|
NoteOptions::default(),
|
||||||
)
|
)
|
||||||
.ui(ui);
|
.ui(ui);
|
||||||
if let Some(bar_action) = timeline_response.bar_action {
|
|
||||||
let txn = nostrdb::Transaction::new(ndb).expect("txn");
|
|
||||||
let mut cur_column = columns.columns_mut();
|
|
||||||
let router = cur_column[col].router_mut();
|
|
||||||
|
|
||||||
bar_action.execute_and_process_result(ndb, router, threads, note_cache, pool, &txn);
|
note_action.map(RenderNavAction::NoteAction)
|
||||||
}
|
|
||||||
|
|
||||||
timeline_response
|
|
||||||
.open_profile
|
|
||||||
.map(AfterRouteExecution::OpenProfile)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::actionbar::NoteActionResponse;
|
use crate::actionbar::NoteAction;
|
||||||
use crate::images::ImageType;
|
use crate::images::ImageType;
|
||||||
use crate::imgcache::ImageCache;
|
use crate::imgcache::ImageCache;
|
||||||
use crate::notecache::NoteCache;
|
use crate::notecache::NoteCache;
|
||||||
@@ -17,7 +17,7 @@ pub struct NoteContents<'a> {
|
|||||||
note: &'a Note<'a>,
|
note: &'a Note<'a>,
|
||||||
note_key: NoteKey,
|
note_key: NoteKey,
|
||||||
options: NoteOptions,
|
options: NoteOptions,
|
||||||
action: NoteActionResponse,
|
action: Option<NoteAction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> NoteContents<'a> {
|
impl<'a> NoteContents<'a> {
|
||||||
@@ -38,11 +38,11 @@ impl<'a> NoteContents<'a> {
|
|||||||
note,
|
note,
|
||||||
note_key,
|
note_key,
|
||||||
options,
|
options,
|
||||||
action: NoteActionResponse::default(),
|
action: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn action(&self) -> &NoteActionResponse {
|
pub fn action(&self) -> &Option<NoteAction> {
|
||||||
&self.action
|
&self.action
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,7 +212,7 @@ fn render_note_contents(
|
|||||||
let note_action = if let Some((id, block_str)) = inline_note {
|
let note_action = if let Some((id, block_str)) = inline_note {
|
||||||
render_note_preview(ui, ndb, note_cache, img_cache, txn, id, block_str).action
|
render_note_preview(ui, ndb, note_cache, img_cache, txn, id, block_str).action
|
||||||
} else {
|
} else {
|
||||||
NoteActionResponse::default()
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
if !images.is_empty() && !options.has_textmode() {
|
if !images.is_empty() && !options.has_textmode() {
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ pub mod reply;
|
|||||||
pub use contents::NoteContents;
|
pub use contents::NoteContents;
|
||||||
pub use context::{NoteContextButton, NoteContextSelection};
|
pub use context::{NoteContextButton, NoteContextSelection};
|
||||||
pub use options::NoteOptions;
|
pub use options::NoteOptions;
|
||||||
pub use post::{PostAction, PostResponse, PostView};
|
pub use post::{PostAction, PostResponse, PostType, PostView};
|
||||||
pub use quote_repost::QuoteRepostView;
|
pub use quote_repost::QuoteRepostView;
|
||||||
pub use reply::PostReplyView;
|
pub use reply::PostReplyView;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
actionbar::{BarAction, NoteActionResponse},
|
actionbar::NoteAction,
|
||||||
app_style::NotedeckTextStyle,
|
app_style::NotedeckTextStyle,
|
||||||
colors,
|
colors,
|
||||||
imgcache::ImageCache,
|
imgcache::ImageCache,
|
||||||
@@ -38,7 +38,7 @@ pub struct NoteView<'a> {
|
|||||||
pub struct NoteResponse {
|
pub struct NoteResponse {
|
||||||
pub response: egui::Response,
|
pub response: egui::Response,
|
||||||
pub context_selection: Option<NoteContextSelection>,
|
pub context_selection: Option<NoteContextSelection>,
|
||||||
pub action: NoteActionResponse,
|
pub action: Option<NoteAction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NoteResponse {
|
impl NoteResponse {
|
||||||
@@ -46,11 +46,11 @@ impl NoteResponse {
|
|||||||
Self {
|
Self {
|
||||||
response,
|
response,
|
||||||
context_selection: None,
|
context_selection: None,
|
||||||
action: NoteActionResponse::default(),
|
action: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_action(mut self, action: NoteActionResponse) -> Self {
|
pub fn with_action(mut self, action: Option<NoteAction>) -> Self {
|
||||||
self.action = action;
|
self.action = action;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -437,8 +437,7 @@ impl<'a> NoteView<'a> {
|
|||||||
let note_key = self.note.key().expect("todo: support non-db notes");
|
let note_key = self.note.key().expect("todo: support non-db notes");
|
||||||
let txn = self.note.txn().expect("todo: support non-db notes");
|
let txn = self.note.txn().expect("todo: support non-db notes");
|
||||||
|
|
||||||
let mut open_profile: Option<Pubkey> = None;
|
let mut note_action: Option<NoteAction> = None;
|
||||||
let mut bar_action: Option<BarAction> = None;
|
|
||||||
let mut selected_option: Option<NoteContextSelection> = None;
|
let mut selected_option: Option<NoteContextSelection> = None;
|
||||||
|
|
||||||
let profile = self.ndb.get_profile_by_pubkey(txn, self.note.pubkey());
|
let profile = self.ndb.get_profile_by_pubkey(txn, self.note.pubkey());
|
||||||
@@ -454,7 +453,7 @@ impl<'a> NoteView<'a> {
|
|||||||
let response = if self.options().has_wide() {
|
let response = if self.options().has_wide() {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
if self.pfp(note_key, &profile, ui).clicked() {
|
if self.pfp(note_key, &profile, ui).clicked() {
|
||||||
open_profile = Some(Pubkey::new(*self.note.pubkey()));
|
note_action = Some(NoteAction::OpenProfile(Pubkey::new(*self.note.pubkey())));
|
||||||
};
|
};
|
||||||
|
|
||||||
let size = ui.available_size();
|
let size = ui.available_size();
|
||||||
@@ -498,12 +497,15 @@ impl<'a> NoteView<'a> {
|
|||||||
self.options(),
|
self.options(),
|
||||||
);
|
);
|
||||||
let resp = ui.add(&mut contents);
|
let resp = ui.add(&mut contents);
|
||||||
bar_action = bar_action.or(contents.action().bar_action);
|
|
||||||
open_profile = open_profile.or(contents.action().open_profile);
|
if let Some(action) = contents.action() {
|
||||||
|
note_action = Some(*action);
|
||||||
|
}
|
||||||
|
|
||||||
if self.options().has_actionbar() {
|
if self.options().has_actionbar() {
|
||||||
let ab = render_note_actionbar(ui, self.note.id(), note_key);
|
if let Some(action) = render_note_actionbar(ui, self.note.id(), note_key).inner {
|
||||||
bar_action = bar_action.or(ab.inner);
|
note_action = Some(action);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resp
|
resp
|
||||||
@@ -511,7 +513,7 @@ impl<'a> NoteView<'a> {
|
|||||||
// main design
|
// main design
|
||||||
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
||||||
if self.pfp(note_key, &profile, ui).clicked() {
|
if self.pfp(note_key, &profile, ui).clicked() {
|
||||||
open_profile = Some(Pubkey::new(*self.note.pubkey()));
|
note_action = Some(NoteAction::OpenProfile(Pubkey::new(*self.note.pubkey())));
|
||||||
};
|
};
|
||||||
|
|
||||||
ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| {
|
ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| {
|
||||||
@@ -548,32 +550,34 @@ impl<'a> NoteView<'a> {
|
|||||||
self.options(),
|
self.options(),
|
||||||
);
|
);
|
||||||
ui.add(&mut contents);
|
ui.add(&mut contents);
|
||||||
bar_action = bar_action.or(contents.action().bar_action);
|
|
||||||
open_profile = open_profile.or(contents.action().open_profile);
|
if let Some(action) = contents.action() {
|
||||||
|
note_action = Some(*action);
|
||||||
|
}
|
||||||
|
|
||||||
if self.options().has_actionbar() {
|
if self.options().has_actionbar() {
|
||||||
let ab = render_note_actionbar(ui, self.note.id(), note_key);
|
if let Some(action) =
|
||||||
bar_action = bar_action.or(ab.inner);
|
render_note_actionbar(ui, self.note.id(), note_key).inner
|
||||||
|
{
|
||||||
|
note_action = Some(action);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.response
|
.response
|
||||||
};
|
};
|
||||||
|
|
||||||
bar_action = check_note_hitbox(
|
note_action = check_note_hitbox(
|
||||||
ui,
|
ui,
|
||||||
self.note.id(),
|
self.note.id(),
|
||||||
note_key,
|
note_key,
|
||||||
&response,
|
&response,
|
||||||
maybe_hitbox,
|
maybe_hitbox,
|
||||||
bar_action,
|
note_action,
|
||||||
);
|
);
|
||||||
|
|
||||||
NoteResponse::new(response)
|
NoteResponse::new(response)
|
||||||
.with_action(NoteActionResponse {
|
.with_action(note_action)
|
||||||
bar_action,
|
|
||||||
open_profile,
|
|
||||||
})
|
|
||||||
.select_option(selected_option)
|
.select_option(selected_option)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -630,8 +634,8 @@ fn check_note_hitbox(
|
|||||||
note_key: NoteKey,
|
note_key: NoteKey,
|
||||||
note_response: &Response,
|
note_response: &Response,
|
||||||
maybe_hitbox: Option<Response>,
|
maybe_hitbox: Option<Response>,
|
||||||
prior_action: Option<BarAction>,
|
prior_action: Option<NoteAction>,
|
||||||
) -> Option<BarAction> {
|
) -> Option<NoteAction> {
|
||||||
// Stash the dimensions of the note content so we can render the
|
// Stash the dimensions of the note content so we can render the
|
||||||
// hitbox in the next frame
|
// hitbox in the next frame
|
||||||
ui.ctx().data_mut(|d| {
|
ui.ctx().data_mut(|d| {
|
||||||
@@ -640,7 +644,7 @@ fn check_note_hitbox(
|
|||||||
|
|
||||||
// If there was an hitbox and it was clicked open the thread
|
// If there was an hitbox and it was clicked open the thread
|
||||||
match maybe_hitbox {
|
match maybe_hitbox {
|
||||||
Some(hitbox) if hitbox.clicked() => Some(BarAction::OpenThread(NoteId::new(*note_id))),
|
Some(hitbox) if hitbox.clicked() => Some(NoteAction::OpenThread(NoteId::new(*note_id))),
|
||||||
_ => prior_action,
|
_ => prior_action,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -649,15 +653,15 @@ fn render_note_actionbar(
|
|||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
note_id: &[u8; 32],
|
note_id: &[u8; 32],
|
||||||
note_key: NoteKey,
|
note_key: NoteKey,
|
||||||
) -> egui::InnerResponse<Option<BarAction>> {
|
) -> egui::InnerResponse<Option<NoteAction>> {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
let reply_resp = reply_button(ui, note_key);
|
let reply_resp = reply_button(ui, note_key);
|
||||||
let quote_resp = quote_repost_button(ui, note_key);
|
let quote_resp = quote_repost_button(ui, note_key);
|
||||||
|
|
||||||
if reply_resp.clicked() {
|
if reply_resp.clicked() {
|
||||||
Some(BarAction::Reply(NoteId::new(*note_id)))
|
Some(NoteAction::Reply(NoteId::new(*note_id)))
|
||||||
} else if quote_resp.clicked() {
|
} else if quote_resp.clicked() {
|
||||||
Some(BarAction::Quote(NoteId::new(*note_id)))
|
Some(NoteAction::Quote(NoteId::new(*note_id)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
use crate::draft::{Draft, DraftSource};
|
use crate::draft::{Draft, Drafts};
|
||||||
use crate::imgcache::ImageCache;
|
use crate::imgcache::ImageCache;
|
||||||
use crate::notecache::NoteCache;
|
use crate::notecache::NoteCache;
|
||||||
use crate::post::NewPost;
|
use crate::post::NewPost;
|
||||||
use crate::ui;
|
use crate::ui;
|
||||||
use crate::ui::{Preview, PreviewConfig, View};
|
use crate::ui::{Preview, PreviewConfig, View};
|
||||||
|
use crate::Result;
|
||||||
use egui::widgets::text_edit::TextEdit;
|
use egui::widgets::text_edit::TextEdit;
|
||||||
use egui::{Frame, Layout};
|
use egui::{Frame, Layout};
|
||||||
use enostr::{FilledKeypair, FullKeypair, RelayPool};
|
use enostr::{FilledKeypair, FullKeypair, NoteId, RelayPool};
|
||||||
use nostrdb::{Config, Ndb, Note, Transaction};
|
use nostrdb::{Config, Ndb, Transaction};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
use super::contents::render_note_preview;
|
use super::contents::render_note_preview;
|
||||||
@@ -15,35 +16,59 @@ use super::contents::render_note_preview;
|
|||||||
pub struct PostView<'a> {
|
pub struct PostView<'a> {
|
||||||
ndb: &'a Ndb,
|
ndb: &'a Ndb,
|
||||||
draft: &'a mut Draft,
|
draft: &'a mut Draft,
|
||||||
draft_source: DraftSource<'a>,
|
post_type: PostType,
|
||||||
img_cache: &'a mut ImageCache,
|
img_cache: &'a mut ImageCache,
|
||||||
note_cache: &'a mut NoteCache,
|
note_cache: &'a mut NoteCache,
|
||||||
poster: FilledKeypair<'a>,
|
poster: FilledKeypair<'a>,
|
||||||
id_source: Option<egui::Id>,
|
id_source: Option<egui::Id>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum PostAction {
|
#[derive(Clone)]
|
||||||
Post(NewPost),
|
pub enum PostType {
|
||||||
|
New,
|
||||||
|
Quote(NoteId),
|
||||||
|
Reply(NoteId),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PostAction {
|
||||||
|
post_type: PostType,
|
||||||
|
post: NewPost,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PostAction {
|
impl PostAction {
|
||||||
pub fn execute<'b>(
|
pub fn new(post_type: PostType, post: NewPost) -> Self {
|
||||||
poster: FilledKeypair<'_>,
|
PostAction { post_type, post }
|
||||||
action: &'b PostAction,
|
}
|
||||||
pool: &mut RelayPool,
|
|
||||||
draft: &mut Draft,
|
|
||||||
get_note: impl Fn(&'b NewPost, &[u8; 32]) -> Note<'b>,
|
|
||||||
) {
|
|
||||||
match action {
|
|
||||||
PostAction::Post(np) => {
|
|
||||||
let note = get_note(np, &poster.secret_key.to_secret_bytes());
|
|
||||||
|
|
||||||
let raw_msg = format!("[\"EVENT\",{}]", note.json().unwrap());
|
pub fn execute(
|
||||||
info!("sending {}", raw_msg);
|
&self,
|
||||||
pool.send(&enostr::ClientMessage::raw(raw_msg));
|
ndb: &Ndb,
|
||||||
draft.clear();
|
txn: &Transaction,
|
||||||
|
pool: &mut RelayPool,
|
||||||
|
drafts: &mut Drafts,
|
||||||
|
) -> Result<()> {
|
||||||
|
let seckey = self.post.account.secret_key.to_secret_bytes();
|
||||||
|
|
||||||
|
let note = match self.post_type {
|
||||||
|
PostType::New => self.post.to_note(&seckey),
|
||||||
|
|
||||||
|
PostType::Reply(target) => {
|
||||||
|
let replying_to = ndb.get_note_by_id(txn, target.bytes())?;
|
||||||
|
self.post.to_reply(&seckey, &replying_to)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
PostType::Quote(target) => {
|
||||||
|
let quoting = ndb.get_note_by_id(txn, target.bytes())?;
|
||||||
|
self.post.to_quote(&seckey, "ing)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let raw_msg = format!("[\"EVENT\",{}]", note.json().unwrap());
|
||||||
|
info!("sending {}", raw_msg);
|
||||||
|
pool.send(&enostr::ClientMessage::raw(raw_msg));
|
||||||
|
drafts.get_from_post_type(&self.post_type).clear();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +81,7 @@ impl<'a> PostView<'a> {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
ndb: &'a Ndb,
|
ndb: &'a Ndb,
|
||||||
draft: &'a mut Draft,
|
draft: &'a mut Draft,
|
||||||
draft_source: DraftSource<'a>,
|
post_type: PostType,
|
||||||
img_cache: &'a mut ImageCache,
|
img_cache: &'a mut ImageCache,
|
||||||
note_cache: &'a mut NoteCache,
|
note_cache: &'a mut NoteCache,
|
||||||
poster: FilledKeypair<'a>,
|
poster: FilledKeypair<'a>,
|
||||||
@@ -69,7 +94,7 @@ impl<'a> PostView<'a> {
|
|||||||
note_cache,
|
note_cache,
|
||||||
poster,
|
poster,
|
||||||
id_source,
|
id_source,
|
||||||
draft_source,
|
post_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +187,7 @@ impl<'a> PostView<'a> {
|
|||||||
|
|
||||||
let action = ui
|
let action = ui
|
||||||
.horizontal(|ui| {
|
.horizontal(|ui| {
|
||||||
if let DraftSource::Quote(id) = self.draft_source {
|
if let PostType::Quote(id) = self.post_type {
|
||||||
let avail_size = ui.available_size_before_wrap();
|
let avail_size = ui.available_size_before_wrap();
|
||||||
ui.with_layout(Layout::left_to_right(egui::Align::TOP), |ui| {
|
ui.with_layout(Layout::left_to_right(egui::Align::TOP), |ui| {
|
||||||
Frame::none().show(ui, |ui| {
|
Frame::none().show(ui, |ui| {
|
||||||
@@ -174,7 +199,7 @@ impl<'a> PostView<'a> {
|
|||||||
self.note_cache,
|
self.note_cache,
|
||||||
self.img_cache,
|
self.img_cache,
|
||||||
txn,
|
txn,
|
||||||
id,
|
id.bytes(),
|
||||||
"",
|
"",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -187,10 +212,11 @@ impl<'a> PostView<'a> {
|
|||||||
.add_sized([91.0, 32.0], egui::Button::new("Post now"))
|
.add_sized([91.0, 32.0], egui::Button::new("Post now"))
|
||||||
.clicked()
|
.clicked()
|
||||||
{
|
{
|
||||||
Some(PostAction::Post(NewPost::new(
|
let new_post = NewPost::new(
|
||||||
self.draft.buffer.clone(),
|
self.draft.buffer.clone(),
|
||||||
self.poster.to_full(),
|
self.poster.to_full(),
|
||||||
)))
|
);
|
||||||
|
Some(PostAction::new(self.post_type.clone(), new_post))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -241,7 +267,7 @@ mod preview {
|
|||||||
PostView::new(
|
PostView::new(
|
||||||
&self.ndb,
|
&self.ndb,
|
||||||
&mut self.draft,
|
&mut self.draft,
|
||||||
DraftSource::Compose,
|
PostType::New,
|
||||||
&mut self.img_cache,
|
&mut self.img_cache,
|
||||||
&mut self.note_cache,
|
&mut self.note_cache,
|
||||||
self.poster.to_filled(),
|
self.poster.to_filled(),
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use enostr::FilledKeypair;
|
use enostr::{FilledKeypair, NoteId};
|
||||||
use nostrdb::Ndb;
|
use nostrdb::Ndb;
|
||||||
|
|
||||||
use crate::{draft::Draft, imgcache::ImageCache, notecache::NoteCache, ui};
|
use crate::{draft::Draft, imgcache::ImageCache, notecache::NoteCache, ui};
|
||||||
|
|
||||||
use super::PostResponse;
|
use super::{PostResponse, PostType};
|
||||||
|
|
||||||
pub struct QuoteRepostView<'a> {
|
pub struct QuoteRepostView<'a> {
|
||||||
ndb: &'a Ndb,
|
ndb: &'a Ndb,
|
||||||
@@ -43,7 +43,7 @@ impl<'a> QuoteRepostView<'a> {
|
|||||||
ui::PostView::new(
|
ui::PostView::new(
|
||||||
self.ndb,
|
self.ndb,
|
||||||
self.draft,
|
self.draft,
|
||||||
crate::draft::DraftSource::Quote(quoting_note_id),
|
PostType::Quote(NoteId::new(quoting_note_id.to_owned())),
|
||||||
self.img_cache,
|
self.img_cache,
|
||||||
self.note_cache,
|
self.note_cache,
|
||||||
self.poster,
|
self.poster,
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ use crate::draft::Draft;
|
|||||||
use crate::imgcache::ImageCache;
|
use crate::imgcache::ImageCache;
|
||||||
use crate::notecache::NoteCache;
|
use crate::notecache::NoteCache;
|
||||||
use crate::ui;
|
use crate::ui;
|
||||||
use crate::ui::note::PostResponse;
|
use crate::ui::note::{PostResponse, PostType};
|
||||||
use enostr::FilledKeypair;
|
use enostr::{FilledKeypair, NoteId};
|
||||||
use nostrdb::Ndb;
|
use nostrdb::Ndb;
|
||||||
|
|
||||||
pub struct PostReplyView<'a> {
|
pub struct PostReplyView<'a> {
|
||||||
@@ -79,7 +79,7 @@ impl<'a> PostReplyView<'a> {
|
|||||||
ui::PostView::new(
|
ui::PostView::new(
|
||||||
self.ndb,
|
self.ndb,
|
||||||
self.draft,
|
self.draft,
|
||||||
crate::draft::DraftSource::Reply(replying_to),
|
PostType::Reply(NoteId::new(*replying_to)),
|
||||||
self.img_cache,
|
self.img_cache,
|
||||||
self.note_cache,
|
self.note_cache,
|
||||||
self.poster,
|
self.poster,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ pub use picture::ProfilePic;
|
|||||||
pub use preview::ProfilePreview;
|
pub use preview::ProfilePreview;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
actionbar::NoteActionResponse, imgcache::ImageCache, notecache::NoteCache,
|
actionbar::NoteAction, imgcache::ImageCache, notecache::NoteCache,
|
||||||
notes_holder::NotesHolderStorage, profile::Profile,
|
notes_holder::NotesHolderStorage, profile::Profile,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ impl<'a> ProfileView<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ui(&mut self, ui: &mut egui::Ui) -> NoteActionResponse {
|
pub fn ui(&mut self, ui: &mut egui::Ui) -> Option<NoteAction> {
|
||||||
let scroll_id = egui::Id::new(("profile_scroll", self.col_id, self.pubkey));
|
let scroll_id = egui::Id::new(("profile_scroll", self.col_id, self.pubkey));
|
||||||
|
|
||||||
ScrollArea::vertical()
|
ScrollArea::vertical()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
actionbar::NoteActionResponse,
|
actionbar::NoteAction,
|
||||||
imgcache::ImageCache,
|
imgcache::ImageCache,
|
||||||
notecache::NoteCache,
|
notecache::NoteCache,
|
||||||
notes_holder::{NotesHolder, NotesHolderStorage},
|
notes_holder::{NotesHolder, NotesHolderStorage},
|
||||||
@@ -52,7 +52,7 @@ impl<'a> ThreadView<'a> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ui(&mut self, ui: &mut egui::Ui) -> NoteActionResponse {
|
pub fn ui(&mut self, ui: &mut egui::Ui) -> Option<NoteAction> {
|
||||||
let txn = Transaction::new(self.ndb).expect("txn");
|
let txn = Transaction::new(self.ndb).expect("txn");
|
||||||
|
|
||||||
let selected_note_key = if let Ok(key) = self
|
let selected_note_key = if let Ok(key) = self
|
||||||
@@ -63,7 +63,7 @@ impl<'a> ThreadView<'a> {
|
|||||||
key
|
key
|
||||||
} else {
|
} else {
|
||||||
// TODO: render 404 ?
|
// TODO: render 404 ?
|
||||||
return NoteActionResponse::default();
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
ui.label(
|
ui.label(
|
||||||
@@ -80,7 +80,7 @@ impl<'a> ThreadView<'a> {
|
|||||||
let note = if let Ok(note) = self.ndb.get_note_by_key(&txn, selected_note_key) {
|
let note = if let Ok(note) = self.ndb.get_note_by_key(&txn, selected_note_key) {
|
||||||
note
|
note
|
||||||
} else {
|
} else {
|
||||||
return NoteActionResponse::default();
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let root_id = {
|
let root_id = {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::actionbar::{BarAction, NoteActionResponse};
|
use crate::actionbar::NoteAction;
|
||||||
use crate::timeline::TimelineTab;
|
use crate::timeline::TimelineTab;
|
||||||
use crate::{
|
use crate::{
|
||||||
column::Columns, imgcache::ImageCache, notecache::NoteCache, timeline::TimelineId, ui,
|
column::Columns, imgcache::ImageCache, notecache::NoteCache, timeline::TimelineId, ui,
|
||||||
@@ -41,7 +41,7 @@ impl<'a> TimelineView<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ui(&mut self, ui: &mut egui::Ui) -> NoteActionResponse {
|
pub fn ui(&mut self, ui: &mut egui::Ui) -> Option<NoteAction> {
|
||||||
timeline_ui(
|
timeline_ui(
|
||||||
ui,
|
ui,
|
||||||
self.ndb,
|
self.ndb,
|
||||||
@@ -70,7 +70,7 @@ fn timeline_ui(
|
|||||||
img_cache: &mut ImageCache,
|
img_cache: &mut ImageCache,
|
||||||
reversed: bool,
|
reversed: bool,
|
||||||
note_options: NoteOptions,
|
note_options: NoteOptions,
|
||||||
) -> NoteActionResponse {
|
) -> Option<NoteAction> {
|
||||||
//padding(4.0, ui, |ui| ui.heading("Notifications"));
|
//padding(4.0, ui, |ui| ui.heading("Notifications"));
|
||||||
/*
|
/*
|
||||||
let font_id = egui::TextStyle::Body.resolve(ui.style());
|
let font_id = egui::TextStyle::Body.resolve(ui.style());
|
||||||
@@ -85,7 +85,7 @@ fn timeline_ui(
|
|||||||
error!("tried to render timeline in column, but timeline was missing");
|
error!("tried to render timeline in column, but timeline was missing");
|
||||||
// TODO (jb55): render error when timeline is missing?
|
// TODO (jb55): render error when timeline is missing?
|
||||||
// this shouldn't happen...
|
// this shouldn't happen...
|
||||||
return NoteActionResponse::default();
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
timeline.selected_view = tabs_ui(ui);
|
timeline.selected_view = tabs_ui(ui);
|
||||||
@@ -108,7 +108,7 @@ fn timeline_ui(
|
|||||||
error!("tried to render timeline in column, but timeline was missing");
|
error!("tried to render timeline in column, but timeline was missing");
|
||||||
// TODO (jb55): render error when timeline is missing?
|
// TODO (jb55): render error when timeline is missing?
|
||||||
// this shouldn't happen...
|
// this shouldn't happen...
|
||||||
return NoteActionResponse::default();
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let txn = Transaction::new(ndb).expect("failed to create txn");
|
let txn = Transaction::new(ndb).expect("failed to create txn");
|
||||||
@@ -241,9 +241,8 @@ impl<'a> TimelineTabView<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show(&mut self, ui: &mut egui::Ui) -> NoteActionResponse {
|
pub fn show(&mut self, ui: &mut egui::Ui) -> Option<NoteAction> {
|
||||||
let mut open_profile = None;
|
let mut action: Option<NoteAction> = None;
|
||||||
let mut bar_action: Option<BarAction> = None;
|
|
||||||
let len = self.tab.notes.len();
|
let len = self.tab.notes.len();
|
||||||
|
|
||||||
self.tab
|
self.tab
|
||||||
@@ -274,8 +273,9 @@ impl<'a> TimelineTabView<'a> {
|
|||||||
.note_options(self.note_options)
|
.note_options(self.note_options)
|
||||||
.show(ui);
|
.show(ui);
|
||||||
|
|
||||||
bar_action = bar_action.or(resp.action.bar_action);
|
if let Some(note_action) = resp.action {
|
||||||
open_profile = open_profile.or(resp.action.open_profile);
|
action = Some(note_action)
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(context) = resp.context_selection {
|
if let Some(context) = resp.context_selection {
|
||||||
context.process(ui, ¬e);
|
context.process(ui, ¬e);
|
||||||
@@ -288,9 +288,6 @@ impl<'a> TimelineTabView<'a> {
|
|||||||
1
|
1
|
||||||
});
|
});
|
||||||
|
|
||||||
NoteActionResponse {
|
action
|
||||||
open_profile,
|
|
||||||
bar_action,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user