Files
dms-chat/forms/DiscordConnectForm.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

84 lines
2.9 KiB
QML

import QtQuick
import QtQuick.Layouts
import qs.Common
import qs.Widgets
// Discord has no username/password path here by design (see the project
// plan's Discord milestone) - the QR flow is Discord's own official
// cross-device login (the same one discord.com/app's "Log in with QR Code"
// offers), just driven from chatd instead of a browser. chatd does all the
// protocol work (backend/discord.rs) and pushes progress back as events;
// this form only ever needs to request a login and render whatever it's
// told to render (QR image / status text) - see ChatView.qml's
// discordLoginQr/discordLoginScanned/discordLoginResult handling.
ColumnLayout {
id: root
signal connectRequested()
property string qrPath: ""
property string statusText: ""
property bool pending: false
// The QML property-binding-vs-assignment rule bites here: `pending` is
// only ever *assigned* (never externally bound) so this component can
// freely clear it itself once anything comes back - a bound property
// would get permanently detached from its binding the instant this
// component's own onClicked assigned to it.
onQrPathChanged: root.pending = false
onStatusTextChanged: root.pending = false
spacing: Theme.spacingXS
StyledText {
Layout.fillWidth: true
text: "Log in the same way the Discord app's own \"Log in with QR Code\" does: open Discord on your phone, go to Settings → Scan QR Code, and point it at the code below."
wrapMode: Text.WordWrap
color: Theme.surfaceVariantText
}
DankButton {
text: root.pending ? "Generating..." : (root.qrPath ? "Show a new QR code" : "Show QR code")
enabled: !root.pending
onClicked: {
root.pending = true;
root.qrPath = "";
root.statusText = "";
root.connectRequested();
}
}
Rectangle {
Layout.preferredWidth: 220
Layout.preferredHeight: 220
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Theme.spacingS
visible: root.qrPath !== ""
color: "white"
radius: Theme.cornerRadius
Image {
anchors.fill: parent
anchors.margins: Theme.spacingM
// chatd renders the QR code to a temp PNG and hands back a
// plain filesystem path (see backend/discord.rs) rather than
// embedding it as a base64 data URI in the event - keeps every
// line on the JSON-RPC socket small.
source: root.qrPath ? "file://" + root.qrPath : ""
fillMode: Image.PreserveAspectFit
smooth: false
cache: false
}
}
StyledText {
Layout.fillWidth: true
Layout.topMargin: Theme.spacingXS
visible: root.statusText !== ""
text: root.statusText
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
color: Theme.surfaceVariantText
}
}