Feed UI work

This commit is contained in:
Mike Dilger 2022-12-22 06:34:54 +13:00
parent c304c6ed7e
commit e44936d7d1
4 changed files with 156 additions and 40 deletions

BIN
placeholder_avatar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -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]
)
}

View File

@ -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,
}
}
}

View File

@ -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 {