mirror of
https://github.com/mikedilger/gossip.git
synced 2024-09-28 16:00:58 +00:00
Feed UI work
This commit is contained in:
parent
c304c6ed7e
commit
e44936d7d1
BIN
placeholder_avatar.png
Normal file
BIN
placeholder_avatar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
151
src/ui/feed.rs
151
src/ui/feed.rs
@ -1,48 +1,139 @@
|
||||
use super::GossipUi;
|
||||
use eframe::egui;
|
||||
use egui::{Context, ScrollArea, Ui};
|
||||
use egui::{Align, Color32, Context, Layout, RichText, ScrollArea, TextStyle, Ui, Vec2};
|
||||
use nostr_proto::PublicKey;
|
||||
|
||||
pub(super) fn update(_app: &mut GossipUi, ctx: &Context, _frame: &mut eframe::Frame, ui: &mut Ui) {
|
||||
pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Frame, ui: &mut Ui) {
|
||||
let feed = crate::globals::blocking_get_feed();
|
||||
|
||||
let screen_rect = ctx.input().screen_rect; // Rect
|
||||
//let screen_rect = ctx.input().screen_rect; // Rect
|
||||
|
||||
ScrollArea::vertical().show(ui, |ui| {
|
||||
for id in feed.iter() {
|
||||
// Stop rendering at the bottom of the window:
|
||||
let pos2 = ui.next_widget_position();
|
||||
if pos2.y > screen_rect.max.y {
|
||||
break;
|
||||
// (This confuses the scrollbar a bit, so I'm taking it out for now)
|
||||
//let pos2 = ui.next_widget_position();
|
||||
//if pos2.y > screen_rect.max.y {
|
||||
// break;
|
||||
//}
|
||||
|
||||
let maybe_fevent = crate::globals::GLOBALS
|
||||
.feed_events
|
||||
.blocking_lock()
|
||||
.get(id)
|
||||
.cloned();
|
||||
if maybe_fevent.is_none() {
|
||||
continue;
|
||||
}
|
||||
let fevent = maybe_fevent.unwrap();
|
||||
|
||||
if let Some(fevent) = crate::globals::GLOBALS.feed_events.blocking_lock().get(id) {
|
||||
if let Some(event) = &fevent.event {
|
||||
ui.label(crate::date_ago::date_ago(event.created_at));
|
||||
if fevent.event.is_none() {
|
||||
continue;
|
||||
} // don't render related info w/o nostr event.
|
||||
let event = fevent.event.as_ref().unwrap().to_owned();
|
||||
|
||||
if fevent.reactions.upvotes > 0 {
|
||||
ui.label(&format!("Upvotes={}", fevent.reactions.upvotes));
|
||||
}
|
||||
if fevent.reactions.downvotes > 0 {
|
||||
ui.label(&format!("Downvotes={}", fevent.reactions.downvotes));
|
||||
}
|
||||
let maybe_person = crate::globals::GLOBALS
|
||||
.people
|
||||
.blocking_lock()
|
||||
.get(&event.pubkey)
|
||||
.cloned();
|
||||
|
||||
if let Some(person) = crate::globals::GLOBALS
|
||||
.people
|
||||
.blocking_lock()
|
||||
.get(&event.pubkey)
|
||||
{
|
||||
if let Some(name) = &person.name {
|
||||
ui.label(name);
|
||||
} else {
|
||||
ui.label(event.pubkey.as_hex_string());
|
||||
// Person Things we can render:
|
||||
// pubkey
|
||||
// name
|
||||
// about
|
||||
// picture
|
||||
// dns_id
|
||||
// dns_id_valid
|
||||
// dns_id_last_checked
|
||||
// metadata_at
|
||||
// followed
|
||||
|
||||
// Event Things we can render:
|
||||
// id
|
||||
// pubkey
|
||||
// created_at,
|
||||
// kind,
|
||||
// tags,
|
||||
// content,
|
||||
// ots,
|
||||
// sig
|
||||
// feed_related,
|
||||
// replies,
|
||||
// in_reply_to,
|
||||
// reactions,
|
||||
// deleted_reason,
|
||||
// client,
|
||||
// hashtags,
|
||||
// subject,
|
||||
// urls,
|
||||
// last_reply_at
|
||||
|
||||
// Try LayoutJob
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
// Avatar first
|
||||
ui.image(&app.placeholder_avatar, Vec2 { x: 36.0, y: 36.0 });
|
||||
|
||||
// Everything else next
|
||||
ui.vertical(|ui| {
|
||||
// First row
|
||||
ui.horizontal(|ui| {
|
||||
if let Some(person) = maybe_person {
|
||||
if let Some(name) = &person.name {
|
||||
ui.label(
|
||||
RichText::new(name).text_style(TextStyle::Name("Bold".into())),
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ui.label(event.pubkey.as_hex_string());
|
||||
}
|
||||
|
||||
ui.separator();
|
||||
|
||||
ui.label(pubkey_short(&event.pubkey));
|
||||
|
||||
ui.with_layout(Layout::right_to_left(Align::TOP), |ui| {
|
||||
ui.label(
|
||||
RichText::new(crate::date_ago::date_ago(event.created_at))
|
||||
.text_style(TextStyle::Name("Oblique".into()))
|
||||
.weak(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Second row
|
||||
ui.horizontal(|ui| {
|
||||
if fevent.reactions.upvotes > 0 {
|
||||
ui.label(
|
||||
RichText::new(&format!("+{}", fevent.reactions.upvotes))
|
||||
.text_style(TextStyle::Name("Bold".into()))
|
||||
.color(Color32::DARK_GREEN),
|
||||
);
|
||||
}
|
||||
if fevent.reactions.downvotes > 0 {
|
||||
ui.label(
|
||||
RichText::new(&format!("-{}", fevent.reactions.downvotes))
|
||||
.text_style(TextStyle::Name("Bold".into()))
|
||||
.color(Color32::DARK_RED),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
ui.label(&event.content);
|
||||
ui.separator();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
ui.separator();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn pubkey_short(pubkey: &PublicKey) -> String {
|
||||
let hex = pubkey.as_hex_string();
|
||||
format!(
|
||||
"{}_{}...{}_{}",
|
||||
&hex[0..4],
|
||||
&hex[4..8],
|
||||
&hex[56..60],
|
||||
&hex[60..64]
|
||||
)
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ struct GossipUi {
|
||||
page: Page,
|
||||
about: About,
|
||||
icon: TextureHandle,
|
||||
placeholder_avatar: TextureHandle,
|
||||
}
|
||||
|
||||
impl GossipUi {
|
||||
@ -72,21 +73,37 @@ impl GossipUi {
|
||||
style.text_styles = style::text_styles();
|
||||
cctx.egui_ctx.set_style(style);
|
||||
|
||||
let icon_bytes = include_bytes!("../../gossip.png");
|
||||
let image = image::load_from_memory(icon_bytes).unwrap();
|
||||
let size = [image.width() as _, image.height() as _];
|
||||
let image_buffer = image.to_rgba8();
|
||||
let pixels = image_buffer.as_flat_samples();
|
||||
let icon_texture_handle = cctx.egui_ctx.load_texture(
|
||||
"icon",
|
||||
ImageData::Color(ColorImage::from_rgba_unmultiplied(size, pixels.as_slice())),
|
||||
TextureOptions::default(), // magnification, minification
|
||||
);
|
||||
let icon_texture_handle = {
|
||||
let bytes = include_bytes!("../../gossip.png");
|
||||
let image = image::load_from_memory(bytes).unwrap();
|
||||
let size = [image.width() as _, image.height() as _];
|
||||
let image_buffer = image.to_rgba8();
|
||||
let pixels = image_buffer.as_flat_samples();
|
||||
cctx.egui_ctx.load_texture(
|
||||
"icon",
|
||||
ImageData::Color(ColorImage::from_rgba_unmultiplied(size, pixels.as_slice())),
|
||||
TextureOptions::default(), // magnification, minification
|
||||
)
|
||||
};
|
||||
|
||||
let placeholder_avatar_texture_handle = {
|
||||
let bytes = include_bytes!("../../placeholder_avatar.png");
|
||||
let image = image::load_from_memory(bytes).unwrap();
|
||||
let size = [image.width() as _, image.height() as _];
|
||||
let image_buffer = image.to_rgba8();
|
||||
let pixels = image_buffer.as_flat_samples();
|
||||
cctx.egui_ctx.load_texture(
|
||||
"placeholder_avatar",
|
||||
ImageData::Color(ColorImage::from_rgba_unmultiplied(size, pixels.as_slice())),
|
||||
TextureOptions::default(), // magnification, minification
|
||||
)
|
||||
};
|
||||
|
||||
GossipUi {
|
||||
page: Page::Feed,
|
||||
about: crate::about::about(),
|
||||
icon: icon_texture_handle,
|
||||
placeholder_avatar: placeholder_avatar_texture_handle,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,6 +117,14 @@ pub(super) fn text_styles() -> BTreeMap<TextStyle, FontId> {
|
||||
},
|
||||
);
|
||||
|
||||
text_styles.insert(
|
||||
TextStyle::Name("Oblique".into()),
|
||||
FontId {
|
||||
size: 14.0,
|
||||
family: FontFamily::Name("Oblique".into()),
|
||||
},
|
||||
);
|
||||
|
||||
text_styles.insert(
|
||||
TextStyle::Name("MonoBold".into()),
|
||||
FontId {
|
||||
|
Loading…
Reference in New Issue
Block a user