chore: improve the activity check (#145)
* better check for activity * .
This commit is contained in:
@@ -636,12 +636,18 @@ impl ChatSpace {
|
|||||||
|
|
||||||
/// Fetches metadata for a list of public keys
|
/// Fetches metadata for a list of public keys
|
||||||
async fn fetch_metadata_for_pubkeys(public_keys: HashSet<PublicKey>) {
|
async fn fetch_metadata_for_pubkeys(public_keys: HashSet<PublicKey>) {
|
||||||
|
if public_keys.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let client = nostr_client();
|
let client = nostr_client();
|
||||||
let css = css();
|
let css = css();
|
||||||
|
|
||||||
let kinds = vec![Kind::Metadata, Kind::ContactList, Kind::RelayList];
|
let kinds = vec![Kind::Metadata, Kind::ContactList, Kind::RelayList];
|
||||||
let limit = public_keys.len() * kinds.len() + 20; // + 20 to ensure Coop has enough metadata
|
let limit = public_keys.len() * kinds.len() + 20;
|
||||||
let filter = Filter::new().limit(limit).authors(public_keys).kinds(kinds);
|
|
||||||
|
// A filter to fetch metadata
|
||||||
|
let filter = Filter::new().authors(public_keys).kinds(kinds).limit(limit);
|
||||||
|
|
||||||
client
|
client
|
||||||
.subscribe_to(BOOTSTRAP_RELAYS, filter, css.auto_close_opts)
|
.subscribe_to(BOOTSTRAP_RELAYS, filter, css.auto_close_opts)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use common::display::{shorten_pubkey, ReadableProfile};
|
use common::display::{shorten_pubkey, ReadableProfile, ReadableTimestamp};
|
||||||
use common::nip05::nip05_verify;
|
use common::nip05::nip05_verify;
|
||||||
use global::constants::BOOTSTRAP_RELAYS;
|
use global::constants::BOOTSTRAP_RELAYS;
|
||||||
use global::nostr_client;
|
use global::nostr_client;
|
||||||
@@ -30,7 +30,7 @@ pub struct Screening {
|
|||||||
verified: bool,
|
verified: bool,
|
||||||
followed: bool,
|
followed: bool,
|
||||||
dm_relays: Option<bool>,
|
dm_relays: Option<bool>,
|
||||||
active: Option<bool>,
|
last_active: Option<Timestamp>,
|
||||||
mutual_contacts: Vec<Profile>,
|
mutual_contacts: Vec<Profile>,
|
||||||
_tasks: SmallVec<[Task<()>; 4]>,
|
_tasks: SmallVec<[Task<()>; 4]>,
|
||||||
}
|
}
|
||||||
@@ -68,19 +68,15 @@ impl Screening {
|
|||||||
|
|
||||||
let activity_check = cx.background_spawn(async move {
|
let activity_check = cx.background_spawn(async move {
|
||||||
let client = nostr_client();
|
let client = nostr_client();
|
||||||
let mut activity = false;
|
let filter = Filter::new().author(public_key).limit(1);
|
||||||
|
let mut activity: Option<Timestamp> = None;
|
||||||
let filter = Filter::new()
|
|
||||||
.author(public_key)
|
|
||||||
.since(Timestamp::now() - Duration::from_secs(172800))
|
|
||||||
.limit(1);
|
|
||||||
|
|
||||||
if let Ok(mut stream) = client
|
if let Ok(mut stream) = client
|
||||||
.stream_events_from(BOOTSTRAP_RELAYS, filter, Duration::from_secs(2))
|
.stream_events_from(BOOTSTRAP_RELAYS, filter, Duration::from_secs(2))
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
while stream.next().await.is_some() {
|
while let Some(event) = stream.next().await {
|
||||||
activity = true
|
activity = Some(event.created_at);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +129,7 @@ impl Screening {
|
|||||||
let active = activity_check.await;
|
let active = activity_check.await;
|
||||||
|
|
||||||
this.update(cx, |this, cx| {
|
this.update(cx, |this, cx| {
|
||||||
this.active = Some(active);
|
this.last_active = active;
|
||||||
cx.notify();
|
cx.notify();
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
@@ -173,7 +169,7 @@ impl Screening {
|
|||||||
verified: false,
|
verified: false,
|
||||||
followed: false,
|
followed: false,
|
||||||
dm_relays: None,
|
dm_relays: None,
|
||||||
active: None,
|
last_active: None,
|
||||||
mutual_contacts: vec![],
|
mutual_contacts: vec![],
|
||||||
_tasks: tasks,
|
_tasks: tasks,
|
||||||
}
|
}
|
||||||
@@ -261,6 +257,7 @@ impl Render for Screening {
|
|||||||
let proxy = AppSettings::get_proxy_user_avatars(cx);
|
let proxy = AppSettings::get_proxy_user_avatars(cx);
|
||||||
let shorten_pubkey = shorten_pubkey(self.profile.public_key(), 8);
|
let shorten_pubkey = shorten_pubkey(self.profile.public_key(), 8);
|
||||||
let total_mutuals = self.mutual_contacts.len();
|
let total_mutuals = self.mutual_contacts.len();
|
||||||
|
let last_active = self.last_active.map(|_| true);
|
||||||
|
|
||||||
v_flex()
|
v_flex()
|
||||||
.gap_4()
|
.gap_4()
|
||||||
@@ -353,20 +350,36 @@ impl Render for Screening {
|
|||||||
.items_start()
|
.items_start()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.text_sm()
|
.text_sm()
|
||||||
.child(status_badge(self.active, cx))
|
.child(status_badge(last_active, cx))
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
.text_sm()
|
.text_sm()
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.gap_0p5()
|
||||||
.child(shared_t!("screening.active_label"))
|
.child(shared_t!("screening.active_label"))
|
||||||
|
.child(
|
||||||
|
Button::new("active")
|
||||||
|
.icon(IconName::Info)
|
||||||
|
.xsmall()
|
||||||
|
.ghost()
|
||||||
|
.rounded(ButtonRounded::Full)
|
||||||
|
.tooltip(t!("screening.active_tooltip")),
|
||||||
|
),
|
||||||
|
)
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
|
.w_full()
|
||||||
.line_clamp(1)
|
.line_clamp(1)
|
||||||
.text_color(cx.theme().text_muted)
|
.text_color(cx.theme().text_muted)
|
||||||
.child({
|
.map(|this| {
|
||||||
if self.active == Some(true) {
|
if let Some(date) = self.last_active {
|
||||||
shared_t!("screening.active")
|
this.child(shared_t!(
|
||||||
|
"screening.active_at",
|
||||||
|
d = date.to_human_time()
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
shared_t!("screening.no_active")
|
this.child(shared_t!("screening.no_active"))
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
@@ -480,7 +493,11 @@ impl Render for Screening {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn status_badge(status: Option<bool>, cx: &App) -> Div {
|
fn status_badge(status: Option<bool>, cx: &App) -> Div {
|
||||||
div().pt_1().flex_shrink_0().map(|this| {
|
h_flex()
|
||||||
|
.size_6()
|
||||||
|
.justify_center()
|
||||||
|
.flex_shrink_0()
|
||||||
|
.map(|this| {
|
||||||
if let Some(status) = status {
|
if let Some(status) = status {
|
||||||
this.child(Icon::new(IconName::CheckCircleFill).small().text_color({
|
this.child(Icon::new(IconName::CheckCircleFill).small().text_color({
|
||||||
if status {
|
if status {
|
||||||
@@ -490,7 +507,7 @@ fn status_badge(status: Option<bool>, cx: &App) -> Div {
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
this.child(Indicator::new().xsmall())
|
this.child(Indicator::new().small())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,11 +220,13 @@ screening:
|
|||||||
not_contact:
|
not_contact:
|
||||||
en: "This person is not one of your contacts."
|
en: "This person is not one of your contacts."
|
||||||
active_label:
|
active_label:
|
||||||
en: "Activity"
|
en: "Activity on Public Relays"
|
||||||
active:
|
active_tooltip:
|
||||||
en: "This person has activity in the last 2 days"
|
en: "This may be inaccurate if the user only publishes to their private relays."
|
||||||
no_active:
|
no_active:
|
||||||
en: "This person has no activity in the last 2 days"
|
en: "This person hasn't had any activity."
|
||||||
|
active_at:
|
||||||
|
en: "Last active: %{d}."
|
||||||
mutual_label:
|
mutual_label:
|
||||||
en: "Mutual contacts"
|
en: "Mutual contacts"
|
||||||
mutual:
|
mutual:
|
||||||
|
|||||||
Reference in New Issue
Block a user