render follow pack by index from virtual list

Signed-off-by: kernelkind <kernelkind@gmail.com>
This commit is contained in:
kernelkind
2025-08-25 21:16:05 -04:00
parent c06d18f76b
commit 8b5464641d
2 changed files with 91 additions and 43 deletions

View File

@@ -5,7 +5,7 @@ use nostrdb::Ndb;
use notedeck::{Images, JobPool, JobsCache, Localization}; use notedeck::{Images, JobPool, JobsCache, Localization};
use notedeck_ui::{ use notedeck_ui::{
colors, colors,
nip51_set::{Nip51SetUiCache, Nip51SetWidget, Nip51SetWidgetFlags, Nip51SetWidgetResponse}, nip51_set::{Nip51SetUiCache, Nip51SetWidget, Nip51SetWidgetAction, Nip51SetWidgetFlags},
}; };
use crate::{onboarding::Onboarding, ui::widgets::styled_button}; use crate::{onboarding::Onboarding, ui::widgets::styled_button};
@@ -71,7 +71,11 @@ impl<'a> FollowPackOnboardingView<'a> {
.max_height(max_height) .max_height(max_height)
.show(ui, |ui| { .show(ui, |ui| {
egui::Frame::new().inner_margin(8.0).show(ui, |ui| { egui::Frame::new().inner_margin(8.0).show(ui, |ui| {
if let Some(resp) = Nip51SetWidget::new( self.onboarding.list.borrow_mut().ui_custom_layout(
ui,
follow_pack_state.len(),
|ui, index| {
let resp = Nip51SetWidget::new(
follow_pack_state, follow_pack_state,
self.ui_state, self.ui_state,
self.ndb, self.ndb,
@@ -81,14 +85,23 @@ impl<'a> FollowPackOnboardingView<'a> {
self.jobs, self.jobs,
) )
.with_flags(Nip51SetWidgetFlags::TRUST_IMAGES) .with_flags(Nip51SetWidgetFlags::TRUST_IMAGES)
.ui(ui) .render_at_index(ui, index);
{
match resp { if let Some(cur_action) = resp.action {
Nip51SetWidgetResponse::ViewProfile(pubkey) => { match cur_action {
Nip51SetWidgetAction::ViewProfile(pubkey) => {
action = Some(OnboardingResponse::ViewProfile(pubkey)); action = Some(OnboardingResponse::ViewProfile(pubkey));
} }
} }
} }
if resp.rendered {
1
} else {
0
}
},
);
}) })
}); });

View File

@@ -42,7 +42,7 @@ impl Default for Nip51SetWidgetFlags {
} }
} }
pub enum Nip51SetWidgetResponse { pub enum Nip51SetWidgetAction {
ViewProfile(Pubkey), ViewProfile(Pubkey),
} }
@@ -73,21 +73,22 @@ impl<'a> Nip51SetWidget<'a> {
self self
} }
pub fn ui(&mut self, ui: &mut egui::Ui) -> Option<Nip51SetWidgetResponse> { fn render_set(&mut self, ui: &mut egui::Ui, set: &Nip51Set) -> Nip51SetWidgetResponse {
let mut resp = None; if should_skip(set, &self.flags) {
for pack in self.state.iter() { return Nip51SetWidgetResponse {
if should_skip(pack, &self.flags) { action: None,
continue; rendered: false,
};
} }
egui::Frame::new() let action = egui::Frame::new()
.corner_radius(CornerRadius::same(8)) .corner_radius(CornerRadius::same(8))
.fill(ui.visuals().extreme_bg_color) .fill(ui.visuals().extreme_bg_color)
.inner_margin(Margin::same(8)) .inner_margin(Margin::same(8))
.show(ui, |ui| { .show(ui, |ui| {
if let Some(cur_resp) = render_pack( render_pack(
ui, ui,
pack, set,
self.ui_state, self.ui_state,
self.ndb, self.ndb,
self.images, self.images,
@@ -95,10 +96,39 @@ impl<'a> Nip51SetWidget<'a> {
self.jobs, self.jobs,
self.loc, self.loc,
self.flags.contains(Nip51SetWidgetFlags::TRUST_IMAGES), self.flags.contains(Nip51SetWidgetFlags::TRUST_IMAGES),
) { )
resp = Some(cur_resp); })
.inner;
Nip51SetWidgetResponse {
action,
rendered: true,
}
}
pub fn render_at_index(&mut self, ui: &mut egui::Ui, index: usize) -> Nip51SetWidgetResponse {
let Some(set) = self.state.at_index(index) else {
return Nip51SetWidgetResponse {
action: None,
rendered: false,
};
};
self.render_set(ui, set)
}
pub fn ui(&mut self, ui: &mut egui::Ui) -> Option<Nip51SetWidgetAction> {
let mut resp = None;
for pack in self.state.iter() {
let res = self.render_set(ui, pack);
if let Some(action) = res.action {
resp = Some(action);
}
if !res.rendered {
continue;
} }
});
ui.add_space(8.0); ui.add_space(8.0);
} }
@@ -107,6 +137,11 @@ impl<'a> Nip51SetWidget<'a> {
} }
} }
pub struct Nip51SetWidgetResponse {
pub action: Option<Nip51SetWidgetAction>,
pub rendered: bool,
}
fn should_skip(set: &Nip51Set, required: &Nip51SetWidgetFlags) -> bool { fn should_skip(set: &Nip51Set, required: &Nip51SetWidgetFlags) -> bool {
(required.contains(Nip51SetWidgetFlags::REQUIRES_TITLE) && set.title.is_none()) (required.contains(Nip51SetWidgetFlags::REQUIRES_TITLE) && set.title.is_none())
|| (required.contains(Nip51SetWidgetFlags::REQUIRES_IMAGE) && set.image.is_none()) || (required.contains(Nip51SetWidgetFlags::REQUIRES_IMAGE) && set.image.is_none())
@@ -126,7 +161,7 @@ fn render_pack(
jobs: &mut JobsCache, jobs: &mut JobsCache,
loc: &mut Localization, loc: &mut Localization,
image_trusted: bool, image_trusted: bool,
) -> Option<Nip51SetWidgetResponse> { ) -> Option<Nip51SetWidgetAction> {
let max_img_size = vec2(ui.available_width(), 200.0); let max_img_size = vec2(ui.available_width(), 200.0);
ui.allocate_new_ui(UiBuilder::new(), |ui| 's: { ui.allocate_new_ui(UiBuilder::new(), |ui| 's: {
@@ -210,7 +245,7 @@ fn render_pack(
ui.separator(); ui.separator();
if render_profile_item(ui, images, m_profile.as_ref(), cur_state) { if render_profile_item(ui, images, m_profile.as_ref(), cur_state) {
resp = Some(Nip51SetWidgetResponse::ViewProfile(*pk)); resp = Some(Nip51SetWidgetAction::ViewProfile(*pk));
} }
} }