chore: cleanup (again)

This commit is contained in:
kieran 2025-01-09 14:54:06 +00:00
parent 85ef186048
commit 785e8dbd22
No known key found for this signature in database
GPG Key ID: DE71CEB3925BE941
23 changed files with 74 additions and 57 deletions

View File

@ -36,8 +36,8 @@ pub fn start_android(app: AndroidApp) {
let mut notedeck = let mut notedeck =
notedeck_chrome::Notedeck::new(&cc.egui_ctx, data_path.clone(), &args); notedeck_chrome::Notedeck::new(&cc.egui_ctx, data_path.clone(), &args);
let app = ZapStreamApp::new(cc); let zs_app = ZapStreamApp::new(cc, app.clone());
notedeck.add_app(app); notedeck.add_app(zs_app);
Ok(Box::new(notedeck)) Ok(Box::new(notedeck))
}), }),

View File

@ -15,10 +15,38 @@ pub struct ZapStreamApp {
routes_rx: mpsc::Receiver<RouteType>, routes_rx: mpsc::Receiver<RouteType>,
routes_tx: mpsc::Sender<RouteType>, routes_tx: mpsc::Sender<RouteType>,
#[cfg(target_os = "android")]
app: android_activity::AndroidApp,
widget: Box<dyn NostrWidget>, widget: Box<dyn NostrWidget>,
profiles: ProfileLoader, profiles: ProfileLoader,
} }
#[cfg(target_os = "android")]
impl ZapStreamApp {
pub fn new(cc: &CreationContext, app: android_activity::AndroidApp) -> Self {
let mut fd = FontDefinitions::default();
fd.font_data.insert(
"Outfit".to_string(),
FontData::from_static(include_bytes!("../assets/Outfit-Light.ttf")),
);
fd.families
.insert(FontFamily::Proportional, vec!["Outfit".to_string()]);
cc.egui_ctx.set_fonts(fd);
let (tx, rx) = mpsc::channel();
Self {
current: RouteType::HomePage,
widget: Box::new(page::HomePage::new()),
profiles: ProfileLoader::new(),
routes_tx: tx,
routes_rx: rx,
app,
}
}
}
#[cfg(not(target_os = "android"))]
impl ZapStreamApp { impl ZapStreamApp {
pub fn new(cc: &CreationContext) -> Self { pub fn new(cc: &CreationContext) -> Self {
let mut fd = FontDefinitions::default(); let mut fd = FontDefinitions::default();
@ -45,8 +73,8 @@ impl notedeck::App for ZapStreamApp {
fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut Ui) { fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut Ui) {
ctx.accounts.update(ctx.ndb, ctx.pool, ui.ctx()); ctx.accounts.update(ctx.ndb, ctx.pool, ui.ctx());
while let Some(PoolEvent { event, relay }) = ctx.pool.try_recv() { while let Some(PoolEvent { event, relay }) = ctx.pool.try_recv() {
match (&event).into() { if let RelayEvent::Message(msg) = (&event).into() {
RelayEvent::Message(msg) => match msg { match msg {
RelayMessage::OK(_) => {} RelayMessage::OK(_) => {}
RelayMessage::Eose(_) => {} RelayMessage::Eose(_) => {}
RelayMessage::Event(_sub, ev) => { RelayMessage::Event(_sub, ev) => {
@ -55,8 +83,7 @@ impl notedeck::App for ZapStreamApp {
} }
} }
RelayMessage::Notice(m) => warn!("Notice from {}: {}", relay, m), RelayMessage::Notice(m) => warn!("Notice from {}: {}", relay, m),
}, }
_ => {}
} }
} }
@ -141,10 +168,10 @@ impl ZapStreamApp {
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
impl ZapStreamApp { impl ZapStreamApp {
fn frame_margin(&self) -> Margin { fn frame_margin(&self) -> Margin {
if let Some(wd) = self.native_window() { if let Some(wd) = self.app.native_window() {
let (w, h) = (wd.width(), wd.height()); let (w, h) = (wd.width(), wd.height());
let c_rect = self.content_rect(); let c_rect = self.app.content_rect();
let dpi = self.config().density().unwrap_or(160); let dpi = self.app.config().density().unwrap_or(160);
let dpi_scale = dpi as f32 / 160.0; let dpi_scale = dpi as f32 / 160.0;
// TODO: this calc is weird but seems to work on my phone // TODO: this calc is weird but seems to work on my phone
Margin { Margin {
@ -152,8 +179,7 @@ impl ZapStreamApp {
left: c_rect.left as f32, left: c_rect.left as f32,
right: (w - c_rect.right) as f32, right: (w - c_rect.right) as f32,
top: (c_rect.top - (h - c_rect.bottom)) as f32, top: (c_rect.top - (h - c_rect.bottom)) as f32,
} } / dpi_scale
.div(dpi_scale)
} else { } else {
Margin::ZERO Margin::ZERO
} }

View File

@ -14,12 +14,9 @@ mod theme;
mod widgets; mod widgets;
mod zap; mod zap;
#[cfg(target_os = "android")]
use android_activity::AndroidApp;
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
#[no_mangle] #[no_mangle]
#[tokio::main] #[tokio::main]
pub async fn android_main(app: AndroidApp) { pub async fn android_main(app: android_activity::AndroidApp) {
android::start_android(app); android::start_android(app);
} }

View File

@ -1,6 +1,5 @@
use crate::note_util::NoteUtil; use crate::note_util::NoteUtil;
use bech32::{Hrp, NoChecksum}; use bech32::{Hrp, NoChecksum};
use egui::TextBuffer;
use nostr::prelude::hex; use nostr::prelude::hex;
use nostrdb::{Filter, Note}; use nostrdb::{Filter, Note};
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};

View File

@ -9,7 +9,7 @@ pub trait NoteUtil {
F: Fn(Vec<NdbStr>) -> bool; F: Fn(Vec<NdbStr>) -> bool;
} }
impl<'a> NoteUtil for Note<'a> { impl NoteUtil for Note<'_> {
fn id_hex(&self) -> String { fn id_hex(&self) -> String {
hex::encode(self.id()) hex::encode(self.id())
} }

View File

@ -26,7 +26,7 @@ impl<'a> NotesView<'a> {
} }
pub fn add(&mut self, note: &'a Note<'a>) -> Option<&'a Note<'a>> { pub fn add(&mut self, note: &'a Note<'a>) -> Option<&'a Note<'a>> {
let k = Self::key(&note); let k = Self::key(note);
if let Some(v) = self.events.get(&k) { if let Some(v) = self.events.get(&k) {
if v.created_at() < note.created_at() { if v.created_at() < note.created_at() {
return self.events.insert(k, note); return self.events.insert(k, note);

View File

@ -34,7 +34,7 @@ impl NostrWidget for HomePage {
let events: Vec<Note> = self let events: Vec<Note> = self
.events .events
.iter() .iter()
.map_while(|n| services.ctx.ndb.get_note_by_key(&services.tx, n.key).ok()) .map_while(|n| services.ctx.ndb.get_note_by_key(services.tx, n.key).ok())
.collect(); .collect();
let events_live = NotesView::from_vec( let events_live = NotesView::from_vec(
@ -87,8 +87,8 @@ impl NostrWidget for HomePage {
fn update(&mut self, services: &mut RouteServices<'_, '_>) -> anyhow::Result<()> { fn update(&mut self, services: &mut RouteServices<'_, '_>) -> anyhow::Result<()> {
sub_or_poll( sub_or_poll(
services.ctx.ndb, services.ctx.ndb,
&services.tx, services.tx,
&mut services.ctx.pool, services.ctx.pool,
&mut self.events, &mut self.events,
&mut self.sub, &mut self.sub,
Self::get_filters(), Self::get_filters(),

View File

@ -42,7 +42,7 @@ impl NostrWidget for LoginPage {
ids.process_action( ids.process_action(
services.ctx.unknown_ids, services.ctx.unknown_ids,
services.ctx.ndb, services.ctx.ndb,
&services.tx, services.tx,
); );
services.ctx.accounts.select_account(0); services.ctx.accounts.select_account(0);
services.navigate(RouteType::HomePage); services.navigate(RouteType::HomePage);
@ -56,7 +56,7 @@ impl NostrWidget for LoginPage {
ids.process_action( ids.process_action(
services.ctx.unknown_ids, services.ctx.unknown_ids,
services.ctx.ndb, services.ctx.ndb,
&services.tx, services.tx,
); );
services.ctx.accounts.select_account(0); services.ctx.accounts.select_account(0);
services.navigate(RouteType::HomePage); services.navigate(RouteType::HomePage);
@ -71,7 +71,7 @@ impl NostrWidget for LoginPage {
ids.process_action( ids.process_action(
services.ctx.unknown_ids, services.ctx.unknown_ids,
services.ctx.ndb, services.ctx.ndb,
&services.tx, services.tx,
); );
services.navigate(RouteType::HomePage); services.navigate(RouteType::HomePage);
return; return;

View File

@ -3,7 +3,6 @@ use crate::services::ffmpeg_loader::FfmpegLoader;
use egui::load::SizedTexture; use egui::load::SizedTexture;
use egui::{Context, Image, TextureHandle}; use egui::{Context, Image, TextureHandle};
use enostr::EventClientMessage; use enostr::EventClientMessage;
use itertools::Itertools;
use log::{info, warn}; use log::{info, warn};
use nostr::{Event, EventBuilder, JsonUtil, Kind, Tag}; use nostr::{Event, EventBuilder, JsonUtil, Kind, Tag};
use nostrdb::{NdbProfile, NoteKey, Transaction}; use nostrdb::{NdbProfile, NoteKey, Transaction};
@ -53,7 +52,7 @@ pub struct RouteServices<'a, 'ctx> {
pub ctx: &'a mut AppContext<'ctx>, pub ctx: &'a mut AppContext<'ctx>,
} }
impl<'a, 'ctx> RouteServices<'a, 'ctx> { impl<'a> RouteServices<'a, '_> {
pub fn navigate(&self, route: RouteType) { pub fn navigate(&self, route: RouteType) {
self.router.send(route).expect("route send failed"); self.router.send(route).expect("route send failed");
self.egui.request_repaint(); self.egui.request_repaint();
@ -88,7 +87,7 @@ impl<'a, 'ctx> RouteServices<'a, 'ctx> {
.ok() .ok()
.flatten(); .flatten();
if p.is_none() { if p.is_none() {
self.action(RouteAction::DemandProfile(pk.clone())); self.action(RouteAction::DemandProfile(*pk));
} }
p p
} }
@ -105,19 +104,17 @@ impl<'a, 'ctx> RouteServices<'a, 'ctx> {
} }
pub fn write_live_chat_msg(&self, link: &NostrLink, msg: &str) -> Option<Event> { pub fn write_live_chat_msg(&self, link: &NostrLink, msg: &str) -> Option<Event> {
if msg.len() == 0 { if msg.is_empty() {
return None; return None;
} }
if let Some(acc) = self.ctx.accounts.get_selected_account() { if let Some(acc) = self.ctx.accounts.get_selected_account() {
if let Some(key) = &acc.secret_key { if let Some(key) = &acc.secret_key {
let nostr_key = let nostr_key =
nostr::Keys::new(nostr::SecretKey::from_slice(key.as_secret_bytes()).unwrap()); nostr::Keys::new(nostr::SecretKey::from_slice(key.as_secret_bytes()).unwrap());
return Some( return EventBuilder::new(Kind::LiveEventMessage, msg)
EventBuilder::new(Kind::LiveEventMessage, msg) .tag(Tag::parse(link.to_tag()).unwrap())
.tag(Tag::parse(&link.to_tag()).unwrap())
.sign_with_keys(&nostr_key) .sign_with_keys(&nostr_key)
.ok()?, .ok();
);
} }
} }
None None

View File

@ -64,7 +64,7 @@ impl StreamPage {
ui.add(PlaceholderRect) ui.add(PlaceholderRect)
} }
}); });
StreamTitle::new(&event).render(ui, services); StreamTitle::new(event).render(ui, services);
if let Some(c) = self.chat.as_mut() { if let Some(c) = self.chat.as_mut() {
ui.allocate_ui( ui.allocate_ui(
@ -107,7 +107,7 @@ impl StreamPage {
} }
}); });
ui.add_space(10.); ui.add_space(10.);
StreamTitle::new(&event).render(ui, services); StreamTitle::new(event).render(ui, services);
}); });
ui.allocate_ui_with_layout( ui.allocate_ui_with_layout(
vec2(chat_w, max_h), vec2(chat_w, max_h),
@ -166,9 +166,9 @@ impl NostrWidget for StreamPage {
} }
if ui.available_width() < 720.0 { if ui.available_width() < 720.0 {
self.render_mobile(&event, ui, services) self.render_mobile(event, ui, services)
} else { } else {
self.render_desktop(&event, ui, services) self.render_desktop(event, ui, services)
} }
} else { } else {
ui.label("Loading..") ui.label("Loading..")
@ -179,8 +179,8 @@ impl NostrWidget for StreamPage {
let filters = self.get_filters(); let filters = self.get_filters();
sub_or_poll( sub_or_poll(
services.ctx.ndb, services.ctx.ndb,
&services.tx, services.tx,
&mut services.ctx.pool, services.ctx.pool,
&mut self.events, &mut self.events,
&mut self.sub, &mut self.sub,
filters, filters,

View File

@ -39,7 +39,7 @@ pub trait StreamInfo {
fn viewers(&self) -> Option<u32>; fn viewers(&self) -> Option<u32>;
} }
impl<'a> StreamInfo for Note<'a> { impl StreamInfo for Note<'_> {
fn title(&self) -> Option<&str> { fn title(&self) -> Option<&str> {
if let Some(s) = self.get_tag_value("title") { if let Some(s) = self.get_tag_value("title") {
s.variant().str() s.variant().str()

View File

@ -18,7 +18,7 @@ impl Avatar {
pub fn pubkey(pk: &[u8; 32], ndb: &Ndb, tx: &Transaction) -> Self { pub fn pubkey(pk: &[u8; 32], ndb: &Ndb, tx: &Transaction) -> Self {
let picture = ndb let picture = ndb
.get_profile_by_pubkey(&tx, pk) .get_profile_by_pubkey(tx, pk)
.map(|p| p.record().profile().map(|p| p.picture()).unwrap_or(None)) .map(|p| p.record().profile().map(|p| p.picture()).unwrap_or(None))
.unwrap_or(None); .unwrap_or(None);
Self { Self {
@ -57,7 +57,7 @@ impl Avatar {
return Self::placeholder(ui, size_v); return Self::placeholder(ui, size_v);
} }
match &self.image { match &self.image {
Some(img) => image_from_cache(img_cache, ui.ctx(), &img) Some(img) => image_from_cache(img_cache, ui.ctx(), img)
.fit_to_exact_size(size) .fit_to_exact_size(size)
.rounding(Rounding::same(size_v)) .rounding(Rounding::same(size_v))
.ui(ui), .ui(ui),

View File

@ -89,7 +89,7 @@ impl NostrWidget for Chat {
sub_or_poll( sub_or_poll(
services.ctx.ndb, services.ctx.ndb,
services.tx, services.tx,
&mut services.ctx.pool, services.ctx.pool,
&mut self.events, &mut self.events,
&mut self.sub, &mut self.sub,
filters, filters,

View File

@ -1,6 +1,6 @@
use crate::stream_info::StreamInfo; use crate::stream_info::StreamInfo;
use crate::theme::{NEUTRAL_500, PRIMARY}; use crate::theme::{NEUTRAL_500, PRIMARY};
use crate::widgets::{Avatar, NostrWidget}; use crate::widgets::Avatar;
use eframe::epaint::text::TextWrapMode; use eframe::epaint::text::TextWrapMode;
use egui::text::LayoutJob; use egui::text::LayoutJob;
use egui::{Align, Color32, Label, Response, TextFormat, Ui}; use egui::{Align, Color32, Label, Response, TextFormat, Ui};
@ -48,7 +48,7 @@ impl<'a> ChatMessage<'a> {
format.color = Color32::WHITE; format.color = Color32::WHITE;
job.append(self.ev.content(), 5.0, format.clone()); job.append(self.ev.content(), 5.0, format.clone());
Avatar::from_profile(&self.profile) Avatar::from_profile(self.profile)
.size(24.) .size(24.)
.render(ui, img_cache); .render(ui, img_cache);
ui.add(Label::new(job).wrap_mode(TextWrapMode::Wrap)); ui.add(Label::new(job).wrap_mode(TextWrapMode::Wrap));

View File

@ -54,7 +54,7 @@ impl<'a> ChatZap<'a> {
job.append(&format!("\n{}", self.zap.message), 0.0, format.clone()); job.append(&format!("\n{}", self.zap.message), 0.0, format.clone());
} }
Avatar::from_profile(&self.profile) Avatar::from_profile(self.profile)
.size(24.) .size(24.)
.render(ui, img_cache); .render(ui, img_cache);
ui.add(Label::new(job).wrap_mode(TextWrapMode::Wrap)); ui.add(Label::new(job).wrap_mode(TextWrapMode::Wrap));

View File

@ -1,6 +1,6 @@
use crate::route::{RouteServices, RouteType}; use crate::route::{RouteServices, RouteType};
use crate::widgets::avatar::Avatar; use crate::widgets::avatar::Avatar;
use crate::widgets::{Button, NostrWidget}; use crate::widgets::Button;
use eframe::emath::Align; use eframe::emath::Align;
use eframe::epaint::Vec2; use eframe::epaint::Vec2;
use egui::{CursorIcon, Frame, Layout, Margin, Response, Sense, Ui, Widget}; use egui::{CursorIcon, Frame, Layout, Margin, Response, Sense, Ui, Widget};

View File

@ -1,6 +1,6 @@
use crate::route::RouteServices; use crate::route::RouteServices;
use crate::theme::FONT_SIZE; use crate::theme::FONT_SIZE;
use crate::widgets::{Avatar, NostrWidget, Username}; use crate::widgets::{Avatar, Username};
use egui::{Response, Ui}; use egui::{Response, Ui};
pub struct Profile<'a> { pub struct Profile<'a> {

View File

@ -2,7 +2,6 @@ use crate::note_view::NotesView;
use crate::route::RouteServices; use crate::route::RouteServices;
use crate::stream_info::StreamInfo; use crate::stream_info::StreamInfo;
use crate::widgets::stream_tile::StreamEvent; use crate::widgets::stream_tile::StreamEvent;
use crate::widgets::NostrWidget;
use egui::{vec2, Frame, Grid, Margin, Response, Ui, WidgetText}; use egui::{vec2, Frame, Grid, Margin, Response, Ui, WidgetText};
use itertools::Itertools; use itertools::Itertools;

View File

@ -3,7 +3,6 @@ use crate::route::{RouteServices, RouteType};
use crate::stream_info::{StreamInfo, StreamStatus}; use crate::stream_info::{StreamInfo, StreamStatus};
use crate::theme::{NEUTRAL_800, NEUTRAL_900, PRIMARY, ROUNDING_DEFAULT}; use crate::theme::{NEUTRAL_800, NEUTRAL_900, PRIMARY, ROUNDING_DEFAULT};
use crate::widgets::avatar::Avatar; use crate::widgets::avatar::Avatar;
use crate::widgets::NostrWidget;
use eframe::epaint::{Rounding, Vec2}; use eframe::epaint::{Rounding, Vec2};
use egui::epaint::RectShape; use egui::epaint::RectShape;
use egui::load::TexturePoll; use egui::load::TexturePoll;

View File

@ -1,7 +1,7 @@
use crate::note_util::NoteUtil; use crate::note_util::NoteUtil;
use crate::route::RouteServices; use crate::route::RouteServices;
use crate::stream_info::StreamInfo; use crate::stream_info::StreamInfo;
use crate::widgets::{NostrWidget, Profile}; use crate::widgets::Profile;
use egui::{Color32, Frame, Label, Margin, Response, RichText, TextWrapMode, Ui}; use egui::{Color32, Frame, Label, Margin, Response, RichText, TextWrapMode, Ui};
use nostrdb::Note; use nostrdb::Note;
@ -32,7 +32,7 @@ impl<'a> StreamTitle<'a> {
.get_tag_value("summary") .get_tag_value("summary")
.and_then(|r| r.variant().str()) .and_then(|r| r.variant().str())
{ {
if summary.len() > 0 { if !summary.is_empty() {
let summary = RichText::new(summary).color(Color32::WHITE); let summary = RichText::new(summary).color(Color32::WHITE);
ui.add(Label::new(summary).wrap_mode(TextWrapMode::Truncate)); ui.add(Label::new(summary).wrap_mode(TextWrapMode::Truncate));
} }

View File

@ -37,7 +37,8 @@ impl Widget for NativeTextInput<'_> {
if let Some(hint_text) = self.hint_text { if let Some(hint_text) = self.hint_text {
editor = editor.hint_text(egui::RichText::new(hint_text).color(NEUTRAL_500)); editor = editor.hint_text(egui::RichText::new(hint_text).color(NEUTRAL_500));
} }
let response = if self.frame {
if self.frame {
Frame::none() Frame::none()
.inner_margin(MARGIN_DEFAULT) .inner_margin(MARGIN_DEFAULT)
.fill(NEUTRAL_900) .fill(NEUTRAL_900)
@ -46,7 +47,6 @@ impl Widget for NativeTextInput<'_> {
.inner .inner
} else { } else {
ui.add(editor) ui.add(editor)
}; }
response
} }
} }

View File

@ -12,7 +12,7 @@ impl<'a> Username<'a> {
} }
} }
impl<'a> Widget for Username<'a> { impl Widget for Username<'_> {
fn ui(self, ui: &mut Ui) -> Response { fn ui(self, ui: &mut Ui) -> Response {
let name = self let name = self
.profile .profile

View File

@ -35,7 +35,7 @@ impl WriteChat {
.clicked() .clicked()
|| self.msg.ends_with('\n') || self.msg.ends_with('\n')
{ {
if let Some(ev) = services.write_live_chat_msg(&self.link, &self.msg.trim()) if let Some(ev) = services.write_live_chat_msg(&self.link, self.msg.trim())
{ {
info!("Sending: {:?}", ev); info!("Sending: {:?}", ev);
services.broadcast_event(ev); services.broadcast_event(ev);