mirror of
https://github.com/aljazceru/notedeck.git
synced 2025-12-20 09:54:19 +01:00
migrate accounts to be referenced through pks instead of indices
Signed-off-by: kernelkind <kernelkind@gmail.com>
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
use tracing::{debug, error, info};
|
use tracing::{debug, error, info};
|
||||||
|
|
||||||
|
use crate::account::cache::AccountCache;
|
||||||
use crate::account::mute::AccountMutedData;
|
use crate::account::mute::AccountMutedData;
|
||||||
use crate::account::relay::{AccountRelayData, RelayDefaults};
|
use crate::account::relay::{AccountRelayData, RelayDefaults};
|
||||||
use crate::{AccountStorage, MuteFun, RelaySpec, SingleUnkIdAction, UnknownIds, UserAccount};
|
use crate::{AccountStorage, MuteFun, RelaySpec, SingleUnkIdAction, UserAccount};
|
||||||
use enostr::{ClientMessage, FilledKeypair, Keypair, Pubkey, RelayPool};
|
use enostr::{ClientMessage, FilledKeypair, Keypair, Pubkey, RelayPool};
|
||||||
use nostrdb::{Ndb, Note, Transaction};
|
use nostrdb::{Ndb, Note, Transaction};
|
||||||
use std::cmp::Ordering;
|
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
|
|
||||||
// TODO: remove this
|
// TODO: remove this
|
||||||
@@ -14,13 +14,11 @@ use std::sync::Arc;
|
|||||||
/// The interface for managing the user's accounts.
|
/// The interface for managing the user's accounts.
|
||||||
/// Represents all user-facing operations related to account management.
|
/// Represents all user-facing operations related to account management.
|
||||||
pub struct Accounts {
|
pub struct Accounts {
|
||||||
currently_selected_account: Option<usize>,
|
pub cache: AccountCache,
|
||||||
accounts: Vec<UserAccount>,
|
|
||||||
key_store: Option<AccountStorage>,
|
key_store: Option<AccountStorage>,
|
||||||
account_data: BTreeMap<[u8; 32], AccountData>,
|
account_data: BTreeMap<[u8; 32], AccountData>,
|
||||||
relay_defaults: RelayDefaults,
|
relay_defaults: RelayDefaults,
|
||||||
needs_relay_config: bool,
|
needs_relay_config: bool,
|
||||||
fallback: Pubkey,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Accounts {
|
impl Accounts {
|
||||||
@@ -29,21 +27,21 @@ impl Accounts {
|
|||||||
forced_relays: Vec<String>,
|
forced_relays: Vec<String>,
|
||||||
fallback: Pubkey,
|
fallback: Pubkey,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let accounts = match &key_store {
|
let (mut cache, _) = AccountCache::new(UserAccount::new(Keypair::only_pubkey(fallback)));
|
||||||
Some(keystore) => match keystore.get_accounts() {
|
if let Some(keystore) = &key_store {
|
||||||
Ok(k) => k,
|
match keystore.get_accounts() {
|
||||||
|
Ok(accounts) => {
|
||||||
|
for account in accounts {
|
||||||
|
cache.add(account);
|
||||||
|
}
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::error!("could not get keys: {e}");
|
tracing::error!("could not get keys: {e}");
|
||||||
Vec::new()
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
None => Vec::new(),
|
if let Some(selected) = keystore.get_selected_key().ok().flatten() {
|
||||||
};
|
cache.select(selected);
|
||||||
|
}
|
||||||
let currently_selected_account = if let Some(key_store) = &key_store {
|
|
||||||
get_selected_index(&accounts, key_store)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let account_data = BTreeMap::new();
|
let account_data = BTreeMap::new();
|
||||||
@@ -51,69 +49,22 @@ impl Accounts {
|
|||||||
let relay_defaults = RelayDefaults::new(forced_relays);
|
let relay_defaults = RelayDefaults::new(forced_relays);
|
||||||
|
|
||||||
Accounts {
|
Accounts {
|
||||||
currently_selected_account,
|
cache,
|
||||||
accounts,
|
|
||||||
key_store,
|
key_store,
|
||||||
account_data,
|
account_data,
|
||||||
relay_defaults,
|
relay_defaults,
|
||||||
needs_relay_config: true,
|
needs_relay_config: true,
|
||||||
fallback,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_accounts(&self) -> &Vec<UserAccount> {
|
pub fn remove_account(&mut self, pk: &Pubkey) {
|
||||||
&self.accounts
|
let Some(removed) = self.cache.remove(pk) else {
|
||||||
}
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
pub fn get_account(&self, ind: usize) -> Option<&UserAccount> {
|
|
||||||
self.accounts.get(ind)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn find_account(&self, pk: &[u8; 32]) -> Option<&UserAccount> {
|
|
||||||
self.accounts
|
|
||||||
.iter()
|
|
||||||
.find(|acc| acc.key.pubkey.bytes() == pk)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn find_account_mut(&mut self, pk: &[u8; 32]) -> Option<&mut UserAccount> {
|
|
||||||
self.accounts
|
|
||||||
.iter_mut()
|
|
||||||
.find(|acc| acc.key.pubkey.bytes() == pk)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_fallback(&mut self, fallback: Pubkey) {
|
|
||||||
self.fallback = fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn remove_account(&mut self, index: usize) {
|
|
||||||
if let Some(account) = self.accounts.get(index) {
|
|
||||||
if let Some(key_store) = &self.key_store {
|
if let Some(key_store) = &self.key_store {
|
||||||
if let Err(e) = key_store.remove_key(&account.key) {
|
if let Err(e) = key_store.remove_key(&removed.key) {
|
||||||
tracing::error!("Could not remove account at index {index}: {e}");
|
tracing::error!("Could not remove account {pk}: {e}");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.accounts.remove(index);
|
|
||||||
|
|
||||||
if let Some(selected_index) = self.currently_selected_account {
|
|
||||||
match selected_index.cmp(&index) {
|
|
||||||
Ordering::Greater => {
|
|
||||||
self.select_account(selected_index - 1);
|
|
||||||
}
|
|
||||||
Ordering::Equal => {
|
|
||||||
if self.accounts.is_empty() {
|
|
||||||
// If no accounts remain, clear the selection
|
|
||||||
self.clear_selected_account();
|
|
||||||
} else if index >= self.accounts.len() {
|
|
||||||
// If the removed account was the last one, select the new last account
|
|
||||||
self.select_account(self.accounts.len() - 1);
|
|
||||||
} else {
|
|
||||||
// Otherwise, select the account at the same position
|
|
||||||
self.select_account(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ordering::Less => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,74 +73,44 @@ impl Accounts {
|
|||||||
self.needs_relay_config = true;
|
self.needs_relay_config = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn contains_account(&self, pubkey: &[u8; 32]) -> Option<ContainsAccount> {
|
|
||||||
for (index, account) in self.accounts.iter().enumerate() {
|
|
||||||
let has_pubkey = account.key.pubkey.bytes() == pubkey;
|
|
||||||
let has_nsec = account.key.secret_key.is_some();
|
|
||||||
if has_pubkey {
|
|
||||||
return Some(ContainsAccount { has_nsec, index });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn contains_full_kp(&self, pubkey: &enostr::Pubkey) -> bool {
|
pub fn contains_full_kp(&self, pubkey: &enostr::Pubkey) -> bool {
|
||||||
if let Some(contains) = self.contains_account(pubkey.bytes()) {
|
self.cache
|
||||||
contains.has_nsec
|
.get(pubkey)
|
||||||
} else {
|
.is_some_and(|u| u.key.secret_key.is_some())
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use = "UnknownIdAction's must be handled. Use .process_unknown_id_action()"]
|
#[must_use = "UnknownIdAction's must be handled. Use .process_unknown_id_action()"]
|
||||||
pub fn add_account(&mut self, key: Keypair) -> Option<AddAccountResponse> {
|
pub fn add_account(&mut self, kp: Keypair) -> Option<AddAccountResponse> {
|
||||||
let pubkey = key.pubkey;
|
let acc = if let Some(acc) = self.cache.get_mut(&kp.pubkey) {
|
||||||
let switch_to_index = if let Some(contains_acc) = self.contains_account(pubkey.bytes()) {
|
if kp.secret_key.is_none() || acc.key.secret_key.is_some() {
|
||||||
if key.secret_key.is_some() && !contains_acc.has_nsec {
|
tracing::info!("Already have account, not adding");
|
||||||
info!(
|
return None;
|
||||||
"user provided nsec, but we already have npub {}. Upgrading to nsec",
|
|
||||||
pubkey
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(key_store) = &self.key_store {
|
|
||||||
if let Err(e) = key_store.write_account(&UserAccount::new(key.clone())) {
|
|
||||||
tracing::error!("Could not add key for {:?}: {e}", key.pubkey);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.accounts[contains_acc.index].key = key;
|
acc.key = kp.clone();
|
||||||
|
AccType::Acc(&*acc)
|
||||||
} else {
|
} else {
|
||||||
info!("already have account, not adding {}", pubkey);
|
AccType::Entry(self.cache.add(UserAccount::new(kp.clone())))
|
||||||
}
|
|
||||||
contains_acc.index
|
|
||||||
} else {
|
|
||||||
info!("adding new account {}", pubkey);
|
|
||||||
if let Some(key_store) = &self.key_store {
|
|
||||||
if let Err(e) = key_store.write_account(&UserAccount::new(key.clone())) {
|
|
||||||
tracing::error!("Could not add key for {:?}: {e}", key.pubkey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.accounts.push(UserAccount::new(key));
|
|
||||||
self.accounts.len() - 1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(key_store) = &self.key_store {
|
||||||
|
if let Err(e) = key_store.write_account(acc.get_acc()) {
|
||||||
|
tracing::error!("Could not add key for {:?}: {e}", kp.pubkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Some(AddAccountResponse {
|
Some(AddAccountResponse {
|
||||||
switch_to: switch_to_index,
|
switch_to: kp.pubkey,
|
||||||
unk_id_action: SingleUnkIdAction::pubkey(pubkey),
|
unk_id_action: SingleUnkIdAction::pubkey(kp.pubkey),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the `UserAccount` via callback and save the result to disk.
|
/// Update the `UserAccount` via callback and save the result to disk.
|
||||||
/// return true if the update was successful
|
/// return true if the update was successful
|
||||||
pub fn update_current_account(&mut self, update: impl FnOnce(&mut UserAccount)) -> bool {
|
pub fn update_current_account(&mut self, update: impl FnOnce(&mut UserAccount)) -> bool {
|
||||||
{
|
let cur_account = self.get_selected_account_mut();
|
||||||
let Some(cur_account) = self.get_selected_account_mut() else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
update(cur_account);
|
update(cur_account);
|
||||||
}
|
|
||||||
|
|
||||||
let cur_acc = self.get_selected_account();
|
let cur_acc = self.get_selected_account();
|
||||||
|
|
||||||
@@ -205,19 +126,8 @@ impl Accounts {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn num_accounts(&self) -> usize {
|
pub fn selected_filled(&self) -> Option<FilledKeypair<'_>> {
|
||||||
self.accounts.len()
|
self.get_selected_account().key.to_full()
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_selected_account_index(&self) -> Option<usize> {
|
|
||||||
self.currently_selected_account
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn selected_or_first_nsec(&self) -> Option<FilledKeypair<'_>> {
|
|
||||||
self.get_selected_account()
|
|
||||||
.key
|
|
||||||
.to_full()
|
|
||||||
.or_else(|| self.accounts.iter().find_map(|a| a.key.to_full()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the selected account's pubkey as bytes. Common operation so
|
/// Get the selected account's pubkey as bytes. Common operation so
|
||||||
@@ -231,30 +141,15 @@ impl Accounts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_selected_account(&self) -> &UserAccount {
|
pub fn get_selected_account(&self) -> &UserAccount {
|
||||||
self.currently_selected_account
|
self.cache.selected()
|
||||||
.and_then(|i| self.get_account(i))
|
|
||||||
// NOTE: yeah, this is incorrect but we just need to seperate out the changes in smaller commits
|
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn selected_account_has_wallet(&self) -> bool {
|
pub fn selected_account_has_wallet(&self) -> bool {
|
||||||
self.get_selected_account().wallet.is_some()
|
self.get_selected_account().wallet.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_selected_account_mut(&mut self) -> Option<&mut UserAccount> {
|
pub fn get_selected_account_mut(&mut self) -> &mut UserAccount {
|
||||||
self.currently_selected_account
|
self.cache.selected_mut()
|
||||||
.map(|i| self.accounts.get_mut(i))?
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_account_mut_optimized(&mut self, pk: &[u8; 32]) -> Option<&mut UserAccount> {
|
|
||||||
if let Some(ind) = self.currently_selected_account {
|
|
||||||
if ind < self.accounts.len() {
|
|
||||||
return Some(&mut self.accounts[ind]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.accounts
|
|
||||||
.iter_mut()
|
|
||||||
.find(|acc| acc.key.pubkey.bytes() == pk)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_selected_account_data(&mut self) -> Option<&mut AccountData> {
|
pub fn get_selected_account_data(&mut self) -> Option<&mut AccountData> {
|
||||||
@@ -262,37 +157,21 @@ impl Accounts {
|
|||||||
self.account_data.get_mut(&account_pubkey)
|
self.account_data.get_mut(&account_pubkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_account(&mut self, index: usize) {
|
pub fn select_account(&mut self, pk: &Pubkey) {
|
||||||
if let Some(account) = self.accounts.get(index) {
|
if self.cache.select(*pk) {
|
||||||
self.currently_selected_account = Some(index);
|
|
||||||
if let Some(key_store) = &self.key_store {
|
if let Some(key_store) = &self.key_store {
|
||||||
if let Err(e) = key_store.select_key(Some(account.key.pubkey)) {
|
if let Err(e) = key_store.select_key(Some(*pk)) {
|
||||||
tracing::error!("Could not select key {:?}: {e}", account.key.pubkey);
|
tracing::error!("Could not select key {:?}: {e}", pk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_selected_account(&mut self) {
|
|
||||||
self.currently_selected_account = None;
|
|
||||||
if let Some(key_store) = &self.key_store {
|
|
||||||
if let Err(e) = key_store.select_key(None) {
|
|
||||||
tracing::error!("Could not select None key: {e}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mutefun(&self) -> Box<MuteFun> {
|
pub fn mutefun(&self) -> Box<MuteFun> {
|
||||||
if let Some(index) = self.currently_selected_account {
|
let pubkey = self.cache.selected().key.pubkey.bytes();
|
||||||
if let Some(account) = self.accounts.get(index) {
|
|
||||||
let pubkey = account.key.pubkey.bytes();
|
|
||||||
if let Some(account_data) = self.account_data.get(pubkey) {
|
if let Some(account_data) = self.account_data.get(pubkey) {
|
||||||
let muted = Arc::clone(&account_data.muted.muted);
|
let muted = Arc::clone(&account_data.muted.muted);
|
||||||
return Box::new(move |note: &Note, thread: &[u8; 32]| {
|
return Box::new(move |note: &Note, thread: &[u8; 32]| muted.is_muted(note, thread));
|
||||||
muted.is_muted(note, thread)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Box::new(|_: &Note, _: &[u8; 32]| false)
|
Box::new(|_: &Note, _: &[u8; 32]| false)
|
||||||
}
|
}
|
||||||
@@ -320,14 +199,14 @@ impl Accounts {
|
|||||||
// which have still data but are no longer in our account list (removed).
|
// which have still data but are no longer in our account list (removed).
|
||||||
fn delta_accounts(&self) -> (Vec<[u8; 32]>, Vec<[u8; 32]>) {
|
fn delta_accounts(&self) -> (Vec<[u8; 32]>, Vec<[u8; 32]>) {
|
||||||
let mut added = Vec::new();
|
let mut added = Vec::new();
|
||||||
for pubkey in self.accounts.iter().map(|a| a.key.pubkey.bytes()) {
|
for pubkey in (&self.cache).into_iter().map(|(pk, _)| pk.bytes()) {
|
||||||
if !self.account_data.contains_key(pubkey) {
|
if !self.account_data.contains_key(pubkey) {
|
||||||
added.push(*pubkey);
|
added.push(*pubkey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut removed = Vec::new();
|
let mut removed = Vec::new();
|
||||||
for pubkey in self.account_data.keys() {
|
for pubkey in self.account_data.keys() {
|
||||||
if self.contains_account(pubkey).is_none() {
|
if self.cache.get_bytes(pubkey).is_none() {
|
||||||
removed.push(*pubkey);
|
removed.push(*pubkey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -351,13 +230,6 @@ impl Accounts {
|
|||||||
self.account_data.remove(pubkey);
|
self.account_data.remove(pubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_no_accounts(&mut self, unknown_ids: &mut UnknownIds, ndb: &Ndb, txn: &Transaction) {
|
|
||||||
if let Some(resp) = self.add_account(Keypair::new(self.fallback, None)) {
|
|
||||||
resp.unk_id_action.process_action(unknown_ids, ndb, txn);
|
|
||||||
}
|
|
||||||
self.select_account(self.num_accounts() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_for_updates(&mut self, ndb: &Ndb) -> bool {
|
fn poll_for_updates(&mut self, ndb: &Ndb) -> bool {
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
for (pubkey, data) in &mut self.account_data {
|
for (pubkey, data) in &mut self.account_data {
|
||||||
@@ -396,8 +268,7 @@ impl Accounts {
|
|||||||
) {
|
) {
|
||||||
debug!(
|
debug!(
|
||||||
"updating relay configuration for currently selected {:?}",
|
"updating relay configuration for currently selected {:?}",
|
||||||
self.currently_selected_account
|
self.cache.selected().key.pubkey.hex()
|
||||||
.map(|i| hex::encode(self.accounts.get(i).unwrap().key.pubkey.bytes()))
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// If forced relays are set use them only
|
// If forced relays are set use them only
|
||||||
@@ -444,13 +315,7 @@ impl Accounts {
|
|||||||
debug!("current relays: {:?}", pool.urls());
|
debug!("current relays: {:?}", pool.urls());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(
|
pub fn update(&mut self, ndb: &mut Ndb, pool: &mut RelayPool, ctx: &egui::Context) {
|
||||||
&mut self,
|
|
||||||
ndb: &mut Ndb,
|
|
||||||
pool: &mut RelayPool,
|
|
||||||
ctx: &egui::Context,
|
|
||||||
unknown_ids: &mut UnknownIds,
|
|
||||||
) {
|
|
||||||
// IMPORTANT - This function is called in the UI update loop,
|
// IMPORTANT - This function is called in the UI update loop,
|
||||||
// make sure it is fast when idle
|
// make sure it is fast when idle
|
||||||
|
|
||||||
@@ -463,8 +328,11 @@ impl Accounts {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Do we need to deactivate any existing account subs?
|
// Do we need to deactivate any existing account subs?
|
||||||
for (ndx, account) in self.accounts.iter().enumerate() {
|
|
||||||
if Some(ndx) != self.currently_selected_account {
|
let selected = self.cache.selected();
|
||||||
|
|
||||||
|
for (pk, account) in &self.cache {
|
||||||
|
if *pk != selected.key.pubkey {
|
||||||
// this account is not currently selected
|
// this account is not currently selected
|
||||||
if let Some(data) = self.account_data.get_mut(account.key.pubkey.bytes()) {
|
if let Some(data) = self.account_data.get_mut(account.key.pubkey.bytes()) {
|
||||||
if data.relay.sub.is_some() {
|
if data.relay.sub.is_some() {
|
||||||
@@ -490,10 +358,6 @@ impl Accounts {
|
|||||||
need_reconfig = true;
|
need_reconfig = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.accounts.is_empty() {
|
|
||||||
let txn = Transaction::new(ndb).unwrap();
|
|
||||||
self.handle_no_accounts(unknown_ids, ndb, &txn);
|
|
||||||
}
|
|
||||||
// Did any accounts receive updates (ie NIP-65 relay lists)
|
// Did any accounts receive updates (ie NIP-65 relay lists)
|
||||||
need_reconfig = self.poll_for_updates(ndb) || need_reconfig;
|
need_reconfig = self.poll_for_updates(ndb) || need_reconfig;
|
||||||
|
|
||||||
@@ -516,16 +380,8 @@ impl Accounts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_full<'a>(&'a self, pubkey: &[u8; 32]) -> Option<FilledKeypair<'a>> {
|
pub fn get_full<'a>(&'a self, pubkey: &Pubkey) -> Option<FilledKeypair<'a>> {
|
||||||
if let Some(contains) = self.contains_account(pubkey) {
|
self.cache.get(pubkey).and_then(|r| r.key.to_full())
|
||||||
if contains.has_nsec {
|
|
||||||
if let Some(kp) = self.get_account(contains.index) {
|
|
||||||
return kp.key.to_full();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modify_advertised_relays(
|
fn modify_advertised_relays(
|
||||||
@@ -539,12 +395,9 @@ impl Accounts {
|
|||||||
RelayAction::Add => info!("add advertised relay \"{}\"", relay_url),
|
RelayAction::Add => info!("add advertised relay \"{}\"", relay_url),
|
||||||
RelayAction::Remove => info!("remove advertised relay \"{}\"", relay_url),
|
RelayAction::Remove => info!("remove advertised relay \"{}\"", relay_url),
|
||||||
}
|
}
|
||||||
match self.currently_selected_account {
|
|
||||||
None => error!("no account is currently selected."),
|
let selected = self.cache.selected();
|
||||||
Some(index) => match self.accounts.get(index) {
|
let key_bytes: [u8; 32] = *self.cache.selected().key.pubkey.bytes();
|
||||||
None => error!("selected account index {} is out of range.", index),
|
|
||||||
Some(keypair) => {
|
|
||||||
let key_bytes: [u8; 32] = *keypair.key.pubkey.bytes();
|
|
||||||
match self.account_data.get_mut(&key_bytes) {
|
match self.account_data.get_mut(&key_bytes) {
|
||||||
None => error!("no account data found for the provided key."),
|
None => error!("no account data found for the provided key."),
|
||||||
Some(account_data) => {
|
Some(account_data) => {
|
||||||
@@ -552,8 +405,7 @@ impl Accounts {
|
|||||||
if advertised.is_empty() {
|
if advertised.is_empty() {
|
||||||
// If the selected account has no advertised relays,
|
// If the selected account has no advertised relays,
|
||||||
// initialize with the bootstrapping set.
|
// initialize with the bootstrapping set.
|
||||||
advertised
|
advertised.extend(self.relay_defaults.bootstrap_relays.iter().cloned());
|
||||||
.extend(self.relay_defaults.bootstrap_relays.iter().cloned());
|
|
||||||
}
|
}
|
||||||
match action {
|
match action {
|
||||||
RelayAction::Add => {
|
RelayAction::Add => {
|
||||||
@@ -566,7 +418,7 @@ impl Accounts {
|
|||||||
self.needs_relay_config = true;
|
self.needs_relay_config = true;
|
||||||
|
|
||||||
// If we have the secret key publish the NIP-65 relay list
|
// If we have the secret key publish the NIP-65 relay list
|
||||||
if let Some(secretkey) = &keypair.key.secret_key {
|
if let Some(secretkey) = &selected.key.secret_key {
|
||||||
account_data
|
account_data
|
||||||
.relay
|
.relay
|
||||||
.publish_nip65_relays(&secretkey.to_secret_bytes(), pool);
|
.publish_nip65_relays(&secretkey.to_secret_bytes(), pool);
|
||||||
@@ -574,9 +426,6 @@ impl Accounts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_advertised_relay(&mut self, relay_to_add: &str, pool: &mut RelayPool) {
|
pub fn add_advertised_relay(&mut self, relay_to_add: &str, pool: &mut RelayPool) {
|
||||||
self.modify_advertised_relays(relay_to_add, pool, RelayAction::Add);
|
self.modify_advertised_relays(relay_to_add, pool, RelayAction::Add);
|
||||||
@@ -587,37 +436,31 @@ impl Accounts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum AccType<'a> {
|
||||||
|
Entry(hashbrown::hash_map::OccupiedEntry<'a, Pubkey, UserAccount>),
|
||||||
|
Acc(&'a UserAccount),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> AccType<'a> {
|
||||||
|
fn get_acc(&'a self) -> &'a UserAccount {
|
||||||
|
match self {
|
||||||
|
AccType::Entry(occupied_entry) => occupied_entry.get(),
|
||||||
|
AccType::Acc(user_account) => user_account,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum RelayAction {
|
enum RelayAction {
|
||||||
Add,
|
Add,
|
||||||
Remove,
|
Remove,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_selected_index(accounts: &[UserAccount], keystore: &AccountStorage) -> Option<usize> {
|
|
||||||
match keystore.get_selected_key() {
|
|
||||||
Ok(Some(pubkey)) => {
|
|
||||||
return accounts
|
|
||||||
.iter()
|
|
||||||
.position(|account| account.key.pubkey == pubkey);
|
|
||||||
}
|
|
||||||
Ok(None) => {}
|
|
||||||
Err(e) => error!("Error getting selected key: {}", e),
|
|
||||||
};
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct ContainsAccount {
|
|
||||||
pub has_nsec: bool,
|
|
||||||
pub index: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AccountData {
|
pub struct AccountData {
|
||||||
pub(crate) relay: AccountRelayData,
|
pub(crate) relay: AccountRelayData,
|
||||||
pub(crate) muted: AccountMutedData,
|
pub(crate) muted: AccountMutedData,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AddAccountResponse {
|
pub struct AddAccountResponse {
|
||||||
pub switch_to: usize,
|
pub switch_to: Pubkey,
|
||||||
pub unk_id_action: SingleUnkIdAction,
|
pub unk_id_action: SingleUnkIdAction,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,8 +95,7 @@ impl eframe::App for Notedeck {
|
|||||||
.on_new_frame(ctx.input(|i| i.time), frame.info().cpu_usage);
|
.on_new_frame(ctx.input(|i| i.time), frame.info().cpu_usage);
|
||||||
|
|
||||||
// handle account updates
|
// handle account updates
|
||||||
self.accounts
|
self.accounts.update(&mut self.ndb, &mut self.pool, ctx);
|
||||||
.update(&mut self.ndb, &mut self.pool, ctx, &mut self.unknown_ids);
|
|
||||||
|
|
||||||
self.zaps
|
self.zaps
|
||||||
.process(&mut self.accounts, &mut self.global_wallet, &self.ndb);
|
.process(&mut self.accounts, &mut self.global_wallet, &self.ndb);
|
||||||
@@ -179,8 +178,6 @@ impl Notedeck {
|
|||||||
|
|
||||||
let mut accounts = Accounts::new(keystore, parsed_args.relays.clone(), FALLBACK_PUBKEY());
|
let mut accounts = Accounts::new(keystore, parsed_args.relays.clone(), FALLBACK_PUBKEY());
|
||||||
|
|
||||||
let num_keys = parsed_args.keys.len();
|
|
||||||
|
|
||||||
let mut unknown_ids = UnknownIds::default();
|
let mut unknown_ids = UnknownIds::default();
|
||||||
let ndb = Ndb::new(&dbpath_str, &config).expect("ndb");
|
let ndb = Ndb::new(&dbpath_str, &config).expect("ndb");
|
||||||
|
|
||||||
@@ -195,8 +192,8 @@ impl Notedeck {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if num_keys != 0 {
|
if let Some(first) = parsed_args.keys.first() {
|
||||||
accounts.select_account(0);
|
accounts.select_account(&first.pubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountManager will setup the pool on first update
|
// AccountManager will setup the pool on first update
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
frame_history::FrameHistory, wallet::GlobalWallet, zaps::Zaps, Accounts, Args, DataPath,
|
account::accounts::Accounts, frame_history::FrameHistory, wallet::GlobalWallet, zaps::Zaps,
|
||||||
Images, JobPool, NoteCache, ThemeHandler, UnknownIds,
|
Args, DataPath, Images, JobPool, NoteCache, ThemeHandler, UnknownIds,
|
||||||
};
|
};
|
||||||
use egui_winit::clipboard::Clipboard;
|
use egui_winit::clipboard::Clipboard;
|
||||||
|
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ use tokio::sync::RwLock;
|
|||||||
use crate::{zaps::UserZapMsats, Accounts, DataPath, DefaultZapMsats, TokenHandler};
|
use crate::{zaps::UserZapMsats, Accounts, DataPath, DefaultZapMsats, TokenHandler};
|
||||||
|
|
||||||
pub fn get_wallet_for<'a>(
|
pub fn get_wallet_for<'a>(
|
||||||
accounts: &'a mut Accounts,
|
accounts: &'a Accounts,
|
||||||
global_wallet: &'a mut GlobalWallet,
|
global_wallet: &'a mut GlobalWallet,
|
||||||
account_pk: &'a [u8; 32],
|
account_pk: &'a [u8; 32],
|
||||||
) -> Option<&'a ZapWallet> {
|
) -> Option<&'a ZapWallet> {
|
||||||
let cur_acc = accounts.get_account_mut_optimized(account_pk)?;
|
let cur_acc = accounts.cache.get_bytes(account_pk)?;
|
||||||
|
|
||||||
if let Some(wallet) = &mut cur_acc.wallet {
|
if let Some(wallet) = &cur_acc.wallet {
|
||||||
return Some(wallet);
|
return Some(wallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,9 +28,7 @@ pub fn get_current_wallet<'a>(
|
|||||||
accounts: &'a mut Accounts,
|
accounts: &'a mut Accounts,
|
||||||
global_wallet: &'a mut GlobalWallet,
|
global_wallet: &'a mut GlobalWallet,
|
||||||
) -> Option<&'a mut ZapWallet> {
|
) -> Option<&'a mut ZapWallet> {
|
||||||
let Some(acc) = accounts.get_selected_account_mut() else {
|
let acc = accounts.get_selected_account_mut();
|
||||||
return global_wallet.wallet.as_mut();
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(wallet) = &mut acc.wallet else {
|
let Some(wallet) = &mut acc.wallet else {
|
||||||
return global_wallet.wallet.as_mut();
|
return global_wallet.wallet.as_mut();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use enostr::FullKeypair;
|
use enostr::{FullKeypair, Pubkey};
|
||||||
use nostrdb::{Ndb, Transaction};
|
use nostrdb::{Ndb, Transaction};
|
||||||
|
|
||||||
use notedeck::{Accounts, Images, SingleUnkIdAction, UnknownIds};
|
use notedeck::{Accounts, Images, SingleUnkIdAction, UnknownIds};
|
||||||
@@ -35,11 +35,11 @@ pub struct SwitchAccountAction {
|
|||||||
pub source_column: usize,
|
pub source_column: usize,
|
||||||
|
|
||||||
/// The account to switch to
|
/// The account to switch to
|
||||||
pub switch_to: usize,
|
pub switch_to: Pubkey,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SwitchAccountAction {
|
impl SwitchAccountAction {
|
||||||
pub fn new(source_column: usize, switch_to: usize) -> Self {
|
pub fn new(source_column: usize, switch_to: Pubkey) -> Self {
|
||||||
SwitchAccountAction {
|
SwitchAccountAction {
|
||||||
source_column,
|
source_column,
|
||||||
switch_to,
|
switch_to,
|
||||||
@@ -50,7 +50,7 @@ impl SwitchAccountAction {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum AccountsAction {
|
pub enum AccountsAction {
|
||||||
Switch(SwitchAccountAction),
|
Switch(SwitchAccountAction),
|
||||||
Remove(usize),
|
Remove(Pubkey),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use = "You must call process_login_action on this to handle unknown ids"]
|
#[must_use = "You must call process_login_action on this to handle unknown ids"]
|
||||||
@@ -120,24 +120,24 @@ pub fn process_accounts_view_response(
|
|||||||
let router = get_active_columns_mut(accounts, decks)
|
let router = get_active_columns_mut(accounts, decks)
|
||||||
.column_mut(col)
|
.column_mut(col)
|
||||||
.router_mut();
|
.router_mut();
|
||||||
let mut selection = None;
|
let mut action = None;
|
||||||
match response {
|
match response {
|
||||||
AccountsViewResponse::RemoveAccount(index) => {
|
AccountsViewResponse::RemoveAccount(pk_to_remove) => {
|
||||||
let acc_sel = AccountsAction::Remove(index);
|
let cur_action = AccountsAction::Remove(pk_to_remove);
|
||||||
info!("account selection: {:?}", acc_sel);
|
info!("account selection: {:?}", action);
|
||||||
selection = Some(acc_sel);
|
action = Some(cur_action);
|
||||||
}
|
}
|
||||||
AccountsViewResponse::SelectAccount(index) => {
|
AccountsViewResponse::SelectAccount(new_pk) => {
|
||||||
let acc_sel = AccountsAction::Switch(SwitchAccountAction::new(col, index));
|
let acc_sel = AccountsAction::Switch(SwitchAccountAction::new(col, new_pk));
|
||||||
info!("account selection: {:?}", acc_sel);
|
info!("account selection: {:?}", acc_sel);
|
||||||
selection = Some(acc_sel);
|
action = Some(acc_sel);
|
||||||
}
|
}
|
||||||
AccountsViewResponse::RouteToLogin => {
|
AccountsViewResponse::RouteToLogin => {
|
||||||
router.route_to(Route::add_account());
|
router.route_to(Route::add_account());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
accounts.needs_relay_config();
|
accounts.needs_relay_config();
|
||||||
selection
|
action
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_login_view_response(
|
pub fn process_login_view_response(
|
||||||
@@ -160,13 +160,13 @@ pub fn process_login_view_response(
|
|||||||
|
|
||||||
decks.add_deck_default(pubkey);
|
decks.add_deck_default(pubkey);
|
||||||
|
|
||||||
if let Some(resp) = r {
|
if let Some(action) = r {
|
||||||
AddAccountAction {
|
AddAccountAction {
|
||||||
accounts_action: Some(AccountsAction::Switch(SwitchAccountAction {
|
accounts_action: Some(AccountsAction::Switch(SwitchAccountAction {
|
||||||
source_column: col,
|
source_column: col,
|
||||||
switch_to: resp.switch_to,
|
switch_to: action.switch_to,
|
||||||
})),
|
})),
|
||||||
unk_id_action: resp.unk_id_action,
|
unk_id_action: action.unk_id_action,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AddAccountAction {
|
AddAccountAction {
|
||||||
|
|||||||
@@ -97,10 +97,8 @@ fn execute_note_action(
|
|||||||
NoteAction::Quote(note_id) => {
|
NoteAction::Quote(note_id) => {
|
||||||
router_action = Some(RouterAction::route_to(Route::quote(note_id)));
|
router_action = Some(RouterAction::route_to(Route::quote(note_id)));
|
||||||
}
|
}
|
||||||
NoteAction::Zap(zap_action) => 's: {
|
NoteAction::Zap(zap_action) => {
|
||||||
let Some(cur_acc) = accounts.get_selected_account_mut() else {
|
let cur_acc = accounts.get_selected_account_mut();
|
||||||
break 's;
|
|
||||||
};
|
|
||||||
|
|
||||||
let sender = cur_acc.key.pubkey;
|
let sender = cur_acc.key.pubkey;
|
||||||
|
|
||||||
|
|||||||
@@ -428,8 +428,8 @@ impl Damus {
|
|||||||
} else {
|
} else {
|
||||||
info!("DecksCache: creating new with demo configuration");
|
info!("DecksCache: creating new with demo configuration");
|
||||||
let mut cache = DecksCache::new_with_demo_config(&mut timeline_cache, ctx);
|
let mut cache = DecksCache::new_with_demo_config(&mut timeline_cache, ctx);
|
||||||
for account in ctx.accounts.get_accounts() {
|
for (pk, _) in &ctx.accounts.cache {
|
||||||
cache.add_deck_default(account.key.pubkey);
|
cache.add_deck_default(*pk);
|
||||||
}
|
}
|
||||||
set_demo(&mut cache, ctx.ndb, ctx.accounts, ctx.unknown_ids);
|
set_demo(&mut cache, ctx.ndb, ctx.accounts, ctx.unknown_ids);
|
||||||
|
|
||||||
@@ -445,8 +445,6 @@ impl Damus {
|
|||||||
|
|
||||||
let jobs = JobsCache::default();
|
let jobs = JobsCache::default();
|
||||||
|
|
||||||
ctx.accounts.with_fallback(FALLBACK_PUBKEY());
|
|
||||||
|
|
||||||
let threads = Threads::default();
|
let threads = Threads::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@@ -770,13 +768,14 @@ pub fn set_demo(
|
|||||||
accounts: &mut Accounts,
|
accounts: &mut Accounts,
|
||||||
unk_ids: &mut UnknownIds,
|
unk_ids: &mut UnknownIds,
|
||||||
) {
|
) {
|
||||||
|
let fallback = decks_cache.get_fallback_pubkey();
|
||||||
let txn = Transaction::new(ndb).expect("txn");
|
let txn = Transaction::new(ndb).expect("txn");
|
||||||
if let Some(resp) =
|
if let Some(resp) =
|
||||||
accounts.add_account(Keypair::only_pubkey(*decks_cache.get_fallback_pubkey()))
|
accounts.add_account(Keypair::only_pubkey(*decks_cache.get_fallback_pubkey()))
|
||||||
{
|
{
|
||||||
resp.unk_id_action.process_action(unk_ids, ndb, &txn);
|
resp.unk_id_action.process_action(unk_ids, ndb, &txn);
|
||||||
}
|
}
|
||||||
accounts.select_account(accounts.num_accounts() - 1);
|
accounts.select_account(fallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn columns_to_decks_cache(cols: Columns, key: &[u8; 32]) -> DecksCache {
|
fn columns_to_decks_cache(cols: Columns, key: &[u8; 32]) -> DecksCache {
|
||||||
|
|||||||
@@ -78,14 +78,14 @@ impl SwitchingAction {
|
|||||||
match &self {
|
match &self {
|
||||||
SwitchingAction::Accounts(account_action) => match account_action {
|
SwitchingAction::Accounts(account_action) => match account_action {
|
||||||
AccountsAction::Switch(switch_action) => {
|
AccountsAction::Switch(switch_action) => {
|
||||||
ctx.accounts.select_account(switch_action.switch_to);
|
ctx.accounts.select_account(&switch_action.switch_to);
|
||||||
// pop nav after switch
|
// pop nav after switch
|
||||||
get_active_columns_mut(ctx.accounts, decks_cache)
|
get_active_columns_mut(ctx.accounts, decks_cache)
|
||||||
.column_mut(switch_action.source_column)
|
.column_mut(switch_action.source_column)
|
||||||
.router_mut()
|
.router_mut()
|
||||||
.go_back();
|
.go_back();
|
||||||
}
|
}
|
||||||
AccountsAction::Remove(index) => ctx.accounts.remove_account(*index),
|
AccountsAction::Remove(to_remove) => ctx.accounts.remove_account(to_remove),
|
||||||
},
|
},
|
||||||
SwitchingAction::Columns(columns_action) => match *columns_action {
|
SwitchingAction::Columns(columns_action) => match *columns_action {
|
||||||
ColumnsAction::Remove(index) => {
|
ColumnsAction::Remove(index) => {
|
||||||
@@ -481,7 +481,7 @@ fn render_nav_body(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let id = egui::Id::new(("post", col, note.key().unwrap()));
|
let id = egui::Id::new(("post", col, note.key().unwrap()));
|
||||||
let poster = ctx.accounts.selected_or_first_nsec()?;
|
let poster = ctx.accounts.selected_filled()?;
|
||||||
|
|
||||||
let action = {
|
let action = {
|
||||||
let draft = app.drafts.reply_mut(note.id());
|
let draft = app.drafts.reply_mut(note.id());
|
||||||
@@ -519,7 +519,7 @@ fn render_nav_body(
|
|||||||
|
|
||||||
let id = egui::Id::new(("post", col, note.key().unwrap()));
|
let id = egui::Id::new(("post", col, note.key().unwrap()));
|
||||||
|
|
||||||
let poster = ctx.accounts.selected_or_first_nsec()?;
|
let poster = ctx.accounts.selected_filled()?;
|
||||||
let draft = app.drafts.quote_mut(note.id());
|
let draft = app.drafts.quote_mut(note.id());
|
||||||
|
|
||||||
let response = egui::ScrollArea::vertical()
|
let response = egui::ScrollArea::vertical()
|
||||||
@@ -656,7 +656,7 @@ fn render_nav_body(
|
|||||||
}
|
}
|
||||||
Route::EditProfile(pubkey) => {
|
Route::EditProfile(pubkey) => {
|
||||||
let mut action = None;
|
let mut action = None;
|
||||||
if let Some(kp) = ctx.accounts.get_full(pubkey.bytes()) {
|
if let Some(kp) = ctx.accounts.get_full(pubkey) {
|
||||||
let state = app
|
let state = app
|
||||||
.view_state
|
.view_state
|
||||||
.pubkey_to_profile_state
|
.pubkey_to_profile_state
|
||||||
@@ -686,16 +686,17 @@ fn render_nav_body(
|
|||||||
Route::Wallet(wallet_type) => {
|
Route::Wallet(wallet_type) => {
|
||||||
let state = match wallet_type {
|
let state = match wallet_type {
|
||||||
notedeck::WalletType::Auto => 's: {
|
notedeck::WalletType::Auto => 's: {
|
||||||
if let Some(cur_acc) = ctx.accounts.get_selected_account_mut() {
|
if let Some(cur_acc_wallet) =
|
||||||
if let Some(wallet) = &mut cur_acc.wallet {
|
&mut ctx.accounts.get_selected_account_mut().wallet
|
||||||
let default_zap_state = get_default_zap_state(&mut wallet.default_zap);
|
{
|
||||||
|
let default_zap_state =
|
||||||
|
get_default_zap_state(&mut cur_acc_wallet.default_zap);
|
||||||
break 's WalletState::Wallet {
|
break 's WalletState::Wallet {
|
||||||
wallet: &mut wallet.wallet,
|
wallet: &mut cur_acc_wallet.wallet,
|
||||||
default_zap_state,
|
default_zap_state,
|
||||||
can_create_local_wallet: false,
|
can_create_local_wallet: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let Some(wallet) = &mut ctx.global_wallet.wallet else {
|
let Some(wallet) = &mut ctx.global_wallet.wallet else {
|
||||||
break 's WalletState::NoWallet {
|
break 's WalletState::NoWallet {
|
||||||
@@ -712,12 +713,7 @@ fn render_nav_body(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
notedeck::WalletType::Local => 's: {
|
notedeck::WalletType::Local => 's: {
|
||||||
let Some(cur_acc) = ctx.accounts.get_selected_account_mut() else {
|
let cur_acc = ctx.accounts.get_selected_account_mut();
|
||||||
break 's WalletState::NoWallet {
|
|
||||||
state: &mut ctx.global_wallet.ui_state,
|
|
||||||
show_local_only: false,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
let Some(wallet) = &mut cur_acc.wallet else {
|
let Some(wallet) = &mut cur_acc.wallet else {
|
||||||
break 's WalletState::NoWallet {
|
break 's WalletState::NoWallet {
|
||||||
state: &mut ctx.global_wallet.ui_state,
|
state: &mut ctx.global_wallet.ui_state,
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ pub fn render_profile_route(
|
|||||||
if let Some(action) = action {
|
if let Some(action) = action {
|
||||||
match action {
|
match action {
|
||||||
ui::profile::ProfileViewAction::EditProfile => accounts
|
ui::profile::ProfileViewAction::EditProfile => accounts
|
||||||
.get_full(pubkey.bytes())
|
.get_full(pubkey)
|
||||||
.map(|kp| RenderNavAction::ProfileAction(ProfileAction::Edit(kp.to_full()))),
|
.map(|kp| RenderNavAction::ProfileAction(ProfileAction::Edit(kp.to_full()))),
|
||||||
ui::profile::ProfileViewAction::Note(note_action) => {
|
ui::profile::ProfileViewAction::Note(note_action) => {
|
||||||
Some(RenderNavAction::NoteAction(note_action))
|
Some(RenderNavAction::NoteAction(note_action))
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use egui::{
|
use egui::{
|
||||||
Align, Button, Frame, InnerResponse, Layout, RichText, ScrollArea, Ui, UiBuilder, Vec2,
|
Align, Button, Frame, InnerResponse, Layout, RichText, ScrollArea, Ui, UiBuilder, Vec2,
|
||||||
};
|
};
|
||||||
|
use enostr::Pubkey;
|
||||||
use nostrdb::{Ndb, Transaction};
|
use nostrdb::{Ndb, Transaction};
|
||||||
use notedeck::{Accounts, Images};
|
use notedeck::{Accounts, Images};
|
||||||
use notedeck_ui::colors::PINK;
|
use notedeck_ui::colors::PINK;
|
||||||
@@ -16,8 +17,8 @@ pub struct AccountsView<'a> {
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum AccountsViewResponse {
|
pub enum AccountsViewResponse {
|
||||||
SelectAccount(usize),
|
SelectAccount(Pubkey),
|
||||||
RemoveAccount(usize),
|
RemoveAccount(Pubkey),
|
||||||
RouteToLogin,
|
RouteToLogin,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,19 +69,11 @@ impl<'a> AccountsView<'a> {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
for i in 0..accounts.num_accounts() {
|
let selected = accounts.cache.selected();
|
||||||
let (account_pubkey, has_nsec) = match accounts.get_account(i) {
|
for (pk, account) in &accounts.cache {
|
||||||
Some(acc) => (acc.key.pubkey.bytes(), acc.key.secret_key.is_some()),
|
let profile = ndb.get_profile_by_pubkey(&txn, pk).ok();
|
||||||
None => continue,
|
let is_selected = *pk == selected.key.pubkey;
|
||||||
};
|
let has_nsec = account.key.secret_key.is_some();
|
||||||
|
|
||||||
let profile = ndb.get_profile_by_pubkey(&txn, account_pubkey).ok();
|
|
||||||
let is_selected = if let Some(selected) = accounts.get_selected_account_index()
|
|
||||||
{
|
|
||||||
i == selected
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
let profile_peview_view = {
|
let profile_peview_view = {
|
||||||
let max_size = egui::vec2(ui.available_width(), 77.0);
|
let max_size = egui::vec2(ui.available_width(), 77.0);
|
||||||
@@ -96,10 +89,10 @@ impl<'a> AccountsView<'a> {
|
|||||||
if let Some(op) = profile_peview_view {
|
if let Some(op) = profile_peview_view {
|
||||||
return_op = Some(match op {
|
return_op = Some(match op {
|
||||||
ProfilePreviewAction::SwitchTo => {
|
ProfilePreviewAction::SwitchTo => {
|
||||||
AccountsViewResponse::SelectAccount(i)
|
AccountsViewResponse::SelectAccount(*pk)
|
||||||
}
|
}
|
||||||
ProfilePreviewAction::RemoveAccount => {
|
ProfilePreviewAction::RemoveAccount => {
|
||||||
AccountsViewResponse::RemoveAccount(i)
|
AccountsViewResponse::RemoveAccount(*pk)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ impl WalletAction {
|
|||||||
let ui_state = &mut global_wallet.ui_state;
|
let ui_state = &mut global_wallet.ui_state;
|
||||||
if ui_state.for_local_only {
|
if ui_state.for_local_only {
|
||||||
ui_state.for_local_only = false;
|
ui_state.for_local_only = false;
|
||||||
let cur_acc = accounts.get_selected_account_mut()?;
|
let cur_acc = accounts.get_selected_account_mut();
|
||||||
|
|
||||||
if cur_acc.wallet.is_some() {
|
if cur_acc.wallet.is_some() {
|
||||||
return None;
|
return None;
|
||||||
|
|||||||
Reference in New Issue
Block a user