diff options
Diffstat (limited to 'raveos-calamares-module/wifi/ui/wifi.qml')
| -rw-r--r-- | raveos-calamares-module/wifi/ui/wifi.qml | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/raveos-calamares-module/wifi/ui/wifi.qml b/raveos-calamares-module/wifi/ui/wifi.qml new file mode 100644 index 0000000..2bb6cf6 --- /dev/null +++ b/raveos-calamares-module/wifi/ui/wifi.qml @@ -0,0 +1,373 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import "." as WifiModule + +Rectangle { + id: root + color: WifiModule.Style.backgroundColor + + property string selectedSsid: "" + property bool showHiddenNetwork: false + property bool isConnecting: false + + // Function to update language - called from C++ + function updateLanguage() { + WifiModule.Translations.setLanguage(systemLocale) + } + + // Initialize translations on load + Component.onCompleted: { + WifiModule.Translations.setLanguage(systemLocale) + } + + ColumnLayout { + anchors.fill: parent + anchors.margins: WifiModule.Style.margin + spacing: WifiModule.Style.spacing + + // Header + Label { + text: WifiModule.Translations.title + font.pixelSize: WifiModule.Style.fontSizeTitle + font.bold: true + color: WifiModule.Style.textColor + Layout.alignment: Qt.AlignHCenter + } + + Label { + text: WifiModule.Translations.subtitle + font.pixelSize: WifiModule.Style.fontSizeSubtitle + color: WifiModule.Style.textSecondaryColor + wrapMode: Text.WordWrap + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: Text.AlignHCenter + } + + // Connection status banner + Rectangle { + Layout.fillWidth: true + height: 40 + radius: WifiModule.Style.borderRadius + color: nm.connected ? WifiModule.Style.successColor : WifiModule.Style.progressColor + visible: nm.connected || isConnecting + + RowLayout { + anchors.centerIn: parent + spacing: 10 + + BusyIndicator { + running: isConnecting && !nm.connected + visible: isConnecting && !nm.connected + Layout.preferredWidth: 24 + Layout.preferredHeight: 24 + } + + Label { + text: nm.connected ? WifiModule.Translations.connected : WifiModule.Translations.connecting + color: WifiModule.Style.textColor + font.pixelSize: WifiModule.Style.fontSizeNormal + font.bold: true + } + } + } + + // Network list + Rectangle { + Layout.fillWidth: true + Layout.fillHeight: true + color: WifiModule.Style.listBackgroundColor + radius: WifiModule.Style.borderRadiusLarge + border.color: WifiModule.Style.borderColor + border.width: 1 + + ColumnLayout { + anchors.fill: parent + anchors.margins: 1 + spacing: 0 + + // List header with refresh button + Rectangle { + Layout.fillWidth: true + height: 44 + color: WifiModule.Style.listHeaderColor + radius: WifiModule.Style.borderRadiusLarge + + Rectangle { + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + height: 8 + color: parent.color + } + + RowLayout { + anchors.fill: parent + anchors.leftMargin: 12 + anchors.rightMargin: 8 + + Label { + text: WifiModule.Translations.availableNetworks + color: WifiModule.Style.textColor + font.pixelSize: WifiModule.Style.fontSizeSmall + font.bold: true + } + + Item { Layout.fillWidth: true } + + Button { + text: WifiModule.Translations.refresh + Layout.preferredHeight: 32 + onClicked: nm.scan() + + background: Rectangle { + color: parent.hovered ? WifiModule.Style.buttonSecondaryHoverColor : WifiModule.Style.buttonSecondaryColor + radius: 4 + } + + contentItem: Label { + text: parent.text + color: WifiModule.Style.textColor + font.pixelSize: WifiModule.Style.fontSizeSmall + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + } + } + + // WiFi list + ListView { + id: networkList + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + model: nm.networks + + delegate: Rectangle { + width: networkList.width + height: WifiModule.Style.listItemHeight + color: modelData === selectedSsid ? WifiModule.Style.itemSelectedColor : + (mouseArea.containsMouse ? WifiModule.Style.itemHoverColor : "transparent") + + RowLayout { + anchors.fill: parent + anchors.leftMargin: 16 + anchors.rightMargin: 16 + spacing: 12 + + Label { + text: "" + font.pixelSize: 18 + } + + Label { + text: modelData + color: WifiModule.Style.textColor + font.pixelSize: WifiModule.Style.fontSizeNormal + Layout.fillWidth: true + elide: Text.ElideRight + } + + Label { + text: modelData === selectedSsid ? "✓" : "" + color: WifiModule.Style.successCheckColor + font.pixelSize: 16 + font.bold: true + } + } + + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + onClicked: { + selectedSsid = modelData + showHiddenNetwork = false + ssidField.text = modelData + } + } + + Rectangle { + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 16 + anchors.rightMargin: 16 + height: 1 + color: WifiModule.Style.separatorColor + } + } + + Label { + anchors.centerIn: parent + text: WifiModule.Translations.noNetworks + color: WifiModule.Style.textMutedColor + font.pixelSize: WifiModule.Style.fontSizeSmall + horizontalAlignment: Text.AlignHCenter + visible: nm.networks.length === 0 + } + } + } + } + + // Hidden network toggle + Rectangle { + Layout.fillWidth: true + height: WifiModule.Style.inputHeight + color: "#3d7839" + radius: WifiModule.Style.borderRadius + + MouseArea { + anchors.fill: parent + onClicked: { + showHiddenNetwork = !showHiddenNetwork + if (showHiddenNetwork) { + selectedSsid = "" + ssidField.text = "" + ssidField.focus = true + } + } + } + + RowLayout { + anchors.fill: parent + anchors.leftMargin: 16 + anchors.rightMargin: 16 + + Label { + text: WifiModule.Translations.hiddenNetwork + color: WifiModule.Style.textColor + font.pixelSize: WifiModule.Style.fontSizeNormal + } + + Item { Layout.fillWidth: true } + + Rectangle { + width: 44 + height: 24 + radius: 12 + color: showHiddenNetwork ? WifiModule.Style.toggleOnColor : WifiModule.Style.toggleOffColor + + Rectangle { + width: 20 + height: 20 + radius: 10 + color: WifiModule.Style.textColor + x: showHiddenNetwork ? 22 : 2 + anchors.verticalCenter: parent.verticalCenter + + Behavior on x { + NumberAnimation { duration: 150 } + } + } + } + } + } + + // SSID field (for hidden networks) + TextField { + id: ssidField + Layout.fillWidth: true + placeholderText: WifiModule.Translations.ssidPlaceholder + visible: showHiddenNetwork + color: WifiModule.Style.textColor + placeholderTextColor: WifiModule.Style.inputPlaceholderColor + font.pixelSize: WifiModule.Style.fontSizeNormal + + background: Rectangle { + color: WifiModule.Style.inputBackgroundColor + radius: WifiModule.Style.borderRadius + border.color: ssidField.focus ? WifiModule.Style.inputFocusBorderColor : WifiModule.Style.inputBorderColor + border.width: 1 + } + } + + // Password field + TextField { + id: passField + Layout.fillWidth: true + placeholderText: WifiModule.Translations.passwordPlaceholder + echoMode: TextInput.Password + color: WifiModule.Style.textColor + placeholderTextColor: WifiModule.Style.inputPlaceholderColor + font.pixelSize: WifiModule.Style.fontSizeNormal + enabled: selectedSsid !== "" || showHiddenNetwork + opacity: 1 + + background: Rectangle { + color: passField.enabled ? WifiModule.Style.inputBackgroundColor : WifiModule.Style.inputDisabledColor + radius: WifiModule.Style.borderRadius + border.color: passField.focus ? WifiModule.Style.inputFocusBorderColor : WifiModule.Style.inputBorderColor + border.width: 1 + } + } + + // Connect button + Button { + Layout.fillWidth: true + Layout.preferredHeight: WifiModule.Style.buttonHeight + text: WifiModule.Translations.connect + enabled: (selectedSsid !== "" || (showHiddenNetwork && ssidField.text !== "")) && + passField.text !== "" && !isConnecting && !nm.connected + + onClicked: { + isConnecting = true + var ssid = showHiddenNetwork ? ssidField.text : selectedSsid + nm.connectTo(ssid, passField.text) + } + + background: Rectangle { + color: parent.enabled ? (parent.hovered ? WifiModule.Style.buttonPrimaryHoverColor : WifiModule.Style.buttonPrimaryColor) : WifiModule.Style.buttonDisabledColor + radius: WifiModule.Style.borderRadius + } + + contentItem: Label { + text: parent.text + color: parent.enabled ? WifiModule.Style.textColor : WifiModule.Style.textDisabledColor + font.pixelSize: 15 + font.bold: true + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + // Skip info + Label { + text: nm.connected ? + WifiModule.Translations.clickNextToContinue : + WifiModule.Translations.canSkipWithEthernet + color: WifiModule.Style.textMutedColor + font.pixelSize: WifiModule.Style.fontSizeTiny + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: Text.AlignHCenter + } + } + + // Connection state change handler + Connections { + target: nm + function onConnectionChanged() { + if (nm.connected) { + isConnecting = false + } + } + function onConnectionFailed(error) { + isConnecting = false + console.log("Connection failed: " + error) + } + } + + // Timer to reset connecting state if it takes too long + Timer { + id: connectTimeout + interval: 30000 + running: isConnecting + onTriggered: { + if (!nm.connected) { + isConnecting = false + } + } + } +}
\ No newline at end of file |