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:
co-authored by
Claude Opus 5.5
parent
d9a0297cc7
commit
3538274805
@@ -50,6 +50,9 @@ private fun translateOnConnectCommand(cmd: String): String {
|
||||
class IrcConnection(
|
||||
val config: ServerConfig,
|
||||
private val scope: CoroutineScope,
|
||||
// Channels to rejoin on top of config.autoJoinChannels - the ones a previous connection
|
||||
// to this server was in (see ConnectionManager.connect).
|
||||
initialChannels: Collection<String> = emptyList(),
|
||||
private val onLine: (ParsedLine) -> Unit,
|
||||
private val onStatus: (String) -> Unit
|
||||
) {
|
||||
@@ -60,13 +63,17 @@ class IrcConnection(
|
||||
@Volatile private var socket: Socket? = null
|
||||
@Volatile private var writer: PrintWriter? = null
|
||||
private var readJob: Job? = null
|
||||
private var wantConnected = false
|
||||
// @Volatile: disconnect() clears it from the UI thread while the read loop checks it on
|
||||
// an IO thread - it's what stops the loop from auto-reconnecting after a /quit.
|
||||
@Volatile private var wantConnected = false
|
||||
private var backoffMillis = 2000L
|
||||
|
||||
// Every channel we're currently in, whether from config.autoJoinChannels or joined
|
||||
// manually mid-session - so a reconnect rejoins everything, not just the original
|
||||
// auto-join list.
|
||||
private val joinedChannels = java.util.concurrent.CopyOnWriteArraySet<String>()
|
||||
private val joinedChannels = java.util.concurrent.CopyOnWriteArraySet<String>(initialChannels)
|
||||
|
||||
fun trackedChannels(): Set<String> = joinedChannels.toSet()
|
||||
|
||||
// Guards runPostRegistration() against running twice for the same connection cycle
|
||||
// (376 and 422 are mutually exclusive per RFC, but this is cheap insurance) - reset
|
||||
@@ -121,6 +128,9 @@ class IrcConnection(
|
||||
Socket(config.host, config.port)
|
||||
}
|
||||
socket = sock
|
||||
// disconnect() can't interrupt a socket that's still being opened, so
|
||||
// check here before registering on a connection nobody wants anymore.
|
||||
ensureActive()
|
||||
val out = PrintWriter(OutputStreamWriter(sock.getOutputStream(), Charsets.UTF_8), true)
|
||||
writer = out
|
||||
|
||||
@@ -161,6 +171,9 @@ class IrcConnection(
|
||||
handleRawLine(line)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// After disconnect() the read fails because we closed the socket
|
||||
// ourselves - that's not an error worth reporting.
|
||||
if (!wantConnected) break
|
||||
onStatus("Connection error: ${e.message}")
|
||||
ircDebug(config.id, "connection dropped: ${e.message} - tracked channels at drop time: $joinedChannels")
|
||||
} finally {
|
||||
@@ -277,6 +290,9 @@ class IrcConnection(
|
||||
try { writer?.println("QUIT :leaving") } catch (_: Exception) {}
|
||||
readJob?.cancel()
|
||||
closeSocketQuietly()
|
||||
// Ends the outbox consumer - this connection is never reused (a reconnect
|
||||
// makes a new IrcConnection), so it would otherwise idle forever.
|
||||
outbox.close()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user