Files
dms-chat/settings/SneedchatSettingsPanel.qml
SalastilandClaude Sonnet 5 7f3a1d36cd Restructure QML into views/settings/forms, add popout IPC command
- Move the ~17 top-level QML files into views/, settings/, and forms/
  subdirectories, grouped so cross-directory type references stay minimal
  (only 3 files need an added `import` line). Root now only holds the
  four surfaces plugin.json points at directly.
- Add a `dms ipc call dankChat popout` IPC target to open the floating
  window directly, alongside the existing `toggle`, and document both in
  the README along with the new directory layout.
- Add one line of breathing room between the last message and the
  composer bar via the message ListView's bottomMargin (measured with
  FontMetrics rather than a guessed pixel value).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-09 23:41:07 -04:00

120 lines
4.2 KiB
QML

import QtQuick
import QtQuick.Layouts
import qs.Common
import qs.Widgets
// Sneedchat's own settings area, loaded by ChatSettings.qml's protocol
// rail. Unlike IrcSettingsPanel.qml (pure local PluginService preferences,
// used when creating a *new* account), this edits an *existing* account's
// live backend config directly - which room(s) it stays connected to - so
// it needs the current accounts list and a way to reach chatd, threaded in
// from ChatSettings.qml the same way AccountsPanel.qml already receives
// them. Tor transport config lives in its own "Tor" rail category
// (TorSettingsPanel.qml) since there's only one shared embedded Tor client
// for the whole daemon, not one per Sneedchat account.
ColumnLayout {
id: root
property var accounts: []
signal roomsChanged(string accountId, var rooms)
// No server-side "list every room" endpoint exists yet (see the
// project plan's Sneedchat stretch goals) - this is the same fixed
// catalog the account was originally configured with. Extending this
// list to a room the site actually has just means it can be toggled
// on here too; it doesn't need to match the account's already-saved
// room list, which may be a subset.
readonly property var knownChannels: [
{ "id": 1, "name": "general" },
{ "id": 8, "name": "gunt" },
{ "id": 15, "name": "keno-kasino" },
{ "id": 16, "name": "fishtank" },
{ "id": 18, "name": "beauty-parlor" },
{ "id": 19, "name": "sports" }
]
readonly property var sockchatAccount: root.accounts.find(a => a.service === "sockchat") || null
function isChannelEnabled(id) {
return !!(root.sockchatAccount && root.sockchatAccount.sockchatRooms && root.sockchatAccount.sockchatRooms.some(r => r.id === id));
}
function setChannelEnabled(id, enabled) {
if (!root.sockchatAccount)
return;
const current = root.sockchatAccount.sockchatRooms || [];
let next;
if (enabled) {
if (current.some(r => r.id === id))
return;
const ch = root.knownChannels.find(c => c.id === id);
next = current.concat([{ "id": ch.id, "name": ch.name }]);
} else {
next = current.filter(r => r.id !== id);
}
root.roomsChanged(root.sockchatAccount.id, next);
}
spacing: Theme.spacingXS
StyledText {
Layout.fillWidth: true
text: "Sneedchat"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Bold
color: Theme.surfaceVariantText
}
StyledText {
Layout.fillWidth: true
visible: !root.sockchatAccount
text: "No Sneedchat account configured yet - add one from the Accounts pane first."
wrapMode: Text.WordWrap
color: Theme.surfaceVariantText
}
ColumnLayout {
Layout.fillWidth: true
visible: !!root.sockchatAccount
spacing: Theme.spacingXS
StyledText {
Layout.fillWidth: true
text: "Channels"
font.weight: Font.Medium
color: Theme.surfaceVariantText
}
StyledText {
Layout.fillWidth: true
text: "Each enabled channel keeps its own permanent connection - all share one embedded Tor circuit, so enabling more costs very little extra memory."
wrapMode: Text.WordWrap
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
Repeater {
model: root.knownChannels
DankToggle {
required property var modelData
Layout.fillWidth: true
Layout.preferredHeight: height
text: "#" + modelData.name
checked: root.isChannelEnabled(modelData.id)
onToggled: isChecked => root.setChannelEnabled(modelData.id, isChecked)
}
}
StyledText {
Layout.fillWidth: true
text: "Sneedchat is Tor-only - see the Tor settings category for transport and circuit options."
wrapMode: Text.WordWrap
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
}
}