@@ -676,7 +676,7 @@ impl ChatSpace {
|
||||
}
|
||||
|
||||
/// Stores an unwrapped event in local database with reference to original
|
||||
async fn set_unwrapped_event(root: EventId, unwrapped: &Event) -> Result<(), Error> {
|
||||
async fn set_unwrapped_event(gift_wrap: EventId, unwrapped: &Event) -> Result<(), Error> {
|
||||
let client = nostr_client();
|
||||
|
||||
// Save unwrapped event
|
||||
@@ -684,7 +684,7 @@ impl ChatSpace {
|
||||
|
||||
// Create a reference event pointing to the unwrapped event
|
||||
let event = EventBuilder::new(Kind::ApplicationSpecificData, "")
|
||||
.tags(vec![Tag::identifier(root), Tag::event(unwrapped.id)])
|
||||
.tags(vec![Tag::identifier(gift_wrap), Tag::event(unwrapped.id)])
|
||||
.sign(&Keys::generate())
|
||||
.await?;
|
||||
|
||||
@@ -744,8 +744,6 @@ impl ChatSpace {
|
||||
match event.created_at >= app_state.init_at {
|
||||
// New message: send a signal to notify the UI
|
||||
true => {
|
||||
// A small delay to prevent UI flickering
|
||||
smol::Timer::after(Duration::from_millis(200)).await;
|
||||
app_state
|
||||
.signal
|
||||
.send(SignalKind::NewMessage((target.id, event)))
|
||||
|
||||
@@ -164,9 +164,21 @@ impl Chat {
|
||||
cx.subscribe_in(&room, window, move |this, _, signal, window, cx| {
|
||||
match signal {
|
||||
RoomSignal::NewMessage((gift_wrap_id, event)) => {
|
||||
if !this.is_sent_by_coop(gift_wrap_id) {
|
||||
this.insert_message(Message::user(event), false, cx);
|
||||
}
|
||||
let gift_wrap_id = gift_wrap_id.to_owned();
|
||||
let message = Message::user(event);
|
||||
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
let app_state = app_state();
|
||||
let sent_ids = app_state.sent_ids.read().await;
|
||||
|
||||
this.update_in(cx, |this, _window, cx| {
|
||||
if !sent_ids.contains(&gift_wrap_id) {
|
||||
this.insert_message(message, false, cx);
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
RoomSignal::Refresh => {
|
||||
this.load_messages(window, cx);
|
||||
@@ -242,20 +254,19 @@ impl Chat {
|
||||
self._tasks.push(
|
||||
// Run the task in the background
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
match load_messages.await {
|
||||
Ok(events) => {
|
||||
this.update(cx, |this, cx| {
|
||||
let result = load_messages.await;
|
||||
|
||||
this.update_in(cx, |this, window, cx| {
|
||||
match result {
|
||||
Ok(events) => {
|
||||
this.insert_messages(events, cx);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
Err(e) => {
|
||||
cx.update(|window, cx| {
|
||||
window.push_notification(e.to_string(), cx);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
};
|
||||
}
|
||||
Err(e) => {
|
||||
window.push_notification(Notification::error(e.to_string()), cx);
|
||||
}
|
||||
};
|
||||
})
|
||||
.ok();
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -289,11 +300,6 @@ impl Chat {
|
||||
content
|
||||
}
|
||||
|
||||
/// Check if the event is sent by Coop
|
||||
fn is_sent_by_coop(&self, gift_wrap_id: &EventId) -> bool {
|
||||
app_state().sent_ids.read_blocking().contains(gift_wrap_id)
|
||||
}
|
||||
|
||||
/// Send a message to all members of the chat
|
||||
fn send_message(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
// Get the message which includes all attachments
|
||||
@@ -305,12 +311,6 @@ impl Chat {
|
||||
return;
|
||||
}
|
||||
|
||||
// Temporary disable input
|
||||
self.input.update(cx, |this, cx| {
|
||||
this.set_loading(true, cx);
|
||||
this.set_disabled(true, cx);
|
||||
});
|
||||
|
||||
// Get the backup setting
|
||||
let backup = AppSettings::get_backup_messages(cx);
|
||||
|
||||
@@ -328,29 +328,27 @@ impl Chat {
|
||||
// Create a task for sending the message in the background
|
||||
let send_message = room.send_in_background(&content, replies, backup, cx);
|
||||
|
||||
cx.defer_in(window, |this, window, cx| {
|
||||
// Optimistically update message list
|
||||
this.insert_message(Message::user(temp_message), true, cx);
|
||||
// Optimistically update message list
|
||||
self.insert_message(Message::user(temp_message), true, cx);
|
||||
|
||||
// Remove all replies
|
||||
this.remove_all_replies(cx);
|
||||
// Remove all replies
|
||||
self.remove_all_replies(cx);
|
||||
|
||||
// remove all attachments
|
||||
this.remove_all_attachments(cx);
|
||||
// remove all attachments
|
||||
self.remove_all_attachments(cx);
|
||||
|
||||
// Reset the input state
|
||||
this.input.update(cx, |this, cx| {
|
||||
this.set_loading(false, cx);
|
||||
this.set_disabled(false, cx);
|
||||
this.set_value("", window, cx);
|
||||
});
|
||||
// Reset the input state
|
||||
self.input.update(cx, |this, cx| {
|
||||
this.set_value("", window, cx);
|
||||
});
|
||||
|
||||
// Continue sending the message in the background
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
match send_message.await {
|
||||
Ok(reports) => {
|
||||
this.update(cx, |this, cx| {
|
||||
let result = send_message.await;
|
||||
|
||||
this.update_in(cx, |this, window, cx| {
|
||||
match result {
|
||||
Ok(reports) => {
|
||||
this.room.update(cx, |this, cx| {
|
||||
if this.kind != RoomKind::Ongoing {
|
||||
// Update the room kind to ongoing
|
||||
@@ -366,16 +364,13 @@ impl Chat {
|
||||
this.reports_by_id.insert(temp_id, reports);
|
||||
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
Err(e) => {
|
||||
cx.update(|window, cx| {
|
||||
}
|
||||
Err(e) => {
|
||||
window.push_notification(e.to_string(), cx);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
@@ -430,8 +425,9 @@ impl Chat {
|
||||
item_ix: self.list_state.item_count(),
|
||||
offset_in_item: px(0.0),
|
||||
});
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,11 +435,12 @@ impl Chat {
|
||||
fn insert_messages(&mut self, events: Vec<Event>, cx: &mut Context<Self>) {
|
||||
for event in events.into_iter() {
|
||||
let m = Message::user(event);
|
||||
// Bulk inserting messages, so no need to scroll to the latest message
|
||||
self.insert_message(m, false, cx);
|
||||
}
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
/// Insert a warning message into the chat panel
|
||||
fn insert_warning(&mut self, content: impl Into<String>, cx: &mut Context<Self>) {
|
||||
let m = Message::warning(content.into());
|
||||
self.insert_message(m, true, cx);
|
||||
|
||||
@@ -159,10 +159,10 @@ pub struct AppState {
|
||||
|
||||
pub auto_close_opts: Option<SubscribeAutoCloseOptions>,
|
||||
|
||||
pub seen_on_relays: RwLock<HashMap<EventId, HashSet<RelayUrl>>>,
|
||||
|
||||
pub sent_ids: RwLock<HashSet<EventId>>,
|
||||
|
||||
pub seen_on_relays: RwLock<HashMap<EventId, HashSet<RelayUrl>>>,
|
||||
|
||||
pub resent_ids: RwLock<Vec<Output<EventId>>>,
|
||||
|
||||
pub resend_queue: RwLock<HashMap<EventId, RelayUrl>>,
|
||||
@@ -196,8 +196,8 @@ impl AppState {
|
||||
gift_wrap_sub_id: SubscriptionId::new("inbox"),
|
||||
gift_wrap_processing: AtomicBool::new(false),
|
||||
auto_close_opts: Some(opts),
|
||||
seen_on_relays: RwLock::new(HashMap::new()),
|
||||
sent_ids: RwLock::new(HashSet::new()),
|
||||
seen_on_relays: RwLock::new(HashMap::new()),
|
||||
resent_ids: RwLock::new(Vec::new()),
|
||||
resend_queue: RwLock::new(HashMap::new()),
|
||||
}
|
||||
|
||||
@@ -365,21 +365,51 @@ impl Room {
|
||||
|
||||
cx.background_spawn(async move {
|
||||
let client = nostr_client();
|
||||
let public_key = members[members.len() - 1];
|
||||
let signer = client.signer().await?;
|
||||
let public_key = signer.get_public_key().await?;
|
||||
let sent_ids = app_state()
|
||||
.sent_ids
|
||||
.read()
|
||||
.await
|
||||
.iter()
|
||||
.copied()
|
||||
.collect_vec();
|
||||
|
||||
let sent = Filter::new()
|
||||
// Get seen events from database
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::ApplicationSpecificData)
|
||||
.identifiers(sent_ids);
|
||||
|
||||
let seen_events = client.database().query(filter).await?;
|
||||
|
||||
// Extract seen event IDs
|
||||
let seen_ids: Vec<EventId> = seen_events
|
||||
.into_iter()
|
||||
.filter_map(|event| event.tags.event_ids().next().copied())
|
||||
.collect();
|
||||
|
||||
// Get events that sent by current user
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::PrivateDirectMessage)
|
||||
.author(public_key)
|
||||
.pubkeys(members.clone());
|
||||
|
||||
let recv = Filter::new()
|
||||
let sent_events = client.database().query(filter).await?;
|
||||
|
||||
// Get events that received by current user
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::PrivateDirectMessage)
|
||||
.authors(members)
|
||||
.pubkey(public_key);
|
||||
|
||||
let sent_events = client.database().query(sent).await?;
|
||||
let recv_events = client.database().query(recv).await?;
|
||||
let events: Vec<Event> = sent_events.merge(recv_events).into_iter().collect();
|
||||
let recv_events = client.database().query(filter).await?;
|
||||
|
||||
// Merge events
|
||||
let events: Vec<Event> = sent_events
|
||||
.merge(recv_events)
|
||||
.into_iter()
|
||||
.filter(|event| !seen_ids.contains(&event.id))
|
||||
.collect();
|
||||
|
||||
Ok(events)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user