IRC: edit server settings as a draft, applied under the service lock

The IRC App edited the live config while the IRC task could be reading
it to connect. The App now edits a copy; applyConfig() validates it and
swaps it in under the lock, and the task connects from a snapshot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
2026-10-03 18:42:24 +02:00
co-authored by Claude Opus 5.5
parent 4cd6a63498
commit dd16352509
6 changed files with 69 additions and 25 deletions
+7 -6
View File
@@ -98,6 +98,7 @@ bool IrcApp::onChatKey(const KeyEvent& e) {
input_.setText("");
scroll_ = 0;
if (lowered(text) == "/settings") {
draft_.reset(new IrcConfig(irc_.draftConfig()));
page_ = Page::Settings;
fields_.setCount(kFields);
break;
@@ -127,7 +128,7 @@ std::string IrcApp::fieldLabel(int f) const {
}
std::string IrcApp::fieldValue(int f) const {
const IrcConfig& c = irc_.config();
const IrcConfig& c = *draft_;
auto secret = [](const std::string& s) { return s.empty() ? std::string("-") : std::string("(set)"); };
switch (f) {
case kHost: return c.host;
@@ -144,7 +145,7 @@ std::string IrcApp::fieldValue(int f) const {
}
void IrcApp::startEditing(int f) {
const IrcConfig& c = irc_.config();
const IrcConfig& c = *draft_;
fieldEditor_ = LineEditor(f == kAutojoin ? 200 : 63);
switch (f) {
case kHost: fieldEditor_.setText(c.host); break;
@@ -158,7 +159,7 @@ void IrcApp::startEditing(int f) {
}
void IrcApp::finishEditing() {
IrcConfig& c = irc_.config();
IrcConfig& c = *draft_;
const std::string& v = fieldEditor_.text();
switch (fields_.selected()) {
case kHost: c.host = v; break;
@@ -185,12 +186,12 @@ bool IrcApp::onSettingsKey(const KeyEvent& e) {
}
return true;
}
IrcConfig& c = irc_.config();
IrcConfig& c = *draft_;
switch (e.key) {
case Key::Up: fields_.up(); break;
case Key::Down: fields_.down(); break;
case Key::Back:
c.load(c.nick); // discard unsaved edits
draft_.reset(); // discard unsaved edits
page_ = Page::Chat;
break;
case Key::Select:
@@ -201,7 +202,7 @@ bool IrcApp::onSettingsKey(const KeyEvent& e) {
c.pinnedSha256.clear();
break;
case kSave: {
std::string error = irc_.saveConfig();
std::string error = irc_.applyConfig(c);
if (!error.empty()) {
warn(error);
break;