notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit 771537a4f631b35f2e7c89a412b27983b4e9bde7
parent 7d916805bc77c8f23bac387e84f8e039f93a803c
Author: William Casarin <jb55@jb55.com>
Date:   Tue, 11 Mar 2025 16:08:34 -0700

android: hover post button when narrow

Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mcrates/notedeck_chrome/src/android.rs | 2+-
Mcrates/notedeck_columns/src/app.rs | 25++++++++++++++++++++++++-
Mcrates/notedeck_columns/src/ui/mod.rs | 1+
Acrates/notedeck_columns/src/ui/post.rs | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/notedeck_columns/src/ui/side_panel.rs | 66+++++-------------------------------------------------------------
5 files changed, 93 insertions(+), 63 deletions(-)

diff --git a/crates/notedeck_chrome/src/android.rs b/crates/notedeck_chrome/src/android.rs @@ -18,7 +18,7 @@ pub async fn android_main(app: AndroidApp) { use tracing_subscriber::{prelude::*, EnvFilter}; std::env::set_var("RUST_BACKTRACE", "full"); - std::env::set_var("RUST_LOG", "egui=trace,notedeck=debug,notedeck_columns=debug,notedeck_chrome=debug,enostr=debug,android_activity=debug"); + std::env::set_var("RUST_LOG", "egui=debug,egui-winit=debug,notedeck=debug,notedeck_columns=debug,notedeck_chrome=debug,enostr=debug,android_activity=debug"); //std::env::set_var( // "RUST_LOG", diff --git a/crates/notedeck_columns/src/app.rs b/crates/notedeck_columns/src/app.rs @@ -3,7 +3,9 @@ use crate::{ column::Columns, decks::{Decks, DecksCache, FALLBACK_PUBKEY}, draft::Drafts, - nav, storage, + nav, + route::Route, + storage, subscriptions::{SubKind, Subscriptions}, support::Support, timeline::{self, TimelineCache}, @@ -519,6 +521,8 @@ fn circle_icon(ui: &mut egui::Ui, openness: f32, response: &egui::Response) { fn render_damus_mobile(app: &mut Damus, app_ctx: &mut AppContext<'_>, ui: &mut egui::Ui) { //let routes = app.timelines[0].routes.clone(); + let mut rect = ui.available_rect_before_wrap(); + if !app.columns(app_ctx.accounts).columns().is_empty() && nav::render_nav(0, ui.available_rect_before_wrap(), app, app_ctx, ui) .process_render_nav_response(app, app_ctx, ui) @@ -526,6 +530,25 @@ fn render_damus_mobile(app: &mut Damus, app_ctx: &mut AppContext<'_>, ui: &mut e { storage::save_decks_cache(app_ctx.path, &app.decks_cache); } + + rect.min.x = rect.max.x - 100.0; + rect.min.y = rect.max.y - 100.0; + + let interactive = true; + let darkmode = ui.ctx().style().visuals.dark_mode; + + if ui + .put(rect, ui::post::compose_note_button(interactive, darkmode)) + .clicked() + && !app.columns(app_ctx.accounts).columns().is_empty() + { + let router = app.columns_mut(app_ctx.accounts).columns_mut()[0].router_mut(); + if router.top() == &Route::ComposeNote { + router.go_back(); + } else { + router.route_to(Route::ComposeNote); + } + } } #[profiling::function] diff --git a/crates/notedeck_columns/src/ui/mod.rs b/crates/notedeck_columns/src/ui/mod.rs @@ -6,6 +6,7 @@ pub mod configure_deck; pub mod edit_deck; pub mod images; pub mod note; +pub mod post; pub mod preview; pub mod profile; pub mod relay; diff --git a/crates/notedeck_columns/src/ui/post.rs b/crates/notedeck_columns/src/ui/post.rs @@ -0,0 +1,62 @@ +use egui::{vec2, Color32, Stroke, Widget}; +use notedeck_ui::anim::AnimationHelper; + +static ICON_WIDTH: f32 = 40.0; +static ICON_EXPANSION_MULTIPLE: f32 = 1.2; + +pub fn compose_note_button(interactive: bool, dark_mode: bool) -> impl Widget { + move |ui: &mut egui::Ui| -> egui::Response { + let max_size = ICON_WIDTH * ICON_EXPANSION_MULTIPLE; // max size of the widget + + let min_outer_circle_diameter = 40.0; + let min_plus_sign_size = 14.0; // length of the plus sign + let min_line_width = 2.25; // width of the plus sign + + let helper = if interactive { + AnimationHelper::new(ui, "note-compose-button", vec2(max_size, max_size)) + } else { + AnimationHelper::no_animation(ui, vec2(max_size, max_size)) + }; + + let painter = ui.painter_at(helper.get_animation_rect()); + + let use_background_radius = helper.scale_radius(min_outer_circle_diameter); + let use_line_width = helper.scale_1d_pos(min_line_width); + let use_edge_circle_radius = helper.scale_radius(min_line_width); + + let fill_color = if interactive { + notedeck_ui::colors::PINK + } else { + ui.visuals().noninteractive().bg_fill + }; + + painter.circle_filled(helper.center(), use_background_radius, fill_color); + + let min_half_plus_sign_size = min_plus_sign_size / 2.0; + let north_edge = helper.scale_from_center(0.0, min_half_plus_sign_size); + let south_edge = helper.scale_from_center(0.0, -min_half_plus_sign_size); + let west_edge = helper.scale_from_center(-min_half_plus_sign_size, 0.0); + let east_edge = helper.scale_from_center(min_half_plus_sign_size, 0.0); + + let icon_color = if !dark_mode && !interactive { + Color32::BLACK + } else { + Color32::WHITE + }; + + painter.line_segment( + [north_edge, south_edge], + Stroke::new(use_line_width, icon_color), + ); + painter.line_segment( + [west_edge, east_edge], + Stroke::new(use_line_width, icon_color), + ); + painter.circle_filled(north_edge, use_edge_circle_radius, Color32::WHITE); + painter.circle_filled(south_edge, use_edge_circle_radius, Color32::WHITE); + painter.circle_filled(west_edge, use_edge_circle_radius, Color32::WHITE); + painter.circle_filled(east_edge, use_edge_circle_radius, Color32::WHITE); + + helper.take_animation_response() + } +} diff --git a/crates/notedeck_columns/src/ui/side_panel.rs b/crates/notedeck_columns/src/ui/side_panel.rs @@ -1,6 +1,4 @@ -use egui::{ - vec2, Color32, InnerResponse, Layout, Margin, RichText, ScrollArea, Separator, Stroke, Widget, -}; +use egui::{vec2, InnerResponse, Layout, Margin, RichText, ScrollArea, Separator, Stroke, Widget}; use tracing::{error, info}; use crate::{ @@ -97,7 +95,10 @@ impl<'a> DesktopSidePanel<'a> { let is_interactive = self .selected_account .is_some_and(|s| s.key.secret_key.is_some()); - let compose_resp = ui.add(compose_note_button(is_interactive, dark_mode)); + let compose_resp = ui.add(crate::ui::post::compose_note_button( + is_interactive, + dark_mode, + )); let compose_resp = if is_interactive { compose_resp } else { @@ -321,63 +322,6 @@ fn add_column_button(dark_mode: bool) -> impl Widget { } } -fn compose_note_button(interactive: bool, dark_mode: bool) -> impl Widget { - move |ui: &mut egui::Ui| -> egui::Response { - let max_size = ICON_WIDTH * ICON_EXPANSION_MULTIPLE; // max size of the widget - - let min_outer_circle_diameter = 40.0; - let min_plus_sign_size = 14.0; // length of the plus sign - let min_line_width = 2.25; // width of the plus sign - - let helper = if interactive { - AnimationHelper::new(ui, "note-compose-button", vec2(max_size, max_size)) - } else { - AnimationHelper::no_animation(ui, vec2(max_size, max_size)) - }; - - let painter = ui.painter_at(helper.get_animation_rect()); - - let use_background_radius = helper.scale_radius(min_outer_circle_diameter); - let use_line_width = helper.scale_1d_pos(min_line_width); - let use_edge_circle_radius = helper.scale_radius(min_line_width); - - let fill_color = if interactive { - colors::PINK - } else { - ui.visuals().noninteractive().bg_fill - }; - - painter.circle_filled(helper.center(), use_background_radius, fill_color); - - let min_half_plus_sign_size = min_plus_sign_size / 2.0; - let north_edge = helper.scale_from_center(0.0, min_half_plus_sign_size); - let south_edge = helper.scale_from_center(0.0, -min_half_plus_sign_size); - let west_edge = helper.scale_from_center(-min_half_plus_sign_size, 0.0); - let east_edge = helper.scale_from_center(min_half_plus_sign_size, 0.0); - - let icon_color = if !dark_mode && !interactive { - Color32::BLACK - } else { - Color32::WHITE - }; - - painter.line_segment( - [north_edge, south_edge], - Stroke::new(use_line_width, icon_color), - ); - painter.line_segment( - [west_edge, east_edge], - Stroke::new(use_line_width, icon_color), - ); - painter.circle_filled(north_edge, use_edge_circle_radius, Color32::WHITE); - painter.circle_filled(south_edge, use_edge_circle_radius, Color32::WHITE); - painter.circle_filled(west_edge, use_edge_circle_radius, Color32::WHITE); - painter.circle_filled(east_edge, use_edge_circle_radius, Color32::WHITE); - - helper.take_animation_response() - } -} - pub fn search_button() -> impl Widget { |ui: &mut egui::Ui| -> egui::Response { let max_size = ICON_WIDTH * ICON_EXPANSION_MULTIPLE; // max size of the widget