1#![recursion_limit = "256"]
2
3use anyhow::Result;
4use clap::Parser;
5use futures_util::StreamExt;
6use matrix_sdk::{Client, config::SyncSettings, ruma::OwnedRoomId};
7use matrix_sdk_ui::timeline::RoomExt;
8use url::Url;
9
10#[derive(Parser, Debug)]
11struct Cli {
12 #[clap(value_parser)]
14 homeserver: Url,
15
16 #[clap(value_parser)]
18 user_name: String,
19
20 #[clap(value_parser)]
22 password: String,
23
24 #[clap(short, long)]
26 proxy: Option<Url>,
27
28 #[clap(short, long, action)]
30 verbose: bool,
31
32 #[clap(value_parser)]
34 room_id: OwnedRoomId,
35}
36
37async fn login(cli: Cli) -> Result<Client> {
38 let mut builder = Client::builder().homeserver_url(cli.homeserver);
42
43 if let Some(proxy) = cli.proxy {
44 builder = builder.proxy(proxy);
45 }
46
47 let client = builder.build().await?;
48
49 client
50 .matrix_auth()
51 .login_username(&cli.user_name, &cli.password)
52 .initial_device_display_name("rust-sdk")
53 .await?;
54
55 Ok(client)
56}
57
58#[tokio::main]
59async fn main() -> Result<()> {
60 tracing_subscriber::fmt::init();
61
62 let cli = Cli::parse();
63 let room_id = cli.room_id.clone();
64 let client = login(cli).await?;
65
66 let sync_settings = SyncSettings::default();
67
68 println!("Wait for the first sync");
70
71 client.sync_once(sync_settings.clone()).await?;
72
73 let room = client.get_room(&room_id).unwrap();
75 let timeline = room.timeline().await.unwrap();
76 let (timeline_items, mut timeline_stream) = timeline.subscribe().await;
77
78 println!("Initial timeline items: {timeline_items:#?}");
79 tokio::spawn(async move {
80 while let Some(diffs) = timeline_stream.next().await {
81 println!("Received timeline diffs: {diffs:#?}");
82 }
83 });
84
85 client.sync(sync_settings).await?;
87
88 Ok(())
89}