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
|
||||
//#[cfg(target_arch = "wasm32")]
|
||||
//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 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};
|
||||
|
||||
static ICON_WIDTH: f32 = 40.0;
|
||||
@@ -13,7 +15,7 @@ pub static ICON_EXPANSION_MULTIPLE: f32 = 1.2;
|
||||
#[derive(Default)]
|
||||
pub struct Chrome {
|
||||
active: i32,
|
||||
apps: Vec<Box<dyn notedeck::App>>,
|
||||
apps: Vec<NotedeckApp>,
|
||||
}
|
||||
|
||||
pub enum ChromePanelAction {
|
||||
@@ -28,8 +30,18 @@ impl Chrome {
|
||||
Chrome::default()
|
||||
}
|
||||
|
||||
pub fn add_app(&mut self, app: impl notedeck::App + 'static) {
|
||||
self.apps.push(Box::new(app));
|
||||
pub fn add_app(&mut self, app: NotedeckApp) {
|
||||
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) {
|
||||
@@ -44,7 +56,7 @@ impl Chrome {
|
||||
fn show(&mut self, ctx: &mut AppContext, ui: &mut egui::Ui) {
|
||||
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)
|
||||
.size(Size::exact(side_panel_width)) // collapsible sidebar
|
||||
.size(Size::remainder()) // the main app contents
|
||||
@@ -103,9 +115,10 @@ impl Chrome {
|
||||
ctx: &mut AppContext,
|
||||
ui: &mut egui::Ui,
|
||||
) -> 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 settings_resp = ui.add(settings_button(dark_mode));
|
||||
let settings_resp = settings_button(ui);
|
||||
|
||||
let theme_action = match ui.ctx().theme() {
|
||||
egui::Theme::Dark => {
|
||||
@@ -130,7 +143,7 @@ impl Chrome {
|
||||
}
|
||||
};
|
||||
|
||||
if ui.add(support_button()).clicked() {
|
||||
if support_button(ui).clicked() {
|
||||
return Some(ChromePanelAction::Support);
|
||||
}
|
||||
|
||||
@@ -179,7 +192,15 @@ impl Chrome {
|
||||
ui.add(milestone_name());
|
||||
ui.add_space(16.0);
|
||||
//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,19 +243,22 @@ fn expand_side_panel_button() -> impl Widget {
|
||||
}
|
||||
}
|
||||
|
||||
fn support_button() -> impl Widget {
|
||||
|ui: &mut egui::Ui| -> egui::Response {
|
||||
let img_size = 16.0;
|
||||
|
||||
fn expanding_button(
|
||||
name: &'static str,
|
||||
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 {
|
||||
egui::include_image!("../../../assets/icons/help_icon_dark_4x.png")
|
||||
dark_img
|
||||
} else {
|
||||
egui::include_image!("../../../assets/icons/help_icon_inverted_4x.png")
|
||||
light_img
|
||||
};
|
||||
let img = egui::Image::new(img_data).max_width(img_size);
|
||||
let img = egui::Image::new(img_data.clone()).max_width(img_size);
|
||||
|
||||
let helper = AnimationHelper::new(ui, "help-button", egui::vec2(max_size, max_size));
|
||||
let helper = AnimationHelper::new(ui, name, egui::vec2(max_size, max_size));
|
||||
|
||||
let cur_img_size = helper.scale_1d_pos(img_size);
|
||||
img.paint_at(
|
||||
@@ -246,30 +270,42 @@ fn support_button() -> impl Widget {
|
||||
|
||||
helper.take_animation_response()
|
||||
}
|
||||
|
||||
fn support_button(ui: &mut egui::Ui) -> egui::Response {
|
||||
expanding_button(
|
||||
"help-button",
|
||||
16.0,
|
||||
&egui::include_image!("../../../assets/icons/help_icon_inverted_4x.png"),
|
||||
&egui::include_image!("../../../assets/icons/help_icon_dark_4x.png"),
|
||||
ui,
|
||||
)
|
||||
}
|
||||
|
||||
fn settings_button(dark_mode: bool) -> impl Widget {
|
||||
move |ui: &mut egui::Ui| {
|
||||
let img_size = 24.0;
|
||||
let max_size = ICON_WIDTH * ICON_EXPANSION_MULTIPLE; // max size of the widget
|
||||
let img_data = if dark_mode {
|
||||
egui::include_image!("../../../assets/icons/settings_dark_4x.png")
|
||||
} else {
|
||||
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));
|
||||
|
||||
let cur_img_size = helper.scale_1d_pos(img_size);
|
||||
img.paint_at(
|
||||
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,
|
||||
helper
|
||||
.get_animation_rect()
|
||||
.shrink((max_size - cur_img_size) / 2.0),
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
helper.take_animation_response()
|
||||
fn columns_button(ui: &mut egui::Ui) -> egui::Response {
|
||||
let btn = egui::include_image!("../../../assets/icons/columns_80.png");
|
||||
expanding_button("columns-button", 40.0, &btn, &btn, ui)
|
||||
}
|
||||
|
||||
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")]
|
||||
mod android;
|
||||
|
||||
mod app;
|
||||
mod chrome;
|
||||
|
||||
pub use app::NotedeckApp;
|
||||
pub use chrome::Chrome;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
use notedeck::{DataPath, DataPathType, Notedeck};
|
||||
use notedeck_chrome::{
|
||||
setup::{generate_native_options, setup_chrome},
|
||||
Chrome,
|
||||
Chrome, NotedeckApp,
|
||||
};
|
||||
use notedeck_columns::Damus;
|
||||
use notedeck_dave::Dave;
|
||||
@@ -99,8 +99,8 @@ async fn main() {
|
||||
completely_unrecognized
|
||||
);
|
||||
|
||||
chrome.add_app(columns);
|
||||
chrome.add_app(dave);
|
||||
chrome.add_app(NotedeckApp::Columns(columns));
|
||||
chrome.add_app(NotedeckApp::Dave(dave));
|
||||
|
||||
// test dav
|
||||
chrome.set_active(1);
|
||||
|
||||
@@ -21,7 +21,7 @@ use std::sync::mpsc::{self, Receiver};
|
||||
use std::sync::Arc;
|
||||
use time::{format_description::well_known::Rfc3339, OffsetDateTime};
|
||||
|
||||
use avatar::DaveAvatar;
|
||||
pub use avatar::DaveAvatar;
|
||||
use egui::{Rect, Vec2};
|
||||
use egui_wgpu::RenderState;
|
||||
|
||||
@@ -306,6 +306,10 @@ pub struct Dave {
|
||||
}
|
||||
|
||||
impl Dave {
|
||||
pub fn avatar_mut(&mut self) -> Option<&mut DaveAvatar> {
|
||||
self.avatar.as_mut()
|
||||
}
|
||||
|
||||
pub fn new(render_state: Option<&RenderState>) -> Self {
|
||||
let mut config = OpenAIConfig::new(); //.with_api_base("http://ollama.jb55.com/v1");
|
||||
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 {
|
||||
let avatar_size = Vec2::splat(300.0);
|
||||
let pos = Vec2::splat(100.0).to_pos2();
|
||||
let pos = Rect::from_min_max(pos, pos + avatar_size);
|
||||
avatar.render(pos, ui);
|
||||
}
|
||||
*/
|
||||
|
||||
// send again
|
||||
if should_send {
|
||||
|
||||
Reference in New Issue
Block a user