mirror of
https://github.com/damus-io/notedeck.git
synced 2024-09-16 11:53:30 +00:00
progress
This commit is contained in:
parent
ce21e10c90
commit
46f9bde257
1051
Cargo.lock
generated
1051
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,11 @@ rust-version = "1.60"
|
||||
egui = "0.19.0"
|
||||
eframe = { version = "0.19.0", features = ["persistence"] }
|
||||
serde = { version = "1", features = ["derive"] } # You only need this if you want app persistence
|
||||
nostr_rust = { git = "git://jb55.com/nostr_rust", rev = "ccf7e521fe3bb9ca8f86516aef2c1f71db0213ed" }
|
||||
ehttp = "0.2.0"
|
||||
image = { version = "0.24", features = ["jpeg", "png", "webp"] }
|
||||
egui_extras = { version = "0.19.0", features = ["image", "svg"] }
|
||||
poll-promise = "0.2.0"
|
||||
|
||||
# native:
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
|
1
rust-toolchain
Normal file
1
rust-toolchain
Normal file
@ -0,0 +1 @@
|
||||
nightly
|
171
src/app.rs
171
src/app.rs
@ -1,3 +1,12 @@
|
||||
use egui::{Align, Layout, RichText, WidgetText};
|
||||
use egui_extras::RetainedImage;
|
||||
use nostr_rust::events::Event;
|
||||
use poll_promise::Promise;
|
||||
use std::borrow::{Borrow, Cow};
|
||||
use std::collections::HashMap;
|
||||
|
||||
type ImageCache = HashMap<String, Promise<ehttp::Result<RetainedImage>>>;
|
||||
|
||||
/// We derive Deserialize/Serialize so we can persist app state on shutdown.
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
#[serde(default)] // if we add new fields, give them default values when deserializing old state
|
||||
@ -5,6 +14,12 @@ pub struct Damus {
|
||||
// Example stuff:
|
||||
label: String,
|
||||
|
||||
#[serde(skip)]
|
||||
events: Vec<Event>,
|
||||
|
||||
#[serde(skip)]
|
||||
img_cache: ImageCache,
|
||||
|
||||
// this how you opt-out of serialization of a member
|
||||
#[serde(skip)]
|
||||
value: f32,
|
||||
@ -15,6 +30,8 @@ impl Default for Damus {
|
||||
Self {
|
||||
// Example stuff:
|
||||
label: "Hello World!".to_owned(),
|
||||
events: vec![],
|
||||
img_cache: HashMap::new(),
|
||||
value: 2.7,
|
||||
}
|
||||
}
|
||||
@ -36,19 +53,78 @@ impl Damus {
|
||||
}
|
||||
}
|
||||
|
||||
fn timeline_view(app: &mut Damus, ui: &mut egui::Ui) {
|
||||
ui.heading("Timeline");
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
fn parse_response(response: ehttp::Response) -> Result<RetainedImage, String> {
|
||||
let content_type = response.content_type().unwrap_or_default();
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Write something: ");
|
||||
ui.text_edit_singleline(&mut app.label);
|
||||
if content_type.starts_with("image/svg+xml") {
|
||||
RetainedImage::from_svg_bytes(&response.url, &response.bytes)
|
||||
} else if content_type.starts_with("image/") {
|
||||
RetainedImage::from_image_bytes(&response.url, &response.bytes)
|
||||
} else {
|
||||
Err(format!(
|
||||
"Expected image, found content-type {:?}",
|
||||
content_type
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_img(ctx: &egui::Context, url: &str) -> Promise<ehttp::Result<RetainedImage>> {
|
||||
let (sender, promise) = Promise::new();
|
||||
let request = ehttp::Request::get(url);
|
||||
let ctx = ctx.clone();
|
||||
ehttp::fetch(request, move |response| {
|
||||
let image = response.and_then(parse_response);
|
||||
sender.send(image); // send the results back to the UI thread. ctx.request_repaint();
|
||||
});
|
||||
promise
|
||||
}
|
||||
|
||||
ui.add(egui::Slider::new(&mut app.value, 0.0..=10.0).text("value"));
|
||||
if ui.button("Increment").clicked() {
|
||||
app.value += 1.0;
|
||||
fn render_pfp(ctx: &egui::Context, img_cache: &mut ImageCache, ui: &mut egui::Ui, url: String) {
|
||||
let m_cached_promise = img_cache.get_mut(&url);
|
||||
if m_cached_promise.is_none() {
|
||||
img_cache.insert(url.clone(), fetch_img(ctx, &url));
|
||||
}
|
||||
|
||||
match img_cache[&url].ready() {
|
||||
None => {
|
||||
ui.spinner(); // still loading
|
||||
}
|
||||
Some(Err(err)) => {
|
||||
ui.colored_label(ui.visuals().error_fg_color, err); // something went wrong
|
||||
}
|
||||
Some(Ok(image)) => {
|
||||
image.show_max_size(ui, egui::vec2(64.0, 64.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn render_event(ctx: &egui::Context, img_cache: &mut ImageCache, ui: &mut egui::Ui, ev: &Event) {
|
||||
render_pfp(
|
||||
ctx,
|
||||
img_cache,
|
||||
ui,
|
||||
//"https://damus.io/img/damus.svg".into(),
|
||||
"http://cdn.jb55.com/img/red-me.jpg".into(),
|
||||
);
|
||||
ui.label(&ev.content);
|
||||
}
|
||||
|
||||
fn render_events(ctx: &egui::Context, app: &mut Damus, ui: &mut egui::Ui) {
|
||||
for ev in &app.events {
|
||||
ui.spacing_mut().item_spacing.y = 10.0;
|
||||
render_event(ctx, &mut app.img_cache, ui, ev);
|
||||
}
|
||||
}
|
||||
|
||||
fn timeline_view(ctx: &egui::Context, app: &mut Damus, ui: &mut egui::Ui) {
|
||||
ui.heading("Timeline");
|
||||
|
||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
render_events(ctx, app, ui);
|
||||
});
|
||||
|
||||
/*
|
||||
ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.spacing_mut().item_spacing.x = 0.0;
|
||||
@ -62,6 +138,35 @@ fn timeline_view(app: &mut Damus, ui: &mut egui::Ui) {
|
||||
ui.label(".");
|
||||
});
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
fn render_damus(ctx: &egui::Context, _frame: &mut eframe::Frame, app: &mut Damus) {
|
||||
#[cfg(not(target_arch = "wasm32"))] // no File->Quit on web pages!
|
||||
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
|
||||
// The top panel is often a good place for a menu bar:
|
||||
egui::menu::bar(ui, |ui| {
|
||||
ui.menu_button("File", |ui| {
|
||||
if ui.button("Quit").clicked() {
|
||||
_frame.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
egui::SidePanel::left("side_panel").show(ctx, |ui| timeline_view(ctx, app, ui));
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
// The central panel the region left after adding TopPanel's and SidePanel's
|
||||
|
||||
ui.heading("eframe template");
|
||||
ui.hyperlink("https://github.com/emilk/eframe_template");
|
||||
ui.add(egui::github_link_file!(
|
||||
"https://github.com/emilk/eframe_template/blob/master/",
|
||||
"Source code."
|
||||
));
|
||||
egui::warn_if_debug_build(ui);
|
||||
});
|
||||
}
|
||||
|
||||
impl eframe::App for Damus {
|
||||
@ -78,39 +183,25 @@ impl eframe::App for Damus {
|
||||
// Tip: a good default choice is to just keep the `CentralPanel`.
|
||||
// For inspiration and more examples, go to https://emilk.github.io/egui
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))] // no File->Quit on web pages!
|
||||
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
|
||||
// The top panel is often a good place for a menu bar:
|
||||
egui::menu::bar(ui, |ui| {
|
||||
ui.menu_button("File", |ui| {
|
||||
if ui.button("Quit").clicked() {
|
||||
_frame.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
let test_event = Event {
|
||||
id: "6938e3cd841f3111dbdbd909f87fd52c3d1f1e4a07fd121d1243196e532811cb".to_string(),
|
||||
pub_key: "f0a6ff7f70b872de6d82c8daec692a433fd23b6a49f25923c6f034df715cdeec".to_string(),
|
||||
created_at: 1667781968,
|
||||
kind: 1,
|
||||
tags: vec![],
|
||||
content: "yello\nthere".to_string(),
|
||||
sig: "af02c971015995f79e07fa98aaf98adeeb6a56d0005e451ee4e78844cff712a6bc0f2109f72a878975f162dcefde4173b65ebd4c3d3ab3b520a9dcac6acf092d".to_string(),
|
||||
};
|
||||
|
||||
egui::SidePanel::left("side_panel").show(ctx, |ui| timeline_view(self, ui));
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
// The central panel the region left after adding TopPanel's and SidePanel's
|
||||
|
||||
ui.heading("eframe template");
|
||||
ui.hyperlink("https://github.com/emilk/eframe_template");
|
||||
ui.add(egui::github_link_file!(
|
||||
"https://github.com/emilk/eframe_template/blob/master/",
|
||||
"Source code."
|
||||
));
|
||||
egui::warn_if_debug_build(ui);
|
||||
});
|
||||
|
||||
if false {
|
||||
egui::Window::new("Window").show(ctx, |ui| {
|
||||
ui.label("Windows can be moved by dragging them.");
|
||||
ui.label("They are automatically sized based on contents.");
|
||||
ui.label("You can turn on resizing and scrolling if you like.");
|
||||
ui.label("You would normally chose either panels OR windows.");
|
||||
});
|
||||
if self.events.len() == 0 {
|
||||
self.events.push(test_event.clone());
|
||||
println!("{}", &self.events[0].content);
|
||||
self.events.push(test_event.clone());
|
||||
println!("{}", &self.events[1].content);
|
||||
self.events.push(test_event.clone());
|
||||
println!("{}", &self.events[2].content);
|
||||
}
|
||||
|
||||
render_damus(ctx, _frame, self);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user