v0.0.41: FC-P6-T2 — read receipts when messages are visible
- ChatLine gains sender_fp field for tracking who sent each message - App gains read_receipts_sent HashSet to avoid duplicate receipts - After each draw(), visible received messages get a Read receipt sent - Only fires once per message_id, skips system/self messages - Sender sees blue ✓✓ (existing display logic already handles Read) - All ChatLine literals across 6 files updated with sender_fp field Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -35,9 +35,9 @@ impl App {
|
||||
}
|
||||
if text == "/info" {
|
||||
if !self.our_eth.is_empty() {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Identity: {}", self.our_eth), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Identity: {}", self.our_eth), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Fingerprint: {}", self.our_fp), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Fingerprint: {}", self.our_fp), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
return;
|
||||
}
|
||||
if text == "/help" || text == "/?" {
|
||||
@@ -87,7 +87,7 @@ impl App {
|
||||
text: line.to_string(),
|
||||
is_system: true,
|
||||
is_self: false,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
}
|
||||
return;
|
||||
@@ -109,12 +109,12 @@ impl App {
|
||||
{
|
||||
Ok(resp) => if let Ok(data) = resp.json::<serde_json::Value>().await {
|
||||
if let Some(err) = data.get("error") {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Alias removed".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Alias removed".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
},
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -122,9 +122,9 @@ impl App {
|
||||
match db.list_contacts() {
|
||||
Ok(contacts) => {
|
||||
if contacts.is_empty() {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No contacts yet".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No contacts yet".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Contacts ({}):", contacts.len()), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Contacts ({}):", contacts.len()), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
for c in &contacts {
|
||||
let fp = c.get("fingerprint").and_then(|v| v.as_str()).unwrap_or("?");
|
||||
let alias = c.get("alias").and_then(|v| v.as_str());
|
||||
@@ -141,11 +141,11 @@ impl App {
|
||||
Some(a) => format!(" {} @{} ({}) — {} msgs", status, a, &fp[..fp.len().min(12)], count),
|
||||
None => format!(" {} {} — {} msgs", status, &fp[..fp.len().min(16)], count),
|
||||
};
|
||||
self.add_message(ChatLine { sender: "system".into(), text: label, is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: label, is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -153,14 +153,14 @@ impl App {
|
||||
let peer = if text.starts_with("/h ") { text[3..].trim() } else if text.starts_with("/history ") { text[9..].trim() } else { "" };
|
||||
let fp = if let Some(ref p) = self.peer_fp { if !p.starts_with('#') { p.as_str() } else { peer } } else { peer };
|
||||
if fp.is_empty() {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Usage: /history or /h <fingerprint> (or set peer first)".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Usage: /history or /h <fingerprint> (or set peer first)".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else {
|
||||
match db.get_history(fp, 50) {
|
||||
Ok(msgs) => {
|
||||
if msgs.is_empty() {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No history with this peer".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No history with this peer".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("History ({} messages):", msgs.len()), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("History ({} messages):", msgs.len()), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
for m in &msgs {
|
||||
let sender = m.get("sender").and_then(|v| v.as_str()).unwrap_or("?");
|
||||
let txt = m.get("text").and_then(|v| v.as_str()).unwrap_or("");
|
||||
@@ -170,12 +170,12 @@ impl App {
|
||||
text: txt.to_string(),
|
||||
is_system: false,
|
||||
is_self,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -184,17 +184,17 @@ impl App {
|
||||
// Show ethereum address from seed
|
||||
if let Ok(seed) = crate::keystore::load_seed_raw() {
|
||||
let eth = warzone_protocol::ethereum::derive_eth_identity(&seed);
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("ETH: {}", eth.address.to_checksum()), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("ETH: {}", eth.address.to_checksum()), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
return;
|
||||
}
|
||||
if text == "/seed" {
|
||||
if let Ok(seed) = crate::keystore::load_seed_raw() {
|
||||
let mnemonic = warzone_protocol::identity::Seed::from_bytes(seed).to_mnemonic();
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Your recovery seed (keep secret!):".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: mnemonic, is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Your recovery seed (keep secret!):".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: mnemonic, is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Failed to load seed".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Failed to load seed".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -202,10 +202,10 @@ impl App {
|
||||
if let Ok(seed) = crate::keystore::load_seed_raw() {
|
||||
match db.create_backup(&seed) {
|
||||
Ok(path) => {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Backup saved: {}", path.display()), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Backup saved: {}", path.display()), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
Err(e) => {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Backup failed: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Backup failed: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,9 +224,9 @@ impl App {
|
||||
match warzone_protocol::friends::FriendList::decrypt(&seed, &blob) {
|
||||
Ok(list) => {
|
||||
if list.friends.is_empty() {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No friends yet. Use /friend <address> to add.".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No friends yet. Use /friend <address> to add.".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Friends ({}):", list.friends.len()), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Friends ({}):", list.friends.len()), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
for f in &list.friends {
|
||||
// Check presence
|
||||
let presence_url = format!("{}/v1/presence/{}", client.base_url, normfp(&f.address));
|
||||
@@ -241,28 +241,28 @@ impl App {
|
||||
Some(a) => format!(" @{} ({}) — {}", a, &f.address[..f.address.len().min(16)], status),
|
||||
None => format!(" {} — {}", &f.address[..f.address.len().min(16)], status),
|
||||
};
|
||||
self.add_message(ChatLine { sender: "system".into(), text: label, is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: label, is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Failed to decrypt friend list: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Failed to decrypt friend list: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No friends yet. Use /friend <address> to add.".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No friends yet. Use /friend <address> to add.".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
return;
|
||||
}
|
||||
if text.starts_with("/friend ") {
|
||||
let addr = text[8..].trim().to_string();
|
||||
if addr.is_empty() {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Usage: /friend <address>".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Usage: /friend <address>".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
return;
|
||||
}
|
||||
if let Ok(seed) = crate::keystore::load_seed_raw() {
|
||||
@@ -287,14 +287,14 @@ impl App {
|
||||
let encrypted = list.encrypt(&seed);
|
||||
let blob_b64 = base64::engine::general_purpose::STANDARD.encode(&encrypted);
|
||||
let _ = client.client.post(&url).json(&serde_json::json!({"data": blob_b64})).send().await;
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Added {} to friends", addr), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Added {} to friends", addr), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
return;
|
||||
}
|
||||
if text.starts_with("/unfriend ") {
|
||||
let addr = text[10..].trim().to_string();
|
||||
if addr.is_empty() {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Usage: /unfriend <address>".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Usage: /unfriend <address>".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
return;
|
||||
}
|
||||
if let Ok(seed) = crate::keystore::load_seed_raw() {
|
||||
@@ -318,7 +318,7 @@ impl App {
|
||||
let encrypted = list.encrypt(&seed);
|
||||
let blob_b64 = base64::engine::general_purpose::STANDARD.encode(&encrypted);
|
||||
let _ = client.client.post(&url).json(&serde_json::json!({"data": blob_b64})).send().await;
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Removed {} from friends", addr), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Removed {} from friends", addr), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -330,31 +330,31 @@ impl App {
|
||||
if let Ok(data) = resp.json::<serde_json::Value>().await {
|
||||
if let Some(devices) = data.get("devices").and_then(|v| v.as_array()) {
|
||||
if devices.is_empty() {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No active devices".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No active devices".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Active devices ({}):", devices.len()), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Active devices ({}):", devices.len()), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
for d in devices {
|
||||
let id = d.get("device_id").and_then(|v| v.as_str()).unwrap_or("?");
|
||||
let connected = d.get("connected_at").and_then(|v| v.as_i64()).unwrap_or(0);
|
||||
let when = chrono::DateTime::from_timestamp(connected, 0)
|
||||
.map(|dt| dt.format("%Y-%m-%d %H:%M").to_string())
|
||||
.unwrap_or_else(|| "?".to_string());
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!(" {} — connected {}", id, when), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!(" {} — connected {}", id, when), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
} else if let Some(err) = data.get("error") {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
return;
|
||||
}
|
||||
if text.starts_with("/kick ") {
|
||||
let device_id = text[6..].trim();
|
||||
if device_id.is_empty() {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Usage: /kick <device_id>".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Usage: /kick <device_id>".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
return;
|
||||
}
|
||||
let url = format!("{}/v1/devices/{}/kick", client.base_url, device_id);
|
||||
@@ -362,13 +362,13 @@ impl App {
|
||||
Ok(resp) => {
|
||||
if let Ok(data) = resp.json::<serde_json::Value>().await {
|
||||
if let Some(kicked) = data.get("kicked").and_then(|v| v.as_str()) {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Device {} kicked", kicked), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Device {} kicked", kicked), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else if let Some(err) = data.get("error") {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -376,7 +376,7 @@ impl App {
|
||||
let last = self.last_dm_peer.lock().unwrap().clone();
|
||||
if let Some(ref peer) = last {
|
||||
self.peer_fp = Some(peer.clone());
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("→ switched to {}", &peer[..peer.len().min(16)]), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("→ switched to {}", &peer[..peer.len().min(16)]), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
// If there's a message after /r, mutate text and fall through to send
|
||||
let reply_msg = if text.starts_with("/reply ") {
|
||||
text[7..].trim().to_string()
|
||||
@@ -390,7 +390,7 @@ impl App {
|
||||
}
|
||||
text = reply_msg; // Fall through to send logic below
|
||||
} else {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No one to reply to".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No one to reply to".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -414,7 +414,7 @@ impl App {
|
||||
raw
|
||||
};
|
||||
if normfp(&fp) == normfp(&self.our_fp) {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Cannot set yourself as peer".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Cannot set yourself as peer".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
return;
|
||||
}
|
||||
// Resolve peer ETH for display
|
||||
@@ -435,7 +435,7 @@ impl App {
|
||||
text: format!("Peer set to {}", display),
|
||||
is_system: true,
|
||||
is_self: false,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
self.peer_fp = Some(fp);
|
||||
return;
|
||||
@@ -459,7 +459,7 @@ impl App {
|
||||
text: format!("Switched to group #{}", name),
|
||||
is_system: true,
|
||||
is_self: false,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
self.peer_fp = Some(format!("#{}", name));
|
||||
return;
|
||||
@@ -470,7 +470,7 @@ impl App {
|
||||
text: "Switched to DM mode. Use /peer <fp>".into(),
|
||||
is_system: true,
|
||||
is_self: false,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
self.peer_fp = None;
|
||||
return;
|
||||
@@ -486,7 +486,7 @@ impl App {
|
||||
self.group_leave(&name, client).await;
|
||||
self.peer_fp = None;
|
||||
} else {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Not in a group. Use /g <name> first".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Not in a group. Use /g <name> first".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -498,7 +498,7 @@ impl App {
|
||||
let target = text[7..].trim().to_string();
|
||||
self.group_kick(&name, &target, client).await;
|
||||
} else {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Not in a group".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Not in a group".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -509,7 +509,7 @@ impl App {
|
||||
let name = peer[1..].to_string();
|
||||
self.group_members(&name, client).await;
|
||||
} else {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Not in a group".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Not in a group".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -540,7 +540,7 @@ impl App {
|
||||
let peer = match peer {
|
||||
Some(p) if !p.starts_with('#') => p,
|
||||
_ => {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No peer to call. Use /call <fp> or set a peer first.".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No peer to call. Use /call <fp> or set a peer first.".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -559,7 +559,7 @@ impl App {
|
||||
let encoded = match bincode::serialize(&wire) {
|
||||
Ok(e) => e,
|
||||
Err(e) => {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Call failed: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Call failed: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -570,7 +570,7 @@ impl App {
|
||||
.or(Some(&peer))
|
||||
.map(|s| if s.len() > 16 { format!("{}...", &s[..16]) } else { s.to_string() })
|
||||
.unwrap_or_default();
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("📞 Calling {}...", display), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("📞 Calling {}...", display), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
self.call_state = Some(super::types::CallInfo {
|
||||
peer_fp: peer_fp_clean.clone(),
|
||||
peer_display: display.clone(),
|
||||
@@ -579,7 +579,7 @@ impl App {
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Call failed: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Call failed: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -589,7 +589,7 @@ impl App {
|
||||
let peer = match self.last_dm_peer.lock().unwrap().clone() {
|
||||
Some(p) => p,
|
||||
None => {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No incoming call to accept".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No incoming call to accept".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -605,7 +605,7 @@ impl App {
|
||||
};
|
||||
if let Ok(encoded) = bincode::serialize(&wire) {
|
||||
let _ = client.send_message(&normfp(&peer), Some(&self.our_fp), &encoded).await;
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "✓ Call accepted".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "✓ Call accepted".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
self.call_state = Some(super::types::CallInfo {
|
||||
peer_fp: normfp(&peer),
|
||||
peer_display: peer[..peer.len().min(16)].to_string(),
|
||||
@@ -620,7 +620,7 @@ impl App {
|
||||
let peer = match self.last_dm_peer.lock().unwrap().clone() {
|
||||
Some(p) => p,
|
||||
None => {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No incoming call to reject".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No incoming call to reject".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -636,7 +636,7 @@ impl App {
|
||||
};
|
||||
if let Ok(encoded) = bincode::serialize(&wire) {
|
||||
let _ = client.send_message(&normfp(&peer), Some(&self.our_fp), &encoded).await;
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "✗ Call rejected".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "✗ Call rejected".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
self.call_state = None;
|
||||
}
|
||||
return;
|
||||
@@ -647,7 +647,7 @@ impl App {
|
||||
let peer = match peer {
|
||||
Some(p) if !p.starts_with('#') => p,
|
||||
_ => {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No active call".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No active call".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -663,7 +663,7 @@ impl App {
|
||||
};
|
||||
if let Ok(encoded) = bincode::serialize(&wire) {
|
||||
let _ = client.send_message(&normfp(&peer), Some(&self.our_fp), &encoded).await;
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Call ended".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "Call ended".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
self.call_state = None;
|
||||
}
|
||||
return;
|
||||
@@ -690,7 +690,7 @@ impl App {
|
||||
text: "No peer set. Use /peer <fingerprint>".into(),
|
||||
is_system: true,
|
||||
is_self: false,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -703,7 +703,7 @@ impl App {
|
||||
text: "Cannot send messages to yourself".into(),
|
||||
is_system: true,
|
||||
is_self: false,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -716,7 +716,7 @@ impl App {
|
||||
text: "Invalid peer fingerprint".into(),
|
||||
is_system: true,
|
||||
is_self: false,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -754,11 +754,11 @@ impl App {
|
||||
text: text.clone(),
|
||||
is_system: false,
|
||||
is_self: true,
|
||||
message_id: Some(msg_id), timestamp: Local::now(),
|
||||
message_id: Some(msg_id), sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Send failed: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Send failed: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -784,7 +784,7 @@ impl App {
|
||||
text: format!("Encrypt failed: {}", e),
|
||||
is_system: true,
|
||||
is_self: false,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -799,7 +799,7 @@ impl App {
|
||||
text: format!("Failed to fetch bundle: {}", e),
|
||||
is_system: true,
|
||||
is_self: false,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -813,7 +813,7 @@ impl App {
|
||||
text: format!("X3DH failed: {}", e),
|
||||
is_system: true,
|
||||
is_self: false,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -840,7 +840,7 @@ impl App {
|
||||
text: format!("Encrypt failed: {}", e),
|
||||
is_system: true,
|
||||
is_self: false,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -855,7 +855,7 @@ impl App {
|
||||
text: format!("Serialize failed: {}", e),
|
||||
is_system: true,
|
||||
is_self: false,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -873,7 +873,7 @@ impl App {
|
||||
text: text.clone(),
|
||||
is_system: false,
|
||||
is_self: true,
|
||||
message_id: Some(msg_id), timestamp: Local::now(),
|
||||
message_id: Some(msg_id), sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -882,7 +882,7 @@ impl App {
|
||||
text: format!("Send failed: {}", e),
|
||||
is_system: true,
|
||||
is_self: false,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -897,13 +897,13 @@ impl App {
|
||||
Ok(resp) => {
|
||||
if let Ok(data) = resp.json::<serde_json::Value>().await {
|
||||
if let Some(err) = data.get("error") {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Group '{}' created", name), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Group '{}' created", name), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -916,14 +916,14 @@ impl App {
|
||||
Ok(resp) => {
|
||||
if let Ok(data) = resp.json::<serde_json::Value>().await {
|
||||
if let Some(err) = data.get("error") {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else {
|
||||
let members = data.get("members").and_then(|v| v.as_u64()).unwrap_or(0);
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Joined '{}' ({} members)", name, members), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Joined '{}' ({} members)", name, members), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -934,18 +934,18 @@ impl App {
|
||||
if let Ok(data) = resp.json::<serde_json::Value>().await {
|
||||
if let Some(groups) = data.get("groups").and_then(|v| v.as_array()) {
|
||||
if groups.is_empty() {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No groups".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No groups".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else {
|
||||
for g in groups {
|
||||
let name = g.get("name").and_then(|v| v.as_str()).unwrap_or("?");
|
||||
let members = g.get("members").and_then(|v| v.as_u64()).unwrap_or(0);
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!(" #{} ({} members)", name, members), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!(" #{} ({} members)", name, members), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -958,13 +958,13 @@ impl App {
|
||||
Ok(resp) => {
|
||||
if let Ok(data) = resp.json::<serde_json::Value>().await {
|
||||
if let Some(err) = data.get("error") {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Left group '{}'", name), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Left group '{}'", name), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -977,14 +977,14 @@ impl App {
|
||||
Ok(resp) => {
|
||||
if let Ok(data) = resp.json::<serde_json::Value>().await {
|
||||
if let Some(err) = data.get("error") {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else {
|
||||
let kicked = data.get("kicked").and_then(|v| v.as_str()).unwrap_or("?");
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Kicked {} from '{}'", kicked, name), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Kicked {} from '{}'", kicked, name), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -994,7 +994,7 @@ impl App {
|
||||
Ok(resp) => {
|
||||
if let Ok(data) = resp.json::<serde_json::Value>().await {
|
||||
if let Some(members) = data.get("members").and_then(|v| v.as_array()) {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Members of #{}:", name), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Members of #{}:", name), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
for m in members {
|
||||
let fp = m.get("fingerprint").and_then(|v| v.as_str()).unwrap_or("?");
|
||||
let alias = m.get("alias").and_then(|v| v.as_str());
|
||||
@@ -1003,12 +1003,12 @@ impl App {
|
||||
Some(a) => format!(" @{} ({}{})", a, &fp[..fp.len().min(12)], if creator { " ★" } else { "" }),
|
||||
None => format!(" {}...{}", &fp[..fp.len().min(12)], if creator { " ★" } else { "" }),
|
||||
};
|
||||
self.add_message(ChatLine { sender: "system".into(), text: label, is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: label, is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1025,9 +1025,9 @@ impl App {
|
||||
let group_data = match client.client.get(&url).send().await {
|
||||
Ok(resp) => match resp.json::<serde_json::Value>().await {
|
||||
Ok(d) => d,
|
||||
Err(e) => { self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }); return; }
|
||||
Err(e) => { self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }); return; }
|
||||
},
|
||||
Err(e) => { self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }); return; }
|
||||
Err(e) => { self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }); return; }
|
||||
};
|
||||
|
||||
let my_fp = normfp(&self.our_fp);
|
||||
@@ -1100,7 +1100,7 @@ impl App {
|
||||
}
|
||||
|
||||
if wire_messages.is_empty() {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No members to send to".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No members to send to".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1118,11 +1118,11 @@ impl App {
|
||||
text: text.to_string(),
|
||||
is_system: false,
|
||||
is_self: true,
|
||||
message_id: None, timestamp: Local::now(),
|
||||
message_id: None, sender_fp: None, timestamp: Local::now(),
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Send failed: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Send failed: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1136,14 +1136,14 @@ impl App {
|
||||
Ok(resp) => {
|
||||
if let Ok(data) = resp.json::<serde_json::Value>().await {
|
||||
if let Some(err) = data.get("error") {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", err), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else {
|
||||
let alias = data.get("alias").and_then(|v| v.as_str()).unwrap_or(name);
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Alias @{} registered", alias), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Alias @{} registered", alias), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1153,17 +1153,17 @@ impl App {
|
||||
Ok(resp) => {
|
||||
if let Ok(data) = resp.json::<serde_json::Value>().await {
|
||||
if let Some(fp) = data.get("fingerprint").and_then(|v| v.as_str()) {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("@{} → {}", name, fp), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("@{} → {}", name, fp), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
return Some(fp.to_string());
|
||||
}
|
||||
if let Some(err) = data.get("error") {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Unknown alias @{}: {}", name, err), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Unknown alias @{}: {}", name, err), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
Err(e) => {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -1180,17 +1180,17 @@ impl App {
|
||||
let formatted: String = fp.chars().enumerate()
|
||||
.flat_map(|(i, c)| if i > 0 && i % 4 == 0 { vec![':', c] } else { vec![c] })
|
||||
.collect();
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("{} → {}", addr, formatted), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("{} → {}", addr, formatted), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
return Some(fp.to_string());
|
||||
}
|
||||
if let Some(err) = data.get("error") {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Cannot resolve {}: {}", addr, err), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Cannot resolve {}: {}", addr, err), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
Err(e) => {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -1203,18 +1203,18 @@ impl App {
|
||||
if let Ok(data) = resp.json::<serde_json::Value>().await {
|
||||
if let Some(aliases) = data.get("aliases").and_then(|v| v.as_array()) {
|
||||
if aliases.is_empty() {
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No aliases".into(), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: "No aliases".into(), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
} else {
|
||||
for a in aliases {
|
||||
let name = a.get("alias").and_then(|v| v.as_str()).unwrap_or("?");
|
||||
let fp = a.get("fingerprint").and_then(|v| v.as_str()).unwrap_or("?");
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!(" @{} → {}...", name, &fp[..fp.len().min(16)]), is_system: true, is_self: false, message_id: None, timestamp: Local::now() });
|
||||
self.add_message(ChatLine { sender: "system".into(), text: format!(" @{} → {}...", name, &fp[..fp.len().min(16)]), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, timestamp: Local::now() }),
|
||||
Err(e) => self.add_message(ChatLine { sender: "system".into(), text: format!("Error: {}", e), is_system: true, is_self: false, message_id: None, sender_fp: None, timestamp: Local::now() }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user