Added sync functionality if you have several terminals open. Not much on it's own, but it also makes the timestamp of each messages use the created_at property from the blip record instead of just taking whatever the current time is before displaying it.
+20
-15
src/client.rs
+20
-15
src/client.rs
···
1
1
use anyhow::{Context, Result};
2
2
use chrono::Utc;
3
-
use reqwest::{Client as HttpClient, header::{HeaderMap, HeaderValue, AUTHORIZATION}};
3
+
use reqwest::{
4
+
header::{HeaderMap, HeaderValue, AUTHORIZATION},
5
+
Client as HttpClient,
6
+
};
4
7
use serde::{Deserialize, Serialize};
5
8
use serde_json::Value;
6
9
···
62
65
63
66
pub async fn login(&mut self, credentials: &Credentials) -> Result<()> {
64
67
let login_url = format!("{}/xrpc/com.atproto.server.createSession", self.base_url);
65
-
68
+
66
69
let request = LoginRequest {
67
70
identifier: credentials.username.clone(),
68
71
password: credentials.password.clone(),
69
72
};
70
73
71
-
let response = self.http_client
74
+
let response = self
75
+
.http_client
72
76
.post(&login_url)
73
77
.header("Content-Type", "application/json")
74
78
.json(&request)
···
93
97
}
94
98
95
99
pub async fn publish_blip(&self, content: &str) -> Result<String> {
96
-
let session = self.session.as_ref()
100
+
let session = self
101
+
.session
102
+
.as_ref()
97
103
.context("Not authenticated. Please run 'thought login' first.")?;
98
104
105
+
let timestamp = Utc::now().to_rfc3339().replace("+00:00", "Z");
106
+
99
107
let record = BlipRecord {
100
108
record_type: "stream.thought.blip".to_string(),
101
109
content: content.to_string(),
102
-
created_at: Utc::now().to_rfc3339().replace("+00:00", "Z"),
110
+
created_at: timestamp.clone(),
103
111
};
104
112
105
113
let request = CreateRecordRequest {
106
114
repo: session.did.clone(),
107
115
collection: "stream.thought.blip".to_string(),
108
-
record: serde_json::to_value(&record)
109
-
.context("Failed to serialize blip record")?,
116
+
record: serde_json::to_value(&record).context("Failed to serialize blip record")?,
110
117
};
111
118
112
119
let create_url = format!("{}/xrpc/com.atproto.repo.createRecord", self.base_url);
113
-
120
+
114
121
let mut headers = HeaderMap::new();
115
122
headers.insert(
116
123
AUTHORIZATION,
117
124
HeaderValue::from_str(&format!("Bearer {}", session.access_jwt))
118
125
.context("Invalid authorization header")?,
119
126
);
120
-
headers.insert(
121
-
"Content-Type",
122
-
HeaderValue::from_static("application/json"),
123
-
);
127
+
headers.insert("Content-Type", HeaderValue::from_static("application/json"));
124
128
125
-
let response = self.http_client
129
+
let response = self
130
+
.http_client
126
131
.post(&create_url)
127
132
.headers(headers)
128
133
.json(&request)
···
141
146
.await
142
147
.context("Failed to parse create record response")?;
143
148
144
-
Ok(create_response.uri)
149
+
Ok(timestamp)
145
150
}
146
151
147
152
pub fn is_authenticated(&self) -> bool {
···
151
156
pub fn get_user_did(&self) -> Option<String> {
152
157
self.session.as_ref().map(|s| s.did.clone())
153
158
}
154
-
}
159
+
}