mirror of
https://github.com/aljazceru/notedeck.git
synced 2025-12-20 18:04:18 +01:00
ui: reactions closer approximation of iOS design
Signed-off-by: kernelkind <kernelkind@gmail.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
use egui::containers::scroll_area::ScrollBarVisibility;
|
use egui::containers::scroll_area::ScrollBarVisibility;
|
||||||
use egui::{vec2, Direction, Layout, Pos2, ScrollArea, Sense, Stroke};
|
use egui::{vec2, Direction, Layout, Margin, Pos2, ScrollArea, Sense, Stroke};
|
||||||
use egui_tabs::TabColor;
|
use egui_tabs::TabColor;
|
||||||
use enostr::Pubkey;
|
use enostr::Pubkey;
|
||||||
use nostrdb::{ProfileRecord, Transaction};
|
use nostrdb::{ProfileRecord, Transaction};
|
||||||
@@ -7,7 +7,7 @@ use notedeck::name::get_display_name;
|
|||||||
use notedeck::ui::is_narrow;
|
use notedeck::ui::is_narrow;
|
||||||
use notedeck::{JobsCache, Muted, NoteRef};
|
use notedeck::{JobsCache, Muted, NoteRef};
|
||||||
use notedeck_ui::app_images::like_image;
|
use notedeck_ui::app_images::like_image;
|
||||||
use notedeck_ui::{padding, ProfilePic};
|
use notedeck_ui::ProfilePic;
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
use tracing::{error, warn};
|
use tracing::{error, warn};
|
||||||
|
|
||||||
@@ -540,14 +540,16 @@ fn render_reaction_cluster(
|
|||||||
let num_profiles_other = profiles_to_show.len() - 1;
|
let num_profiles_other = profiles_to_show.len() - 1;
|
||||||
|
|
||||||
let mut action = None;
|
let mut action = None;
|
||||||
padding(8.0, ui, |ui| {
|
egui::Frame::new()
|
||||||
|
.inner_margin(Margin::symmetric(8, 4))
|
||||||
|
.show(ui, |ui| {
|
||||||
ui.allocate_ui_with_layout(
|
ui.allocate_ui_with_layout(
|
||||||
vec2(ui.available_width(), 32.0),
|
vec2(ui.available_width(), 32.0),
|
||||||
Layout::left_to_right(egui::Align::Center),
|
Layout::left_to_right(egui::Align::Center),
|
||||||
|ui| {
|
|ui| {
|
||||||
ui.vertical(|ui| {
|
ui.vertical(|ui| {
|
||||||
ui.add_space(16.0);
|
ui.add_space(4.0);
|
||||||
ui.add_sized(vec2(32.0, 32.0), like_image());
|
ui.add_sized(vec2(28.0, 28.0), like_image());
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.add_space(16.0);
|
ui.add_space(16.0);
|
||||||
@@ -562,6 +564,7 @@ fn render_reaction_cluster(
|
|||||||
note_context.img_cache,
|
note_context.img_cache,
|
||||||
entry.record.as_ref(),
|
entry.record.as_ref(),
|
||||||
)
|
)
|
||||||
|
.size(24.0)
|
||||||
.sense(Sense::click()),
|
.sense(Sense::click()),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -606,7 +609,10 @@ fn render_reaction_cluster(
|
|||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add_space(48.0);
|
ui.add_space(48.0);
|
||||||
let resp = NoteView::new(note_context, &reacted_to_note, note_options, jobs).show(ui);
|
let options = note_options
|
||||||
|
.difference(NoteOptions::ActionBar | NoteOptions::OptionsButton)
|
||||||
|
.union(NoteOptions::NotificationPreview);
|
||||||
|
let resp = NoteView::new(note_context, &reacted_to_note, options, jobs).show(ui);
|
||||||
|
|
||||||
if let Some(note_action) = resp.action {
|
if let Some(note_action) = resp.action {
|
||||||
action = Some(note_action);
|
action = Some(note_action);
|
||||||
|
|||||||
@@ -334,14 +334,14 @@ fn render_undecorated_note_contents<'a>(
|
|||||||
.selectable(selectable),
|
.selectable(selectable),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
ui.add(
|
let mut richtext = RichText::new(block_str)
|
||||||
Label::new(
|
.text_style(NotedeckTextStyle::NoteBody.text_style());
|
||||||
RichText::new(block_str)
|
|
||||||
.text_style(NotedeckTextStyle::NoteBody.text_style()),
|
if options.contains(NoteOptions::NotificationPreview) {
|
||||||
)
|
richtext = richtext.color(egui::Color32::from_rgb(0x87, 0x87, 0x8D));
|
||||||
.wrap()
|
}
|
||||||
.selectable(selectable),
|
|
||||||
);
|
ui.add(Label::new(richtext).wrap().selectable(selectable));
|
||||||
}
|
}
|
||||||
// don't render any more blocks
|
// don't render any more blocks
|
||||||
if truncate {
|
if truncate {
|
||||||
|
|||||||
@@ -426,16 +426,19 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
|||||||
) -> egui::InnerResponse<NoteUiResponse> {
|
) -> egui::InnerResponse<NoteUiResponse> {
|
||||||
ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| {
|
ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| {
|
||||||
let mut note_action: Option<NoteAction> = None;
|
let mut note_action: Option<NoteAction> = None;
|
||||||
let pfp_rect = ui
|
let mut pfp_rect = None;
|
||||||
.horizontal(|ui| {
|
|
||||||
|
if !self.flags.contains(NoteOptions::NotificationPreview) {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
let pfp_resp = self.pfp(note_key, profile, ui);
|
let pfp_resp = self.pfp(note_key, profile, ui);
|
||||||
let pfp_rect = pfp_resp.bounding_rect;
|
pfp_rect = Some(pfp_resp.bounding_rect);
|
||||||
note_action = pfp_resp
|
note_action = pfp_resp
|
||||||
.into_action(self.note.pubkey())
|
.into_action(self.note.pubkey())
|
||||||
.or(note_action.take());
|
.or(note_action.take());
|
||||||
|
|
||||||
let size = ui.available_size();
|
let size = ui.available_size();
|
||||||
ui.vertical(|ui| 's: {
|
|
||||||
|
ui.vertical(|ui| {
|
||||||
ui.add_sized(
|
ui.add_sized(
|
||||||
[size.x, self.options().pfp_size() as f32],
|
[size.x, self.options().pfp_size() as f32],
|
||||||
|ui: &mut egui::Ui| {
|
|ui: &mut egui::Ui| {
|
||||||
@@ -460,7 +463,7 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
|||||||
.borrow(self.note.tags());
|
.borrow(self.note.tags());
|
||||||
|
|
||||||
if note_reply.reply().is_none() {
|
if note_reply.reply().is_none() {
|
||||||
break 's;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.horizontal_wrapped(|ui| {
|
ui.horizontal_wrapped(|ui| {
|
||||||
@@ -477,10 +480,8 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
|||||||
.or(note_action.take());
|
.or(note_action.take());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
pfp_rect
|
}
|
||||||
})
|
|
||||||
.inner;
|
|
||||||
|
|
||||||
let mut contents =
|
let mut contents =
|
||||||
NoteContents::new(self.note_context, txn, self.note, self.flags, self.jobs);
|
NoteContents::new(self.note_context, txn, self.note, self.flags, self.jobs);
|
||||||
@@ -530,14 +531,27 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
|||||||
) -> egui::InnerResponse<NoteUiResponse> {
|
) -> egui::InnerResponse<NoteUiResponse> {
|
||||||
// main design
|
// main design
|
||||||
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
||||||
|
let (mut note_action, pfp_rect) =
|
||||||
|
if self.flags.contains(NoteOptions::NotificationPreview) {
|
||||||
|
// do not render pfp
|
||||||
|
(None, None)
|
||||||
|
} else {
|
||||||
let pfp_resp = self.pfp(note_key, profile, ui);
|
let pfp_resp = self.pfp(note_key, profile, ui);
|
||||||
let pfp_rect = pfp_resp.bounding_rect;
|
let pfp_rect = pfp_resp.bounding_rect;
|
||||||
let mut note_action: Option<NoteAction> = pfp_resp.into_action(self.note.pubkey());
|
(pfp_resp.into_action(self.note.pubkey()), Some(pfp_rect))
|
||||||
|
};
|
||||||
|
|
||||||
ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| {
|
ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| {
|
||||||
NoteView::note_header(ui, self.note_context.i18n, self.note, profile, self.flags);
|
if !self.flags.contains(NoteOptions::NotificationPreview) {
|
||||||
|
NoteView::note_header(
|
||||||
|
ui,
|
||||||
|
self.note_context.i18n,
|
||||||
|
self.note,
|
||||||
|
profile,
|
||||||
|
self.flags,
|
||||||
|
);
|
||||||
|
|
||||||
ui.horizontal_wrapped(|ui| 's: {
|
ui.horizontal_wrapped(|ui| {
|
||||||
ui.spacing_mut().item_spacing.x = 1.0;
|
ui.spacing_mut().item_spacing.x = 1.0;
|
||||||
|
|
||||||
let note_reply = self
|
let note_reply = self
|
||||||
@@ -548,7 +562,7 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
|||||||
.borrow(self.note.tags());
|
.borrow(self.note.tags());
|
||||||
|
|
||||||
if note_reply.reply().is_none() {
|
if note_reply.reply().is_none() {
|
||||||
break 's;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
note_action = reply_desc(
|
note_action = reply_desc(
|
||||||
@@ -561,6 +575,7 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
|||||||
)
|
)
|
||||||
.or(note_action.take());
|
.or(note_action.take());
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let mut contents =
|
let mut contents =
|
||||||
NoteContents::new(self.note_context, txn, self.note, self.flags, self.jobs);
|
NoteContents::new(self.note_context, txn, self.note, self.flags, self.jobs);
|
||||||
@@ -639,9 +654,12 @@ impl<'a, 'd> NoteView<'a, 'd> {
|
|||||||
.then_some(NoteAction::note(NoteId::new(*self.note.id())))
|
.then_some(NoteAction::note(NoteId::new(*self.note.id())))
|
||||||
.or(note_action);
|
.or(note_action);
|
||||||
|
|
||||||
NoteResponse::new(response.response)
|
let mut resp = NoteResponse::new(response.response).with_action(note_action);
|
||||||
.with_action(note_action)
|
if let Some(pfp_rect) = note_ui_resp.pfp_rect {
|
||||||
.with_pfp(note_ui_resp.pfp_rect)
|
resp = resp.with_pfp(pfp_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
resp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -687,7 +705,7 @@ fn get_reposted_note<'a>(ndb: &Ndb, txn: &'a Transaction, note: &Note) -> Option
|
|||||||
|
|
||||||
struct NoteUiResponse {
|
struct NoteUiResponse {
|
||||||
action: Option<NoteAction>,
|
action: Option<NoteAction>,
|
||||||
pfp_rect: egui::Rect,
|
pfp_rect: Option<egui::Rect>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PfpResponse {
|
struct PfpResponse {
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ bitflags! {
|
|||||||
|
|
||||||
/// no animation override (accessibility)
|
/// no animation override (accessibility)
|
||||||
const NoAnimations = 1 << 17;
|
const NoAnimations = 1 << 17;
|
||||||
|
|
||||||
|
/// Styled for a notification preview
|
||||||
|
const NotificationPreview = 1 << 18;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user