Point every comment at the file it means
The other half of #168. Thirty-three doc comments named a file that stopped existing when the backends were split into folders - `backend/discord.rs`, `backend/irc.rs` and friends - so a pointer meant to save the next reader a search sent them to nothing at all. Each one resolved to where the named thing actually lives rather than to the folder it probably moved to: `extract_reactions` to discord/messages.rs, `run_qr_login` to discord/login.rs, `backfill_channel_history` to discord/history.rs, `emit_presence` to irc/presence.rs, and so on. A pointer that is merely close is the same failure one step smaller. Two were not path renames at all. The DCC module opened by describing itself as sitting "beside `irc.rs` the way `discord_voice.rs` sits beside `discord.rs`" - an analogy to a layout that no longer exists, rewritten to the one that does. And a runtime field described its roster as the one "userlist.rs builds from", naming a file this repository has never had; it means roomstate.rs's `emit_matrix_presence`, which the same comment goes on to name two lines later. Ten references survive the sweep and should: the Sneedchat backend cites `auth/totp.rs`, `chat/json.rs` and others from **sneedchat-rs**, a different project, each with its URL beside it. Those are attributions rather than directions, and rewriting them to local paths would have been the exact mistake this commit exists to undo. Closes #168. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
+4
-4
@@ -63,7 +63,7 @@ pub struct IrcAccountConfig {
|
||||
/// Tunnel this connection through a SOCKS5 proxy - disabled by default.
|
||||
/// Unlike Sneedchat's embedded-Arti transport, the `irc` crate's proxy
|
||||
/// support only knows how to dial an *external* SOCKS5 proxy (see
|
||||
/// backend/irc.rs's connection setup and net/tor.rs's doc comment on
|
||||
/// backend/irc/connect.rs's setup and net/tor.rs's doc comment on
|
||||
/// why an in-process Arti client can't be handed to it directly) - so
|
||||
/// this requires a real Tor daemon or Tor Browser already running and
|
||||
/// listening at `tor_proxy` (defaults to the standard system Tor port).
|
||||
@@ -84,7 +84,7 @@ impl IrcAccountConfig {
|
||||
}
|
||||
|
||||
/// Discord account shape - unlike IRC/XMPP this has no user-chosen
|
||||
/// identifier at creation time (see backend/discord.rs's QR remote-auth
|
||||
/// identifier at creation time (see backend/discord/login.rs's QR remote-auth
|
||||
/// flow): `user_id`/`username` are learned from Discord's own API only
|
||||
/// after a successful login, and `token` is the raw user token that flow
|
||||
/// produces (used as-is in the `Authorization` header - Discord user
|
||||
@@ -97,7 +97,7 @@ pub struct DiscordAccountConfig {
|
||||
pub display_name: Option<String>,
|
||||
pub token: String,
|
||||
/// Captured once at login from /users/@me's `avatar` hash (see
|
||||
/// backend/discord.rs's run_qr_login) - not refreshed on later
|
||||
/// backend/discord/login.rs's run_qr_login) - not refreshed on later
|
||||
/// reconnects, same precedent as `username` above.
|
||||
#[serde(default)]
|
||||
pub avatar_url: Option<String>,
|
||||
@@ -653,7 +653,7 @@ impl AccountStore {
|
||||
}
|
||||
|
||||
/// Opportunistic refresh, called on every gateway READY (see
|
||||
/// backend/discord.rs's run_gateway) rather than only at initial QR
|
||||
/// backend/discord/gateway.rs's run_gateway) rather than only at initial QR
|
||||
/// login - accounts added before this feature existed have no
|
||||
/// avatar_url yet, and a user's real Discord avatar can change over
|
||||
/// time anyway. Idempotent/cheap enough to just always persist rather
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Discord voice connections.
|
||||
//!
|
||||
//! The main gateway (see discord.rs) negotiates a voice session and hands over
|
||||
//! The main gateway (see gateway.rs) negotiates a voice session and hands over
|
||||
//! two halves of a handshake: a session id on VOICE_STATE_UPDATE, and an
|
||||
//! endpoint plus token on VOICE_SERVER_UPDATE. They arrive in either order and
|
||||
//! neither is usable alone, so this waits for both and then opens the actual
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
//! Receiving a file over DCC, which on IRC is how XDCC bots hand one over.
|
||||
//!
|
||||
//! Beside `irc.rs` the way `discord_voice.rs` sits beside `discord.rs`: it is
|
||||
//! a second protocol that rides on the first, with its own sockets and its own
|
||||
//! state, and folding it into the message loop would bury it.
|
||||
//! Its own file beside the rest of `irc/`, the way `voice.rs` sits beside the
|
||||
//! rest of `discord/`: it is a second protocol that rides on the first, with
|
||||
//! its own sockets and its own state, and folding it into the message loop
|
||||
//! would bury it.
|
||||
//!
|
||||
//! Everything in an offer is chosen by whoever sent it - the name, the size,
|
||||
//! the address, the port - so the whole module is written against that. Three
|
||||
|
||||
@@ -130,7 +130,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// Kicks off a login attempt in the background - see backend/discord.rs's
|
||||
/// Kicks off a login attempt in the background - see backend/discord/login.rs's
|
||||
/// start_qr_login/backend/sneedchat's start_login for the identical
|
||||
/// async-kickoff shape. Progress/result arrive via matrixLoginStatus/
|
||||
/// matrixLoginResult events tagged with `login_id`, not the RPC response
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Client-Server API event-type constants + small per-event extraction
|
||||
//! helpers. Plain `serde_json::Value` + manual field access throughout
|
||||
//! (matching backend/discord.rs's own style for gateway payloads) rather
|
||||
//! (matching backend/discord/gateway.rs's own style for payloads) rather
|
||||
//! than fully-typed structs - `/sync`'s per-room maps are keyed by dynamic
|
||||
//! room ids and its timeline mixes a couple dozen distinct event types, so
|
||||
//! a hand-rolled typed model would need to enumerate exhaustively for no
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//! incremental `/sync` responses carry no naming-relevant state at all
|
||||
//! (re-deriving from an empty/partial delta would wrongly fall back to
|
||||
//! the raw room id) and because live room renames aren't tracked, the
|
||||
//! same accepted limitation backend/discord.rs's own channel-name-as-
|
||||
//! same accepted limitation backend/discord/guilds.rs's own channel-name-as-
|
||||
//! buffer-name design already has for a renamed Discord channel.
|
||||
|
||||
use serde_json::Value;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
//!
|
||||
//! emit_matrix_presence builds and broadcasts a room's current userlist
|
||||
//! (see runtime.rs's presence/get_presence, the same wire mechanism
|
||||
//! backend/irc.rs's emit_presence already uses) from whatever's currently
|
||||
//! backend/irc/presence.rs's emit_presence already uses) from whatever's currently
|
||||
//! cached: the joined-member roster, power levels (sort key), and presence
|
||||
//! (online/offline split) - called any time one of those three changes.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//!
|
||||
//! Ported from sneedchat-rs's `net/http.rs`
|
||||
//! (<https://gitgud.io/jcmoon/sneedchat-rs>). `reqwest` (already used by
|
||||
//! `backend/discord.rs`) cannot use an in-process Arti stream as its
|
||||
//! `backend/discord/http.rs`) cannot use an in-process Arti stream as its
|
||||
//! connector - it only knows how to dial its own connector or a SOCKS5
|
||||
//! proxy *URL* - so rather than run two different transport stacks for this
|
||||
//! one backend, hyper is driven directly. The surface needed is small: GET
|
||||
|
||||
@@ -166,7 +166,7 @@ pub(super) async fn cached_avatar_file(dir: &std::path::Path, user_id: &str) ->
|
||||
/// Cached permanently per user id for this daemon's lifetime, not
|
||||
/// re-checked on every message - an avatar changing later isn't picked
|
||||
/// up until the cache file is manually cleared, the same precedent
|
||||
/// backend/discord.rs's own avatar_url handling already set ("captured
|
||||
/// backend/discord/messages.rs's own avatar_url handling already set ("captured
|
||||
/// once at login... not refreshed on later reconnects").
|
||||
pub(super) async fn cached_avatar_path(http: &http::HttpClient, host: &str, user_id: &str, raw_avatar_url: &str) -> Option<String> {
|
||||
if raw_avatar_url.is_empty() {
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
//!
|
||||
//! Here rather than in a window because the commands are the daemon's: each
|
||||
//! backend parses the ones it implements out of a message that starts with a
|
||||
//! slash (see `backend/irc.rs`'s `send_message` and `backend/matrix/mod.rs`),
|
||||
//! slash (see `backend/irc/send.rs`'s `send_message` and `backend/matrix/send.rs`),
|
||||
//! so this table is the same list read from the other end. A client that held
|
||||
//! its own copy would be a second list to keep in step, and it would be the
|
||||
//! one that drifted.
|
||||
|
||||
+4
-4
@@ -281,13 +281,13 @@ pub struct SenderStyle {
|
||||
/// One emoji's reaction tally on a message. `me` is whether *this*
|
||||
/// account is among the reactors - Discord's REACTION_ADD/REMOVE events
|
||||
/// are per-user, so this is accumulated incrementally rather than
|
||||
/// snapshotted (see backend/discord.rs's reaction handling).
|
||||
/// snapshotted (see backend/discord/messages.rs's reaction handling).
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Reaction {
|
||||
pub emoji: String,
|
||||
pub count: i64,
|
||||
pub me: bool,
|
||||
/// Only meaningful for a custom Discord emoji (see backend/discord.rs's
|
||||
/// Only meaningful for a custom Discord emoji (see backend/discord/messages.rs's
|
||||
/// extract_reactions) - whether the frontend should build its CDN
|
||||
/// image URL with a `.gif` extension instead of `.png`. Always false
|
||||
/// for a plain Unicode emoji, which the frontend renders as text and
|
||||
@@ -298,7 +298,7 @@ pub struct Reaction {
|
||||
|
||||
/// A Discord rich embed (title/description/color/timestamp box - a
|
||||
/// webhook's or bot's own formatted content, distinct from the plain
|
||||
/// `body` text) - see backend/discord.rs's extract_embeds. `color` is
|
||||
/// `body` text) - see backend/discord/messages.rs's extract_embeds. `color` is
|
||||
/// Discord's own decimal RGB value (e.g. 15844367); the frontend renders
|
||||
/// it as a colored accent bar down the embed's left edge, same as
|
||||
/// Discord's own client does, and re-renders it live if a later edit
|
||||
@@ -452,7 +452,7 @@ pub struct Message {
|
||||
#[serde(rename = "isOwn", default)]
|
||||
pub is_own: bool,
|
||||
/// The sender's real avatar image URL (Discord only - see backend/
|
||||
/// discord.rs's author_avatar_url; IRC/XMPP have no such concept).
|
||||
/// discord/messages.rs's author_avatar_url; IRC/XMPP have no such concept).
|
||||
/// Covers the account's own messages too, same mechanism, no special
|
||||
/// casing - Discord's gateway echo of a self-sent message carries the
|
||||
/// full `author` object same as anyone else's.
|
||||
|
||||
+4
-4
@@ -195,7 +195,7 @@ pub async fn dispatch(
|
||||
// worth trying to pull more from Discord first, since the
|
||||
// initial fetch is already covered by the backfill that
|
||||
// runs when the buffer is first discovered (see backend/
|
||||
// discord.rs's backfill_channel_history).
|
||||
// discord/history.rs's backfill_channel_history).
|
||||
if let Some(buffer) = state.runtime.get_buffer(buffer_id) {
|
||||
if let (Some(channel_id), Some(cfg)) =
|
||||
(state.runtime.get_discord_channel(buffer_id), state.accounts.get_discord(&buffer.account_id))
|
||||
@@ -963,7 +963,7 @@ pub async fn dispatch(
|
||||
}
|
||||
|
||||
// Synchronous read of the in-memory snapshot built at READY and kept
|
||||
// current by PRESENCE_UPDATE (see backend/discord.rs) - no network
|
||||
// current by PRESENCE_UPDATE (see backend/discord/presence.rs) - no network
|
||||
// round trip needed here, unlike listMatrixDevices.
|
||||
"listDiscordFriends" => match p_str_opt(params, "accountId") {
|
||||
None => (None, Some("listDiscordFriends requires \"accountId\"".to_string())),
|
||||
@@ -1035,7 +1035,7 @@ pub async fn dispatch(
|
||||
}
|
||||
|
||||
// Fallback for a Discord attachment link whose signed `ex=`/`is=`/
|
||||
// `hm=` query string has expired (see backend/discord.rs's
|
||||
// `hm=` query string has expired (see backend/discord/media.rs's
|
||||
// message_link doc comment for why this backend can't just
|
||||
// silently re-sign one the way a real client does) - opens the
|
||||
// real message in an actual Discord client/web session instead,
|
||||
@@ -2639,7 +2639,7 @@ pub async fn dispatch(
|
||||
// QR login is inherently async/multi-step - this just kicks it off
|
||||
// and returns immediately; progress and the eventual result arrive
|
||||
// via discordLoginQr/discordLoginScanned/discordLoginResult events
|
||||
// tagged with this loginId (see backend/discord.rs).
|
||||
// tagged with this loginId (see backend/discord/login.rs).
|
||||
// An optional "accountId" re-authenticates that existing account
|
||||
// instead of adding a new one - the usual reason to run this again is
|
||||
// a token Discord revoked, not a second account. Logging into a
|
||||
|
||||
+13
-13
@@ -214,7 +214,7 @@ pub enum ConnState {
|
||||
/// revoked/invalidated token, not a network hiccup), so retrying with
|
||||
/// the same stored credential can never succeed. The retry loop stops
|
||||
/// entirely rather than backing off and trying again (see
|
||||
/// backend/discord.rs's run_gateway_with_retry) - the only way out is
|
||||
/// backend/discord/gateway.rs's run_gateway_with_retry) - the only way out is
|
||||
/// a fresh login, which upserts the existing account in place (same
|
||||
/// account id, same buffers/scrollback) rather than creating a new one.
|
||||
AuthFailed,
|
||||
@@ -232,7 +232,7 @@ impl ConnState {
|
||||
}
|
||||
|
||||
/// Per-connected-account handle the RPC layer uses to act on a live IRC
|
||||
/// connection (join/part/send) - see backend/irc.rs for what populates
|
||||
/// connection (join/part/send) - see backend/irc/connect.rs for what populates
|
||||
/// this. `nick` is the *current* nick (may differ from the account's
|
||||
/// configured nick after a collision-driven rename, though that's not
|
||||
/// handled yet - out of scope for this milestone).
|
||||
@@ -275,7 +275,7 @@ pub struct Runtime {
|
||||
/// immediately reconnecting a couple of times in a row was enough to
|
||||
/// trigger it against both Libera and Rizon). This isn't something a
|
||||
/// bigger timeout fixes - the fix is not re-triggering it, by pacing
|
||||
/// out attempts on our own end. See backend/irc.rs's spawn().
|
||||
/// out attempts on our own end. See backend/irc/connect.rs's spawn().
|
||||
last_connect_attempt: Mutex<HashMap<String, std::time::Instant>>,
|
||||
/// Guards against a real race: disconnect() on an already-connected
|
||||
/// account only sends QUIT and returns immediately - it does not wait
|
||||
@@ -385,7 +385,7 @@ pub struct Runtime {
|
||||
/// client" deep link (see rpc/methods.rs's getDiscordMessageLink) -
|
||||
/// the fallback for an attachment link whose signature expired, since
|
||||
/// this backend has no way to silently re-sign one itself (see
|
||||
/// backend/discord.rs's message_link doc comment).
|
||||
/// backend/discord/messages.rs's message_link doc comment).
|
||||
discord_guild_id: Mutex<HashMap<String, String>>,
|
||||
/// Guards backend::discord::extend_history against running twice at
|
||||
/// once for the same buffer - getBacklog can be called concurrently by
|
||||
@@ -396,14 +396,15 @@ pub struct Runtime {
|
||||
/// same page of Discord history twice (no per-message dedup here).
|
||||
discord_history_inflight: Mutex<HashSet<String>>,
|
||||
/// Discord-specific: buffer id -> that channel's guild's usable custom
|
||||
/// emoji ({id, name, animated}) - see backend/discord.rs's
|
||||
/// emoji ({id, name, animated}) - see backend/discord/guilds.rs's
|
||||
/// register_guild_channels, populated straight from GUILD_CREATE with
|
||||
/// no extra request needed. Empty/absent for IRC and any Discord DM.
|
||||
discord_buffer_emojis: Mutex<HashMap<String, Vec<serde_json::Value>>>,
|
||||
/// Discord-specific: account id -> friends list ({userId, username,
|
||||
/// globalName, avatarUrl, status}), seeded from READY's `relationships`
|
||||
/// (type 1 = friend) + `presences`, kept current by live PRESENCE_UPDATE
|
||||
/// dispatches - see backend/discord.rs's READY/PRESENCE_UPDATE handling.
|
||||
/// dispatches - see backend/discord/gateway.rs's READY and
|
||||
/// backend/discord/presence.rs's PRESENCE_UPDATE handling.
|
||||
/// Read synchronously by listDiscordFriends (no network round trip
|
||||
/// needed at query time, unlike Matrix's listMatrixDevices).
|
||||
discord_friends: Mutex<HashMap<String, Vec<serde_json::Value>>>,
|
||||
@@ -632,10 +633,9 @@ pub struct Runtime {
|
||||
/// for every member currently *joined* to that room (see roomstate.rs's
|
||||
/// m.room.member handling - a leave/ban removes the entry entirely,
|
||||
/// unlike matrix_member_avatars above which deliberately keeps stale
|
||||
/// data around). This is the actual roster userlist.rs builds from,
|
||||
/// combined with matrix_power_levels (for sort order) and
|
||||
/// matrix_presence (for the online/offline split) - see emit_matrix_
|
||||
/// presence.
|
||||
/// data around). This is the roster roomstate.rs's emit_matrix_presence
|
||||
/// builds from, combined with matrix_power_levels (for sort order) and
|
||||
/// matrix_presence (for the online/offline split).
|
||||
matrix_room_members: Mutex<HashMap<(String, String), HashMap<String, String>>>,
|
||||
/// Matrix-specific: (account id, room id) -> {user id -> the newest
|
||||
/// event id they have a public read receipt against}. Only one entry per
|
||||
@@ -1930,7 +1930,7 @@ impl Runtime {
|
||||
}
|
||||
|
||||
/// Replaces this account's whole friends snapshot - called once from
|
||||
/// READY (see backend/discord.rs), never incrementally, since that's
|
||||
/// READY (see backend/discord/gateway.rs), never incrementally, since that's
|
||||
/// the only point a full, authoritative relationships list exists.
|
||||
/// Live changes after that are per-user PRESENCE_UPDATE patches via
|
||||
/// update_discord_presence below, not further full replaces.
|
||||
@@ -1946,7 +1946,7 @@ impl Runtime {
|
||||
/// dispatch. Returns false (no-op) for a user_id not already in the
|
||||
/// friends list (a guild-mate's presence, not a friend's - Discord's
|
||||
/// gateway sends PRESENCE_UPDATE for both once subscribed) or when the
|
||||
/// status didn't actually change, so backend/discord.rs can skip
|
||||
/// status didn't actually change, so backend/discord/presence.rs can skip
|
||||
/// emitting a redundant discordPresenceUpdate event.
|
||||
pub fn update_discord_presence(&self, account_id: &str, user_id: &str, status: &str) -> bool {
|
||||
let mut friends = self.discord_friends.lock().unwrap();
|
||||
@@ -3504,7 +3504,7 @@ impl Runtime {
|
||||
.or_else(|| self.own_identity(account_id))
|
||||
.unwrap_or_default();
|
||||
// `force_highlight` is Discord's own resolved-mentions answer (see
|
||||
// backend/discord.rs's mentions_own_user) - authoritative when
|
||||
// backend/discord/messages.rs's mentions_own_user) - authoritative when
|
||||
// present, since the nick-substring fallback below can never match
|
||||
// a Discord mention (the body still has `<@id>` tokens, not the
|
||||
// account's nick, by the time this runs). IRC has no such
|
||||
|
||||
+2
-2
@@ -368,7 +368,7 @@ impl Store {
|
||||
// (never seen on this message before) is a rare first-add,
|
||||
// and the next full backlog fetch/reconnect re-syncs it with
|
||||
// the real value from the message's own snapshot (see
|
||||
// extract_reactions in backend/discord.rs, which does know
|
||||
// extract_reactions in backend/discord/messages.rs, which does know
|
||||
// it) - not worth widening this incremental-update path just
|
||||
// for that narrow a window.
|
||||
reactions.push(Reaction { emoji: emoji.to_string(), count: 1, me: is_me, animated: false });
|
||||
@@ -381,7 +381,7 @@ impl Store {
|
||||
}
|
||||
|
||||
/// Whether this buffer has ever recorded anything - the seed-once guard
|
||||
/// for Discord's history backfill (see backend/discord.rs): a buffer
|
||||
/// for Discord's history backfill (see backend/discord/history.rs): a buffer
|
||||
/// with any messages already (from a prior backfill or from having
|
||||
/// seen live traffic) is left alone rather than re-fetched, since
|
||||
/// there's no per-message dedup against Discord's own message ids here.
|
||||
|
||||
Reference in New Issue
Block a user