1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-06 21:45:38 -05:00

refactor: mega refactoring of a bunch of things

This commit is contained in:
bbedward
2025-07-23 11:56:18 -04:00
parent 14eef59c9f
commit 19adcf3578
52 changed files with 4260 additions and 3879 deletions

View File

@@ -0,0 +1,122 @@
import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Io
import Quickshell.Widgets
import qs.Common
import qs.Services
import qs.Widgets
Rectangle {
id: ethernetCard
width: parent.width
height: 80
radius: Theme.cornerRadius
color: {
if (ethernetPreferenceArea.containsMouse && NetworkService.ethernetConnected && NetworkService.wifiEnabled && NetworkService.networkStatus !== "ethernet")
return Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.8);
return Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.5);
}
border.color: NetworkService.networkStatus === "ethernet" ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
border.width: NetworkService.networkStatus === "ethernet" ? 2 : 1
Column {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
anchors.right: ethernetToggle.left
anchors.rightMargin: Theme.spacingM
spacing: Theme.spacingS
Row {
spacing: Theme.spacingM
DankIcon {
name: "lan"
size: Theme.iconSize
color: NetworkService.networkStatus === "ethernet" ? Theme.primary : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: "Ethernet"
font.pixelSize: Theme.fontSizeMedium
color: NetworkService.networkStatus === "ethernet" ? Theme.primary : Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
}
}
Text {
text: NetworkService.ethernetConnected ? (NetworkService.ethernetIP || "Connected") : "Disconnected"
font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
leftPadding: Theme.iconSize + Theme.spacingM
elide: Text.ElideRight
}
}
// Loading spinner for preference changes
DankIcon {
id: ethernetLoadingSpinner
name: "refresh"
size: Theme.iconSize - 4
color: Theme.primary
anchors.right: ethernetToggle.left
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
visible: NetworkService.changingPreference && NetworkService.targetPreference === "ethernet"
z: 10
RotationAnimation {
target: ethernetLoadingSpinner
property: "rotation"
running: ethernetLoadingSpinner.visible
from: 0
to: 360
duration: 1000
loops: Animation.Infinite
}
}
// Ethernet toggle switch (matching WiFi style)
DankToggle {
id: ethernetToggle
checked: NetworkService.ethernetConnected
enabled: true
anchors.right: parent.right
anchors.rightMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
onClicked: {
NetworkService.toggleNetworkConnection("ethernet");
}
}
// MouseArea for network preference (excluding toggle area)
MouseArea {
id: ethernetPreferenceArea
anchors.fill: parent
anchors.rightMargin: 60 // Exclude toggle area
hoverEnabled: true
cursorShape: (NetworkService.ethernetConnected && NetworkService.wifiEnabled && NetworkService.networkStatus !== "ethernet") ? Qt.PointingHandCursor : Qt.ArrowCursor
enabled: NetworkService.ethernetConnected && NetworkService.wifiEnabled && NetworkService.networkStatus !== "ethernet" && !NetworkService.changingNetworkPreference
onClicked: {
if (NetworkService.ethernetConnected && NetworkService.wifiEnabled) {
console.log("Ethernet card clicked for preference");
if (NetworkService.networkStatus !== "ethernet")
NetworkService.setNetworkPreference("ethernet");
else
NetworkService.setNetworkPreference("auto");
}
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}

View File

@@ -0,0 +1,183 @@
import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Io
import Quickshell.Widgets
import qs.Common
import qs.Services
import qs.Widgets
DankModal {
id: root
property bool networkInfoDialogVisible: false
property string networkSSID: ""
property var networkData: null
property string networkDetails: ""
function showNetworkInfo(ssid, data) {
networkSSID = ssid;
networkData = data;
networkInfoDialogVisible = true;
WifiService.fetchNetworkInfo(ssid);
}
function hideDialog() {
networkInfoDialogVisible = false;
networkSSID = "";
networkData = null;
networkDetails = "";
}
visible: networkInfoDialogVisible
width: 600
height: 500
enableShadow: true
onBackgroundClicked: {
hideDialog();
}
onVisibleChanged: {
if (!visible) {
networkSSID = "";
networkData = null;
networkDetails = "";
}
}
content: Component {
Item {
anchors.fill: parent
Column {
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingL
// Header
Row {
width: parent.width
Column {
width: parent.width - 40
spacing: Theme.spacingXS
Text {
text: "Network Information"
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
}
Text {
text: "Details for \"" + networkSSID + "\""
font.pixelSize: Theme.fontSizeMedium
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
width: parent.width
elide: Text.ElideRight
}
}
DankActionButton {
iconName: "close"
iconSize: Theme.iconSize - 4
iconColor: Theme.surfaceText
hoverColor: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12)
onClicked: {
root.hideDialog();
}
}
}
// Network Details
ScrollView {
width: parent.width
height: parent.height - 140
clip: true
ScrollBar.vertical.policy: ScrollBar.AsNeeded
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
Flickable {
contentWidth: parent.width
contentHeight: detailsRect.height
Rectangle {
id: detailsRect
width: parent.width
height: Math.max(parent.parent.height, detailsText.contentHeight + Theme.spacingM * 2)
radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
border.width: 1
Text {
id: detailsText
anchors.fill: parent
anchors.margins: Theme.spacingM
text: WifiService.networkInfoDetails.replace(/\\n/g, '\n') || "No information available"
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
wrapMode: Text.WordWrap
lineHeight: 1.5
}
}
}
}
// Close Button
Item {
width: parent.width
height: 40
Rectangle {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
width: Math.max(70, closeText.contentWidth + Theme.spacingM * 2)
height: 36
radius: Theme.cornerRadius
color: closeArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
Text {
id: closeText
anchors.centerIn: parent
text: "Close"
font.pixelSize: Theme.fontSizeMedium
color: Theme.background
font.weight: Font.Medium
}
MouseArea {
id: closeArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.hideDialog();
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1,174 @@
import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Io
import Quickshell.Widgets
import qs.Common
import qs.Services
import qs.Widgets
Rectangle {
id: wifiCard
property var refreshTimer
function getWiFiSignalIcon(signalStrength) {
switch (signalStrength) {
case "excellent": return "wifi";
case "good": return "wifi_2_bar";
case "fair": return "wifi_1_bar";
case "poor": return "signal_wifi_0_bar";
default: return "wifi";
}
}
width: parent.width
height: 80
radius: Theme.cornerRadius
color: {
if (wifiPreferenceArea.containsMouse && NetworkService.ethernetConnected && NetworkService.wifiEnabled && NetworkService.networkStatus !== "wifi")
return Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.8);
return Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.5);
}
border.color: NetworkService.networkStatus === "wifi" ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
border.width: NetworkService.networkStatus === "wifi" ? 2 : 1
visible: NetworkService.wifiAvailable
Column {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
anchors.right: wifiToggle.left
anchors.rightMargin: Theme.spacingM
spacing: Theme.spacingS
Row {
spacing: Theme.spacingM
DankIcon {
name: {
if (!NetworkService.wifiEnabled) {
return "wifi_off";
} else if (WifiService.currentWifiSSID !== "") {
return getWiFiSignalIcon(WifiService.wifiSignalStrength);
} else {
return "wifi";
}
}
size: Theme.iconSize
color: NetworkService.networkStatus === "wifi" ? Theme.primary : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: {
if (!NetworkService.wifiEnabled) {
return "WiFi is off";
} else if (NetworkService.wifiEnabled && WifiService.currentWifiSSID) {
return WifiService.currentWifiSSID || "Connected";
} else {
return "Not Connected";
}
}
font.pixelSize: Theme.fontSizeMedium
color: NetworkService.networkStatus === "wifi" ? Theme.primary : Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
}
}
Text {
text: {
if (!NetworkService.wifiEnabled) {
return "Turn on WiFi to see networks";
} else if (NetworkService.wifiEnabled && WifiService.currentWifiSSID) {
return NetworkService.wifiIP || "Connected";
} else {
return "Select a network below";
}
}
font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
leftPadding: Theme.iconSize + Theme.spacingM
elide: Text.ElideRight
}
}
// Loading spinner for preference changes
DankIcon {
id: wifiLoadingSpinner
name: "refresh"
size: Theme.iconSize - 4
color: Theme.primary
anchors.right: wifiToggle.left
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
visible: NetworkService.changingPreference && NetworkService.targetPreference === "wifi"
z: 10
RotationAnimation {
target: wifiLoadingSpinner
property: "rotation"
running: wifiLoadingSpinner.visible
from: 0
to: 360
duration: 1000
loops: Animation.Infinite
}
}
// WiFi toggle switch
DankToggle {
id: wifiToggle
checked: NetworkService.wifiEnabled
enabled: true
toggling: NetworkService.wifiToggling
anchors.right: parent.right
anchors.rightMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
onClicked: {
if (NetworkService.wifiEnabled) {
// When turning WiFi off, clear all cached WiFi data
WifiService.currentWifiSSID = "";
WifiService.wifiSignalStrength = "excellent";
WifiService.wifiNetworks = [];
WifiService.savedWifiNetworks = [];
WifiService.connectionStatus = "";
WifiService.connectingSSID = "";
WifiService.isScanning = false;
NetworkService.refreshNetworkStatus();
}
NetworkService.toggleWifiRadio();
if (refreshTimer) {
refreshTimer.triggered = true;
}
}
}
// MouseArea for network preference (excluding toggle area)
MouseArea {
id: wifiPreferenceArea
anchors.fill: parent
anchors.rightMargin: 60 // Exclude toggle area
hoverEnabled: true
cursorShape: (NetworkService.ethernetConnected && NetworkService.wifiEnabled && NetworkService.networkStatus !== "wifi") ? Qt.PointingHandCursor : Qt.ArrowCursor
enabled: NetworkService.ethernetConnected && NetworkService.wifiEnabled && NetworkService.networkStatus !== "wifi" && !NetworkService.changingNetworkPreference
onClicked: {
if (NetworkService.ethernetConnected && NetworkService.wifiEnabled) {
console.log("WiFi card clicked for preference");
if (NetworkService.networkStatus !== "wifi")
NetworkService.setNetworkPreference("wifi");
else
NetworkService.setNetworkPreference("auto");
}
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}

View File

@@ -0,0 +1,280 @@
import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Io
import Quickshell.Widgets
import qs.Common
import qs.Services
import qs.Widgets
Rectangle {
id: wifiContextMenuWindow
property var networkData: null
property bool menuVisible: false
property var parentItem
property var wifiPasswordDialogRef
property var networkInfoDialogRef
function show(x, y) {
const menuWidth = 160;
wifiContextMenuWindow.visible = true;
Qt.callLater(() => {
const menuHeight = wifiMenuColumn.implicitHeight + Theme.spacingS * 2;
let finalX = x - menuWidth / 2;
let finalY = y + 4;
finalX = Math.max(Theme.spacingS, Math.min(finalX, parentItem.width - menuWidth - Theme.spacingS));
finalY = Math.max(Theme.spacingS, Math.min(finalY, parentItem.height - menuHeight - Theme.spacingS));
if (finalY + menuHeight > parentItem.height - Theme.spacingS) {
finalY = y - menuHeight - 4;
finalY = Math.max(Theme.spacingS, finalY);
}
wifiContextMenuWindow.x = finalX;
wifiContextMenuWindow.y = finalY;
wifiContextMenuWindow.menuVisible = true;
});
}
function hide() {
wifiContextMenuWindow.menuVisible = false;
Qt.callLater(() => {
wifiContextMenuWindow.visible = false;
});
}
visible: false
width: 160
height: wifiMenuColumn.implicitHeight + Theme.spacingS * 2
radius: Theme.cornerRadiusLarge
color: Theme.popupBackground()
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
border.width: 1
z: 1000
opacity: menuVisible ? 1 : 0
scale: menuVisible ? 1 : 0.85
Component.onCompleted: {
menuVisible = false;
visible = false;
}
// Drop shadow
Rectangle {
anchors.fill: parent
anchors.topMargin: 4
anchors.leftMargin: 2
anchors.rightMargin: -2
anchors.bottomMargin: -4
radius: parent.radius
color: Qt.rgba(0, 0, 0, 0.15)
z: parent.z - 1
}
Column {
id: wifiMenuColumn
anchors.fill: parent
anchors.margins: Theme.spacingS
spacing: 1
// Connect/Disconnect option
Rectangle {
width: parent.width
height: 32
radius: Theme.cornerRadiusSmall
color: connectWifiArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingS
DankIcon {
name: wifiContextMenuWindow.networkData && wifiContextMenuWindow.networkData.connected ? "wifi_off" : "wifi"
size: Theme.iconSize - 2
color: Theme.surfaceText
opacity: 0.7
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: wifiContextMenuWindow.networkData && wifiContextMenuWindow.networkData.connected ? "Disconnect" : "Connect"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: connectWifiArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (wifiContextMenuWindow.networkData) {
if (wifiContextMenuWindow.networkData.connected) {
WifiService.disconnectWifi();
} else {
if (wifiContextMenuWindow.networkData.saved) {
WifiService.connectToWifi(wifiContextMenuWindow.networkData.ssid);
} else if (wifiContextMenuWindow.networkData.secured) {
if (wifiPasswordDialogRef) {
wifiPasswordDialogRef.wifiPasswordSSID = wifiContextMenuWindow.networkData.ssid;
wifiPasswordDialogRef.wifiPasswordInput = "";
wifiPasswordDialogRef.wifiPasswordDialogVisible = true;
}
} else {
WifiService.connectToWifi(wifiContextMenuWindow.networkData.ssid);
}
}
}
wifiContextMenuWindow.hide();
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
// Separator
Rectangle {
width: parent.width - Theme.spacingS * 2
height: 5
anchors.horizontalCenter: parent.horizontalCenter
color: "transparent"
Rectangle {
anchors.centerIn: parent
width: parent.width
height: 1
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
}
}
// Forget Network option (only for saved networks)
Rectangle {
width: parent.width
height: 32
radius: Theme.cornerRadiusSmall
color: forgetWifiArea.containsMouse ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12) : "transparent"
visible: wifiContextMenuWindow.networkData && (wifiContextMenuWindow.networkData.saved || wifiContextMenuWindow.networkData.connected)
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingS
DankIcon {
name: "delete"
size: Theme.iconSize - 2
color: forgetWifiArea.containsMouse ? Theme.error : Theme.surfaceText
opacity: 0.7
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: "Forget Network"
font.pixelSize: Theme.fontSizeSmall
color: forgetWifiArea.containsMouse ? Theme.error : Theme.surfaceText
font.weight: Font.Normal
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: forgetWifiArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (wifiContextMenuWindow.networkData) {
WifiService.forgetWifiNetwork(wifiContextMenuWindow.networkData.ssid);
}
wifiContextMenuWindow.hide();
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
// Network Info option
Rectangle {
width: parent.width
height: 32
radius: Theme.cornerRadiusSmall
color: infoWifiArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingS
DankIcon {
name: "info"
size: Theme.iconSize - 2
color: Theme.surfaceText
opacity: 0.7
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: "Network Info"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Normal
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: infoWifiArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (wifiContextMenuWindow.networkData && networkInfoDialogRef) {
networkInfoDialogRef.showNetworkInfo(wifiContextMenuWindow.networkData.ssid, wifiContextMenuWindow.networkData);
}
wifiContextMenuWindow.hide();
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
easing.type: Theme.standardEasing
}
}
}
}
Behavior on opacity {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
}

View File

@@ -0,0 +1,276 @@
import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Io
import Quickshell.Widgets
import qs.Common
import qs.Services
import qs.Widgets
Column {
id: root
property var wifiContextMenuWindow
property var sortedWifiNetworks
property var wifiPasswordDialogRef
function getWiFiSignalIcon(signalStrength) {
switch (signalStrength) {
case "excellent": return "wifi";
case "good": return "wifi_2_bar";
case "fair": return "wifi_1_bar";
case "poor": return "signal_wifi_0_bar";
default: return "wifi";
}
}
anchors.top: parent.top
anchors.topMargin: 100
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
visible: NetworkService.wifiEnabled
spacing: Theme.spacingS
// Available Networks Section with refresh button (spanning version)
Row {
width: parent.width
spacing: Theme.spacingS
Text {
text: "Available Networks"
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: parent.width - 170
height: 1
}
// WiFi refresh button (spanning version)
Rectangle {
width: 28
height: 28
radius: 14
color: refreshAreaSpan.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : WifiService.isScanning ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.06) : "transparent"
DankIcon {
id: refreshIconSpan
anchors.centerIn: parent
name: "refresh"
size: Theme.iconSize - 6
color: refreshAreaSpan.containsMouse ? Theme.primary : Theme.surfaceText
rotation: WifiService.isScanning ? refreshIconSpan.rotation : 0
RotationAnimation {
target: refreshIconSpan
property: "rotation"
running: WifiService.isScanning
from: 0
to: 360
duration: 1000
loops: Animation.Infinite
}
Behavior on rotation {
RotationAnimation {
duration: 200
easing.type: Easing.OutQuad
}
}
}
MouseArea {
id: refreshAreaSpan
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (!WifiService.isScanning) {
// Immediate visual feedback
refreshIconSpan.rotation += 30;
WifiService.scanWifi();
}
}
}
}
}
// Scrollable networks container
Flickable {
width: parent.width
height: parent.height - 40
clip: true
contentWidth: width
contentHeight: spanningNetworksColumn.height
boundsBehavior: Flickable.DragAndOvershootBounds
flickDeceleration: 8000
maximumFlickVelocity: 15000
Column {
id: spanningNetworksColumn
width: parent.width
spacing: Theme.spacingXS
Repeater {
model: NetworkService.wifiAvailable && NetworkService.wifiEnabled ? sortedWifiNetworks : []
Rectangle {
width: parent.width
height: 38
radius: Theme.cornerRadiusSmall
color: networkArea2.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : modelData.connected ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
border.color: modelData.connected ? Theme.primary : "transparent"
border.width: modelData.connected ? 1 : 0
Item {
anchors.fill: parent
anchors.margins: Theme.spacingXS
anchors.rightMargin: Theme.spacingM // Extra right margin for scrollbar
// Signal strength icon
DankIcon {
id: signalIcon2
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
name: getWiFiSignalIcon(modelData.signalStrength)
size: Theme.iconSize - 2
color: modelData.connected ? Theme.primary : Theme.surfaceText
}
// Network info
Column {
anchors.left: signalIcon2.right
anchors.leftMargin: Theme.spacingXS
anchors.right: rightIcons2.left
anchors.rightMargin: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
spacing: 2
Text {
width: parent.width
text: modelData.ssid
font.pixelSize: Theme.fontSizeSmall
color: modelData.connected ? Theme.primary : Theme.surfaceText
font.weight: modelData.connected ? Font.Medium : Font.Normal
elide: Text.ElideRight
}
Text {
width: parent.width
text: {
if (modelData.connected)
return "Connected";
if (WifiService.connectionStatus === "connecting" && WifiService.connectingSSID === modelData.ssid)
return "Connecting...";
if (WifiService.connectionStatus === "invalid_password" && WifiService.connectingSSID === modelData.ssid)
return "Invalid password";
if (modelData.saved)
return "Saved" + (modelData.secured ? " • Secured" : " • Open");
return modelData.secured ? "Secured" : "Open";
}
font.pixelSize: Theme.fontSizeSmall - 1
color: {
if (WifiService.connectionStatus === "connecting" && WifiService.connectingSSID === modelData.ssid)
return Theme.primary;
if (WifiService.connectionStatus === "invalid_password" && WifiService.connectingSSID === modelData.ssid)
return Theme.error;
return Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7);
}
elide: Text.ElideRight
}
}
// Right side icons
Row {
id: rightIcons2
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingXS
// Lock icon (if secured)
DankIcon {
name: "lock"
size: Theme.iconSize - 8
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
visible: modelData.secured
anchors.verticalCenter: parent.verticalCenter
}
// Context menu button
Rectangle {
id: wifiMenuButton
width: 24
height: 24
radius: 12
color: wifiMenuButtonArea.containsMouse ? Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.08) : "transparent"
DankIcon {
name: "more_vert"
size: Theme.iconSize - 8
color: Theme.surfaceText
opacity: 0.6
anchors.centerIn: parent
}
MouseArea {
id: wifiMenuButtonArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
wifiContextMenuWindow.networkData = modelData;
let buttonCenter = wifiMenuButtonArea.width / 2;
let buttonBottom = wifiMenuButtonArea.height;
let globalPos = wifiMenuButtonArea.mapToItem(wifiContextMenuWindow.parentItem, buttonCenter, buttonBottom);
Qt.callLater(() => {
wifiContextMenuWindow.show(globalPos.x, globalPos.y);
});
}
}
Behavior on color {
ColorAnimation {
duration: Theme.shortDuration
}
}
}
}
}
MouseArea {
id: networkArea2
anchors.fill: parent
anchors.rightMargin: 32 // Exclude menu button area
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (modelData.connected)
return;
if (modelData.saved) {
WifiService.connectToWifi(modelData.ssid);
} else if (modelData.secured) {
if (wifiPasswordDialogRef) {
wifiPasswordDialogRef.wifiPasswordSSID = modelData.ssid;
wifiPasswordDialogRef.wifiPasswordInput = "";
wifiPasswordDialogRef.wifiPasswordDialogVisible = true;
}
} else {
WifiService.connectToWifi(modelData.ssid);
}
}
}
}
}
}
ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AsNeeded
}
}
}