integrate EditProfileView
Signed-off-by: kernelkind <kernelkind@gmail.com>
This commit is contained in:
@@ -6,7 +6,8 @@ use crate::{
|
|||||||
deck_state::DeckState,
|
deck_state::DeckState,
|
||||||
decks::{Deck, DecksAction, DecksCache},
|
decks::{Deck, DecksAction, DecksCache},
|
||||||
notes_holder::NotesHolder,
|
notes_holder::NotesHolder,
|
||||||
profile::Profile,
|
profile::{Profile, ProfileAction, SaveProfileChanges},
|
||||||
|
profile_state::ProfileState,
|
||||||
relay_pool_manager::RelayPoolManager,
|
relay_pool_manager::RelayPoolManager,
|
||||||
route::Route,
|
route::Route,
|
||||||
thread::Thread,
|
thread::Thread,
|
||||||
@@ -21,6 +22,7 @@ use crate::{
|
|||||||
configure_deck::ConfigureDeckView,
|
configure_deck::ConfigureDeckView,
|
||||||
edit_deck::{EditDeckResponse, EditDeckView},
|
edit_deck::{EditDeckResponse, EditDeckView},
|
||||||
note::{PostAction, PostType},
|
note::{PostAction, PostType},
|
||||||
|
profile::EditProfileView,
|
||||||
support::SupportView,
|
support::SupportView,
|
||||||
RelayView, View,
|
RelayView, View,
|
||||||
},
|
},
|
||||||
@@ -39,6 +41,7 @@ pub enum RenderNavAction {
|
|||||||
RemoveColumn,
|
RemoveColumn,
|
||||||
PostAction(PostAction),
|
PostAction(PostAction),
|
||||||
NoteAction(NoteAction),
|
NoteAction(NoteAction),
|
||||||
|
ProfileAction(ProfileAction),
|
||||||
SwitchingAction(SwitchingAction),
|
SwitchingAction(SwitchingAction),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +171,15 @@ impl RenderNavResponse {
|
|||||||
RenderNavAction::SwitchingAction(switching_action) => {
|
RenderNavAction::SwitchingAction(switching_action) => {
|
||||||
switching_occured = switching_action.process(&mut app.decks_cache, ctx);
|
switching_occured = switching_action.process(&mut app.decks_cache, ctx);
|
||||||
}
|
}
|
||||||
|
RenderNavAction::ProfileAction(profile_action) => {
|
||||||
|
profile_action.process(
|
||||||
|
ctx.ndb,
|
||||||
|
ctx.pool,
|
||||||
|
get_active_columns_mut(ctx.accounts, &mut app.decks_cache)
|
||||||
|
.column_mut(col)
|
||||||
|
.router_mut(),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,6 +380,35 @@ fn render_nav_body(
|
|||||||
|
|
||||||
action
|
action
|
||||||
}
|
}
|
||||||
|
Route::EditProfile(pubkey) => {
|
||||||
|
let mut action = None;
|
||||||
|
if let Some(kp) = ctx.accounts.get_full(pubkey.bytes()) {
|
||||||
|
let state = app
|
||||||
|
.view_state
|
||||||
|
.pubkey_to_profile_state
|
||||||
|
.entry(*kp.pubkey)
|
||||||
|
.or_insert_with(|| {
|
||||||
|
let txn = Transaction::new(ctx.ndb).expect("txn");
|
||||||
|
if let Ok(record) = ctx.ndb.get_profile_by_pubkey(&txn, kp.pubkey.bytes()) {
|
||||||
|
ProfileState::from_profile(&record)
|
||||||
|
} else {
|
||||||
|
ProfileState::default()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if EditProfileView::new(state, ctx.img_cache).ui(ui) {
|
||||||
|
if let Some(taken_state) =
|
||||||
|
app.view_state.pubkey_to_profile_state.remove(kp.pubkey)
|
||||||
|
{
|
||||||
|
action = Some(RenderNavAction::ProfileAction(ProfileAction::SaveChanges(
|
||||||
|
SaveProfileChanges::new(kp.to_full(), taken_state),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error!("Pubkey in EditProfile route did not have an nsec attached in Accounts");
|
||||||
|
}
|
||||||
|
action
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
use enostr::{Filter, FullKeypair, Pubkey};
|
use enostr::{Filter, FullKeypair, Pubkey, RelayPool};
|
||||||
use nostrdb::{FilterBuilder, Ndb, Note, NoteBuilder, ProfileRecord, Transaction};
|
use nostrdb::{
|
||||||
|
FilterBuilder, Ndb, Note, NoteBuildOptions, NoteBuilder, ProfileRecord, Transaction,
|
||||||
|
};
|
||||||
|
|
||||||
use notedeck::{filter::default_limit, FilterState, MuteFun, NoteCache, NoteRef};
|
use notedeck::{filter::default_limit, FilterState, MuteFun, NoteCache, NoteRef};
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
multi_subscriber::MultiSubscriber,
|
multi_subscriber::MultiSubscriber,
|
||||||
notes_holder::NotesHolder,
|
notes_holder::NotesHolder,
|
||||||
profile_state::ProfileState,
|
profile_state::ProfileState,
|
||||||
|
route::{Route, Router},
|
||||||
timeline::{copy_notes_into_timeline, PubkeySource, Timeline, TimelineKind, TimelineTab},
|
timeline::{copy_notes_into_timeline, PubkeySource, Timeline, TimelineKind, TimelineTab},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -171,7 +175,7 @@ impl SaveProfileChanges {
|
|||||||
add_client_tag(NoteBuilder::new())
|
add_client_tag(NoteBuilder::new())
|
||||||
.kind(0)
|
.kind(0)
|
||||||
.content(&self.state.to_json())
|
.content(&self.state.to_json())
|
||||||
.sign(sec)
|
.options(NoteBuildOptions::default().created_at(true).sign(sec))
|
||||||
.build()
|
.build()
|
||||||
.expect("should build")
|
.expect("should build")
|
||||||
}
|
}
|
||||||
@@ -188,3 +192,23 @@ pub enum ProfileAction {
|
|||||||
Edit(FullKeypair),
|
Edit(FullKeypair),
|
||||||
SaveChanges(SaveProfileChanges),
|
SaveChanges(SaveProfileChanges),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ProfileAction {
|
||||||
|
pub fn process(&self, ndb: &Ndb, pool: &mut RelayPool, router: &mut Router<Route>) {
|
||||||
|
match self {
|
||||||
|
ProfileAction::Edit(kp) => {
|
||||||
|
router.route_to(Route::EditProfile(kp.pubkey));
|
||||||
|
}
|
||||||
|
ProfileAction::SaveChanges(changes) => {
|
||||||
|
let raw_msg = format!("[\"EVENT\",{}]", changes.to_note().json().unwrap());
|
||||||
|
|
||||||
|
let _ = ndb.process_client_event(raw_msg.as_str());
|
||||||
|
|
||||||
|
info!("sending {}", raw_msg);
|
||||||
|
pool.send(&enostr::ClientMessage::raw(raw_msg));
|
||||||
|
|
||||||
|
router.go_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ pub enum Route {
|
|||||||
Relays,
|
Relays,
|
||||||
ComposeNote,
|
ComposeNote,
|
||||||
AddColumn(AddColumnRoute),
|
AddColumn(AddColumnRoute),
|
||||||
|
EditProfile(Pubkey),
|
||||||
Support,
|
Support,
|
||||||
NewDeck,
|
NewDeck,
|
||||||
EditDeck(usize),
|
EditDeck(usize),
|
||||||
@@ -104,6 +105,7 @@ impl Route {
|
|||||||
Route::Support => ColumnTitle::simple("Damus Support"),
|
Route::Support => ColumnTitle::simple("Damus Support"),
|
||||||
Route::NewDeck => ColumnTitle::simple("Add Deck"),
|
Route::NewDeck => ColumnTitle::simple("Add Deck"),
|
||||||
Route::EditDeck(_) => ColumnTitle::simple("Edit Deck"),
|
Route::EditDeck(_) => ColumnTitle::simple("Edit Deck"),
|
||||||
|
Route::EditProfile(_) => ColumnTitle::simple("Edit Profile"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,6 +217,7 @@ impl fmt::Display for Route {
|
|||||||
Route::Support => write!(f, "Support"),
|
Route::Support => write!(f, "Support"),
|
||||||
Route::NewDeck => write!(f, "Add Deck"),
|
Route::NewDeck => write!(f, "Add Deck"),
|
||||||
Route::EditDeck(_) => write!(f, "Edit Deck"),
|
Route::EditDeck(_) => write!(f, "Edit Deck"),
|
||||||
|
Route::EditProfile(_) => write!(f, "Edit Profile"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -541,6 +541,11 @@ fn serialize_route(route: &Route, columns: &Columns) -> Option<String> {
|
|||||||
selections.push(Selection::Keyword(Keyword::Edit));
|
selections.push(Selection::Keyword(Keyword::Edit));
|
||||||
selections.push(Selection::Payload(index.to_string()));
|
selections.push(Selection::Payload(index.to_string()));
|
||||||
}
|
}
|
||||||
|
Route::EditProfile(pubkey) => {
|
||||||
|
selections.push(Selection::Keyword(Keyword::Profile));
|
||||||
|
selections.push(Selection::Keyword(Keyword::Edit));
|
||||||
|
selections.push(Selection::Payload(pubkey.hex()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if selections.is_empty() {
|
if selections.is_empty() {
|
||||||
@@ -649,6 +654,15 @@ fn selections_to_route(selections: Vec<Selection>) -> Option<CleanIntermediaryRo
|
|||||||
Selection::Keyword(Keyword::DeckAuthor) => Some(CleanIntermediaryRoute::ToTimeline(
|
Selection::Keyword(Keyword::DeckAuthor) => Some(CleanIntermediaryRoute::ToTimeline(
|
||||||
TimelineKind::profile(PubkeySource::DeckAuthor),
|
TimelineKind::profile(PubkeySource::DeckAuthor),
|
||||||
)),
|
)),
|
||||||
|
Selection::Keyword(Keyword::Edit) => {
|
||||||
|
if let Selection::Payload(hex) = selections.get(2)? {
|
||||||
|
Some(CleanIntermediaryRoute::ToRoute(Route::EditProfile(
|
||||||
|
Pubkey::from_hex(hex.as_str()).ok()?,
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
Selection::Keyword(Keyword::Universe) => {
|
Selection::Keyword(Keyword::Universe) => {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use crate::{
|
|||||||
draft::Drafts,
|
draft::Drafts,
|
||||||
nav::RenderNavAction,
|
nav::RenderNavAction,
|
||||||
notes_holder::NotesHolderStorage,
|
notes_holder::NotesHolderStorage,
|
||||||
profile::Profile,
|
profile::{Profile, ProfileAction},
|
||||||
thread::Thread,
|
thread::Thread,
|
||||||
timeline::{TimelineId, TimelineKind},
|
timeline::{TimelineId, TimelineKind},
|
||||||
ui::{
|
ui::{
|
||||||
@@ -117,6 +117,7 @@ pub fn render_timeline_route(
|
|||||||
|
|
||||||
TimelineRoute::Profile(pubkey) => render_profile_route(
|
TimelineRoute::Profile(pubkey) => render_profile_route(
|
||||||
&pubkey,
|
&pubkey,
|
||||||
|
accounts,
|
||||||
ndb,
|
ndb,
|
||||||
profiles,
|
profiles,
|
||||||
img_cache,
|
img_cache,
|
||||||
@@ -155,6 +156,7 @@ pub fn render_timeline_route(
|
|||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn render_profile_route(
|
pub fn render_profile_route(
|
||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
|
accounts: &Accounts,
|
||||||
ndb: &Ndb,
|
ndb: &Ndb,
|
||||||
profiles: &mut NotesHolderStorage<Profile>,
|
profiles: &mut NotesHolderStorage<Profile>,
|
||||||
img_cache: &mut ImageCache,
|
img_cache: &mut ImageCache,
|
||||||
@@ -163,8 +165,9 @@ pub fn render_profile_route(
|
|||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
is_muted: &MuteFun,
|
is_muted: &MuteFun,
|
||||||
) -> Option<RenderNavAction> {
|
) -> Option<RenderNavAction> {
|
||||||
let note_action = ProfileView::new(
|
let action = ProfileView::new(
|
||||||
pubkey,
|
pubkey,
|
||||||
|
accounts,
|
||||||
col,
|
col,
|
||||||
profiles,
|
profiles,
|
||||||
ndb,
|
ndb,
|
||||||
@@ -174,5 +177,16 @@ pub fn render_profile_route(
|
|||||||
)
|
)
|
||||||
.ui(ui, is_muted);
|
.ui(ui, is_muted);
|
||||||
|
|
||||||
note_action.map(RenderNavAction::NoteAction)
|
if let Some(action) = action {
|
||||||
|
match action {
|
||||||
|
ui::profile::ProfileViewAction::EditProfile => accounts
|
||||||
|
.get_full(pubkey.bytes())
|
||||||
|
.map(|kp| RenderNavAction::ProfileAction(ProfileAction::Edit(kp.to_full()))),
|
||||||
|
ui::profile::ProfileViewAction::Note(note_action) => {
|
||||||
|
Some(RenderNavAction::NoteAction(note_action))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,6 +256,9 @@ impl<'a> NavTitle<'a> {
|
|||||||
Route::Relays => {}
|
Route::Relays => {}
|
||||||
Route::NewDeck => {}
|
Route::NewDeck => {}
|
||||||
Route::EditDeck(_) => {}
|
Route::EditDeck(_) => {}
|
||||||
|
Route::EditProfile(pubkey) => {
|
||||||
|
self.show_profile(ui, pubkey, pfp_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,11 @@ use tracing::error;
|
|||||||
use crate::{actionbar::NoteAction, notes_holder::NotesHolderStorage, profile::Profile};
|
use crate::{actionbar::NoteAction, notes_holder::NotesHolderStorage, profile::Profile};
|
||||||
|
|
||||||
use super::timeline::{tabs_ui, TimelineTabView};
|
use super::timeline::{tabs_ui, TimelineTabView};
|
||||||
use notedeck::{ImageCache, MuteFun, NoteCache, NotedeckTextStyle};
|
use notedeck::{Accounts, ImageCache, MuteFun, NoteCache, NotedeckTextStyle};
|
||||||
|
|
||||||
pub struct ProfileView<'a> {
|
pub struct ProfileView<'a> {
|
||||||
pubkey: &'a Pubkey,
|
pubkey: &'a Pubkey,
|
||||||
|
accounts: &'a Accounts,
|
||||||
col_id: usize,
|
col_id: usize,
|
||||||
profiles: &'a mut NotesHolderStorage<Profile>,
|
profiles: &'a mut NotesHolderStorage<Profile>,
|
||||||
note_options: NoteOptions,
|
note_options: NoteOptions,
|
||||||
@@ -30,9 +31,16 @@ pub struct ProfileView<'a> {
|
|||||||
img_cache: &'a mut ImageCache,
|
img_cache: &'a mut ImageCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum ProfileViewAction {
|
||||||
|
EditProfile,
|
||||||
|
Note(NoteAction),
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> ProfileView<'a> {
|
impl<'a> ProfileView<'a> {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
pubkey: &'a Pubkey,
|
pubkey: &'a Pubkey,
|
||||||
|
accounts: &'a Accounts,
|
||||||
col_id: usize,
|
col_id: usize,
|
||||||
profiles: &'a mut NotesHolderStorage<Profile>,
|
profiles: &'a mut NotesHolderStorage<Profile>,
|
||||||
ndb: &'a Ndb,
|
ndb: &'a Ndb,
|
||||||
@@ -42,6 +50,7 @@ impl<'a> ProfileView<'a> {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
ProfileView {
|
ProfileView {
|
||||||
pubkey,
|
pubkey,
|
||||||
|
accounts,
|
||||||
col_id,
|
col_id,
|
||||||
profiles,
|
profiles,
|
||||||
ndb,
|
ndb,
|
||||||
@@ -51,15 +60,18 @@ impl<'a> ProfileView<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ui(&mut self, ui: &mut egui::Ui, is_muted: &MuteFun) -> Option<NoteAction> {
|
pub fn ui(&mut self, ui: &mut egui::Ui, is_muted: &MuteFun) -> Option<ProfileViewAction> {
|
||||||
let scroll_id = egui::Id::new(("profile_scroll", self.col_id, self.pubkey));
|
let scroll_id = egui::Id::new(("profile_scroll", self.col_id, self.pubkey));
|
||||||
|
|
||||||
ScrollArea::vertical()
|
ScrollArea::vertical()
|
||||||
.id_salt(scroll_id)
|
.id_salt(scroll_id)
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
|
let mut action = None;
|
||||||
let txn = Transaction::new(self.ndb).expect("txn");
|
let txn = Transaction::new(self.ndb).expect("txn");
|
||||||
if let Ok(profile) = self.ndb.get_profile_by_pubkey(&txn, self.pubkey.bytes()) {
|
if let Ok(profile) = self.ndb.get_profile_by_pubkey(&txn, self.pubkey.bytes()) {
|
||||||
self.profile_body(ui, profile);
|
if self.profile_body(ui, profile) {
|
||||||
|
action = Some(ProfileViewAction::EditProfile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let profile = self
|
let profile = self
|
||||||
.profiles
|
.profiles
|
||||||
@@ -82,7 +94,7 @@ impl<'a> ProfileView<'a> {
|
|||||||
|
|
||||||
let reversed = false;
|
let reversed = false;
|
||||||
|
|
||||||
TimelineTabView::new(
|
if let Some(note_action) = TimelineTabView::new(
|
||||||
profile.timeline.current_view(),
|
profile.timeline.current_view(),
|
||||||
reversed,
|
reversed,
|
||||||
self.note_options,
|
self.note_options,
|
||||||
@@ -92,11 +104,16 @@ impl<'a> ProfileView<'a> {
|
|||||||
self.img_cache,
|
self.img_cache,
|
||||||
)
|
)
|
||||||
.show(ui)
|
.show(ui)
|
||||||
|
{
|
||||||
|
action = Some(ProfileViewAction::Note(note_action));
|
||||||
|
}
|
||||||
|
action
|
||||||
})
|
})
|
||||||
.inner
|
.inner
|
||||||
}
|
}
|
||||||
|
|
||||||
fn profile_body(&mut self, ui: &mut egui::Ui, profile: ProfileRecord<'_>) {
|
fn profile_body(&mut self, ui: &mut egui::Ui, profile: ProfileRecord<'_>) -> bool {
|
||||||
|
let mut action = false;
|
||||||
ui.vertical(|ui| {
|
ui.vertical(|ui| {
|
||||||
banner(
|
banner(
|
||||||
ui,
|
ui,
|
||||||
@@ -129,9 +146,13 @@ impl<'a> ProfileView<'a> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.with_layout(Layout::right_to_left(egui::Align::Max), |ui| {
|
if self.accounts.contains_full_kp(self.pubkey) {
|
||||||
ui.add(edit_profile_button())
|
ui.with_layout(Layout::right_to_left(egui::Align::Max), |ui| {
|
||||||
});
|
if ui.add(edit_profile_button()).clicked() {
|
||||||
|
action = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.add_space(18.0);
|
ui.add_space(18.0);
|
||||||
@@ -163,6 +184,8 @@ impl<'a> ProfileView<'a> {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
action
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user