mirror of
https://github.com/aljazceru/notedeck.git
synced 2025-12-20 18:04:18 +01:00
dave: give dave a new home in the sidebar
Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
19
crates/notedeck_chrome/src/app.rs
Normal file
19
crates/notedeck_chrome/src/app.rs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
use notedeck::AppContext;
|
||||||
|
use notedeck_columns::Damus;
|
||||||
|
use notedeck_dave::Dave;
|
||||||
|
|
||||||
|
pub enum NotedeckApp {
|
||||||
|
Dave(Dave),
|
||||||
|
Columns(Damus),
|
||||||
|
Other(Box<dyn notedeck::App>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl notedeck::App for NotedeckApp {
|
||||||
|
fn update(&mut self, ctx: &mut AppContext, ui: &mut egui::Ui) {
|
||||||
|
match self {
|
||||||
|
NotedeckApp::Dave(dave) => dave.update(ctx, ui),
|
||||||
|
NotedeckApp::Columns(columns) => columns.update(ctx, ui),
|
||||||
|
NotedeckApp::Other(other) => other.update(ctx, ui),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
// Entry point for wasm
|
// Entry point for wasm
|
||||||
//#[cfg(target_arch = "wasm32")]
|
//#[cfg(target_arch = "wasm32")]
|
||||||
//use wasm_bindgen::prelude::*;
|
//use wasm_bindgen::prelude::*;
|
||||||
use egui::{Button, Label, Layout, RichText, ThemePreference, Widget};
|
use crate::app::NotedeckApp;
|
||||||
|
use egui::{vec2, Button, Label, Layout, RichText, ThemePreference, Widget};
|
||||||
use egui_extras::{Size, StripBuilder};
|
use egui_extras::{Size, StripBuilder};
|
||||||
use nostrdb::{ProfileRecord, Transaction};
|
use nostrdb::{ProfileRecord, Transaction};
|
||||||
use notedeck::{AppContext, NotedeckTextStyle, UserAccount};
|
use notedeck::{App, AppContext, NotedeckTextStyle, UserAccount};
|
||||||
|
use notedeck_dave::{Dave, DaveAvatar};
|
||||||
use notedeck_ui::{profile::get_profile_url, AnimationHelper, ProfilePic};
|
use notedeck_ui::{profile::get_profile_url, AnimationHelper, ProfilePic};
|
||||||
|
|
||||||
static ICON_WIDTH: f32 = 40.0;
|
static ICON_WIDTH: f32 = 40.0;
|
||||||
@@ -13,7 +15,7 @@ pub static ICON_EXPANSION_MULTIPLE: f32 = 1.2;
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Chrome {
|
pub struct Chrome {
|
||||||
active: i32,
|
active: i32,
|
||||||
apps: Vec<Box<dyn notedeck::App>>,
|
apps: Vec<NotedeckApp>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ChromePanelAction {
|
pub enum ChromePanelAction {
|
||||||
@@ -28,8 +30,18 @@ impl Chrome {
|
|||||||
Chrome::default()
|
Chrome::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_app(&mut self, app: impl notedeck::App + 'static) {
|
pub fn add_app(&mut self, app: NotedeckApp) {
|
||||||
self.apps.push(Box::new(app));
|
self.apps.push(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_dave(&mut self) -> Option<&mut Dave> {
|
||||||
|
for app in &mut self.apps {
|
||||||
|
if let NotedeckApp::Dave(dave) = app {
|
||||||
|
return Some(dave);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_active(&mut self, app: i32) {
|
pub fn set_active(&mut self, app: i32) {
|
||||||
@@ -44,7 +56,7 @@ impl Chrome {
|
|||||||
fn show(&mut self, ctx: &mut AppContext, ui: &mut egui::Ui) {
|
fn show(&mut self, ctx: &mut AppContext, ui: &mut egui::Ui) {
|
||||||
ui.spacing_mut().item_spacing.x = 0.0;
|
ui.spacing_mut().item_spacing.x = 0.0;
|
||||||
|
|
||||||
let side_panel_width: f32 = 68.0;
|
let side_panel_width: f32 = 70.0;
|
||||||
StripBuilder::new(ui)
|
StripBuilder::new(ui)
|
||||||
.size(Size::exact(side_panel_width)) // collapsible sidebar
|
.size(Size::exact(side_panel_width)) // collapsible sidebar
|
||||||
.size(Size::remainder()) // the main app contents
|
.size(Size::remainder()) // the main app contents
|
||||||
@@ -103,9 +115,10 @@ impl Chrome {
|
|||||||
ctx: &mut AppContext,
|
ctx: &mut AppContext,
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
) -> Option<ChromePanelAction> {
|
) -> Option<ChromePanelAction> {
|
||||||
let dark_mode = ui.ctx().style().visuals.dark_mode;
|
ui.add_space(8.0);
|
||||||
|
|
||||||
let pfp_resp = self.pfp_button(ctx, ui);
|
let pfp_resp = self.pfp_button(ctx, ui);
|
||||||
let settings_resp = ui.add(settings_button(dark_mode));
|
let settings_resp = settings_button(ui);
|
||||||
|
|
||||||
let theme_action = match ui.ctx().theme() {
|
let theme_action = match ui.ctx().theme() {
|
||||||
egui::Theme::Dark => {
|
egui::Theme::Dark => {
|
||||||
@@ -130,7 +143,7 @@ impl Chrome {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if ui.add(support_button()).clicked() {
|
if support_button(ui).clicked() {
|
||||||
return Some(ChromePanelAction::Support);
|
return Some(ChromePanelAction::Support);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +192,15 @@ impl Chrome {
|
|||||||
ui.add(milestone_name());
|
ui.add(milestone_name());
|
||||||
ui.add_space(16.0);
|
ui.add_space(16.0);
|
||||||
//let dark_mode = ui.ctx().style().visuals.dark_mode;
|
//let dark_mode = ui.ctx().style().visuals.dark_mode;
|
||||||
//ui.add(add_column_button(dark_mode))
|
if columns_button(ui).clicked() {
|
||||||
|
self.active = 0;
|
||||||
|
}
|
||||||
|
ui.add_space(32.0);
|
||||||
|
if let Some(dave) = self.get_dave() {
|
||||||
|
if dave_button(dave.avatar_mut(), ui).clicked() {
|
||||||
|
self.active = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,54 +243,69 @@ fn expand_side_panel_button() -> impl Widget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn support_button() -> impl Widget {
|
fn expanding_button(
|
||||||
|ui: &mut egui::Ui| -> egui::Response {
|
name: &'static str,
|
||||||
let img_size = 16.0;
|
img_size: f32,
|
||||||
|
light_img: &egui::ImageSource,
|
||||||
|
dark_img: &egui::ImageSource,
|
||||||
|
ui: &mut egui::Ui,
|
||||||
|
) -> egui::Response {
|
||||||
|
let max_size = ICON_WIDTH * ICON_EXPANSION_MULTIPLE; // max size of the widget
|
||||||
|
let img_data = if ui.visuals().dark_mode {
|
||||||
|
dark_img
|
||||||
|
} else {
|
||||||
|
light_img
|
||||||
|
};
|
||||||
|
let img = egui::Image::new(img_data.clone()).max_width(img_size);
|
||||||
|
|
||||||
let max_size = ICON_WIDTH * ICON_EXPANSION_MULTIPLE; // max size of the widget
|
let helper = AnimationHelper::new(ui, name, egui::vec2(max_size, max_size));
|
||||||
let img_data = if ui.visuals().dark_mode {
|
|
||||||
egui::include_image!("../../../assets/icons/help_icon_dark_4x.png")
|
|
||||||
} else {
|
|
||||||
egui::include_image!("../../../assets/icons/help_icon_inverted_4x.png")
|
|
||||||
};
|
|
||||||
let img = egui::Image::new(img_data).max_width(img_size);
|
|
||||||
|
|
||||||
let helper = AnimationHelper::new(ui, "help-button", egui::vec2(max_size, max_size));
|
let cur_img_size = helper.scale_1d_pos(img_size);
|
||||||
|
img.paint_at(
|
||||||
|
ui,
|
||||||
|
helper
|
||||||
|
.get_animation_rect()
|
||||||
|
.shrink((max_size - cur_img_size) / 2.0),
|
||||||
|
);
|
||||||
|
|
||||||
let cur_img_size = helper.scale_1d_pos(img_size);
|
helper.take_animation_response()
|
||||||
img.paint_at(
|
|
||||||
ui,
|
|
||||||
helper
|
|
||||||
.get_animation_rect()
|
|
||||||
.shrink((max_size - cur_img_size) / 2.0),
|
|
||||||
);
|
|
||||||
|
|
||||||
helper.take_animation_response()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn settings_button(dark_mode: bool) -> impl Widget {
|
fn support_button(ui: &mut egui::Ui) -> egui::Response {
|
||||||
move |ui: &mut egui::Ui| {
|
expanding_button(
|
||||||
let img_size = 24.0;
|
"help-button",
|
||||||
let max_size = ICON_WIDTH * ICON_EXPANSION_MULTIPLE; // max size of the widget
|
16.0,
|
||||||
let img_data = if dark_mode {
|
&egui::include_image!("../../../assets/icons/help_icon_inverted_4x.png"),
|
||||||
egui::include_image!("../../../assets/icons/settings_dark_4x.png")
|
&egui::include_image!("../../../assets/icons/help_icon_dark_4x.png"),
|
||||||
} else {
|
ui,
|
||||||
egui::include_image!("../../../assets/icons/settings_light_4x.png")
|
)
|
||||||
};
|
}
|
||||||
let img = egui::Image::new(img_data).max_width(img_size);
|
|
||||||
|
|
||||||
let helper = AnimationHelper::new(ui, "settings-button", egui::vec2(max_size, max_size));
|
fn settings_button(ui: &mut egui::Ui) -> egui::Response {
|
||||||
|
expanding_button(
|
||||||
|
"settings-button",
|
||||||
|
32.0,
|
||||||
|
&egui::include_image!("../../../assets/icons/settings_light_4x.png"),
|
||||||
|
&egui::include_image!("../../../assets/icons/settings_dark_4x.png"),
|
||||||
|
ui,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
let cur_img_size = helper.scale_1d_pos(img_size);
|
fn columns_button(ui: &mut egui::Ui) -> egui::Response {
|
||||||
img.paint_at(
|
let btn = egui::include_image!("../../../assets/icons/columns_80.png");
|
||||||
ui,
|
expanding_button("columns-button", 40.0, &btn, &btn, ui)
|
||||||
helper
|
}
|
||||||
.get_animation_rect()
|
|
||||||
.shrink((max_size - cur_img_size) / 2.0),
|
|
||||||
);
|
|
||||||
|
|
||||||
helper.take_animation_response()
|
fn dave_button(avatar: Option<&mut DaveAvatar>, ui: &mut egui::Ui) -> egui::Response {
|
||||||
|
if let Some(avatar) = avatar {
|
||||||
|
let size = vec2(60.0, 60.0);
|
||||||
|
let available = ui.available_rect_before_wrap();
|
||||||
|
let center_x = available.center().x;
|
||||||
|
let rect = egui::Rect::from_center_size(egui::pos2(center_x, available.top()), size);
|
||||||
|
avatar.render(rect, ui)
|
||||||
|
} else {
|
||||||
|
// plain icon if wgpu device not available??
|
||||||
|
ui.label("fixme")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ pub mod theme;
|
|||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
mod android;
|
mod android;
|
||||||
|
|
||||||
|
mod app;
|
||||||
mod chrome;
|
mod chrome;
|
||||||
|
|
||||||
|
pub use app::NotedeckApp;
|
||||||
pub use chrome::Chrome;
|
pub use chrome::Chrome;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
use notedeck::{DataPath, DataPathType, Notedeck};
|
use notedeck::{DataPath, DataPathType, Notedeck};
|
||||||
use notedeck_chrome::{
|
use notedeck_chrome::{
|
||||||
setup::{generate_native_options, setup_chrome},
|
setup::{generate_native_options, setup_chrome},
|
||||||
Chrome,
|
Chrome, NotedeckApp,
|
||||||
};
|
};
|
||||||
use notedeck_columns::Damus;
|
use notedeck_columns::Damus;
|
||||||
use notedeck_dave::Dave;
|
use notedeck_dave::Dave;
|
||||||
@@ -99,8 +99,8 @@ async fn main() {
|
|||||||
completely_unrecognized
|
completely_unrecognized
|
||||||
);
|
);
|
||||||
|
|
||||||
chrome.add_app(columns);
|
chrome.add_app(NotedeckApp::Columns(columns));
|
||||||
chrome.add_app(dave);
|
chrome.add_app(NotedeckApp::Dave(dave));
|
||||||
|
|
||||||
// test dav
|
// test dav
|
||||||
chrome.set_active(1);
|
chrome.set_active(1);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use std::sync::mpsc::{self, Receiver};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use time::{format_description::well_known::Rfc3339, OffsetDateTime};
|
use time::{format_description::well_known::Rfc3339, OffsetDateTime};
|
||||||
|
|
||||||
use avatar::DaveAvatar;
|
pub use avatar::DaveAvatar;
|
||||||
use egui::{Rect, Vec2};
|
use egui::{Rect, Vec2};
|
||||||
use egui_wgpu::RenderState;
|
use egui_wgpu::RenderState;
|
||||||
|
|
||||||
@@ -306,6 +306,10 @@ pub struct Dave {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Dave {
|
impl Dave {
|
||||||
|
pub fn avatar_mut(&mut self) -> Option<&mut DaveAvatar> {
|
||||||
|
self.avatar.as_mut()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(render_state: Option<&RenderState>) -> Self {
|
pub fn new(render_state: Option<&RenderState>) -> Self {
|
||||||
let mut config = OpenAIConfig::new(); //.with_api_base("http://ollama.jb55.com/v1");
|
let mut config = OpenAIConfig::new(); //.with_api_base("http://ollama.jb55.com/v1");
|
||||||
if let Ok(api_key) = std::env::var("OPENAI_API_KEY") {
|
if let Ok(api_key) = std::env::var("OPENAI_API_KEY") {
|
||||||
@@ -393,12 +397,15 @@ impl Dave {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
// he lives in the sidebar now
|
||||||
if let Some(avatar) = &mut self.avatar {
|
if let Some(avatar) = &mut self.avatar {
|
||||||
let avatar_size = Vec2::splat(300.0);
|
let avatar_size = Vec2::splat(300.0);
|
||||||
let pos = Vec2::splat(100.0).to_pos2();
|
let pos = Vec2::splat(100.0).to_pos2();
|
||||||
let pos = Rect::from_min_max(pos, pos + avatar_size);
|
let pos = Rect::from_min_max(pos, pos + avatar_size);
|
||||||
avatar.render(pos, ui);
|
avatar.render(pos, ui);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// send again
|
// send again
|
||||||
if should_send {
|
if should_send {
|
||||||
|
|||||||
Reference in New Issue
Block a user