chore: format everything

This commit is contained in:
2 * r + 2 * t 2026-03-20 04:41:56 +11:00
parent 3b08cd6594
commit 9e2ccbede3
58 changed files with 561 additions and 563 deletions

View file

@ -15,6 +15,8 @@ ColumnLayout {
property bool showBackground: false property bool showBackground: false
property bool nested: false property bool nested: false
default property alias content: contentColumn.data
signal toggleRequested signal toggleRequested
spacing: Appearance.spacing.small spacing: Appearance.spacing.small
@ -61,19 +63,18 @@ ColumnLayout {
} }
StateLayer { StateLayer {
anchors.fill: parent
color: Colours.palette.m3onSurface
radius: Appearance.rounding.normal
showHoverBackground: false
function onClicked(): void { function onClicked(): void {
root.toggleRequested(); root.toggleRequested();
root.expanded = !root.expanded; root.expanded = !root.expanded;
} }
anchors.fill: parent
color: Colours.palette.m3onSurface
radius: Appearance.rounding.normal
showHoverBackground: false
} }
} }
default property alias content: contentColumn.data
Item { Item {
id: contentWrapper id: contentWrapper

View file

@ -15,13 +15,13 @@ RowLayout {
property real step: 1 property real step: 1
property alias repeatRate: timer.interval property alias repeatRate: timer.interval
property bool isEditing: false
property string displayText: root.value.toString()
signal valueModified(value: real) signal valueModified(value: real)
spacing: Appearance.spacing.small spacing: Appearance.spacing.small
property bool isEditing: false
property string displayText: root.value.toString()
onValueChanged: { onValueChanged: {
if (!root.isEditing) { if (!root.isEditing) {
root.displayText = root.value.toString(); root.displayText = root.value.toString();
@ -94,11 +94,6 @@ RowLayout {
StateLayer { StateLayer {
id: upState id: upState
color: Colours.palette.m3onPrimary
onPressAndHold: timer.start()
onReleased: timer.stop()
function onClicked(): void { function onClicked(): void {
let newValue = Math.min(root.max, root.value + root.step); let newValue = Math.min(root.max, root.value + root.step);
// Round to avoid floating point precision errors // Round to avoid floating point precision errors
@ -108,6 +103,11 @@ RowLayout {
root.displayText = newValue.toString(); root.displayText = newValue.toString();
root.valueModified(newValue); root.valueModified(newValue);
} }
color: Colours.palette.m3onPrimary
onPressAndHold: timer.start()
onReleased: timer.stop()
} }
MaterialIcon { MaterialIcon {
@ -129,11 +129,6 @@ RowLayout {
StateLayer { StateLayer {
id: downState id: downState
color: Colours.palette.m3onPrimary
onPressAndHold: timer.start()
onReleased: timer.stop()
function onClicked(): void { function onClicked(): void {
let newValue = Math.max(root.min, root.value - root.step); let newValue = Math.max(root.min, root.value - root.step);
// Round to avoid floating point precision errors // Round to avoid floating point precision errors
@ -143,6 +138,11 @@ RowLayout {
root.displayText = newValue.toString(); root.displayText = newValue.toString();
root.valueModified(newValue); root.valueModified(newValue);
} }
color: Colours.palette.m3onPrimary
onPressAndHold: timer.start()
onReleased: timer.stop()
} }
MaterialIcon { MaterialIcon {

View file

@ -53,14 +53,14 @@ StyledRect {
StateLayer { StateLayer {
id: stateLayer id: stateLayer
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
disabled: root.disabled
function onClicked(): void { function onClicked(): void {
if (root.toggle) if (root.toggle)
root.internalChecked = !root.internalChecked; root.internalChecked = !root.internalChecked;
root.clicked(); root.clicked();
} }
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
disabled: root.disabled
} }
MaterialIcon { MaterialIcon {

View file

@ -45,13 +45,13 @@ StyledRect {
StateLayer { StateLayer {
id: stateLayer id: stateLayer
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
function onClicked(): void { function onClicked(): void {
if (root.toggle) if (root.toggle)
root.internalChecked = !root.internalChecked; root.internalChecked = !root.internalChecked;
root.clicked(); root.clicked();
} }
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
} }
RowLayout { RowLayout {

View file

@ -52,14 +52,14 @@ Elevation {
color: Qt.alpha(Colours.palette.m3secondaryContainer, active ? 1 : 0) color: Qt.alpha(Colours.palette.m3secondaryContainer, active ? 1 : 0)
StateLayer { StateLayer {
color: item.active ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
disabled: !root.expanded
function onClicked(): void { function onClicked(): void {
root.itemSelected(item.modelData); root.itemSelected(item.modelData);
root.active = item.modelData; root.active = item.modelData;
root.expanded = false; root.expanded = false;
} }
color: item.active ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
disabled: !root.expanded
} }
RowLayout { RowLayout {

View file

@ -47,14 +47,14 @@ Row {
StateLayer { StateLayer {
id: stateLayer id: stateLayer
function onClicked(): void {
root.active?.clicked();
}
rect.topRightRadius: parent.topRightRadius rect.topRightRadius: parent.topRightRadius
rect.bottomRightRadius: parent.bottomRightRadius rect.bottomRightRadius: parent.bottomRightRadius
color: root.textColour color: root.textColour
disabled: root.disabled disabled: root.disabled
function onClicked(): void {
root.active?.clicked();
}
} }
RowLayout { RowLayout {
@ -109,14 +109,14 @@ Row {
StateLayer { StateLayer {
id: expandStateLayer id: expandStateLayer
function onClicked(): void {
root.expanded = !root.expanded;
}
rect.topLeftRadius: parent.topLeftRadius rect.topLeftRadius: parent.topLeftRadius
rect.bottomLeftRadius: parent.bottomLeftRadius rect.bottomLeftRadius: parent.bottomLeftRadius
color: root.textColour color: root.textColour
disabled: root.disabled disabled: root.disabled
function onClicked(): void {
root.expanded = !root.expanded;
}
} }
MaterialIcon { MaterialIcon {

View file

@ -24,13 +24,13 @@ RadioButton {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
StateLayer { StateLayer {
anchors.margins: -Appearance.padding.smaller
color: root.checked ? Colours.palette.m3onSurface : Colours.palette.m3primary
z: -1
function onClicked(): void { function onClicked(): void {
root.click(); root.click();
} }
anchors.margins: -Appearance.padding.smaller
color: root.checked ? Colours.palette.m3onSurface : Colours.palette.m3primary
z: -1
} }
StyledRect { StyledRect {

View file

@ -11,6 +11,8 @@ ScrollBar {
property bool shouldBeActive property bool shouldBeActive
property real nonAnimPosition property real nonAnimPosition
property bool animating property bool animating
property bool _updatingFromFlickable: false
property bool _updatingFromUser: false
onHoveredChanged: { onHoveredChanged: {
if (hovered) if (hovered)
@ -19,9 +21,6 @@ ScrollBar {
shouldBeActive = flickable.moving; shouldBeActive = flickable.moving;
} }
property bool _updatingFromFlickable: false
property bool _updatingFromUser: false
// Sync nonAnimPosition with Qt's automatic position binding // Sync nonAnimPosition with Qt's automatic position binding
onPositionChanged: { onPositionChanged: {
if (_updatingFromUser) { if (_updatingFromUser) {
@ -118,6 +117,29 @@ ScrollBar {
CustomMouseArea { CustomMouseArea {
id: fullMouse id: fullMouse
function onWheel(event: WheelEvent): void {
root.animating = true;
root._updatingFromUser = true;
let newPos = root.nonAnimPosition;
if (event.angleDelta.y > 0)
newPos = Math.max(0, root.nonAnimPosition - 0.1);
else if (event.angleDelta.y < 0)
newPos = Math.min(1 - root.size, root.nonAnimPosition + 0.1);
root.nonAnimPosition = newPos;
// Update flickable position
// Map scrollbar position [0, 1-size] to contentY [0, maxContentY]
if (root.flickable) {
const contentHeight = root.flickable.contentHeight;
const height = root.flickable.height;
if (contentHeight > height) {
const maxContentY = contentHeight - height;
const maxPos = 1 - root.size;
const contentY = maxPos > 0 ? (newPos / maxPos) * maxContentY : 0;
root.flickable.contentY = Math.max(0, Math.min(maxContentY, contentY));
}
}
}
anchors.fill: parent anchors.fill: parent
preventStealing: true preventStealing: true
@ -157,29 +179,6 @@ ScrollBar {
} }
} }
} }
function onWheel(event: WheelEvent): void {
root.animating = true;
root._updatingFromUser = true;
let newPos = root.nonAnimPosition;
if (event.angleDelta.y > 0)
newPos = Math.max(0, root.nonAnimPosition - 0.1);
else if (event.angleDelta.y < 0)
newPos = Math.min(1 - root.size, root.nonAnimPosition + 0.1);
root.nonAnimPosition = newPos;
// Update flickable position
// Map scrollbar position [0, 1-size] to contentY [0, maxContentY]
if (root.flickable) {
const contentHeight = root.flickable.contentHeight;
const height = root.flickable.height;
if (contentHeight > height) {
const maxContentY = contentHeight - height;
const maxPos = 1 - root.size;
const contentY = maxPos > 0 ? (newPos / maxPos) * maxContentY : 0;
root.flickable.contentY = Math.max(0, Math.min(maxContentY, contentY));
}
}
}
} }
Behavior on position { Behavior on position {

View file

@ -56,13 +56,13 @@ StyledRect {
StateLayer { StateLayer {
id: stateLayer id: stateLayer
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
function onClicked(): void { function onClicked(): void {
if (root.toggle) if (root.toggle)
root.internalChecked = !root.internalChecked; root.internalChecked = !root.internalChecked;
root.clicked(); root.clicked();
} }
color: root.internalChecked ? root.activeOnColour : root.inactiveOnColour
} }
StyledText { StyledText {

View file

@ -46,11 +46,11 @@ StyledRect {
StateLayer { StateLayer {
id: toggleStateLayer id: toggleStateLayer
color: root.toggled ? Colours.palette[`m3on${root.accent}`] : Colours.palette[`m3on${root.accent}Container`]
function onClicked(): void { function onClicked(): void {
root.clicked(); root.clicked();
} }
color: root.toggled ? Colours.palette[`m3on${root.accent}`] : Colours.palette[`m3on${root.accent}Container`]
} }
RowLayout { RowLayout {

View file

@ -24,6 +24,43 @@ Popup {
onTriggered: root.tooltipVisible = false onTriggered: root.tooltipVisible = false
} }
function updatePosition() {
if (!target || !parent)
return;
// Wait for tooltipRect to have its size calculated
Qt.callLater(() => {
if (!target || !parent || !tooltipRect)
return;
// Get target position in parent's coordinate system
const targetPos = target.mapToItem(parent, 0, 0);
const targetCenterX = targetPos.x + target.width / 2;
// Get tooltip size (use width/height if available, otherwise implicit)
const tooltipWidth = tooltipRect.width > 0 ? tooltipRect.width : tooltipRect.implicitWidth;
const tooltipHeight = tooltipRect.height > 0 ? tooltipRect.height : tooltipRect.implicitHeight;
// Center tooltip horizontally on target
let newX = targetCenterX - tooltipWidth / 2;
// Position tooltip above target
let newY = targetPos.y - tooltipHeight - Appearance.spacing.small;
// Keep within bounds
const padding = Appearance.padding.normal;
if (newX < padding) {
newX = padding;
} else if (newX + tooltipWidth > (parent.width - padding)) {
newX = parent.width - tooltipWidth - padding;
}
// Update popup position
x = newX;
y = newY;
});
}
// Popup properties - doesn't affect layout // Popup properties - doesn't affect layout
parent: { parent: {
let p = target; let p = target;
@ -73,43 +110,6 @@ Popup {
} }
} }
function updatePosition() {
if (!target || !parent)
return;
// Wait for tooltipRect to have its size calculated
Qt.callLater(() => {
if (!target || !parent || !tooltipRect)
return;
// Get target position in parent's coordinate system
const targetPos = target.mapToItem(parent, 0, 0);
const targetCenterX = targetPos.x + target.width / 2;
// Get tooltip size (use width/height if available, otherwise implicit)
const tooltipWidth = tooltipRect.width > 0 ? tooltipRect.width : tooltipRect.implicitWidth;
const tooltipHeight = tooltipRect.height > 0 ? tooltipRect.height : tooltipRect.implicitHeight;
// Center tooltip horizontally on target
let newX = targetCenterX - tooltipWidth / 2;
// Position tooltip above target
let newY = targetPos.y - tooltipHeight - Appearance.spacing.small;
// Keep within bounds
const padding = Appearance.padding.normal;
if (newX < padding) {
newX = padding;
} else if (newX + tooltipWidth > (parent.width - padding)) {
newX = parent.width - tooltipWidth - padding;
}
// Update popup position
x = newX;
y = newY;
});
}
enter: Transition { enter: Transition {
Anim { Anim {
property: "opacity" property: "opacity"

View file

@ -49,11 +49,11 @@ StyledRect {
implicitHeight: cancelText.implicitHeight + Appearance.padding.normal * 2 implicitHeight: cancelText.implicitHeight + Appearance.padding.normal * 2
StateLayer { StateLayer {
disabled: !root.dialog.selectionValid
function onClicked(): void { function onClicked(): void {
root.dialog.accepted(root.folder.currentItem.modelData.path); root.dialog.accepted(root.folder.currentItem.modelData.path);
} }
disabled: !root.dialog.selectionValid
} }
StyledText { StyledText {

View file

@ -28,12 +28,12 @@ StyledRect {
implicitHeight: upIcon.implicitHeight + Appearance.padding.small * 2 implicitHeight: upIcon.implicitHeight + Appearance.padding.small * 2
StateLayer { StateLayer {
radius: Appearance.rounding.small
disabled: root.dialog.cwd.length === 1
function onClicked(): void { function onClicked(): void {
root.dialog.cwd.pop(); root.dialog.cwd.pop();
} }
radius: Appearance.rounding.small
disabled: root.dialog.cwd.length === 1
} }
MaterialIcon { MaterialIcon {
@ -94,11 +94,11 @@ StyledRect {
anchors.fill: parent anchors.fill: parent
active: folder.index < root.dialog.cwd.length - 1 active: folder.index < root.dialog.cwd.length - 1
sourceComponent: StateLayer { sourceComponent: StateLayer {
radius: Appearance.rounding.small
function onClicked(): void { function onClicked(): void {
root.dialog.cwd = root.dialog.cwd.slice(0, folder.index + 1); root.dialog.cwd = root.dialog.cwd.slice(0, folder.index + 1);
} }
radius: Appearance.rounding.small
} }
} }

View file

@ -51,14 +51,14 @@ StyledRect {
color: Qt.alpha(Colours.palette.m3secondaryContainer, selected ? 1 : 0) color: Qt.alpha(Colours.palette.m3secondaryContainer, selected ? 1 : 0)
StateLayer { StateLayer {
color: place.selected ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
function onClicked(): void { function onClicked(): void {
if (place.modelData === "Home") if (place.modelData === "Home")
root.dialog.cwd = ["Home"]; root.dialog.cwd = ["Home"];
else else
root.dialog.cwd = ["Home", place.modelData]; root.dialog.cwd = ["Home", place.modelData];
} }
color: place.selected ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
} }
RowLayout { RowLayout {

View file

@ -79,12 +79,12 @@ Item {
} }
StateLayer { StateLayer {
radius: parent.radius
color: Colours.palette.m3onPrimary
function onClicked(): void { function onClicked(): void {
dialog.open(); dialog.open();
} }
radius: parent.radius
color: Colours.palette.m3onPrimary
} }
StyledText { StyledText {

View file

@ -65,11 +65,11 @@ Item {
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
StateLayer { StateLayer {
radius: Appearance.rounding.normal
function onClicked(): void { function onClicked(): void {
root.wrapper.detach("winfo"); root.wrapper.detach("winfo");
} }
radius: Appearance.rounding.normal
} }
MaterialIcon { MaterialIcon {

View file

@ -205,12 +205,12 @@ Column {
implicitHeight: icon.implicitHeight + Appearance.padding.small * 2 implicitHeight: icon.implicitHeight + Appearance.padding.small * 2
StateLayer { StateLayer {
radius: Appearance.rounding.full
color: profiles.current === parent.icon ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
function onClicked(): void { function onClicked(): void {
PowerProfiles.profile = parent.profile; PowerProfiles.profile = parent.profile;
} }
radius: Appearance.rounding.full
color: profiles.current === parent.icon ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
} }
MaterialIcon { MaterialIcon {

View file

@ -117,12 +117,12 @@ ColumnLayout {
} }
StateLayer { StateLayer {
color: device.modelData.state === BluetoothDeviceState.Connected ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
disabled: device.loading
function onClicked(): void { function onClicked(): void {
device.modelData.connected = !device.modelData.connected; device.modelData.connected = !device.modelData.connected;
} }
color: device.modelData.state === BluetoothDeviceState.Connected ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
disabled: device.loading
} }
MaterialIcon { MaterialIcon {
@ -149,11 +149,11 @@ ColumnLayout {
implicitHeight: connectBtn.implicitHeight implicitHeight: connectBtn.implicitHeight
StateLayer { StateLayer {
radius: Appearance.rounding.full
function onClicked(): void { function onClicked(): void {
device.modelData.forget(); device.modelData.forget();
} }
radius: Appearance.rounding.full
} }
MaterialIcon { MaterialIcon {

View file

@ -123,9 +123,6 @@ ColumnLayout {
} }
StateLayer { StateLayer {
color: networkItem.modelData.active ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
disabled: networkItem.loading || !Nmcli.wifiEnabled
function onClicked(): void { function onClicked(): void {
if (networkItem.modelData.active) { if (networkItem.modelData.active) {
Nmcli.disconnectFromNetwork(); Nmcli.disconnectFromNetwork();
@ -142,6 +139,9 @@ ColumnLayout {
// This is handled by the onActiveChanged connection below // This is handled by the onActiveChanged connection below
} }
} }
color: networkItem.modelData.active ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
disabled: networkItem.loading || !Nmcli.wifiEnabled
} }
MaterialIcon { MaterialIcon {
@ -173,12 +173,12 @@ ColumnLayout {
color: Colours.palette.m3primaryContainer color: Colours.palette.m3primaryContainer
StateLayer { StateLayer {
color: Colours.palette.m3onPrimaryContainer
disabled: Nmcli.scanning || !Nmcli.wifiEnabled
function onClicked(): void { function onClicked(): void {
Nmcli.rescanWifi(); Nmcli.rescanWifi();
} }
color: Colours.palette.m3onPrimaryContainer
disabled: Nmcli.scanning || !Nmcli.wifiEnabled
} }
RowLayout { RowLayout {
@ -303,9 +303,6 @@ ColumnLayout {
} }
StateLayer { StateLayer {
color: ethernetItem.modelData.connected ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
disabled: ethernetItem.loading
function onClicked(): void { function onClicked(): void {
if (ethernetItem.modelData.connected && ethernetItem.modelData.connection) { if (ethernetItem.modelData.connected && ethernetItem.modelData.connection) {
Nmcli.disconnectEthernet(ethernetItem.modelData.connection, () => {}); Nmcli.disconnectEthernet(ethernetItem.modelData.connection, () => {});
@ -313,6 +310,9 @@ ColumnLayout {
Nmcli.connectEthernet(ethernetItem.modelData.connection || "", ethernetItem.modelData.interface || "", () => {}); Nmcli.connectEthernet(ethernetItem.modelData.connection || "", ethernetItem.modelData.interface || "", () => {});
} }
} }
color: ethernetItem.modelData.connected ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
disabled: ethernetItem.loading
} }
MaterialIcon { MaterialIcon {

View file

@ -91,13 +91,6 @@ StackView {
implicitHeight: label.implicitHeight implicitHeight: label.implicitHeight
StateLayer { StateLayer {
anchors.margins: -Appearance.padding.small / 2
anchors.leftMargin: -Appearance.padding.smaller
anchors.rightMargin: -Appearance.padding.smaller
radius: item.radius
disabled: !item.modelData.enabled
function onClicked(): void { function onClicked(): void {
const entry = item.modelData; const entry = item.modelData;
if (entry.hasChildren) if (entry.hasChildren)
@ -110,6 +103,13 @@ StackView {
root.popouts.hasCurrent = false; root.popouts.hasCurrent = false;
} }
} }
anchors.margins: -Appearance.padding.small / 2
anchors.leftMargin: -Appearance.padding.smaller
anchors.rightMargin: -Appearance.padding.smaller
radius: item.radius
disabled: !item.modelData.enabled
} }
Loader { Loader {
@ -191,12 +191,12 @@ StackView {
color: Colours.palette.m3secondaryContainer color: Colours.palette.m3secondaryContainer
StateLayer { StateLayer {
radius: parent.radius
color: Colours.palette.m3onSecondaryContainer
function onClicked(): void { function onClicked(): void {
root.pop(); root.pop();
} }
radius: parent.radius
color: Colours.palette.m3onSecondaryContainer
} }
} }

View file

@ -18,6 +18,57 @@ ColumnLayout {
readonly property bool shouldBeVisible: root.wrapper.currentName === "wirelesspassword" readonly property bool shouldBeVisible: root.wrapper.currentName === "wirelesspassword"
function checkConnectionStatus(): void {
if (!root.shouldBeVisible || !connectButton.connecting) {
return;
}
// Check if we're connected to the target network (case-insensitive SSID comparison)
const isConnected = root.network && Nmcli.active && Nmcli.active.ssid && Nmcli.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim();
if (isConnected) {
// Successfully connected - give it a moment for network list to update
// Use Timer for actual delay
connectionSuccessTimer.start();
return;
}
// Check for connection failures - if pending connection was cleared but we're not connected
if (Nmcli.pendingConnection === null && connectButton.connecting) {
// Wait a bit more before giving up (allow time for connection to establish)
if (connectionMonitor.repeatCount > 10) {
connectionMonitor.stop();
connectButton.connecting = false;
connectButton.hasError = true;
connectButton.enabled = true;
connectButton.text = qsTr("Connect");
passwordContainer.passwordBuffer = "";
// Delete the failed connection
if (root.network && root.network.ssid) {
Nmcli.forgetNetwork(root.network.ssid);
}
}
}
}
function closeDialog(): void {
if (isClosing) {
return;
}
isClosing = true;
passwordContainer.passwordBuffer = "";
connectButton.connecting = false;
connectButton.hasError = false;
connectButton.text = qsTr("Connect");
connectionMonitor.stop();
// Return to network popout
if (root.wrapper.currentName === "wirelesspassword") {
root.wrapper.currentName = "network";
}
}
Connections { Connections {
target: root.wrapper target: root.wrapper
function onCurrentNameChanged() { function onCurrentNameChanged() {
@ -305,13 +356,13 @@ ColumnLayout {
} }
StateLayer { StateLayer {
hoverEnabled: false
cursorShape: Qt.IBeamCursor
radius: Appearance.rounding.normal
function onClicked(): void { function onClicked(): void {
passwordContainer.forceActiveFocus(); passwordContainer.forceActiveFocus();
} }
hoverEnabled: false
cursorShape: Qt.IBeamCursor
radius: Appearance.rounding.normal
} }
StyledText { StyledText {
@ -495,39 +546,6 @@ ColumnLayout {
} }
} }
function checkConnectionStatus(): void {
if (!root.shouldBeVisible || !connectButton.connecting) {
return;
}
// Check if we're connected to the target network (case-insensitive SSID comparison)
const isConnected = root.network && Nmcli.active && Nmcli.active.ssid && Nmcli.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim();
if (isConnected) {
// Successfully connected - give it a moment for network list to update
// Use Timer for actual delay
connectionSuccessTimer.start();
return;
}
// Check for connection failures - if pending connection was cleared but we're not connected
if (Nmcli.pendingConnection === null && connectButton.connecting) {
// Wait a bit more before giving up (allow time for connection to establish)
if (connectionMonitor.repeatCount > 10) {
connectionMonitor.stop();
connectButton.connecting = false;
connectButton.hasError = true;
connectButton.enabled = true;
connectButton.text = qsTr("Connect");
passwordContainer.passwordBuffer = "";
// Delete the failed connection
if (root.network && root.network.ssid) {
Nmcli.forgetNetwork(root.network.ssid);
}
}
}
}
Timer { Timer {
id: connectionMonitor id: connectionMonitor
@ -590,22 +608,4 @@ ColumnLayout {
} }
} }
} }
function closeDialog(): void {
if (isClosing) {
return;
}
isClosing = true;
passwordContainer.passwordBuffer = "";
connectButton.connecting = false;
connectButton.hasError = false;
connectButton.text = qsTr("Connect");
connectionMonitor.stop();
// Return to network popout
if (root.wrapper.currentName === "wirelesspassword") {
root.wrapper.currentName = "network";
}
}
} }

View file

@ -16,18 +16,19 @@ ColumnLayout {
required property Item wrapper required property Item wrapper
function refresh() {
kb.refresh();
}
spacing: Appearance.spacing.small spacing: Appearance.spacing.small
width: Config.bar.sizes.kbLayoutWidth width: Config.bar.sizes.kbLayoutWidth
Component.onCompleted: kb.start()
KbLayoutModel { KbLayoutModel {
id: kb id: kb
} }
function refresh() {
kb.refresh();
}
Component.onCompleted: kb.start()
StyledText { StyledText {
Layout.topMargin: Appearance.padding.normal Layout.topMargin: Appearance.padding.normal
Layout.rightMargin: Appearance.padding.small Layout.rightMargin: Appearance.padding.small
@ -97,6 +98,11 @@ ColumnLayout {
StateLayer { StateLayer {
id: layer id: layer
function onClicked(): void {
if (!isDisabled)
kb.switchTo(layoutIndex);
}
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@ -104,11 +110,6 @@ ColumnLayout {
radius: Appearance.rounding.full radius: Appearance.rounding.full
enabled: !isDisabled enabled: !isDisabled
function onClicked(): void {
if (!isDisabled)
kb.switchTo(layoutIndex);
}
} }
StyledText { StyledText {

View file

@ -36,33 +36,6 @@ Item {
_switchProc.running = true; _switchProc.running = true;
} }
ListModel {
id: _layoutsModel
}
property var _xkbMap: ({})
property bool _notifiedLimit: false
Process {
id: _xkbXmlBase
command: ["xmllint", "--xpath", "//layout/configItem[name and description]", "/usr/share/X11/xkb/rules/base.xml"]
stdout: StdioCollector {
onStreamFinished: _buildXmlMap(text)
}
onRunningChanged: if (!running && (typeof exitCode !== "undefined") && exitCode !== 0)
_xkbXmlEvdev.running = true
}
Process {
id: _xkbXmlEvdev
command: ["xmllint", "--xpath", "//layout/configItem[name and description]", "/usr/share/X11/xkb/rules/evdev.xml"]
stdout: StdioCollector {
onStreamFinished: _buildXmlMap(text)
}
}
function _buildXmlMap(xml) { function _buildXmlMap(xml) {
const map = {}; const map = {};
@ -108,6 +81,78 @@ Item {
return `${lang} (${code})`; return `${lang} (${code})`;
} }
function _setLayouts(raw) {
const parts = raw.split(",").map(s => s.trim()).filter(Boolean);
_layoutsModel.clear();
const seen = new Set();
let idx = 0;
for (const p of parts) {
if (seen.has(p))
continue;
seen.add(p);
_layoutsModel.append({
layoutIndex: idx,
token: p,
label: _pretty(p)
});
idx++;
}
}
function _rebuildVisible() {
_visibleModel.clear();
let arr = [];
for (let i = 0; i < _layoutsModel.count; i++)
arr.push(_layoutsModel.get(i));
arr = arr.filter(i => i.layoutIndex !== activeIndex);
arr.forEach(i => _visibleModel.append(i));
if (!Config.utilities.toasts.kbLimit)
return;
if (_layoutsModel.count > 4) {
Toaster.toast(qsTr("Keyboard layout limit"), qsTr("XKB supports only 4 layouts at a time"), "warning");
}
}
function _pretty(token) {
const code = token.replace(/\(.*\)$/, "").trim();
if (_xkbMap[code])
return code.toUpperCase() + " - " + _xkbMap[code];
return code.toUpperCase() + " - " + code;
}
ListModel {
id: _layoutsModel
}
property var _xkbMap: ({})
property bool _notifiedLimit: false
Process {
id: _xkbXmlBase
command: ["xmllint", "--xpath", "//layout/configItem[name and description]", "/usr/share/X11/xkb/rules/base.xml"]
stdout: StdioCollector {
onStreamFinished: _buildXmlMap(text)
}
onRunningChanged: if (!running && (typeof exitCode !== "undefined") && exitCode !== 0)
_xkbXmlEvdev.running = true
}
Process {
id: _xkbXmlEvdev
command: ["xmllint", "--xpath", "//layout/configItem[name and description]", "/usr/share/X11/xkb/rules/evdev.xml"]
stdout: StdioCollector {
onStreamFinished: _buildXmlMap(text)
}
}
Process { Process {
id: _getKbLayoutOpt id: _getKbLayoutOpt
@ -175,49 +220,4 @@ Item {
onRunningChanged: if (!running) onRunningChanged: if (!running)
_fetchActiveLayouts.running = true _fetchActiveLayouts.running = true
} }
function _setLayouts(raw) {
const parts = raw.split(",").map(s => s.trim()).filter(Boolean);
_layoutsModel.clear();
const seen = new Set();
let idx = 0;
for (const p of parts) {
if (seen.has(p))
continue;
seen.add(p);
_layoutsModel.append({
layoutIndex: idx,
token: p,
label: _pretty(p)
});
idx++;
}
}
function _rebuildVisible() {
_visibleModel.clear();
let arr = [];
for (let i = 0; i < _layoutsModel.count; i++)
arr.push(_layoutsModel.get(i));
arr = arr.filter(i => i.layoutIndex !== activeIndex);
arr.forEach(i => _visibleModel.append(i));
if (!Config.utilities.toasts.kbLimit)
return;
if (_layoutsModel.count > 4) {
Toaster.toast(qsTr("Keyboard layout limit"), qsTr("XKB supports only 4 layouts at a time"), "warning");
}
}
function _pretty(token) {
const code = token.replace(/\(.*\)$/, "").trim();
if (_xkbMap[code])
return code.toUpperCase() + " - " + _xkbMap[code];
return code.toUpperCase() + " - " + code;
}
} }

View file

@ -59,8 +59,6 @@ Item {
StateLayer { StateLayer {
id: normalWinState id: normalWinState
color: Colours.palette.m3onPrimaryContainer
function onClicked(): void { function onClicked(): void {
root.session.root.close(); root.session.root.close();
WindowFactory.create(null, { WindowFactory.create(null, {
@ -68,6 +66,8 @@ Item {
navExpanded: root.session.navExpanded navExpanded: root.session.navExpanded
}); });
} }
color: Colours.palette.m3onPrimaryContainer
} }
MaterialIcon { MaterialIcon {
@ -175,8 +175,6 @@ Item {
implicitHeight: icon.implicitHeight + Appearance.padding.small implicitHeight: icon.implicitHeight + Appearance.padding.small
StateLayer { StateLayer {
color: item.active ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
function onClicked(): void { function onClicked(): void {
// Prevent tab switching during initial opening animation to avoid blank pages // Prevent tab switching during initial opening animation to avoid blank pages
if (!root.initialOpeningComplete) { if (!root.initialOpeningComplete) {
@ -184,6 +182,8 @@ Item {
} }
root.session.active = item.label; root.session.active = item.label;
} }
color: item.active ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
} }
MaterialIcon { MaterialIcon {

View file

@ -101,10 +101,6 @@ ClippingRectangle {
required property int paneIndex required property int paneIndex
required property string componentPath required property string componentPath
implicitWidth: root.width
implicitHeight: root.height
property bool hasBeenLoaded: false property bool hasBeenLoaded: false
function updateActive(): void { function updateActive(): void {
@ -127,6 +123,9 @@ ClippingRectangle {
loader.active = shouldBeActive; loader.active = shouldBeActive;
} }
implicitWidth: root.width
implicitHeight: root.height
Loader { Loader {
id: loader id: loader

View file

@ -34,11 +34,11 @@ StyledRect {
implicitHeight: closeIcon.implicitHeight + Appearance.padding.small implicitHeight: closeIcon.implicitHeight + Appearance.padding.small
StateLayer { StateLayer {
radius: Appearance.rounding.full
function onClicked(): void { function onClicked(): void {
QsWindow.window.destroy(); QsWindow.window.destroy();
} }
radius: Appearance.rounding.full
} }
MaterialIcon { MaterialIcon {

View file

@ -54,8 +54,6 @@ Item {
property real visualiserRounding: Config.background.visualiser.rounding ?? 1 property real visualiserRounding: Config.background.visualiser.rounding ?? 1
property real visualiserSpacing: Config.background.visualiser.spacing ?? 1 property real visualiserSpacing: Config.background.visualiser.spacing ?? 1
anchors.fill: parent
function saveConfig() { function saveConfig() {
Config.appearance.anim.durations.scale = root.animDurationsScale; Config.appearance.anim.durations.scale = root.animDurationsScale;
@ -97,6 +95,8 @@ Item {
Config.save(); Config.save();
} }
anchors.fill: parent
Component { Component {
id: appearanceRightContentComponent id: appearanceRightContentComponent
@ -167,14 +167,13 @@ Item {
ColumnLayout { ColumnLayout {
id: sidebarLayout id: sidebarLayout
readonly property var rootPane: sidebarFlickable.rootPane
readonly property bool allSectionsExpanded: themeModeSection.expanded && colorVariantSection.expanded && colorSchemeSection.expanded && animationsSection.expanded && fontsSection.expanded && scalesSection.expanded && transparencySection.expanded && borderSection.expanded && backgroundSection.expanded
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
spacing: Appearance.spacing.small spacing: Appearance.spacing.small
readonly property var rootPane: sidebarFlickable.rootPane
readonly property bool allSectionsExpanded: themeModeSection.expanded && colorVariantSection.expanded && colorSchemeSection.expanded && animationsSection.expanded && fontsSection.expanded && scalesSection.expanded && transparencySection.expanded && borderSection.expanded && backgroundSection.expanded
RowLayout { RowLayout {
spacing: Appearance.spacing.smaller spacing: Appearance.spacing.smaller

View file

@ -55,9 +55,6 @@ CollapsibleSection {
SectionContainer { SectionContainer {
id: posContainer id: posContainer
contentSpacing: Appearance.spacing.small
z: 1
readonly property var pos: (rootPane.desktopClockPosition || "top-left").split('-') readonly property var pos: (rootPane.desktopClockPosition || "top-left").split('-')
readonly property string currentV: pos[0] readonly property string currentV: pos[0]
readonly property string currentH: pos[1] readonly property string currentH: pos[1]
@ -67,6 +64,9 @@ CollapsibleSection {
rootPane.saveConfig(); rootPane.saveConfig();
} }
contentSpacing: Appearance.spacing.small
z: 1
StyledText { StyledText {
text: qsTr("Positioning") text: qsTr("Positioning")
font.pointSize: Appearance.font.size.larger font.pointSize: Appearance.font.size.larger

View file

@ -241,13 +241,13 @@ StyledFlickable {
scale: root.session.bt.editingDeviceName ? 1 : 0.5 scale: root.session.bt.editingDeviceName ? 1 : 0.5
StateLayer { StateLayer {
color: Colours.palette.m3onSecondaryContainer
disabled: !root.session.bt.editingDeviceName
function onClicked(): void { function onClicked(): void {
root.session.bt.editingDeviceName = false; root.session.bt.editingDeviceName = false;
deviceNameEdit.text = Qt.binding(() => root.device?.name ?? ""); deviceNameEdit.text = Qt.binding(() => root.device?.name ?? "");
} }
color: Colours.palette.m3onSecondaryContainer
disabled: !root.session.bt.editingDeviceName
} }
MaterialIcon { MaterialIcon {
@ -279,8 +279,6 @@ StyledFlickable {
color: Qt.alpha(Colours.palette.m3primary, root.session.bt.editingDeviceName ? 1 : 0) color: Qt.alpha(Colours.palette.m3primary, root.session.bt.editingDeviceName ? 1 : 0)
StateLayer { StateLayer {
color: root.session.bt.editingDeviceName ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
function onClicked(): void { function onClicked(): void {
root.session.bt.editingDeviceName = !root.session.bt.editingDeviceName; root.session.bt.editingDeviceName = !root.session.bt.editingDeviceName;
if (root.session.bt.editingDeviceName) if (root.session.bt.editingDeviceName)
@ -288,6 +286,8 @@ StyledFlickable {
else else
deviceNameEdit.accepted(); deviceNameEdit.accepted();
} }
color: root.session.bt.editingDeviceName ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
} }
MaterialIcon { MaterialIcon {
@ -630,11 +630,11 @@ StyledFlickable {
StateLayer { StateLayer {
id: fabState id: fabState
color: root.session.bt.fabMenuOpen ? Colours.palette.m3onPrimary : Colours.palette.m3onPrimaryContainer
function onClicked(): void { function onClicked(): void {
root.session.bt.fabMenuOpen = !root.session.bt.fabMenuOpen; root.session.bt.fabMenuOpen = !root.session.bt.fabMenuOpen;
} }
color: root.session.bt.fabMenuOpen ? Colours.palette.m3onPrimary : Colours.palette.m3onPrimaryContainer
} }
MaterialIcon { MaterialIcon {

View file

@ -222,9 +222,6 @@ DeviceList {
} }
StateLayer { StateLayer {
color: device.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface
disabled: device.loading
function onClicked(): void { function onClicked(): void {
if (device.loading) if (device.loading)
return; return;
@ -239,6 +236,9 @@ DeviceList {
} }
} }
} }
color: device.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface
disabled: device.loading
} }
MaterialIcon { MaterialIcon {

View file

@ -131,11 +131,11 @@ ColumnLayout {
implicitHeight: adapterPicker.implicitHeight + Appearance.padding.smaller * 2 implicitHeight: adapterPicker.implicitHeight + Appearance.padding.smaller * 2
StateLayer { StateLayer {
radius: Appearance.rounding.small
function onClicked(): void { function onClicked(): void {
adapterPickerButton.expanded = !adapterPickerButton.expanded; adapterPickerButton.expanded = !adapterPickerButton.expanded;
} }
radius: Appearance.rounding.small
} }
RowLayout { RowLayout {
@ -210,12 +210,12 @@ ColumnLayout {
implicitHeight: adapterInner.implicitHeight + Appearance.padding.normal * 2 implicitHeight: adapterInner.implicitHeight + Appearance.padding.normal * 2
StateLayer { StateLayer {
disabled: !adapterPickerButton.expanded
function onClicked(): void { function onClicked(): void {
adapterPickerButton.expanded = false; adapterPickerButton.expanded = false;
root.session.bt.currentAdapter = adapter.modelData; root.session.bt.currentAdapter = adapter.modelData;
} }
disabled: !adapterPickerButton.expanded
} }
RowLayout { RowLayout {
@ -381,13 +381,13 @@ ColumnLayout {
scale: root.session.bt.editingAdapterName ? 1 : 0.5 scale: root.session.bt.editingAdapterName ? 1 : 0.5
StateLayer { StateLayer {
color: Colours.palette.m3onSecondaryContainer
disabled: !root.session.bt.editingAdapterName
function onClicked(): void { function onClicked(): void {
root.session.bt.editingAdapterName = false; root.session.bt.editingAdapterName = false;
adapterNameEdit.text = Qt.binding(() => root.session.bt.currentAdapter?.name ?? ""); adapterNameEdit.text = Qt.binding(() => root.session.bt.currentAdapter?.name ?? "");
} }
color: Colours.palette.m3onSecondaryContainer
disabled: !root.session.bt.editingAdapterName
} }
MaterialIcon { MaterialIcon {
@ -419,8 +419,6 @@ ColumnLayout {
color: Qt.alpha(Colours.palette.m3primary, root.session.bt.editingAdapterName ? 1 : 0) color: Qt.alpha(Colours.palette.m3primary, root.session.bt.editingAdapterName ? 1 : 0)
StateLayer { StateLayer {
color: root.session.bt.editingAdapterName ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
function onClicked(): void { function onClicked(): void {
root.session.bt.editingAdapterName = !root.session.bt.editingAdapterName; root.session.bt.editingAdapterName = !root.session.bt.editingAdapterName;
if (root.session.bt.editingAdapterName) if (root.session.bt.editingAdapterName)
@ -428,6 +426,8 @@ ColumnLayout {
else else
adapterNameEdit.accepted(); adapterNameEdit.accepted();
} }
color: root.session.bt.editingAdapterName ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
} }
MaterialIcon { MaterialIcon {

View file

@ -41,16 +41,16 @@ GridView {
readonly property real itemRadius: Appearance.rounding.normal readonly property real itemRadius: Appearance.rounding.normal
StateLayer { StateLayer {
function onClicked(): void {
Wallpapers.setWallpaper(modelData.path);
}
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: itemMargin anchors.leftMargin: itemMargin
anchors.rightMargin: itemMargin anchors.rightMargin: itemMargin
anchors.topMargin: itemMargin anchors.topMargin: itemMargin
anchors.bottomMargin: itemMargin anchors.bottomMargin: itemMargin
radius: itemRadius radius: itemRadius
function onClicked(): void {
Wallpapers.setWallpaper(modelData.path);
}
} }
StyledClippingRect { StyledClippingRect {

View file

@ -40,8 +40,6 @@ Item {
property bool showStorage: Config.dashboard.performance.showStorage ?? true property bool showStorage: Config.dashboard.performance.showStorage ?? true
property bool showNetwork: Config.dashboard.performance.showNetwork ?? true property bool showNetwork: Config.dashboard.performance.showNetwork ?? true
anchors.fill: parent
function saveConfig() { function saveConfig() {
Config.dashboard.enabled = root.enabled; Config.dashboard.enabled = root.enabled;
Config.dashboard.showOnHover = root.showOnHover; Config.dashboard.showOnHover = root.showOnHover;
@ -62,6 +60,8 @@ Item {
Config.save(); Config.save();
} }
anchors.fill: parent
ClippingRectangle { ClippingRectangle {
id: dashboardClippingRect id: dashboardClippingRect

View file

@ -25,21 +25,8 @@ Item {
property var selectedApp: root.session.launcher.active property var selectedApp: root.session.launcher.active
property bool hideFromLauncherChecked: false property bool hideFromLauncherChecked: false
property bool favouriteChecked: false property bool favouriteChecked: false
property string searchText: ""
anchors.fill: parent property list<var> filteredApps: []
onSelectedAppChanged: {
root.session.launcher.active = root.selectedApp;
updateToggleState();
}
Connections {
target: root.session.launcher
function onActiveChanged() {
root.selectedApp = root.session.launcher.active;
updateToggleState();
}
}
function updateToggleState() { function updateToggleState() {
if (!root.selectedApp) { if (!root.selectedApp) {
@ -78,16 +65,6 @@ Item {
Config.save(); Config.save();
} }
AppDb {
id: allAppsDb
path: `${Paths.state}/apps.sqlite`
favouriteApps: Config.launcher.favouriteApps
entries: DesktopEntries.applications.values
}
property string searchText: ""
function filterApps(search: string): list<var> { function filterApps(search: string): list<var> {
if (!search || search.trim() === "") { if (!search || search.trim() === "") {
const apps = []; const apps = [];
@ -120,12 +97,33 @@ Item {
return results.sort((a, b) => b._score - a._score).map(r => r.obj._item); return results.sort((a, b) => b._score - a._score).map(r => r.obj._item);
} }
property list<var> filteredApps: []
function updateFilteredApps() { function updateFilteredApps() {
filteredApps = filterApps(searchText); filteredApps = filterApps(searchText);
} }
anchors.fill: parent
onSelectedAppChanged: {
root.session.launcher.active = root.selectedApp;
updateToggleState();
}
Connections {
target: root.session.launcher
function onActiveChanged() {
root.selectedApp = root.session.launcher.active;
updateToggleState();
}
}
AppDb {
id: allAppsDb
path: `${Paths.state}/apps.sqlite`
favouriteApps: Config.launcher.favouriteApps
entries: DesktopEntries.applications.values
}
onSearchTextChanged: { onSearchTextChanged: {
updateFilteredApps(); updateFilteredApps();
} }
@ -308,11 +306,11 @@ Item {
delegate: StyledRect { delegate: StyledRect {
required property var modelData required property var modelData
width: parent ? parent.width : 0
implicitHeight: 40
readonly property bool isSelected: root.selectedApp === modelData readonly property bool isSelected: root.selectedApp === modelData
width: parent ? parent.width : 0
implicitHeight: 40
color: isSelected ? Colours.layer(Colours.palette.m3surfaceContainer, 2) : "transparent" color: isSelected ? Colours.layer(Colours.palette.m3surfaceContainer, 2) : "transparent"
radius: Appearance.rounding.normal radius: Appearance.rounding.normal
@ -418,6 +416,8 @@ Item {
Loader { Loader {
id: rightLauncherLoader id: rightLauncherLoader
property var displayedApp: rightLauncherPane.displayedApp
anchors.fill: parent anchors.fill: parent
asynchronous: true asynchronous: true
@ -429,8 +429,6 @@ Item {
sourceComponent: rightLauncherPane.targetComponent sourceComponent: rightLauncherPane.targetComponent
active: true active: true
property var displayedApp: rightLauncherPane.displayedApp
onItemChanged: { onItemChanged: {
if (item && rightLauncherPane.pane && rightLauncherPane.displayedApp !== rightLauncherPane.pane) { if (item && rightLauncherPane.pane && rightLauncherPane.displayedApp !== rightLauncherPane.pane) {
rightLauncherPane.displayedApp = rightLauncherPane.pane; rightLauncherPane.displayedApp = rightLauncherPane.pane;
@ -515,10 +513,9 @@ Item {
ColumnLayout { ColumnLayout {
id: appDetailsLayout id: appDetailsLayout
anchors.fill: parent
readonly property var displayedApp: parent && parent.displayedApp !== undefined ? parent.displayedApp : null readonly property var displayedApp: parent && parent.displayedApp !== undefined ? parent.displayedApp : null
anchors.fill: parent
spacing: Appearance.spacing.normal spacing: Appearance.spacing.normal
SettingsHeader { SettingsHeader {

View file

@ -147,8 +147,6 @@ DeviceList {
color: Qt.alpha(Colours.palette.m3primaryContainer, modelData.connected ? 1 : 0) color: Qt.alpha(Colours.palette.m3primaryContainer, modelData.connected ? 1 : 0)
StateLayer { StateLayer {
color: modelData.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface
function onClicked(): void { function onClicked(): void {
if (modelData.connected && modelData.connection) { if (modelData.connected && modelData.connection) {
Nmcli.disconnectEthernet(modelData.connection, () => {}); Nmcli.disconnectEthernet(modelData.connection, () => {});
@ -156,6 +154,8 @@ DeviceList {
Nmcli.connectEthernet(modelData.connection || "", modelData.interface || "", () => {}); Nmcli.connectEthernet(modelData.connection || "", modelData.interface || "", () => {});
} }
} }
color: modelData.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface
} }
MaterialIcon { MaterialIcon {

View file

@ -201,6 +201,10 @@ DeviceDetails {
property string displayName: "" property string displayName: ""
property string interfaceName: "" property string interfaceName: ""
function closeWithAnimation(): void {
close();
}
parent: Overlay.overlay parent: Overlay.overlay
anchors.centerIn: parent anchors.centerIn: parent
width: Math.min(400, parent.width - Appearance.padding.large * 2) width: Math.min(400, parent.width - Appearance.padding.large * 2)
@ -246,10 +250,6 @@ DeviceDetails {
} }
} }
function closeWithAnimation(): void {
close();
}
Overlay.modal: Rectangle { Overlay.modal: Rectangle {
color: Qt.rgba(0, 0, 0, 0.4 * editVpnDialog.opacity) color: Qt.rgba(0, 0, 0, 0.4 * editVpnDialog.opacity)
} }

View file

@ -181,7 +181,6 @@ ColumnLayout {
color: Qt.alpha(Colours.palette.m3primaryContainer, VPN.connected && modelData.enabled ? 1 : 0) color: Qt.alpha(Colours.palette.m3primaryContainer, VPN.connected && modelData.enabled ? 1 : 0)
StateLayer { StateLayer {
enabled: !VPN.connecting
function onClicked(): void { function onClicked(): void {
const clickedIndex = modelData.index; const clickedIndex = modelData.index;
@ -216,6 +215,8 @@ ColumnLayout {
} }
} }
} }
enabled: !VPN.connecting
} }
MaterialIcon { MaterialIcon {
@ -271,6 +272,43 @@ ColumnLayout {
property string displayName: "" property string displayName: ""
property string interfaceName: "" property string interfaceName: ""
function showProviderSelection(): void {
currentState = "selection";
open();
}
function closeWithAnimation(): void {
close();
}
function showAddForm(providerType: string, defaultDisplayName: string): void {
editIndex = -1;
providerName = providerType;
displayName = defaultDisplayName;
interfaceName = "";
if (currentState === "selection") {
transitionToForm.start();
} else {
currentState = "form";
isClosing = false;
open();
}
}
function showEditForm(index: int): void {
const provider = Config.utilities.vpn.provider[index];
const isObject = typeof provider === "object";
editIndex = index;
providerName = isObject ? (provider.name || "custom") : String(provider);
displayName = isObject ? (provider.displayName || providerName) : providerName;
interfaceName = isObject ? (provider.interface || "") : "";
currentState = "form";
open();
}
parent: Overlay.overlay parent: Overlay.overlay
x: Math.round((parent.width - width) / 2) x: Math.round((parent.width - width) / 2)
y: Math.round((parent.height - height) / 2) y: Math.round((parent.height - height) / 2)
@ -321,43 +359,6 @@ ColumnLayout {
} }
} }
function showProviderSelection(): void {
currentState = "selection";
open();
}
function closeWithAnimation(): void {
close();
}
function showAddForm(providerType: string, defaultDisplayName: string): void {
editIndex = -1;
providerName = providerType;
displayName = defaultDisplayName;
interfaceName = "";
if (currentState === "selection") {
transitionToForm.start();
} else {
currentState = "form";
isClosing = false;
open();
}
}
function showEditForm(index: int): void {
const provider = Config.utilities.vpn.provider[index];
const isObject = typeof provider === "object";
editIndex = index;
providerName = isObject ? (provider.name || "custom") : String(provider);
displayName = isObject ? (provider.displayName || providerName) : providerName;
interfaceName = isObject ? (provider.interface || "") : "";
currentState = "form";
open();
}
Overlay.modal: Rectangle { Overlay.modal: Rectangle {
color: Qt.rgba(0, 0, 0, 0.4 * vpnDialog.opacity) color: Qt.rgba(0, 0, 0, 0.4 * vpnDialog.opacity)
} }

View file

@ -29,6 +29,47 @@ Item {
} }
property bool isClosing: false property bool isClosing: false
function checkConnectionStatus(): void {
if (!root.visible || !connectButton.connecting) {
return;
}
const isConnected = root.network && Nmcli.active && Nmcli.active.ssid && Nmcli.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim();
if (isConnected) {
connectionSuccessTimer.start();
return;
}
if (Nmcli.pendingConnection === null && connectButton.connecting) {
if (connectionMonitor.repeatCount > 10) {
connectionMonitor.stop();
connectButton.connecting = false;
connectButton.hasError = true;
connectButton.enabled = true;
connectButton.text = qsTr("Connect");
passwordContainer.passwordBuffer = "";
if (root.network && root.network.ssid) {
Nmcli.forgetNetwork(root.network.ssid);
}
}
}
}
function closeDialog(): void {
if (isClosing) {
return;
}
isClosing = true;
passwordContainer.passwordBuffer = "";
connectButton.connecting = false;
connectButton.hasError = false;
connectButton.text = qsTr("Connect");
connectionMonitor.stop();
}
visible: session.network.showPasswordDialog || isClosing visible: session.network.showPasswordDialog || isClosing
enabled: session.network.showPasswordDialog && !isClosing enabled: session.network.showPasswordDialog && !isClosing
focus: enabled focus: enabled
@ -238,12 +279,12 @@ Item {
} }
StateLayer { StateLayer {
hoverEnabled: false
cursorShape: Qt.IBeamCursor
function onClicked(): void { function onClicked(): void {
passwordContainer.forceActiveFocus(); passwordContainer.forceActiveFocus();
} }
hoverEnabled: false
cursorShape: Qt.IBeamCursor
} }
StyledText { StyledText {
@ -416,33 +457,6 @@ Item {
} }
} }
function checkConnectionStatus(): void {
if (!root.visible || !connectButton.connecting) {
return;
}
const isConnected = root.network && Nmcli.active && Nmcli.active.ssid && Nmcli.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim();
if (isConnected) {
connectionSuccessTimer.start();
return;
}
if (Nmcli.pendingConnection === null && connectButton.connecting) {
if (connectionMonitor.repeatCount > 10) {
connectionMonitor.stop();
connectButton.connecting = false;
connectButton.hasError = true;
connectButton.enabled = true;
connectButton.text = qsTr("Connect");
passwordContainer.passwordBuffer = "";
if (root.network && root.network.ssid) {
Nmcli.forgetNetwork(root.network.ssid);
}
}
}
}
Timer { Timer {
id: connectionMonitor id: connectionMonitor
@ -499,17 +513,4 @@ Item {
} }
} }
} }
function closeDialog(): void {
if (isClosing) {
return;
}
isClosing = true;
passwordContainer.passwordBuffer = "";
connectButton.connecting = false;
connectButton.hasError = false;
connectButton.text = qsTr("Connect");
connectionMonitor.stop();
}
} }

View file

@ -53,21 +53,6 @@ Item {
property list<string> monitorNames: Hypr.monitorNames() property list<string> monitorNames: Hypr.monitorNames()
property list<string> excludedScreens: Config.bar.excludedScreens ?? [] property list<string> excludedScreens: Config.bar.excludedScreens ?? []
anchors.fill: parent
Component.onCompleted: {
if (Config.bar.entries) {
entriesModel.clear();
for (let i = 0; i < Config.bar.entries.length; i++) {
const entry = Config.bar.entries[i];
entriesModel.append({
id: entry.id,
enabled: entry.enabled !== false
});
}
}
}
function saveConfig(entryIndex, entryEnabled) { function saveConfig(entryIndex, entryEnabled) {
Config.bar.activeWindow.compact = root.activeWindowCompact; Config.bar.activeWindow.compact = root.activeWindowCompact;
Config.bar.activeWindow.inverted = root.activeWindowInverted; Config.bar.activeWindow.inverted = root.activeWindowInverted;
@ -118,6 +103,21 @@ Item {
Config.save(); Config.save();
} }
anchors.fill: parent
Component.onCompleted: {
if (Config.bar.entries) {
entriesModel.clear();
for (let i = 0; i < Config.bar.entries.length; i++) {
const entry = Config.bar.entries[i];
entriesModel.append({
id: entry.id,
enabled: entry.enabled !== false
});
}
}
}
ListModel { ListModel {
id: entriesModel id: entriesModel
} }

View file

@ -12,16 +12,16 @@ StyledRect {
required property real contentHeight required property real contentHeight
implicitHeight: contentHeight
radius: Appearance.rounding.large
color: Colours.tPalette.m3surfaceContainer
function searchCandidates(title, artist) { function searchCandidates(title, artist) {
LyricsService.currentRequestId++; LyricsService.currentRequestId++;
LyricsService.fetchNetEaseCandidates(title, artist, LyricsService.currentRequestId); LyricsService.fetchNetEaseCandidates(title, artist, LyricsService.currentRequestId);
} }
implicitHeight: contentHeight
radius: Appearance.rounding.large
color: Colours.tPalette.m3surfaceContainer
Loader { Loader {
asynchronous: true asynchronous: true
anchors.fill: parent anchors.fill: parent

View file

@ -111,6 +111,13 @@ Item {
contentItem: CustomMouseArea { contentItem: CustomMouseArea {
id: mouse id: mouse
function onWheel(event: WheelEvent): void {
if (event.angleDelta.y < 0)
root.state.currentTab = Math.min(root.state.currentTab + 1, bar.count - 1);
else if (event.angleDelta.y > 0)
root.state.currentTab = Math.max(root.state.currentTab - 1, 0);
}
implicitWidth: Math.max(icon.width, label.width) implicitWidth: Math.max(icon.width, label.width)
implicitHeight: icon.height + label.height implicitHeight: icon.height + label.height
@ -129,13 +136,6 @@ Item {
rippleAnim.restart(); rippleAnim.restart();
} }
function onWheel(event: WheelEvent): void {
if (event.angleDelta.y < 0)
root.state.currentTab = Math.min(root.state.currentTab + 1, bar.count - 1);
else if (event.angleDelta.y > 0)
root.state.currentTab = Math.max(root.state.currentTab - 1, 0);
}
SequentialAnimation { SequentialAnimation {
id: rippleAnim id: rippleAnim

View file

@ -17,13 +17,6 @@ CustomMouseArea {
readonly property int currMonth: state.currentDate.getMonth() readonly property int currMonth: state.currentDate.getMonth()
readonly property int currYear: state.currentDate.getFullYear() readonly property int currYear: state.currentDate.getFullYear()
anchors.left: parent.left
anchors.right: parent.right
implicitHeight: inner.implicitHeight + inner.anchors.margins * 2
acceptedButtons: Qt.MiddleButton
onClicked: root.state.currentDate = new Date()
function onWheel(event: WheelEvent): void { function onWheel(event: WheelEvent): void {
if (event.angleDelta.y > 0) if (event.angleDelta.y > 0)
root.state.currentDate = new Date(root.currYear, root.currMonth - 1, 1); root.state.currentDate = new Date(root.currYear, root.currMonth - 1, 1);
@ -31,6 +24,13 @@ CustomMouseArea {
root.state.currentDate = new Date(root.currYear, root.currMonth + 1, 1); root.state.currentDate = new Date(root.currYear, root.currMonth + 1, 1);
} }
anchors.left: parent.left
anchors.right: parent.right
implicitHeight: inner.implicitHeight + inner.anchors.margins * 2
acceptedButtons: Qt.MiddleButton
onClicked: root.state.currentDate = new Date()
ColumnLayout { ColumnLayout {
id: inner id: inner
@ -51,11 +51,11 @@ CustomMouseArea {
StateLayer { StateLayer {
id: prevMonthStateLayer id: prevMonthStateLayer
radius: Appearance.rounding.full
function onClicked(): void { function onClicked(): void {
root.state.currentDate = new Date(root.currYear, root.currMonth - 1, 1); root.state.currentDate = new Date(root.currYear, root.currMonth - 1, 1);
} }
radius: Appearance.rounding.full
} }
MaterialIcon { MaterialIcon {
@ -76,6 +76,10 @@ CustomMouseArea {
implicitHeight: monthYearDisplay.implicitHeight + Appearance.padding.small * 2 implicitHeight: monthYearDisplay.implicitHeight + Appearance.padding.small * 2
StateLayer { StateLayer {
function onClicked(): void {
root.state.currentDate = new Date();
}
anchors.fill: monthYearDisplay anchors.fill: monthYearDisplay
anchors.margins: -Appearance.padding.small anchors.margins: -Appearance.padding.small
anchors.leftMargin: -Appearance.padding.normal anchors.leftMargin: -Appearance.padding.normal
@ -86,10 +90,6 @@ CustomMouseArea {
const now = new Date(); const now = new Date();
return root.currMonth === now.getMonth() && root.currYear === now.getFullYear(); return root.currMonth === now.getMonth() && root.currYear === now.getFullYear();
} }
function onClicked(): void {
root.state.currentDate = new Date();
}
} }
StyledText { StyledText {
@ -111,11 +111,11 @@ CustomMouseArea {
StateLayer { StateLayer {
id: nextMonthStateLayer id: nextMonthStateLayer
radius: Appearance.rounding.full
function onClicked(): void { function onClicked(): void {
root.state.currentDate = new Date(root.currYear, root.currMonth + 1, 1); root.state.currentDate = new Date(root.currYear, root.currMonth + 1, 1);
} }
radius: Appearance.rounding.full
} }
MaterialIcon { MaterialIcon {

View file

@ -231,12 +231,12 @@ Item {
implicitHeight: implicitWidth implicitHeight: implicitWidth
StateLayer { StateLayer {
disabled: !control.canUse
radius: Appearance.rounding.full
function onClicked(): void { function onClicked(): void {
control.onClicked(); control.onClicked();
} }
disabled: !control.canUse
radius: Appearance.rounding.full
} }
MaterialIcon { MaterialIcon {

View file

@ -71,12 +71,12 @@ Row {
opacity: parent.containsMouse ? 1 : 0 opacity: parent.containsMouse ? 1 : 0
StateLayer { StateLayer {
color: Colours.palette.m3onPrimary
function onClicked(): void { function onClicked(): void {
root.visibilities.launcher = false; root.visibilities.launcher = false;
root.facePicker.open(); root.facePicker.open();
} }
color: Colours.palette.m3onPrimary
} }
MaterialIcon { MaterialIcon {

View file

@ -16,11 +16,11 @@ Item {
anchors.right: parent?.right anchors.right: parent?.right
StateLayer { StateLayer {
radius: Appearance.rounding.normal
function onClicked(): void { function onClicked(): void {
root.modelData?.onClicked(root.list); root.modelData?.onClicked(root.list);
} }
radius: Appearance.rounding.normal
} }
Item { Item {

View file

@ -19,12 +19,12 @@ Item {
anchors.right: parent?.right anchors.right: parent?.right
StateLayer { StateLayer {
radius: Appearance.rounding.normal
function onClicked(): void { function onClicked(): void {
Apps.launch(root.modelData); Apps.launch(root.modelData);
root.visibilities.launcher = false; root.visibilities.launcher = false;
} }
radius: Appearance.rounding.normal
} }
Item { Item {

View file

@ -12,27 +12,27 @@ Item {
required property var list required property var list
readonly property string math: list.search.text.slice(`${Config.launcher.actionPrefix}calc `.length) readonly property string math: list.search.text.slice(`${Config.launcher.actionPrefix}calc `.length)
onMathChanged: {
if (math.length > 0)
Qalculator.evalAsync(math);
}
function onClicked(): void { function onClicked(): void {
Quickshell.execDetached(["wl-copy", Qalculator.rawResult]); Quickshell.execDetached(["wl-copy", Qalculator.rawResult]);
root.list.visibilities.launcher = false; root.list.visibilities.launcher = false;
} }
onMathChanged: {
if (math.length > 0)
Qalculator.evalAsync(math);
}
implicitHeight: Config.launcher.sizes.itemHeight implicitHeight: Config.launcher.sizes.itemHeight
anchors.left: parent?.left anchors.left: parent?.left
anchors.right: parent?.right anchors.right: parent?.right
StateLayer { StateLayer {
radius: Appearance.rounding.normal
function onClicked(): void { function onClicked(): void {
root.onClicked(); root.onClicked();
} }
radius: Appearance.rounding.normal
} }
RowLayout { RowLayout {
@ -80,12 +80,12 @@ Item {
StateLayer { StateLayer {
id: stateLayer id: stateLayer
color: Colours.palette.m3onTertiary
function onClicked(): void { function onClicked(): void {
Quickshell.execDetached(["app2unit", "--", ...Config.general.apps.terminal, "fish", "-C", `exec qalc -i '${root.math}'`]); Quickshell.execDetached(["app2unit", "--", ...Config.general.apps.terminal, "fish", "-C", `exec qalc -i '${root.math}'`]);
root.list.visibilities.launcher = false; root.list.visibilities.launcher = false;
} }
color: Colours.palette.m3onTertiary
} }
StyledText { StyledText {

View file

@ -16,11 +16,11 @@ Item {
anchors.right: parent?.right anchors.right: parent?.right
StateLayer { StateLayer {
radius: Appearance.rounding.normal
function onClicked(): void { function onClicked(): void {
root.modelData?.onClicked(root.list); root.modelData?.onClicked(root.list);
} }
radius: Appearance.rounding.normal
} }
Item { Item {

View file

@ -16,11 +16,11 @@ Item {
anchors.right: parent?.right anchors.right: parent?.right
StateLayer { StateLayer {
radius: Appearance.rounding.normal
function onClicked(): void { function onClicked(): void {
root.modelData?.onClicked(root.list); root.modelData?.onClicked(root.list);
} }
radius: Appearance.rounding.normal
} }
Item { Item {

View file

@ -26,12 +26,12 @@ Item {
implicitHeight: image.height + label.height + Appearance.spacing.small / 2 + Appearance.padding.large + Appearance.padding.normal implicitHeight: image.height + label.height + Appearance.spacing.small / 2 + Appearance.padding.large + Appearance.padding.normal
StateLayer { StateLayer {
radius: Appearance.rounding.normal
function onClicked(): void { function onClicked(): void {
Wallpapers.setWallpaper(root.modelData.path); Wallpapers.setWallpaper(root.modelData.path);
root.visibilities.launcher = false; root.visibilities.launcher = false;
} }
radius: Appearance.rounding.normal
} }
Elevation { Elevation {

View file

@ -135,12 +135,12 @@ ColumnLayout {
} }
StateLayer { StateLayer {
hoverEnabled: false
cursorShape: Qt.IBeamCursor
function onClicked(): void { function onClicked(): void {
parent.forceActiveFocus(); parent.forceActiveFocus();
} }
hoverEnabled: false
cursorShape: Qt.IBeamCursor
} }
RowLayout { RowLayout {
@ -194,11 +194,11 @@ ColumnLayout {
radius: Appearance.rounding.full radius: Appearance.rounding.full
StateLayer { StateLayer {
color: root.lock.pam.buffer ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
function onClicked(): void { function onClicked(): void {
root.lock.pam.passwd.start(); root.lock.pam.passwd.start();
} }
color: root.lock.pam.buffer ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
} }
MaterialIcon { MaterialIcon {

View file

@ -171,11 +171,11 @@ Item {
StateLayer { StateLayer {
id: controlState id: controlState
color: control.active ? Colours.palette[`m3on${control.colour}`] : Colours.palette[`m3on${control.colour}Container`]
function onClicked(): void { function onClicked(): void {
control.onClicked(); control.onClicked();
} }
color: control.active ? Colours.palette[`m3on${control.colour}`] : Colours.palette[`m3on${control.colour}Container`]
} }
MaterialIcon { MaterialIcon {

View file

@ -176,11 +176,11 @@ StyledRect {
Layout.preferredWidth: root.notifs.length > Config.notifs.groupPreviewNum ? implicitWidth : 0 Layout.preferredWidth: root.notifs.length > Config.notifs.groupPreviewNum ? implicitWidth : 0
StateLayer { StateLayer {
color: root.urgency === "critical" ? Colours.palette.m3onError : Colours.palette.m3onSurface
function onClicked(): void { function onClicked(): void {
root.expanded = !root.expanded; root.expanded = !root.expanded;
} }
color: root.urgency === "critical" ? Colours.palette.m3onError : Colours.palette.m3onSurface
} }
RowLayout { RowLayout {

View file

@ -361,12 +361,12 @@ StyledRect {
implicitHeight: expandIcon.height implicitHeight: expandIcon.height
StateLayer { StateLayer {
radius: Appearance.rounding.full
color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
function onClicked() { function onClicked() {
root.expanded = !root.expanded; root.expanded = !root.expanded;
} }
radius: Appearance.rounding.full
color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
} }
MaterialIcon { MaterialIcon {
@ -491,12 +491,12 @@ StyledRect {
implicitHeight: actionText.height + Appearance.padding.small * 2 implicitHeight: actionText.height + Appearance.padding.small * 2
StateLayer { StateLayer {
radius: Appearance.rounding.full
color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onSecondary : Colours.palette.m3onSurface
function onClicked(): void { function onClicked(): void {
action.modelData.invoke(); action.modelData.invoke();
} }
radius: Appearance.rounding.full
color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onSecondary : Colours.palette.m3onSurface
} }
StyledText { StyledText {

View file

@ -115,12 +115,12 @@ Column {
} }
StateLayer { StateLayer {
radius: parent.radius
color: button.activeFocus ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
function onClicked(): void { function onClicked(): void {
Quickshell.execDetached(button.command); Quickshell.execDetached(button.command);
} }
radius: parent.radius
color: button.activeFocus ? Colours.palette.m3onSecondaryContainer : Colours.palette.m3onSurface
} }
MaterialIcon { MaterialIcon {

View file

@ -204,11 +204,11 @@ StyledRect {
radius: Appearance.rounding.full radius: Appearance.rounding.full
StateLayer { StateLayer {
color: root.urgency === NotificationUrgency.Critical ? Colours.palette.m3onError : Colours.palette.m3onSurface
function onClicked(): void { function onClicked(): void {
root.toggleExpand(!root.expanded); root.toggleExpand(!root.expanded);
} }
color: root.urgency === NotificationUrgency.Critical ? Colours.palette.m3onError : Colours.palette.m3onSurface
} }
RowLayout { RowLayout {

View file

@ -35,11 +35,11 @@ ColumnLayout {
implicitHeight: moveToWsIcon.implicitHeight + Appearance.padding.small implicitHeight: moveToWsIcon.implicitHeight + Appearance.padding.small
StateLayer { StateLayer {
color: Colours.palette.m3onPrimary
function onClicked(): void { function onClicked(): void {
root.moveToWsExpanded = !root.moveToWsExpanded; root.moveToWsExpanded = !root.moveToWsExpanded;
} }
color: Colours.palette.m3onPrimary
} }
MaterialIcon { MaterialIcon {
@ -161,11 +161,11 @@ ColumnLayout {
StateLayer { StateLayer {
id: stateLayer id: stateLayer
color: parent.onColor
function onClicked(): void { function onClicked(): void {
parent.onClicked(); parent.onClicked();
} }
color: parent.onColor
} }
StyledText { StyledText {

View file

@ -148,30 +148,6 @@ Singleton {
property date time: new Date() property date time: new Date()
property string timeStr: qsTr("now") property string timeStr: qsTr("now")
function updateTimeStr(): void {
const diff = Date.now() - time.getTime();
const m = Math.floor(diff / 60000);
if (m < 1) {
timeStr = qsTr("now");
timeStrTimer.interval = 5000;
} else {
const h = Math.floor(m / 60);
const d = Math.floor(h / 24);
if (d > 0) {
timeStr = `${d}d`;
timeStrTimer.interval = 3600000;
} else if (h > 0) {
timeStr = `${h}h`;
timeStrTimer.interval = 300000;
} else {
timeStr = `${m}m`;
timeStrTimer.interval = m < 10 ? 30000 : 60000;
}
}
}
readonly property Timer timeStrTimer: Timer { readonly property Timer timeStrTimer: Timer {
running: !notif.closed running: !notif.closed
repeat: true repeat: true
@ -308,6 +284,30 @@ Singleton {
} }
} }
function updateTimeStr(): void {
const diff = Date.now() - time.getTime();
const m = Math.floor(diff / 60000);
if (m < 1) {
timeStr = qsTr("now");
timeStrTimer.interval = 5000;
} else {
const h = Math.floor(m / 60);
const d = Math.floor(h / 24);
if (d > 0) {
timeStr = `${d}d`;
timeStrTimer.interval = 3600000;
} else if (h > 0) {
timeStr = `${h}h`;
timeStrTimer.interval = 300000;
} else {
timeStr = `${m}m`;
timeStrTimer.interval = m < 10 ? 30000 : 60000;
}
}
}
function lock(item: Item): void { function lock(item: Item): void {
locks.add(item); locks.add(item);
} }