Make bare /quit disconnect only that server, keep windows open, bump to 0.1.9

/quit now disconnects the window's server without closing anything: every
buffer of that server and wIRC main get a "Disconnected" line, the server card
shows Disconnected with its Connect button, history is flushed to disk, and
there's no auto-reconnect. Connect rejoins the channels we were in (including
ones joined with /join, now tracked) into the still-open windows. Sending while
disconnected shows a "Not connected" line in that window. Exit wIRC still
disconnects everything and closes the app.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
weishaupt
2026-10-06 12:46:59 -04:00
co-authored by Claude Opus 5.5
parent d9a0297cc7
commit 3538274805
7 changed files with 162 additions and 31 deletions
+9 -5
View File
@@ -48,7 +48,9 @@ fun MainScreen(
var servers by remember { mutableStateOf(repo.loadAll()) }
var showAddDialog by remember { mutableStateOf(false) }
var editingServer by remember { mutableStateOf<ServerConfig?>(null) }
var connectedIds by remember { mutableStateOf(setOf<String>()) }
// From ConnectionManager rather than local state, so a /quit typed in a channel window
// flips that server's card back to Disconnected with its Connect button.
val connectedIds by ConnectionManager.connectedIds.collectAsState()
var channelInputs by remember { mutableStateOf(mapOf<String, String>()) }
var openedChannels by remember { mutableStateOf(mapOf<String, List<String>>()) }
val coroutineScope = rememberCoroutineScope()
@@ -85,9 +87,8 @@ fun MainScreen(
Text("+ Add Server")
}
Spacer(Modifier.width(8.dp))
// Same end result as typing "/quit" alone in a channel window - disconnects
// every server and terminates the process - just reachable without needing
// a channel window open first.
// Disconnects every server and terminates the process. (A bare "/quit" in a
// channel window only disconnects that window's server.)
TextButton(onClick = onExitApp) {
Text("Exit wIRC")
}
@@ -108,8 +109,9 @@ fun MainScreen(
openedChannels = openedChannels[server.id] ?: emptyList(),
onChannelInputChange = { text -> channelInputs = channelInputs + (server.id to text) },
onConnect = {
// Also rejoins the channels this server was in before a /quit - their
// windows are still open, and opening one that already is is a no-op.
ConnectionManager.connect(server)
connectedIds = connectedIds + server.id
if (server.autoJoinChannels.isNotEmpty()) {
// Auto-join sends JOIN correctly on connect (see IrcConnection),
// but nothing else opens a window for it like the manual
@@ -243,6 +245,8 @@ private fun ServerCard(
Spacer(Modifier.height(8.dp))
if (!isConnected) {
Text("Disconnected", style = MaterialTheme.typography.bodySmall)
Spacer(Modifier.height(4.dp))
Button(onClick = onConnect) { Text("Connect") }
} else {
Text("Connected", style = MaterialTheme.typography.bodySmall)