initial navigation
This commit is contained in:
@@ -2,103 +2,69 @@ use crate::colors::PINK;
|
||||
use crate::{
|
||||
account_manager::AccountManager,
|
||||
app_style::NotedeckTextStyle,
|
||||
ui::{Preview, PreviewConfig, View},
|
||||
ui::{profile_preview_controller, Preview, PreviewConfig, View},
|
||||
Damus,
|
||||
};
|
||||
use egui::{Align, Button, Frame, Image, Layout, RichText, ScrollArea, Vec2};
|
||||
|
||||
use super::profile::preview::SimpleProfilePreview;
|
||||
use super::profile::{ProfilePreviewOp, SimpleProfilePreviewController};
|
||||
use super::profile::ProfilePreviewOp;
|
||||
|
||||
pub struct AccountManagementView<'a> {
|
||||
mobile: bool,
|
||||
account_manager: &'a mut AccountManager,
|
||||
simple_preview_controller: SimpleProfilePreviewController<'a>,
|
||||
}
|
||||
pub struct AccountManagementView {}
|
||||
|
||||
impl<'a> View for AccountManagementView<'a> {
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
if self.mobile {
|
||||
self.show_mobile(ui);
|
||||
} else {
|
||||
self.show(ui);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AccountManagementView<'a> {
|
||||
pub fn new(
|
||||
mobile: bool,
|
||||
account_manager: &'a mut AccountManager,
|
||||
simple_preview_controller: SimpleProfilePreviewController<'a>,
|
||||
) -> Self {
|
||||
AccountManagementView {
|
||||
mobile,
|
||||
account_manager,
|
||||
simple_preview_controller,
|
||||
}
|
||||
}
|
||||
|
||||
fn show(&mut self, ui: &mut egui::Ui) {
|
||||
impl AccountManagementView {
|
||||
fn show(app: &mut Damus, ui: &mut egui::Ui) {
|
||||
Frame::none().outer_margin(24.0).show(ui, |ui| {
|
||||
self.top_section_buttons_widget(ui);
|
||||
Self::top_section_buttons_widget(ui);
|
||||
ui.add_space(8.0);
|
||||
scroll_area().show(ui, |ui| {
|
||||
self.show_accounts(ui);
|
||||
Self::show_accounts(app, ui);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn show_accounts(&mut self, ui: &mut egui::Ui) {
|
||||
let maybe_remove = self.simple_preview_controller.set_profile_previews(
|
||||
self.account_manager,
|
||||
ui,
|
||||
account_card_ui(),
|
||||
);
|
||||
fn show_accounts(app: &mut Damus, ui: &mut egui::Ui) {
|
||||
let maybe_remove =
|
||||
profile_preview_controller::set_profile_previews(app, ui, account_card_ui());
|
||||
|
||||
self.maybe_remove_accounts(maybe_remove);
|
||||
Self::maybe_remove_accounts(&mut app.account_manager, maybe_remove);
|
||||
}
|
||||
|
||||
fn show_accounts_mobile(&mut self, ui: &mut egui::Ui) {
|
||||
fn show_accounts_mobile(app: &mut Damus, ui: &mut egui::Ui) {
|
||||
ui.allocate_ui_with_layout(
|
||||
Vec2::new(ui.available_size_before_wrap().x, 32.0),
|
||||
Layout::top_down(egui::Align::Min),
|
||||
|ui| {
|
||||
// create all account 'cards' and get the indicies the user requested to remove
|
||||
let maybe_remove = self.simple_preview_controller.set_profile_previews(
|
||||
self.account_manager,
|
||||
let maybe_remove = profile_preview_controller::set_profile_previews(
|
||||
app,
|
||||
ui,
|
||||
account_card_ui(), // closure for creating an account 'card'
|
||||
);
|
||||
|
||||
// remove all account indicies user requested
|
||||
self.maybe_remove_accounts(maybe_remove);
|
||||
Self::maybe_remove_accounts(&mut app.account_manager, maybe_remove);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn maybe_remove_accounts(&mut self, account_indices: Option<Vec<usize>>) {
|
||||
fn maybe_remove_accounts(manager: &mut AccountManager, account_indices: Option<Vec<usize>>) {
|
||||
if let Some(to_remove) = account_indices {
|
||||
to_remove
|
||||
.iter()
|
||||
.for_each(|index| self.account_manager.remove_account(*index));
|
||||
.for_each(|index| manager.remove_account(*index));
|
||||
}
|
||||
}
|
||||
|
||||
fn show_mobile(&mut self, ui: &mut egui::Ui) -> egui::Response {
|
||||
egui::CentralPanel::default()
|
||||
.show(ui.ctx(), |ui| {
|
||||
mobile_title(ui);
|
||||
self.top_section_buttons_widget(ui);
|
||||
fn show_mobile(app: &mut Damus, ui: &mut egui::Ui) {
|
||||
mobile_title(ui);
|
||||
Self::top_section_buttons_widget(ui);
|
||||
|
||||
ui.add_space(8.0);
|
||||
scroll_area().show(ui, |ui| {
|
||||
self.show_accounts_mobile(ui);
|
||||
});
|
||||
})
|
||||
.response
|
||||
ui.add_space(8.0);
|
||||
scroll_area().show(ui, |ui| Self::show_accounts_mobile(app, ui));
|
||||
}
|
||||
|
||||
fn top_section_buttons_widget(&mut self, ui: &mut egui::Ui) -> egui::Response {
|
||||
fn top_section_buttons_widget(ui: &mut egui::Ui) -> egui::Response {
|
||||
ui.horizontal(|ui| {
|
||||
ui.allocate_ui_with_layout(
|
||||
Vec2::new(ui.available_size_before_wrap().x, 32.0),
|
||||
@@ -233,44 +199,36 @@ fn selected_widget() -> impl egui::Widget {
|
||||
// PREVIEWS
|
||||
|
||||
mod preview {
|
||||
use nostrdb::Ndb;
|
||||
|
||||
|
||||
use super::*;
|
||||
use crate::{imgcache::ImageCache, test_data::get_accmgr_and_ndb_and_imgcache};
|
||||
use crate::test_data::get_account_manager_test_app;
|
||||
|
||||
pub struct AccountManagementPreview {
|
||||
is_mobile: bool,
|
||||
account_manager: AccountManager,
|
||||
ndb: Ndb,
|
||||
img_cache: ImageCache,
|
||||
app: Damus,
|
||||
}
|
||||
|
||||
impl AccountManagementPreview {
|
||||
fn new(is_mobile: bool) -> Self {
|
||||
let (account_manager, ndb, img_cache) = get_accmgr_and_ndb_and_imgcache();
|
||||
let app = get_account_manager_test_app(is_mobile);
|
||||
|
||||
AccountManagementPreview {
|
||||
is_mobile,
|
||||
account_manager,
|
||||
ndb,
|
||||
img_cache,
|
||||
}
|
||||
AccountManagementPreview { is_mobile, app }
|
||||
}
|
||||
}
|
||||
|
||||
impl View for AccountManagementPreview {
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.add_space(24.0);
|
||||
AccountManagementView::new(
|
||||
self.is_mobile,
|
||||
&mut self.account_manager,
|
||||
SimpleProfilePreviewController::new(&self.ndb, &mut self.img_cache),
|
||||
)
|
||||
.ui(ui);
|
||||
if self.is_mobile {
|
||||
AccountManagementView::show_mobile(&mut self.app, ui);
|
||||
} else {
|
||||
AccountManagementView::show(&mut self.app, ui);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Preview for AccountManagementView<'a> {
|
||||
impl Preview for AccountManagementView {
|
||||
type Prev = AccountManagementPreview;
|
||||
|
||||
fn preview(cfg: PreviewConfig) -> Self::Prev {
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
use crate::{
|
||||
account_manager::{AccountManager, UserAccount},
|
||||
colors::PINK,
|
||||
profile::DisplayName,
|
||||
Result,
|
||||
account_manager::UserAccount, colors::PINK, profile::DisplayName,
|
||||
ui::profile_preview_controller, Damus, Result,
|
||||
};
|
||||
|
||||
use nostrdb::Ndb;
|
||||
|
||||
use egui::{
|
||||
Align, Button, Color32, Frame, Id, Image, Layout, Margin, RichText, Rounding, ScrollArea,
|
||||
Sense, Vec2,
|
||||
};
|
||||
|
||||
use super::profile::{preview::SimpleProfilePreview, SimpleProfilePreviewController};
|
||||
use super::profile::preview::SimpleProfilePreview;
|
||||
|
||||
pub struct AccountSelectionWidget<'a> {
|
||||
is_mobile: bool,
|
||||
account_manager: &'a AccountManager,
|
||||
simple_preview_controller: SimpleProfilePreviewController<'a>,
|
||||
}
|
||||
pub struct AccountSelectionWidget {}
|
||||
|
||||
enum AccountSelectAction {
|
||||
RemoveAccount { _index: usize },
|
||||
@@ -28,36 +25,24 @@ struct AccountSelectResponse {
|
||||
action: Option<AccountSelectAction>,
|
||||
}
|
||||
|
||||
impl<'a> AccountSelectionWidget<'a> {
|
||||
pub fn new(
|
||||
is_mobile: bool,
|
||||
account_manager: &'a AccountManager,
|
||||
simple_preview_controller: SimpleProfilePreviewController<'a>,
|
||||
) -> Self {
|
||||
AccountSelectionWidget {
|
||||
is_mobile,
|
||||
account_manager,
|
||||
simple_preview_controller,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ui(&'a mut self, ui: &mut egui::Ui) {
|
||||
if self.is_mobile {
|
||||
self.show_mobile(ui);
|
||||
impl AccountSelectionWidget {
|
||||
pub fn ui(app: &mut Damus, ui: &mut egui::Ui) {
|
||||
if app.is_mobile() {
|
||||
Self::show_mobile(ui);
|
||||
} else {
|
||||
self.show(ui);
|
||||
Self::show(app, ui);
|
||||
}
|
||||
}
|
||||
|
||||
fn show(&mut self, ui: &mut egui::Ui) -> AccountSelectResponse {
|
||||
fn show(app: &mut Damus, ui: &mut egui::Ui) -> AccountSelectResponse {
|
||||
let mut res = AccountSelectResponse::default();
|
||||
let mut selected_index = self.account_manager.get_selected_account_index();
|
||||
let mut selected_index = app.account_manager.get_selected_account_index();
|
||||
|
||||
Frame::none().outer_margin(8.0).show(ui, |ui| {
|
||||
res = top_section_widget(ui);
|
||||
|
||||
scroll_area().show(ui, |ui| {
|
||||
if let Some(_index) = self.show_accounts(ui) {
|
||||
if let Some(_index) = Self::show_accounts(app, ui) {
|
||||
selected_index = Some(_index);
|
||||
res.action = Some(AccountSelectAction::SelectAccount { _index });
|
||||
}
|
||||
@@ -66,9 +51,9 @@ impl<'a> AccountSelectionWidget<'a> {
|
||||
ui.add(add_account_button());
|
||||
|
||||
if let Some(_index) = selected_index {
|
||||
if let Some(account) = self.account_manager.get_account(_index) {
|
||||
if let Some(account) = app.account_manager.get_account(_index) {
|
||||
ui.add_space(8.0);
|
||||
if self.handle_sign_out(ui, account) {
|
||||
if Self::handle_sign_out(&app.ndb, ui, account) {
|
||||
res.action = Some(AccountSelectAction::RemoveAccount { _index })
|
||||
}
|
||||
}
|
||||
@@ -80,29 +65,30 @@ impl<'a> AccountSelectionWidget<'a> {
|
||||
res
|
||||
}
|
||||
|
||||
fn handle_sign_out(&mut self, ui: &mut egui::Ui, account: &UserAccount) -> bool {
|
||||
if let Ok(response) = self.sign_out_button(ui, account) {
|
||||
fn handle_sign_out(ndb: &Ndb, ui: &mut egui::Ui, account: &UserAccount) -> bool {
|
||||
if let Ok(response) = Self::sign_out_button(ndb, ui, account) {
|
||||
response.clicked()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn show_mobile(&mut self, ui: &mut egui::Ui) -> egui::Response {
|
||||
fn show_mobile(ui: &mut egui::Ui) -> egui::Response {
|
||||
let _ = ui;
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn show_accounts(&mut self, ui: &mut egui::Ui) -> Option<usize> {
|
||||
self.simple_preview_controller.view_profile_previews(
|
||||
self.account_manager,
|
||||
ui,
|
||||
account_switcher_card_ui(),
|
||||
)
|
||||
fn show_accounts(app: &mut Damus, ui: &mut egui::Ui) -> Option<usize> {
|
||||
profile_preview_controller::view_profile_previews(app, ui, account_switcher_card_ui)
|
||||
}
|
||||
|
||||
fn sign_out_button(&self, ui: &mut egui::Ui, account: &UserAccount) -> Result<egui::Response> {
|
||||
self.simple_preview_controller.show_with_nickname(
|
||||
fn sign_out_button(
|
||||
ndb: &Ndb,
|
||||
ui: &mut egui::Ui,
|
||||
account: &UserAccount,
|
||||
) -> Result<egui::Response> {
|
||||
profile_preview_controller::show_with_nickname(
|
||||
ndb,
|
||||
ui,
|
||||
account.pubkey.bytes(),
|
||||
|ui: &mut egui::Ui, username: &DisplayName| {
|
||||
@@ -122,42 +108,40 @@ impl<'a> AccountSelectionWidget<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn account_switcher_card_ui() -> fn(
|
||||
fn account_switcher_card_ui(
|
||||
ui: &mut egui::Ui,
|
||||
preview: SimpleProfilePreview,
|
||||
width: f32,
|
||||
is_selected: bool,
|
||||
index: usize,
|
||||
) -> bool {
|
||||
|ui, preview, width, is_selected, index| {
|
||||
let resp = ui.add_sized(Vec2::new(width, 50.0), |ui: &mut egui::Ui| {
|
||||
Frame::none()
|
||||
.show(ui, |ui| {
|
||||
ui.add_space(8.0);
|
||||
ui.horizontal(|ui| {
|
||||
if is_selected {
|
||||
Frame::none()
|
||||
.rounding(Rounding::same(8.0))
|
||||
.inner_margin(Margin::same(8.0))
|
||||
.fill(Color32::from_rgb(0x45, 0x1B, 0x59))
|
||||
.show(ui, |ui| {
|
||||
ui.add(preview);
|
||||
ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
|
||||
ui.add(selection_widget());
|
||||
});
|
||||
let resp = ui.add_sized(Vec2::new(width, 50.0), |ui: &mut egui::Ui| {
|
||||
Frame::none()
|
||||
.show(ui, |ui| {
|
||||
ui.add_space(8.0);
|
||||
ui.horizontal(|ui| {
|
||||
if is_selected {
|
||||
Frame::none()
|
||||
.rounding(Rounding::same(8.0))
|
||||
.inner_margin(Margin::same(8.0))
|
||||
.fill(Color32::from_rgb(0x45, 0x1B, 0x59))
|
||||
.show(ui, |ui| {
|
||||
ui.add(preview);
|
||||
ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
|
||||
ui.add(selection_widget());
|
||||
});
|
||||
} else {
|
||||
ui.add_space(8.0);
|
||||
ui.add(preview);
|
||||
}
|
||||
});
|
||||
})
|
||||
.response
|
||||
});
|
||||
});
|
||||
} else {
|
||||
ui.add_space(8.0);
|
||||
ui.add(preview);
|
||||
}
|
||||
});
|
||||
})
|
||||
.response
|
||||
});
|
||||
|
||||
ui.interact(resp.rect, Id::new(index), Sense::click())
|
||||
.clicked()
|
||||
}
|
||||
ui.interact(resp.rect, Id::new(index), Sense::click())
|
||||
.clicked()
|
||||
}
|
||||
|
||||
fn selection_widget() -> impl egui::Widget {
|
||||
@@ -215,48 +199,33 @@ fn add_account_button() -> egui::Button<'static> {
|
||||
}
|
||||
|
||||
mod previews {
|
||||
use nostrdb::Ndb;
|
||||
|
||||
use crate::{
|
||||
account_manager::AccountManager,
|
||||
imgcache::ImageCache,
|
||||
test_data,
|
||||
ui::{profile::SimpleProfilePreviewController, Preview, PreviewConfig, View},
|
||||
ui::{Preview, PreviewConfig, View},
|
||||
Damus,
|
||||
};
|
||||
|
||||
use super::AccountSelectionWidget;
|
||||
|
||||
pub struct AccountSelectionPreview {
|
||||
is_mobile: bool,
|
||||
account_manager: AccountManager,
|
||||
ndb: Ndb,
|
||||
img_cache: ImageCache,
|
||||
app: Damus,
|
||||
}
|
||||
|
||||
impl AccountSelectionPreview {
|
||||
fn new(is_mobile: bool) -> Self {
|
||||
let (account_manager, ndb, img_cache) = test_data::get_accmgr_and_ndb_and_imgcache();
|
||||
AccountSelectionPreview {
|
||||
is_mobile,
|
||||
account_manager,
|
||||
ndb,
|
||||
img_cache,
|
||||
}
|
||||
let app = test_data::get_account_manager_test_app(is_mobile);
|
||||
AccountSelectionPreview { app }
|
||||
}
|
||||
}
|
||||
|
||||
impl View for AccountSelectionPreview {
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
AccountSelectionWidget::new(
|
||||
self.is_mobile,
|
||||
&self.account_manager,
|
||||
SimpleProfilePreviewController::new(&self.ndb, &mut self.img_cache),
|
||||
)
|
||||
.ui(ui);
|
||||
AccountSelectionWidget::show(&mut self.app, ui);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Preview for AccountSelectionWidget<'a> {
|
||||
impl Preview for AccountSelectionWidget {
|
||||
type Prev = AccountSelectionPreview;
|
||||
|
||||
fn preview(cfg: PreviewConfig) -> Self::Prev {
|
||||
|
||||
@@ -13,11 +13,11 @@ pub mod username;
|
||||
pub use account_management::AccountManagementView;
|
||||
pub use account_switcher::AccountSelectionWidget;
|
||||
pub use mention::Mention;
|
||||
pub use note::Note;
|
||||
pub use note::{BarAction, Note, NoteResponse};
|
||||
pub use preview::{Preview, PreviewApp, PreviewConfig};
|
||||
pub use profile::{ProfilePic, ProfilePreview};
|
||||
pub use profile::{profile_preview_controller, ProfilePic, ProfilePreview};
|
||||
pub use relay::RelayView;
|
||||
pub use side_panel::DesktopSidePanel;
|
||||
pub use side_panel::{DesktopSidePanel, SidePanelAction};
|
||||
pub use username::Username;
|
||||
|
||||
use egui::Margin;
|
||||
|
||||
@@ -15,12 +15,17 @@ pub struct Note<'a> {
|
||||
flags: NoteOptions,
|
||||
}
|
||||
|
||||
pub struct NoteResponse {
|
||||
pub response: egui::Response,
|
||||
pub action: Option<BarAction>,
|
||||
}
|
||||
|
||||
impl<'a> egui::Widget for Note<'a> {
|
||||
fn ui(self, ui: &mut egui::Ui) -> egui::Response {
|
||||
if self.app.textmode {
|
||||
self.textmode_ui(ui)
|
||||
} else {
|
||||
self.standard_ui(ui)
|
||||
self.show(ui).response
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,103 +191,115 @@ impl<'a> Note<'a> {
|
||||
.response
|
||||
}
|
||||
|
||||
pub fn standard_ui(self, ui: &mut egui::Ui) -> egui::Response {
|
||||
pub fn show(self, ui: &mut egui::Ui) -> NoteResponse {
|
||||
#[cfg(feature = "profiling")]
|
||||
puffin::profile_function!();
|
||||
let note_key = self.note.key().expect("todo: support non-db notes");
|
||||
let txn = self.note.txn().expect("todo: support non-db notes");
|
||||
let mut note_action: Option<BarAction> = None;
|
||||
|
||||
ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
||||
ui.spacing_mut().item_spacing.x = 16.0;
|
||||
let response = ui
|
||||
.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| {
|
||||
ui.spacing_mut().item_spacing.x = 16.0;
|
||||
|
||||
let profile = self.app.ndb.get_profile_by_pubkey(txn, self.note.pubkey());
|
||||
let profile = self.app.ndb.get_profile_by_pubkey(txn, self.note.pubkey());
|
||||
|
||||
match profile
|
||||
.as_ref()
|
||||
.ok()
|
||||
.and_then(|p| p.record().profile()?.picture())
|
||||
{
|
||||
// these have different lifetimes and types,
|
||||
// so the calls must be separate
|
||||
Some(pic) => {
|
||||
let expand_size = 5.0;
|
||||
let anim_speed = 0.05;
|
||||
let profile_key = profile.as_ref().unwrap().record().note_key();
|
||||
let note_key = note_key.as_u64();
|
||||
match profile
|
||||
.as_ref()
|
||||
.ok()
|
||||
.and_then(|p| p.record().profile()?.picture())
|
||||
{
|
||||
// these have different lifetimes and types,
|
||||
// so the calls must be separate
|
||||
Some(pic) => {
|
||||
let expand_size = 5.0;
|
||||
let anim_speed = 0.05;
|
||||
let profile_key = profile.as_ref().unwrap().record().note_key();
|
||||
let note_key = note_key.as_u64();
|
||||
|
||||
if self.app.is_mobile() {
|
||||
ui.add(ui::ProfilePic::new(&mut self.app.img_cache, pic));
|
||||
} else {
|
||||
let (rect, size) = ui::anim::hover_expand(
|
||||
ui,
|
||||
egui::Id::new(ProfileAnimId {
|
||||
profile_key,
|
||||
note_key,
|
||||
}),
|
||||
ui::ProfilePic::default_size(),
|
||||
expand_size,
|
||||
anim_speed,
|
||||
);
|
||||
if self.app.is_mobile() {
|
||||
ui.add(ui::ProfilePic::new(&mut self.app.img_cache, pic));
|
||||
} else {
|
||||
let (rect, size) = ui::anim::hover_expand(
|
||||
ui,
|
||||
egui::Id::new(ProfileAnimId {
|
||||
profile_key,
|
||||
note_key,
|
||||
}),
|
||||
ui::ProfilePic::default_size(),
|
||||
expand_size,
|
||||
anim_speed,
|
||||
);
|
||||
|
||||
ui.put(
|
||||
rect,
|
||||
ui::ProfilePic::new(&mut self.app.img_cache, pic).size(size),
|
||||
)
|
||||
.on_hover_ui_at_pointer(|ui| {
|
||||
ui.set_max_width(300.0);
|
||||
ui.add(ui::ProfilePreview::new(
|
||||
profile.as_ref().unwrap(),
|
||||
&mut self.app.img_cache,
|
||||
));
|
||||
});
|
||||
ui.put(
|
||||
rect,
|
||||
ui::ProfilePic::new(&mut self.app.img_cache, pic).size(size),
|
||||
)
|
||||
.on_hover_ui_at_pointer(|ui| {
|
||||
ui.set_max_width(300.0);
|
||||
ui.add(ui::ProfilePreview::new(
|
||||
profile.as_ref().unwrap(),
|
||||
&mut self.app.img_cache,
|
||||
));
|
||||
});
|
||||
}
|
||||
}
|
||||
None => {
|
||||
ui.add(ui::ProfilePic::new(
|
||||
&mut self.app.img_cache,
|
||||
ui::ProfilePic::no_pfp_url(),
|
||||
));
|
||||
}
|
||||
}
|
||||
None => {
|
||||
ui.add(ui::ProfilePic::new(
|
||||
&mut self.app.img_cache,
|
||||
ui::ProfilePic::no_pfp_url(),
|
||||
|
||||
ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.spacing_mut().item_spacing.x = 2.0;
|
||||
ui.add(
|
||||
ui::Username::new(profile.as_ref().ok(), self.note.pubkey())
|
||||
.abbreviated(20),
|
||||
);
|
||||
|
||||
let cached_note = self
|
||||
.app
|
||||
.note_cache_mut()
|
||||
.cached_note_or_insert_mut(note_key, self.note);
|
||||
render_reltime(ui, cached_note, true);
|
||||
});
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.spacing_mut().item_spacing.x = 2.0;
|
||||
reply_desc(ui, txn, self.app, note_key, self.note);
|
||||
});
|
||||
|
||||
ui.add(NoteContents::new(
|
||||
self.app,
|
||||
txn,
|
||||
self.note,
|
||||
note_key,
|
||||
self.options(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.spacing_mut().item_spacing.x = 2.0;
|
||||
ui.add(
|
||||
ui::Username::new(profile.as_ref().ok(), self.note.pubkey())
|
||||
.abbreviated(20),
|
||||
);
|
||||
|
||||
let cached_note = self
|
||||
.app
|
||||
.note_cache_mut()
|
||||
.cached_note_or_insert_mut(note_key, self.note);
|
||||
render_reltime(ui, cached_note, true);
|
||||
if self.options().has_actionbar() {
|
||||
note_action = render_note_actionbar(ui).inner;
|
||||
}
|
||||
});
|
||||
})
|
||||
.response;
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.spacing_mut().item_spacing.x = 2.0;
|
||||
reply_desc(ui, txn, self.app, note_key, self.note);
|
||||
});
|
||||
|
||||
ui.add(NoteContents::new(
|
||||
self.app,
|
||||
txn,
|
||||
self.note,
|
||||
note_key,
|
||||
self.options(),
|
||||
));
|
||||
|
||||
if self.options().has_actionbar() {
|
||||
render_note_actionbar(ui);
|
||||
}
|
||||
});
|
||||
})
|
||||
.response
|
||||
NoteResponse {
|
||||
response,
|
||||
action: note_action,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn render_note_actionbar(ui: &mut egui::Ui) -> egui::InnerResponse<()> {
|
||||
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||
pub enum BarAction {
|
||||
Reply,
|
||||
}
|
||||
|
||||
fn render_note_actionbar(ui: &mut egui::Ui) -> egui::InnerResponse<Option<BarAction>> {
|
||||
ui.horizontal(|ui| {
|
||||
let img_data = if ui.style().visuals.dark_mode {
|
||||
egui::include_image!("../../../assets/icons/reply.png")
|
||||
@@ -299,9 +316,11 @@ fn render_note_actionbar(ui: &mut egui::Ui) -> egui::InnerResponse<()> {
|
||||
.fill(ui.style().visuals.panel_fill),
|
||||
)
|
||||
.clicked()
|
||||
{}
|
||||
|
||||
//if ui.add(egui::Button::new("like")).clicked() {}
|
||||
{
|
||||
Some(BarAction::Reply)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
pub mod picture;
|
||||
pub mod preview;
|
||||
mod profile_preview_controller;
|
||||
pub mod profile_preview_controller;
|
||||
|
||||
pub use picture::ProfilePic;
|
||||
pub use preview::ProfilePreview;
|
||||
pub use profile_preview_controller::{ProfilePreviewOp, SimpleProfilePreviewController};
|
||||
pub use profile_preview_controller::ProfilePreviewOp;
|
||||
|
||||
@@ -1,168 +1,155 @@
|
||||
use nostrdb::{Ndb, Transaction};
|
||||
|
||||
use crate::{account_manager::AccountManager, imgcache::ImageCache, DisplayName, Result};
|
||||
use crate::{Damus, DisplayName, Result};
|
||||
|
||||
use super::{
|
||||
preview::{get_display_name, get_profile_url, SimpleProfilePreview},
|
||||
ProfilePic,
|
||||
};
|
||||
|
||||
pub struct SimpleProfilePreviewController<'a> {
|
||||
ndb: &'a Ndb,
|
||||
img_cache: &'a mut ImageCache,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ProfilePreviewOp {
|
||||
RemoveAccount,
|
||||
SwitchTo,
|
||||
}
|
||||
|
||||
impl<'a> SimpleProfilePreviewController<'a> {
|
||||
pub fn new(ndb: &'a Ndb, img_cache: &'a mut ImageCache) -> Self {
|
||||
SimpleProfilePreviewController { ndb, img_cache }
|
||||
}
|
||||
|
||||
pub fn set_profile_previews(
|
||||
&mut self,
|
||||
account_manager: &mut AccountManager,
|
||||
pub fn set_profile_previews(
|
||||
app: &mut Damus,
|
||||
ui: &mut egui::Ui,
|
||||
add_preview_ui: fn(
|
||||
ui: &mut egui::Ui,
|
||||
add_preview_ui: fn(
|
||||
ui: &mut egui::Ui,
|
||||
preview: SimpleProfilePreview,
|
||||
width: f32,
|
||||
is_selected: bool,
|
||||
) -> Option<ProfilePreviewOp>,
|
||||
) -> Option<Vec<usize>> {
|
||||
let mut to_remove: Option<Vec<usize>> = None;
|
||||
preview: SimpleProfilePreview,
|
||||
width: f32,
|
||||
is_selected: bool,
|
||||
) -> Option<ProfilePreviewOp>,
|
||||
) -> Option<Vec<usize>> {
|
||||
let mut to_remove: Option<Vec<usize>> = None;
|
||||
|
||||
let width = ui.available_width();
|
||||
let width = ui.available_width();
|
||||
|
||||
let txn = if let Ok(txn) = Transaction::new(self.ndb) {
|
||||
txn
|
||||
let txn = if let Ok(txn) = Transaction::new(&app.ndb) {
|
||||
txn
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
|
||||
for i in 0..app.account_manager.num_accounts() {
|
||||
let account = if let Some(account) = app.account_manager.get_account(i) {
|
||||
account
|
||||
} else {
|
||||
return None;
|
||||
continue;
|
||||
};
|
||||
|
||||
for i in 0..account_manager.num_accounts() {
|
||||
let account = if let Some(account) = account_manager.get_account(i) {
|
||||
account
|
||||
let profile =
|
||||
if let Ok(profile) = app.ndb.get_profile_by_pubkey(&txn, account.pubkey.bytes()) {
|
||||
profile
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let profile =
|
||||
if let Ok(profile) = self.ndb.get_profile_by_pubkey(&txn, account.pubkey.bytes()) {
|
||||
profile
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
let preview = SimpleProfilePreview::new(&profile, &mut app.img_cache);
|
||||
|
||||
let preview = SimpleProfilePreview::new(&profile, self.img_cache);
|
||||
let is_selected = if let Some(selected) = app.account_manager.get_selected_account_index() {
|
||||
i == selected
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let is_selected = if let Some(selected) = account_manager.get_selected_account_index() {
|
||||
i == selected
|
||||
} else {
|
||||
false
|
||||
};
|
||||
let op = if let Some(op) = add_preview_ui(ui, preview, width, is_selected) {
|
||||
op
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let op = if let Some(op) = add_preview_ui(ui, preview, width, is_selected) {
|
||||
op
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
match op {
|
||||
ProfilePreviewOp::RemoveAccount => {
|
||||
if to_remove.is_none() {
|
||||
to_remove = Some(Vec::new());
|
||||
}
|
||||
to_remove.as_mut().unwrap().push(i);
|
||||
match op {
|
||||
ProfilePreviewOp::RemoveAccount => {
|
||||
if to_remove.is_none() {
|
||||
to_remove = Some(Vec::new());
|
||||
}
|
||||
ProfilePreviewOp::SwitchTo => account_manager.select_account(i),
|
||||
to_remove.as_mut().unwrap().push(i);
|
||||
}
|
||||
ProfilePreviewOp::SwitchTo => app.account_manager.select_account(i),
|
||||
}
|
||||
|
||||
to_remove
|
||||
}
|
||||
|
||||
pub fn view_profile_previews(
|
||||
&mut self,
|
||||
account_manager: &AccountManager,
|
||||
ui: &mut egui::Ui,
|
||||
add_preview_ui: fn(
|
||||
ui: &mut egui::Ui,
|
||||
preview: SimpleProfilePreview,
|
||||
width: f32,
|
||||
is_selected: bool,
|
||||
index: usize,
|
||||
) -> bool,
|
||||
) -> Option<usize> {
|
||||
let width = ui.available_width();
|
||||
to_remove
|
||||
}
|
||||
|
||||
let txn = if let Ok(txn) = Transaction::new(self.ndb) {
|
||||
txn
|
||||
pub fn view_profile_previews(
|
||||
app: &mut Damus,
|
||||
ui: &mut egui::Ui,
|
||||
add_preview_ui: fn(
|
||||
ui: &mut egui::Ui,
|
||||
preview: SimpleProfilePreview,
|
||||
width: f32,
|
||||
is_selected: bool,
|
||||
index: usize,
|
||||
) -> bool,
|
||||
) -> Option<usize> {
|
||||
let width = ui.available_width();
|
||||
|
||||
let txn = if let Ok(txn) = Transaction::new(&app.ndb) {
|
||||
txn
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
|
||||
for i in 0..app.account_manager.num_accounts() {
|
||||
let account = if let Some(account) = app.account_manager.get_account(i) {
|
||||
account
|
||||
} else {
|
||||
return None;
|
||||
continue;
|
||||
};
|
||||
|
||||
for i in 0..account_manager.num_accounts() {
|
||||
let account = if let Some(account) = account_manager.get_account(i) {
|
||||
account
|
||||
let profile =
|
||||
if let Ok(profile) = app.ndb.get_profile_by_pubkey(&txn, account.pubkey.bytes()) {
|
||||
profile
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let profile =
|
||||
if let Ok(profile) = self.ndb.get_profile_by_pubkey(&txn, account.pubkey.bytes()) {
|
||||
profile
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
let preview = SimpleProfilePreview::new(&profile, &mut app.img_cache);
|
||||
|
||||
let preview = SimpleProfilePreview::new(&profile, self.img_cache);
|
||||
let is_selected = if let Some(selected) = app.account_manager.get_selected_account_index() {
|
||||
i == selected
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let is_selected = if let Some(selected) = account_manager.get_selected_account_index() {
|
||||
i == selected
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if add_preview_ui(ui, preview, width, is_selected, i) {
|
||||
return Some(i);
|
||||
}
|
||||
if add_preview_ui(ui, preview, width, is_selected, i) {
|
||||
return Some(i);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn show_with_nickname(
|
||||
&self,
|
||||
ui: &mut egui::Ui,
|
||||
key: &[u8; 32],
|
||||
ui_element: fn(ui: &mut egui::Ui, username: &DisplayName) -> egui::Response,
|
||||
) -> Result<egui::Response> {
|
||||
let txn = Transaction::new(self.ndb)?;
|
||||
let profile = self.ndb.get_profile_by_pubkey(&txn, key)?;
|
||||
Ok(ui_element(ui, &get_display_name(&profile)))
|
||||
}
|
||||
|
||||
pub fn show_with_pfp(
|
||||
self,
|
||||
ui: &mut egui::Ui,
|
||||
key: &[u8; 32],
|
||||
ui_element: fn(ui: &mut egui::Ui, pfp: ProfilePic) -> egui::Response,
|
||||
) -> Option<egui::Response> {
|
||||
if let Ok(txn) = Transaction::new(self.ndb) {
|
||||
let profile = self.ndb.get_profile_by_pubkey(&txn, key);
|
||||
|
||||
if let Ok(profile) = profile {
|
||||
return Some(ui_element(
|
||||
ui,
|
||||
ProfilePic::new(self.img_cache, get_profile_url(&profile)),
|
||||
));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn show_with_nickname(
|
||||
ndb: &Ndb,
|
||||
ui: &mut egui::Ui,
|
||||
key: &[u8; 32],
|
||||
ui_element: fn(ui: &mut egui::Ui, username: &DisplayName) -> egui::Response,
|
||||
) -> Result<egui::Response> {
|
||||
let txn = Transaction::new(ndb)?;
|
||||
let profile = ndb.get_profile_by_pubkey(&txn, key)?;
|
||||
Ok(ui_element(ui, &get_display_name(&profile)))
|
||||
}
|
||||
|
||||
pub fn show_with_pfp(
|
||||
app: &mut Damus,
|
||||
ui: &mut egui::Ui,
|
||||
key: &[u8; 32],
|
||||
ui_element: fn(ui: &mut egui::Ui, pfp: ProfilePic) -> egui::Response,
|
||||
) -> Option<egui::Response> {
|
||||
if let Ok(txn) = Transaction::new(&app.ndb) {
|
||||
let profile = app.ndb.get_profile_by_pubkey(&txn, key);
|
||||
|
||||
if let Ok(profile) = profile {
|
||||
return Some(ui_element(
|
||||
ui,
|
||||
ProfilePic::new(&mut app.img_cache, get_profile_url(&profile)),
|
||||
));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
use egui::{Button, Layout, SidePanel, Vec2, Widget};
|
||||
|
||||
use crate::account_manager::AccountManager;
|
||||
use crate::{ui::profile_preview_controller, Damus};
|
||||
|
||||
use super::{profile::SimpleProfilePreviewController, ProfilePic, View};
|
||||
use super::{ProfilePic, View};
|
||||
|
||||
pub struct DesktopSidePanel<'a> {
|
||||
selected_account: Option<&'a [u8; 32]>,
|
||||
simple_preview_controller: SimpleProfilePreviewController<'a>,
|
||||
app: &'a mut Damus,
|
||||
}
|
||||
|
||||
impl<'a> View for DesktopSidePanel<'a> {
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
self.show(ui);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
|
||||
@@ -28,21 +33,9 @@ impl SidePanelResponse {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Widget for DesktopSidePanel<'a> {
|
||||
fn ui(self, ui: &mut egui::Ui) -> egui::Response {
|
||||
self.show(ui).response
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DesktopSidePanel<'a> {
|
||||
pub fn new(
|
||||
selected_account: Option<&'a [u8; 32]>,
|
||||
simple_preview_controller: SimpleProfilePreviewController<'a>,
|
||||
) -> Self {
|
||||
DesktopSidePanel {
|
||||
selected_account,
|
||||
simple_preview_controller,
|
||||
}
|
||||
pub fn new(app: &'a mut Damus) -> Self {
|
||||
DesktopSidePanel { app }
|
||||
}
|
||||
|
||||
pub fn panel() -> SidePanel {
|
||||
@@ -51,7 +44,7 @@ impl<'a> DesktopSidePanel<'a> {
|
||||
.exact_width(40.0)
|
||||
}
|
||||
|
||||
pub fn show(self, ui: &mut egui::Ui) -> SidePanelResponse {
|
||||
pub fn show(&mut self, ui: &mut egui::Ui) -> SidePanelResponse {
|
||||
let dark_mode = ui.ctx().style().visuals.dark_mode;
|
||||
let spacing_amt = 16.0;
|
||||
|
||||
@@ -77,12 +70,15 @@ impl<'a> DesktopSidePanel<'a> {
|
||||
SidePanelResponse::new(inner.inner, inner.response)
|
||||
}
|
||||
|
||||
fn pfp_button(self, ui: &mut egui::Ui) -> egui::Response {
|
||||
if let Some(selected_account) = self.selected_account {
|
||||
if let Some(response) =
|
||||
self.simple_preview_controller
|
||||
.show_with_pfp(ui, selected_account, show_pfp())
|
||||
{
|
||||
fn pfp_button(&mut self, ui: &mut egui::Ui) -> egui::Response {
|
||||
let selected_account = self.app.account_manager.get_selected_account();
|
||||
if let Some(selected_account) = selected_account {
|
||||
if let Some(response) = profile_preview_controller::show_with_pfp(
|
||||
self.app,
|
||||
ui,
|
||||
&selected_account.pubkey.bytes().clone(),
|
||||
show_pfp(),
|
||||
) {
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -123,10 +119,9 @@ fn add_column_button(dark_mode: bool) -> egui::Button<'static> {
|
||||
}
|
||||
|
||||
mod preview {
|
||||
use nostrdb::Ndb;
|
||||
|
||||
|
||||
use crate::{
|
||||
imgcache::ImageCache,
|
||||
test_data,
|
||||
ui::{Preview, PreviewConfig},
|
||||
};
|
||||
@@ -134,33 +129,25 @@ mod preview {
|
||||
use super::*;
|
||||
|
||||
pub struct DesktopSidePanelPreview {
|
||||
account_manager: AccountManager,
|
||||
ndb: Ndb,
|
||||
img_cache: ImageCache,
|
||||
app: Damus,
|
||||
}
|
||||
|
||||
impl DesktopSidePanelPreview {
|
||||
fn new() -> Self {
|
||||
let (account_manager, ndb, img_cache) = test_data::get_accmgr_and_ndb_and_imgcache();
|
||||
DesktopSidePanelPreview {
|
||||
account_manager,
|
||||
ndb,
|
||||
img_cache,
|
||||
}
|
||||
fn new(is_mobile: bool) -> Self {
|
||||
let app = test_data::get_account_manager_test_app(is_mobile);
|
||||
DesktopSidePanelPreview { app }
|
||||
}
|
||||
}
|
||||
|
||||
impl View for DesktopSidePanelPreview {
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
let selected_account = self
|
||||
let _selected_account = self
|
||||
.app
|
||||
.account_manager
|
||||
.get_selected_account()
|
||||
.map(|x| x.pubkey.bytes());
|
||||
|
||||
let panel = DesktopSidePanel::new(
|
||||
selected_account,
|
||||
SimpleProfilePreviewController::new(&self.ndb, &mut self.img_cache),
|
||||
);
|
||||
let mut panel = DesktopSidePanel::new(&mut self.app);
|
||||
|
||||
DesktopSidePanel::panel().show(ui.ctx(), |ui| panel.ui(ui));
|
||||
}
|
||||
@@ -169,8 +156,8 @@ mod preview {
|
||||
impl<'a> Preview for DesktopSidePanel<'a> {
|
||||
type Prev = DesktopSidePanelPreview;
|
||||
|
||||
fn preview(_cfg: PreviewConfig) -> Self::Prev {
|
||||
DesktopSidePanelPreview::new()
|
||||
fn preview(cfg: PreviewConfig) -> Self::Prev {
|
||||
DesktopSidePanelPreview::new(cfg.is_mobile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user