fix(peer): serve full browse listings + harden the listener; TUI transfer/UX work
Peer layer: - Stream peer messages with a partial-write queue instead of write_all, so a large SharedFileListResponse over the non-blocking socket is no longer truncated (third-party clients like SoulseekQt can now browse our shares). - Bound the peer-init handshake with a read timeout and handle each accepted connection on its own thread, so one stalled peer can't wedge the listener. - e2e: third-party direct/brokered/large-share browse + stalled-peer coverage. TUI: - Uploads share the downloads table columns (real Speed) and the info pane now renders details for a selected upload. - Download progress bar counts only in-progress transfers and hides when idle. - Always-visible unread badge (private messages + rooms) in the shortcuts bar, self-drawn blink so it works under tmux. - Persist the unread private-message count across restarts.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use chrono::{DateTime, Local};
|
||||
use soulseek_rs::types::{RoomEvent, RoomInfo};
|
||||
|
||||
/// One line in a room's chat log. A `None` username marks a system line
|
||||
@@ -6,19 +7,23 @@ use soulseek_rs::types::{RoomEvent, RoomInfo};
|
||||
pub struct RoomLine {
|
||||
pub username: Option<String>,
|
||||
pub text: String,
|
||||
/// Local wall-clock time the line was appended.
|
||||
pub at: DateTime<Local>,
|
||||
}
|
||||
|
||||
impl RoomLine {
|
||||
const fn chat(username: String, text: String) -> Self {
|
||||
fn chat(username: String, text: String) -> Self {
|
||||
Self {
|
||||
username: Some(username),
|
||||
text,
|
||||
at: Local::now(),
|
||||
}
|
||||
}
|
||||
const fn system(text: String) -> Self {
|
||||
fn system(text: String) -> Self {
|
||||
Self {
|
||||
username: None,
|
||||
text,
|
||||
at: Local::now(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user