fix: designs

This commit is contained in:
kieran 2024-11-05 13:24:10 +00:00
parent ce5f206f6a
commit e718b8e322
No known key found for this signature in database
GPG Key ID: DE71CEB3925BE941
7 changed files with 117 additions and 89 deletions

View File

@ -77,6 +77,9 @@ impl Login {
} }
pub fn write_live_chat_msg(&self, link: &NostrLink, msg: &str) -> Result<Event, Error> { pub fn write_live_chat_msg(&self, link: &NostrLink, msg: &str) -> Result<Event, Error> {
if msg.len() == 0 {
return Err(anyhow::anyhow!("Empty message"));
}
let secret = self.secret_key()?; let secret = self.secret_key()?;
EventBuilder::new(Kind::LiveEventMessage, msg, [Tag::parse(&link.to_tag())?]) EventBuilder::new(Kind::LiveEventMessage, msg, [Tag::parse(&link.to_tag())?])
.to_event(&secret) .to_event(&secret)

View File

@ -3,8 +3,9 @@ use crate::note_util::OwnedNote;
use crate::route::RouteServices; use crate::route::RouteServices;
use crate::services::ndb_wrapper::{NDBWrapper, SubWrapper}; use crate::services::ndb_wrapper::{NDBWrapper, SubWrapper};
use crate::stream_info::StreamInfo; use crate::stream_info::StreamInfo;
use crate::theme::{MARGIN_DEFAULT, NEUTRAL_800, ROUNDING_DEFAULT};
use crate::widgets::{Chat, NostrWidget, StreamPlayer, StreamTitle, WriteChat}; use crate::widgets::{Chat, NostrWidget, StreamPlayer, StreamTitle, WriteChat};
use egui::{vec2, Response, Ui, Vec2, Widget}; use egui::{vec2, Align, Frame, Layout, Response, Stroke, Ui, Vec2, Widget};
use nostrdb::{Filter, Note, NoteKey, Transaction}; use nostrdb::{Filter, Note, NoteKey, Transaction};
use std::borrow::Borrow; use std::borrow::Borrow;
@ -37,31 +38,37 @@ impl StreamPage {
ui: &mut Ui, ui: &mut Ui,
services: &mut RouteServices<'_>, services: &mut RouteServices<'_>,
) -> Response { ) -> Response {
if let Some(player) = &mut self.player {
player.ui(ui);
}
StreamTitle::new(&event).render(ui, services);
let chat_h = 60.0; let chat_h = 60.0;
let w = ui.available_width(); let w = ui.available_width();
let h = ui let h = ui
.available_height() .available_height()
.max(ui.available_rect_before_wrap().height()) .max(ui.available_rect_before_wrap().height());
.max(chat_h); ui.allocate_ui_with_layout(
ui.allocate_ui(Vec2::new(w, h - chat_h), |ui| { Vec2::new(w, h),
if let Some(c) = self.chat.as_mut() { Layout::top_down_justified(Align::Min),
c.render(ui, services); |ui| {
} else { if let Some(player) = &mut self.player {
ui.label("Loading.."); let video_h =
} ((ui.available_width() / 16.0) * 9.0).min(ui.available_height() * 0.33);
// consume rest of space ui.allocate_ui(vec2(ui.available_width(), video_h), |ui| player.ui(ui));
if ui.available_height().is_finite() { }
ui.add_space(ui.available_height()); StreamTitle::new(&event).render(ui, services);
}
}); if let Some(c) = self.chat.as_mut() {
ui.allocate_ui(vec2(w, chat_h), |ui| { ui.allocate_ui(
self.new_msg.render(ui, services); vec2(ui.available_width(), ui.available_height() - chat_h),
}); |ui| c.render(ui, services),
);
} else {
ui.label("Loading..");
}
// consume rest of space
if ui.available_height().is_finite() {
ui.add_space(ui.available_height() - chat_h);
}
self.new_msg.render(ui, services);
},
);
ui.response() ui.response()
} }
@ -76,33 +83,45 @@ impl StreamPage {
let video_width = ui.available_width() - chat_w; let video_width = ui.available_width() - chat_w;
let video_height = max_h.min((video_width / 16.0) * 9.0); let video_height = max_h.min((video_width / 16.0) * 9.0);
ui.horizontal_top(|ui| { ui.with_layout(
ui.vertical(|ui| { Layout::left_to_right(Align::TOP).with_main_justify(true),
if let Some(player) = &mut self.player { |ui| {
ui.allocate_ui(vec2(video_width, video_height), |ui| player.ui(ui));
}
ui.add_space(10.);
StreamTitle::new(&event).render(ui, services);
});
ui.allocate_ui(vec2(chat_w, max_h), |ui| {
ui.vertical(|ui| { ui.vertical(|ui| {
let chat_h = 60.0; if let Some(player) = &mut self.player {
if let Some(c) = self.chat.as_mut() { ui.allocate_ui(vec2(video_width, video_height), |ui| player.ui(ui));
ui.allocate_ui(vec2(chat_w, max_h - chat_h), |ui| {
c.render(ui, services);
if ui.available_height().is_finite() {
ui.add_space(ui.available_height() - chat_h);
}
});
} else {
ui.label("Loading..");
} }
ui.allocate_ui(vec2(chat_w, chat_h), |ui| { ui.add_space(10.);
self.new_msg.render(ui, services); StreamTitle::new(&event).render(ui, services);
}); });
}) ui.allocate_ui_with_layout(
}); vec2(chat_w, max_h),
}); Layout::top_down_justified(Align::Min),
|ui| {
Frame::none()
.stroke(Stroke::new(1.0, NEUTRAL_800))
.outer_margin(MARGIN_DEFAULT)
.rounding(ROUNDING_DEFAULT)
.show(ui, |ui| {
let chat_h = 60.0;
if let Some(c) = self.chat.as_mut() {
ui.allocate_ui(
vec2(ui.available_width(), ui.available_height() - chat_h),
|ui| {
c.render(ui, services);
},
);
} else {
ui.label("Loading..");
}
if ui.available_height().is_finite() {
ui.add_space(ui.available_height() - chat_h);
}
self.new_msg.render(ui, services);
});
},
);
},
);
ui.response() ui.response()
} }

View File

@ -41,7 +41,7 @@ impl ImageCache {
ctx, ctx,
dir: out, dir: out,
placeholder, placeholder,
cache: Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(100).unwrap()))), cache: Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(1000).unwrap()))),
fetch_cache: Arc::new(Mutex::new(HashSet::new())), fetch_cache: Arc::new(Mutex::new(HashSet::new())),
} }
} }

View File

@ -17,9 +17,7 @@ impl StreamPlayer {
impl Widget for &mut StreamPlayer { impl Widget for &mut StreamPlayer {
fn ui(self, ui: &mut Ui) -> Response { fn ui(self, ui: &mut Ui) -> Response {
let w = ui.available_width(); let size = ui.available_size();
let h = w / 16. * 9.;
let size = Vec2::new(w, h);
if let Some(p) = self.player.as_mut() { if let Some(p) = self.player.as_mut() {
ui.add_sized(size, p) ui.add_sized(size, p)

View File

@ -33,8 +33,10 @@ impl<'a> NostrWidget for StreamTitle<'a> {
.get_tag_value("summary") .get_tag_value("summary")
.and_then(|r| r.variant().str()) .and_then(|r| r.variant().str())
{ {
let summary = RichText::new(summary).color(Color32::WHITE); if summary.len() > 0 {
ui.add(Label::new(summary).wrap_mode(TextWrapMode::Truncate)); let summary = RichText::new(summary).color(Color32::WHITE);
ui.add(Label::new(summary).wrap_mode(TextWrapMode::Truncate));
}
} }
}) })
.response .response

View File

@ -1,5 +1,5 @@
use crate::route::{RouteAction, RouteServices}; use crate::route::{RouteAction, RouteServices};
use crate::theme::{MARGIN_DEFAULT, NEUTRAL_500, NEUTRAL_800, ROUNDING_DEFAULT}; use crate::theme::{MARGIN_DEFAULT, NEUTRAL_500, NEUTRAL_900, ROUNDING_DEFAULT};
use crate::widgets::NostrWidget; use crate::widgets::NostrWidget;
use egui::{Frame, Response, TextEdit, Ui}; use egui::{Frame, Response, TextEdit, Ui};
@ -7,6 +7,7 @@ use egui::{Frame, Response, TextEdit, Ui};
pub struct NativeTextInput<'a> { pub struct NativeTextInput<'a> {
pub text: &'a mut String, pub text: &'a mut String,
hint_text: Option<&'a str>, hint_text: Option<&'a str>,
frame: bool,
} }
impl<'a> NativeTextInput<'a> { impl<'a> NativeTextInput<'a> {
@ -14,6 +15,7 @@ impl<'a> NativeTextInput<'a> {
Self { Self {
text, text,
hint_text: None, hint_text: None,
frame: false,
} }
} }
@ -21,20 +23,31 @@ impl<'a> NativeTextInput<'a> {
self.hint_text = Some(hint_text); self.hint_text = Some(hint_text);
self self
} }
pub fn with_frame(mut self, frame: bool) -> Self {
self.frame = frame;
self
}
} }
impl<'a> NostrWidget for NativeTextInput<'a> { impl<'a> NostrWidget for NativeTextInput<'a> {
fn render(&mut self, ui: &mut Ui, services: &mut RouteServices<'_>) -> Response { fn render(&mut self, ui: &mut Ui, services: &mut RouteServices<'_>) -> Response {
let mut editor = TextEdit::singleline(self.text).frame(false); let mut editor = TextEdit::singleline(self.text)
.frame(false)
.desired_width(f32::INFINITY);
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 = Frame::none() let response = if self.frame {
.inner_margin(MARGIN_DEFAULT) Frame::none()
.fill(NEUTRAL_800) .inner_margin(MARGIN_DEFAULT)
.rounding(ROUNDING_DEFAULT) .fill(NEUTRAL_900)
.show(ui, |ui| ui.add(editor)) .rounding(ROUNDING_DEFAULT)
.inner; .show(ui, |ui| ui.add(editor))
.inner
} else {
ui.add(editor)
};
if response.lost_focus() { if response.lost_focus() {
services.action(RouteAction::HideKeyboard); services.action(RouteAction::HideKeyboard);
} }

View File

@ -25,36 +25,29 @@ impl NostrWidget for WriteChat {
let logo_bytes = include_bytes!("../resources/send-03.svg"); let logo_bytes = include_bytes!("../resources/send-03.svg");
Frame::none() Frame::none()
.inner_margin(MARGIN_DEFAULT) .inner_margin(MARGIN_DEFAULT)
.stroke(Stroke::new(1.0, NEUTRAL_900)) .outer_margin(MARGIN_DEFAULT)
.fill(NEUTRAL_900)
.rounding(ROUNDING_DEFAULT)
.show(ui, |ui| { .show(ui, |ui| {
Frame::none() ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
.fill(NEUTRAL_900) if services
.rounding(ROUNDING_DEFAULT) .img_cache
.inner_margin(MARGIN_DEFAULT) .load_bytes("send-03.svg", logo_bytes)
.show(ui, |ui| { .sense(Sense::click())
ui.horizontal(|ui| { .ui(ui)
if services .clicked()
.img_cache {
.load_bytes("send-03.svg", logo_bytes) if let Ok(ev) = services.login.write_live_chat_msg(&self.link, &self.msg) {
.sense(Sense::click()) info!("Sending: {:?}", ev);
.ui(ui) services.broadcast_event(ev);
.clicked() }
{ self.msg.clear();
if let Ok(ev) = }
services.login.write_live_chat_msg(&self.link, &self.msg)
{
info!("Sending: {:?}", ev);
services.broadcast_event(ev);
}
self.msg.clear();
}
ui.allocate_ui(ui.available_size(), |ui| { let mut editor =
let mut editor = NativeTextInput::new(&mut self.msg); NativeTextInput::new(&mut self.msg).with_hint_text("Message..");
editor.render(ui, services); editor.render(ui, services);
}); });
});
})
}) })
.response .response
} }