Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/backend_task/identity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod add_key_to_identity;
mod load_identity;
mod load_identity_from_wallet;
mod refresh_identity;
mod refresh_loaded_identities_dpns_names;
mod register_dpns_name;
mod register_identity;
mod top_up_identity;
Expand Down Expand Up @@ -255,6 +256,7 @@ pub(crate) enum IdentityTask {
Transfer(QualifiedIdentity, Identifier, Credits, Option<KeyID>),
RegisterDpnsName(RegisterDpnsNameInput),
RefreshIdentity(QualifiedIdentity),
RefreshLoadedIdentitiesOwnedDPNSNames,
}

fn verify_key_input(
Expand Down Expand Up @@ -467,6 +469,9 @@ impl AppContext {
IdentityTask::TopUpIdentity(top_up_info) => {
self.top_up_identity(top_up_info, sender).await
}
IdentityTask::RefreshLoadedIdentitiesOwnedDPNSNames => {
self.refresh_loaded_identities_dpns_names(sender).await
}
}
}
}
85 changes: 85 additions & 0 deletions src/backend_task/identity/refresh_loaded_identities_dpns_names.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use super::BackendTaskSuccessResult;
use crate::app::TaskResult;
use crate::context::AppContext;
use crate::model::qualified_identity::DPNSNameInfo;
use dash_sdk::dpp::document::DocumentV0Getters;
use dash_sdk::dpp::identity::accessors::IdentityGettersV0;
use dash_sdk::dpp::platform_value::Value;
use dash_sdk::drive::query::{WhereClause, WhereOperator};
use dash_sdk::platform::{Document, DocumentQuery, FetchMany};
use tokio::sync::mpsc;

impl AppContext {
pub(super) async fn refresh_loaded_identities_dpns_names(
&self,
sender: mpsc::Sender<TaskResult>,
) -> Result<BackendTaskSuccessResult, String> {
let qualified_identities = self
.load_local_qualified_identities()
.map_err(|e| format!("Error refreshing owned DPNS names: Database error: {}", e))?;

for mut qualified_identity in qualified_identities {
let identity_id = qualified_identity.identity.id();

// Fetch DPNS names using SDK
let dpns_names_document_query = DocumentQuery {
data_contract: self.dpns_contract.clone(),
document_type_name: "domain".to_string(),
where_clauses: vec![WhereClause {
field: "records.identity".to_string(),
operator: WhereOperator::Equal,
value: Value::Identifier(identity_id.into()),
}],
order_by_clauses: vec![],
limit: 100,
start: None,
};

let owned_dpns_names = Document::fetch_many(&self.sdk, dpns_names_document_query)
.await
.map(|document_map| {
document_map
.values()
.filter_map(|maybe_doc| {
maybe_doc.as_ref().and_then(|doc| {
let name = doc
.get("normalizedLabel")
.map(|label| label.to_str().unwrap_or_default());
let acquired_at = doc
.created_at()
.into_iter()
.chain(doc.transferred_at())
.max();

match (name, acquired_at) {
(Some(name), Some(acquired_at)) => Some(DPNSNameInfo {
name: name.to_string(),
acquired_at,
}),
_ => None,
}
})
})
.collect::<Vec<DPNSNameInfo>>()
})
.map_err(|e| format!("Error refreshing owned DPNS names: {}", e))?;

qualified_identity.dpns_names = owned_dpns_names;

// Update qualified identity in the database
self.update_local_qualified_identity(&qualified_identity)
.map_err(|e| format!("Error refreshing owned DPNS names: Database error: {}", e))?;
}

sender.send(TaskResult::Refresh).await.map_err(|e| {
format!(
"Error refreshing owned DPNS names. Sender failed to send TaskResult: {}",
e.to_string()
)
})?;

Ok(BackendTaskSuccessResult::Message(
"Successfully refreshed loaded identities dpns names".to_string(),
))
}
}
97 changes: 70 additions & 27 deletions src/ui/dpns_contested_names_screen.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::components::dpns_subscreen_chooser_panel::add_dpns_subscreen_chooser_panel;
use super::components::top_panel;
use super::{Screen, ScreenType};
use crate::app::{AppAction, DesiredAppAction};
use crate::backend_task::contested_names::ContestedResourceTask;
use crate::backend_task::identity::IdentityTask;
use crate::backend_task::BackendTask;
use crate::context::AppContext;
use crate::model::contested_name::{ContestState, ContestedName};
Expand Down Expand Up @@ -60,7 +60,7 @@ pub struct DPNSContestedNamesScreen {
voting_identities: Vec<QualifiedIdentity>,
user_identities: Vec<QualifiedIdentity>,
contested_names: Arc<Mutex<Vec<ContestedName>>>,
local_dpns_names: Vec<(Identifier, DPNSNameInfo)>,
local_dpns_names: Arc<Mutex<Vec<(Identifier, DPNSNameInfo)>>>,
pub app_context: Arc<AppContext>,
error_message: Option<(String, MessageType, DateTime<Utc>)>,
sort_column: SortColumn,
Expand All @@ -83,11 +83,11 @@ impl DPNSContestedNamesScreen {
}),
DPNSSubscreen::Owned => Vec::new(),
}));
let local_dpns_names = match dpns_subscreen {
let local_dpns_names = Arc::new(Mutex::new(match dpns_subscreen {
DPNSSubscreen::Active => Vec::new(),
DPNSSubscreen::Past => Vec::new(),
DPNSSubscreen::Owned => app_context.local_dpns_names().unwrap_or_default(),
};
}));
let voting_identities = app_context
.db
.get_local_voting_identities(&app_context)
Expand All @@ -97,10 +97,10 @@ impl DPNSContestedNamesScreen {
.get_local_user_identities(&app_context)
.unwrap_or_default();
Self {
voting_identities: voting_identities,
user_identities: user_identities,
voting_identities,
user_identities,
contested_names,
local_dpns_names: local_dpns_names,
local_dpns_names,
app_context: app_context.clone(),
error_message: None,
sort_column: SortColumn::ContestedName,
Expand Down Expand Up @@ -184,8 +184,8 @@ impl DPNSContestedNamesScreen {
let now = Utc::now();
let elapsed = now.signed_duration_since(*timestamp);

// Automatically dismiss the error message after 5 seconds
if elapsed.num_seconds() > 5 {
// Automatically dismiss the error message after 10 seconds
if elapsed.num_seconds() > 10 {
self.dismiss_error();
}
}
Expand Down Expand Up @@ -237,9 +237,23 @@ impl DPNSContestedNamesScreen {
ui.label("Please check back later or try refreshing the list.");
ui.add_space(20.0);
if ui.button("Refresh").clicked() {
app_action |= AppAction::BackendTask(BackendTask::ContestedResourceTask(
ContestedResourceTask::QueryDPNSContestedResources,
));
if self.refreshing {
app_action |= AppAction::None;
} else {
match self.dpns_subscreen {
DPNSSubscreen::Active | DPNSSubscreen::Past => {
app_action |=
AppAction::BackendTask(BackendTask::ContestedResourceTask(
ContestedResourceTask::QueryDPNSContestedResources,
));
}
DPNSSubscreen::Owned => {
app_action |= AppAction::BackendTask(BackendTask::IdentityTask(
IdentityTask::RefreshLoadedIdentitiesOwnedDPNSNames,
));
}
}
}
}
});

Expand Down Expand Up @@ -577,8 +591,12 @@ impl DPNSContestedNamesScreen {
}

fn render_table_local_dpns_names(&mut self, ui: &mut Ui) {
// Clone and sort a local copy of the `local_dpns_names` vector
let mut sorted_names = self.local_dpns_names.clone();
let mut sorted_names = {
let dpns_names_guard = self.local_dpns_names.lock().unwrap();
let dpns_names = dpns_names_guard.clone();
dpns_names
};

sorted_names.sort_by(|a, b| match self.sort_column {
SortColumn::ContestedName => {
let order = a.1.name.cmp(&b.1.name); // Sort by DPNS Name
Expand Down Expand Up @@ -748,6 +766,7 @@ impl DPNSContestedNamesScreen {
impl ScreenLike for DPNSContestedNamesScreen {
fn refresh(&mut self) {
let mut contested_names = self.contested_names.lock().unwrap();
let mut dpns_names = self.local_dpns_names.lock().unwrap();
match self.dpns_subscreen {
DPNSSubscreen::Active => {
*contested_names = self
Expand All @@ -759,7 +778,7 @@ impl ScreenLike for DPNSContestedNamesScreen {
*contested_names = self.app_context.all_contested_names().unwrap_or_default();
}
DPNSSubscreen::Owned => {
self.local_dpns_names = self.app_context.local_dpns_names().unwrap_or_default();
*dpns_names = self.app_context.local_dpns_names().unwrap_or_default();
}
}
}
Expand All @@ -780,6 +799,7 @@ impl ScreenLike for DPNSContestedNamesScreen {
.into();

let mut contested_names = self.contested_names.lock().unwrap();
let mut dpns_names = self.local_dpns_names.lock().unwrap();
match self.dpns_subscreen {
DPNSSubscreen::Active => {
*contested_names = self
Expand All @@ -791,14 +811,16 @@ impl ScreenLike for DPNSContestedNamesScreen {
*contested_names = self.app_context.all_contested_names().unwrap_or_default();
}
DPNSSubscreen::Owned => {
self.local_dpns_names = self.app_context.local_dpns_names().unwrap_or_default();
*dpns_names = self.app_context.local_dpns_names().unwrap_or_default();
}
}
}

fn display_message(&mut self, message: &str, message_type: MessageType) {
if message.contains("Finished querying DPNS contested resources")
|| message.contains("Successfully refreshed loaded identities dpns names")
|| message.contains("Contested resource query failed")
|| message.contains("Error refreshing owned DPNS names")
{
self.refreshing = false;
}
Expand All @@ -807,12 +829,21 @@ impl ScreenLike for DPNSContestedNamesScreen {

fn ui(&mut self, ctx: &Context) -> AppAction {
self.check_error_expiration();
let mut top_panel_refresh_button = (
"Refresh",
DesiredAppAction::BackendTask(BackendTask::ContestedResourceTask(
ContestedResourceTask::QueryDPNSContestedResources,
)),
);
let mut top_panel_refresh_button = match self.dpns_subscreen {
DPNSSubscreen::Active | DPNSSubscreen::Past => (
"Refresh",
DesiredAppAction::BackendTask(BackendTask::ContestedResourceTask(
ContestedResourceTask::QueryDPNSContestedResources,
)),
),
DPNSSubscreen::Owned => (
"Refresh",
DesiredAppAction::BackendTask(BackendTask::IdentityTask(
IdentityTask::RefreshLoadedIdentitiesOwnedDPNSNames,
)),
),
};

if self.refreshing {
top_panel_refresh_button = ("Refreshing...", DesiredAppAction::None)
}
Expand Down Expand Up @@ -902,6 +933,11 @@ impl ScreenLike for DPNSContestedNamesScreen {
let contested_names = self.contested_names.lock().unwrap();
!contested_names.is_empty()
};
// Check if there are any owned dpns names to display
let has_dpns_names = {
let dpns_names = self.local_dpns_names.lock().unwrap();
!dpns_names.is_empty()
};

// Render the proper table
match self.dpns_subscreen {
Expand All @@ -920,7 +956,7 @@ impl ScreenLike for DPNSContestedNamesScreen {
}
}
DPNSSubscreen::Owned => {
if !self.local_dpns_names.is_empty() {
if has_dpns_names {
self.render_table_local_dpns_names(ui);
} else {
action |= self.render_no_active_contests_or_owned_names(ui);
Expand All @@ -929,12 +965,19 @@ impl ScreenLike for DPNSContestedNamesScreen {
}
});

if action
== AppAction::BackendTask(BackendTask::ContestedResourceTask(
match action {
AppAction::BackendTask(BackendTask::ContestedResourceTask(
ContestedResourceTask::QueryDPNSContestedResources,
))
{
self.refreshing = true;
| AppAction::BackendTask(BackendTask::IdentityTask(
IdentityTask::RefreshLoadedIdentitiesOwnedDPNSNames,
)) => {
self.refreshing = true;
}
AppAction::SetMainScreen(_) => {
self.refreshing = false;
}
_ => {}
}

action
Expand Down