feat: add tracking for which signer encrypted the message (#27)

Reviewed-on: #27
Co-authored-by: Ren Amamiya <reya@lume.nu>
Co-committed-by: Ren Amamiya <reya@lume.nu>
This commit was merged in pull request #27.
This commit is contained in:
Ren Amamiya
2026-04-01 02:53:49 +00:00
committed by reya
parent 8345def015
commit d9b16aea9a
2 changed files with 43 additions and 6 deletions

View File

@@ -75,6 +75,9 @@ impl Signal {
}
}
type Dekey = bool;
type GiftWrapId = EventId;
/// Chat Registry
#[derive(Debug)]
pub struct ChatRegistry {
@@ -88,7 +91,7 @@ pub struct ChatRegistry {
seens: Arc<RwLock<HashMap<EventId, HashSet<RelayUrl>>>>,
/// Mapping of unwrapped event ids to their gift wrap event ids
event_map: Arc<RwLock<HashMap<EventId, EventId>>>,
event_map: Arc<RwLock<HashMap<EventId, (GiftWrapId, Dekey)>>>,
/// Tracking the status of unwrapping gift wrap events.
tracking_flag: Arc<AtomicBool>,
@@ -191,7 +194,10 @@ impl ChatRegistry {
};
match *message {
RelayMessage::Event { event, .. } => {
RelayMessage::Event {
event,
subscription_id,
} => {
// Keep track of which relays have seen this event
{
let mut seens = seens.write().await;
@@ -214,7 +220,8 @@ impl ChatRegistry {
// Map the rumor id to the gift wrap event id for later lookup
{
let mut event_map = event_map.write().await;
event_map.insert(rumor.id.unwrap(), event.id);
let dekey = subscription_id.as_ref() == &sub_id1;
event_map.insert(rumor.id.unwrap(), (event.id, dekey));
}
// Check if the rumor has a recipient
@@ -222,8 +229,6 @@ impl ChatRegistry {
let signal =
Signal::error(event.as_ref(), "Recipient is missing");
tx.send_async(signal).await?;
continue;
}
// Check if the rumor was created after the chat was initialized (for detecting new messages)
@@ -231,6 +236,7 @@ impl ChatRegistry {
let signal = Signal::message(event.id, rumor);
tx.send_async(signal).await?;
} else {
// Mark the chat still processing new messages
status.store(true, Ordering::Release);
}
}
@@ -473,7 +479,7 @@ impl ChatRegistry {
self.event_map
.read_blocking()
.get(id)
.map(|id| self.seen_on(id))
.map(|(id, _dekey)| self.seen_on(id))
}
/// Get the relays that have seen a given gift wrap id.
@@ -485,6 +491,15 @@ impl ChatRegistry {
.unwrap_or_default()
}
/// Check if a given rumor was encrypted by the dekey.
pub fn encrypted_by_dekey(&self, id: &EventId) -> bool {
self.event_map
.read_blocking()
.get(id)
.map(|(_, dekey)| *dekey)
.unwrap_or(false)
}
/// Add a new room to the start of list.
pub fn add_room<I>(&mut self, room: I, cx: &mut Context<Self>)
where
@@ -563,6 +578,10 @@ impl ChatRegistry {
/// Reset the registry.
pub fn reset(&mut self, cx: &mut Context<Self>) {
self.rooms.clear();
self.trashes.update(cx, |this, cx| {
this.clear();
cx.notify();
});
cx.notify();
}

View File

@@ -471,6 +471,12 @@ impl ChatPanel {
self.reports_by_id.read(cx).get(id).is_some()
}
/// Check if a message was encrypted by the dekey
fn encrypted_by_dekey(&self, id: &EventId, cx: &App) -> bool {
let chat = ChatRegistry::global(cx);
chat.read(cx).encrypted_by_dekey(id)
}
/// Get all sent reports for a message by its ID
fn sent_reports(&self, id: &EventId, cx: &App) -> Option<Vec<SendReport>> {
self.reports_by_id.read(cx).get(id).cloned()
@@ -843,6 +849,7 @@ impl ChatPanel {
let replies = message.replies_to.as_slice();
let has_replies = !replies.is_empty();
let has_reports = self.has_reports(&id, cx);
let encrypted_by_dekey = self.encrypted_by_dekey(&id, cx);
// Hide avatar setting
let hide_avatar = AppSettings::get_hide_avatar(cx);
@@ -888,6 +895,17 @@ impl ChatPanel {
.text_color(cx.theme().text)
.child(author.name()),
)
.when(encrypted_by_dekey, |this| {
this.child(
Button::new(format!("dekey-{ix}"))
.icon(IconName::Shield)
.ghost()
.xsmall()
.px_4()
.tooltip("Encrypted by Dekey")
.disabled(true),
)
})
.child(message.created_at.to_human_time())
.when(has_reports, |this| {
this.child(deferred(self.render_sent_reports(&id, cx)))