chore: Improve Request Screening (#101)

* open chat while screening

* close panel on ignore

* bypass screening

* .

* improve settings

* refine modal

* .

* .

* .

* .

* .
This commit is contained in:
reya
2025-07-27 07:22:31 +07:00
committed by GitHub
parent 91cca37d69
commit 3cf9dde882
40 changed files with 1038 additions and 2035 deletions

View File

@@ -7,6 +7,7 @@ publish.workspace = true
[dependencies]
common = { path = "../common" }
global = { path = "../global" }
settings = { path = "../settings" }
rust-i18n.workspace = true
i18n.workspace = true

View File

@@ -2,7 +2,7 @@ use std::cmp::Reverse;
use std::collections::{BTreeMap, BTreeSet, HashMap};
use anyhow::Error;
use common::room_hash;
use common::event::EventUtils;
use fuzzy_matcher::skim::SkimMatcherV2;
use fuzzy_matcher::FuzzyMatcher;
use global::nostr_client;
@@ -12,6 +12,7 @@ use gpui::{
use itertools::Itertools;
use nostr_sdk::prelude::*;
use room::RoomKind;
use settings::AppSettings;
use smallvec::{smallvec, SmallVec};
use crate::room::Room;
@@ -32,6 +33,7 @@ impl Global for GlobalRegistry {}
#[derive(Debug)]
pub enum RoomEmitter {
Open(WeakEntity<Room>),
Close(u64),
Request(RoomKind),
}
@@ -202,6 +204,13 @@ impl Registry {
cx.notify();
}
/// Close a room.
pub fn close_room(&mut self, id: u64, cx: &mut Context<Self>) {
if self.rooms.iter().any(|r| r.read(cx).id == id) {
cx.emit(RoomEmitter::Close(id));
}
}
/// Sort rooms by their created at.
pub fn sort(&mut self, cx: &mut Context<Self>) {
self.rooms.sort_by_key(|ev| Reverse(ev.read(cx).created_at));
@@ -238,15 +247,12 @@ impl Registry {
cx.notify();
}
/// Load all rooms from the lmdb.
///
/// This method:
/// 1. Fetches all private direct messages from the lmdb
/// 2. Groups them by ID
/// 3. Determines each room's type based on message frequency and trust status
/// 4. Creates Room entities for each unique room
/// Load all rooms from the database.
pub fn load_rooms(&mut self, window: &mut Window, cx: &mut Context<Self>) {
log::info!("Starting to load rooms from database...");
log::info!("Starting to load chat rooms...");
// Get the contact bypass setting
let contact_bypass = AppSettings::get_contact_bypass(cx);
let task: Task<Result<BTreeSet<Room>, Error>> = cx.background_spawn(async move {
let client = nostr_client();
@@ -275,14 +281,22 @@ impl Registry {
.sorted_by_key(|event| Reverse(event.created_at))
.filter(|ev| ev.tags.public_keys().peekable().peek().is_some())
{
let hash = room_hash(&event);
if rooms.iter().any(|room| room.id == hash) {
if rooms.iter().any(|room| room.id == event.uniq_id()) {
continue;
}
let mut public_keys = event.tags.public_keys().copied().collect_vec();
public_keys.push(event.pubkey);
// Get all public keys from the event
let public_keys = event.all_pubkeys();
// Bypass screening flag
let mut bypass = false;
// If user enabled bypass screening for contacts
// Check if room's members are in contact with current user
if contact_bypass {
let contacts = client.database().contacts_public_keys(public_key).await?;
bypass = public_keys.iter().any(|k| contacts.contains(k));
}
// Check if the current user has sent at least one message to this room
let filter = Filter::new()
@@ -296,7 +310,7 @@ impl Registry {
// Create a new room
let room = Room::new(&event).rearrange_by(public_key);
if is_ongoing {
if is_ongoing || bypass {
rooms.insert(room.kind(RoomKind::Ongoing));
} else {
rooms.insert(room);
@@ -375,7 +389,7 @@ impl Registry {
window: &mut Window,
cx: &mut Context<Self>,
) {
let id = room_hash(&event);
let id = event.uniq_id();
let author = event.pubkey;
if let Some(room) = self.rooms.iter().find(|room| room.read(cx).id == id) {

View File

@@ -3,6 +3,7 @@ use std::cmp::Ordering;
use anyhow::{anyhow, Error};
use chrono::{Local, TimeZone};
use common::display::DisplayProfile;
use common::event::EventUtils;
use global::nostr_client;
use gpui::{App, AppContext, Context, EventEmitter, SharedString, Task, Window};
use itertools::Itertools;
@@ -72,16 +73,12 @@ impl EventEmitter<Incoming> for Room {}
impl Room {
pub fn new(event: &Event) -> Self {
let id = common::room_hash(event);
let id = event.uniq_id();
let created_at = event.created_at;
// Get all pubkeys from the event's tags
let mut pubkeys: Vec<PublicKey> = event.tags.public_keys().cloned().collect();
// The author is always put at the end of the vector
pubkeys.push(event.pubkey);
let public_keys = event.all_pubkeys();
// Convert pubkeys into members
let members = pubkeys.into_iter().unique().sorted().collect();
let members = public_keys.into_iter().unique().sorted().collect();
// Get the subject from the event's tags
let subject = if let Some(tag) = event.tags.find(TagKind::Subject) {
@@ -363,12 +360,7 @@ impl Room {
.await?
.into_iter()
.sorted_by_key(|ev| ev.created_at)
.filter(|ev| {
let mut other_pubkeys = ev.tags.public_keys().copied().collect::<Vec<_>>();
other_pubkeys.push(ev.pubkey);
// Check if the event is belong to a member of the current room
common::compare(&other_pubkeys, &pubkeys)
})
.filter(|ev| ev.compare_pubkeys(&pubkeys))
.collect::<Vec<_>>();
for event in events.into_iter() {