tauri_plugin_matrix_svelte/matrix/
events.rs

1use matrix_sdk::{
2    encryption::VerificationState,
3    ruma::{
4        events::{
5            key::verification::request::ToDeviceKeyVerificationRequestEvent,
6            room::message::{MessageType, OriginalSyncRoomMessageEvent},
7        },
8        MilliSecondsSinceUnixEpoch, OwnedRoomId,
9    },
10    Client,
11};
12use matrix_sdk_ui::timeline::EventTimelineItem;
13use tauri::{AppHandle, Runtime};
14
15use super::{
16    emoji_verification::request_verification_handler, event_preview::text_preview_of_timeline_item,
17};
18
19// These event handlers handle only the verification events. Other events are managed by the matrix_sdk_ui sync service.
20pub fn add_event_handlers<R: Runtime>(
21    client: Client,
22    app_handle: &AppHandle<R>,
23) -> anyhow::Result<Client> {
24    let first_app_handle = app_handle.clone();
25
26    let mut verification_state_subscriber = client.encryption().verification_state();
27    println!(
28        "Initial verification state is {:?}",
29        verification_state_subscriber.get()
30    );
31    tauri::async_runtime::spawn(async move {
32        while let Some(state) = verification_state_subscriber.next().await {
33            println!("Received a verification state update: {state:?}");
34            // Cx::post_action(VerificationStateAction::Update(state));
35            // TODO: display verification state
36            if let VerificationState::Verified = state {
37                break;
38            }
39        }
40    });
41    client.add_event_handler(
42        |ev: ToDeviceKeyVerificationRequestEvent, client: Client| async move {
43            if let Some(request) = client
44                .encryption()
45                .get_verification_request(&ev.sender, &ev.content.transaction_id)
46                .await
47            {
48                tauri::async_runtime::spawn(request_verification_handler(
49                            client,
50                            request,
51                            first_app_handle,
52                        ));
53            }
54            else {
55                eprintln!("Skipping invalid verification request from {}, transaction ID: {}\n   Content: {:?}",
56                    ev.sender, ev.content.transaction_id, ev.content,
57                );
58            }
59        },
60    );
61
62    let second_app_handle = app_handle.clone();
63    client.add_event_handler(
64        |ev: OriginalSyncRoomMessageEvent, client: Client| async move {
65            if let MessageType::VerificationRequest(_) = &ev.content.msgtype {
66                if let Some(request) = client
67                    .encryption()
68                    .get_verification_request(&ev.sender, &ev.event_id)
69                    .await
70                {
71                    tauri::async_runtime::spawn(request_verification_handler(
72                                client,
73                                request,
74                                second_app_handle,
75                            ));
76                }
77                else {
78                    eprintln!("Skipping invalid verification request from {}, event ID: {}\n   Content: {:?}",
79                        ev.sender, ev.event_id, ev.content,
80                    );
81                }
82            }
83        }
84    );
85    Ok(client)
86}
87
88/// Returns the timestamp and text preview of the given `latest_event` timeline item.
89///
90/// If the sender profile of the event is not yet available, this function will
91/// generate a preview using the sender's user ID instead of their display name,
92/// and will submit a background async request to fetch the details for this event.
93pub fn get_latest_event_details(
94    latest_event: &EventTimelineItem,
95    room_id: &OwnedRoomId,
96) -> (MilliSecondsSinceUnixEpoch, String) {
97    #[cfg(debug_assertions)]
98    println!("Formating event coming from: {:?}", latest_event.sender());
99
100    let sender_username = super::utils::get_or_fetch_event_sender(latest_event, Some(room_id));
101    (
102        latest_event.timestamp(),
103        text_preview_of_timeline_item(latest_event.content(), &sender_username)
104            .format_with(&sender_username, true),
105    )
106}