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

chore: Tidy up superfluous whitespace (#503)

This commit is contained in:
Mattias
2025-10-20 04:35:17 +02:00
committed by GitHub
parent d6b690ae2f
commit 1feb77aadb
39 changed files with 379 additions and 379 deletions

View File

@@ -191,9 +191,9 @@ shell.qml # Main entry point (minimal orchestration)
Singleton { Singleton {
id: root id: root
property type value: defaultValue property type value: defaultValue
function performAction() { /* implementation */ } function performAction() { /* implementation */ }
} }
``` ```
@@ -251,23 +251,23 @@ shell.qml # Main entry point (minimal orchestration)
// For regular components // For regular components
Item { Item {
id: root id: root
property type name: value property type name: value
signal customSignal(type param) signal customSignal(type param)
onSignal: { /* handler */ } onSignal: { /* handler */ }
Component { /* children */ } Component { /* children */ }
} }
// For services (singletons) // For services (singletons)
Singleton { Singleton {
id: root id: root
property bool featureAvailable: false property bool featureAvailable: false
property type currentValue: defaultValue property type currentValue: defaultValue
function performAction(param) { /* implementation */ } function performAction(param) { /* implementation */ }
} }
``` ```
@@ -305,7 +305,7 @@ shell.qml # Main entry point (minimal orchestration)
```qml ```qml
// In services - detect capabilities // In services - detect capabilities
property bool brightnessAvailable: false property bool brightnessAvailable: false
// In modules - adapt UI accordingly // In modules - adapt UI accordingly
DankSlider { DankSlider {
visible: DisplayService.brightnessAvailable visible: DisplayService.brightnessAvailable
@@ -335,7 +335,7 @@ shell.qml # Main entry point (minimal orchestration)
console.log("Info message") // General info console.log("Info message") // General info
console.warn("Warning message") // Warnings console.warn("Warning message") // Warnings
console.error("Error message") // Errors console.error("Error message") // Errors
// Include context in service operations // Include context in service operations
onExited: (exitCode) => { onExited: (exitCode) => {
if (exitCode !== 0) { if (exitCode !== 0) {

View File

@@ -16,7 +16,7 @@ Singleton {
return [fullUnderscore, fullHyphen, _lang].filter(c => c && c !== "en"); return [fullUnderscore, fullHyphen, _lang].filter(c => c && c !== "en");
} }
readonly property url translationsFolder: Qt.resolvedUrl("../translations/poexports") readonly property url translationsFolder: Qt.resolvedUrl("../translations/poexports")
property string currentLocale: "en" property string currentLocale: "en"

View File

@@ -1180,7 +1180,7 @@ Singleton {
showWorkspaceIndex = enabled showWorkspaceIndex = enabled
saveSettings() saveSettings()
} }
function setWorkspaceScrolling(enabled) { function setWorkspaceScrolling(enabled) {
workspaceScrolling = enabled workspaceScrolling = enabled
saveSettings() saveSettings()

View File

@@ -61,7 +61,7 @@ Singleton {
} }
readonly property string rawWallpaperPath: { readonly property string rawWallpaperPath: {
if (typeof SessionData === "undefined") return "" if (typeof SessionData === "undefined") return ""
if (SessionData.perMonitorWallpaper) { if (SessionData.perMonitorWallpaper) {
// Use first monitor's wallpaper for dynamic theming // Use first monitor's wallpaper for dynamic theming
var screens = Quickshell.screens var screens = Quickshell.screens

View File

@@ -84,7 +84,7 @@ Item {
id: clipboardListView id: clipboardListView
anchors.fill: parent anchors.fill: parent
model: filteredModel model: filteredModel
currentIndex: clipboardContent.modal ? clipboardContent.modal.selectedIndex : 0 currentIndex: clipboardContent.modal ? clipboardContent.modal.selectedIndex : 0
spacing: Theme.spacingXS spacing: Theme.spacingXS
interactive: true interactive: true
@@ -94,7 +94,7 @@ Item {
boundsMovement: Flickable.FollowBoundsBehavior boundsMovement: Flickable.FollowBoundsBehavior
pressDelay: 0 pressDelay: 0
flickableDirection: Flickable.VerticalFlick flickableDirection: Flickable.VerticalFlick
function ensureVisible(index) { function ensureVisible(index) {
if (index < 0 || index >= count) { if (index < 0 || index >= count) {
return return
@@ -108,13 +108,13 @@ Item {
contentY = itemBottom - height contentY = itemBottom - height
} }
} }
onCurrentIndexChanged: { onCurrentIndexChanged: {
if (clipboardContent.modal && clipboardContent.modal.keyboardNavigationActive && currentIndex >= 0) { if (clipboardContent.modal && clipboardContent.modal.keyboardNavigationActive && currentIndex >= 0) {
ensureVisible(currentIndex) ensureVisible(currentIndex)
} }
} }
StyledText { StyledText {
text: I18n.tr("No clipboard entries found") text: I18n.tr("No clipboard entries found")
anchors.centerIn: parent anchors.centerIn: parent
@@ -122,11 +122,11 @@ Item {
color: Theme.surfaceVariantText color: Theme.surfaceVariantText
visible: filteredModel.count === 0 visible: filteredModel.count === 0
} }
delegate: ClipboardEntry { delegate: ClipboardEntry {
required property int index required property int index
required property var model required property var model
width: clipboardListView.width width: clipboardListView.width
height: ClipboardConstants.itemHeight height: ClipboardConstants.itemHeight
entryData: model.entry entryData: model.entry

View File

@@ -111,18 +111,18 @@ DankModal {
if (!normalizedPath.startsWith("file://")) { if (!normalizedPath.startsWith("file://")) {
normalizedPath = "file://" + filePath normalizedPath = "file://" + filePath
} }
// Check if file exists by looking through the folder model // Check if file exists by looking through the folder model
var exists = false var exists = false
var fileName = filePath.split('/').pop() var fileName = filePath.split('/').pop()
for (var i = 0; i < folderModel.count; i++) { for (var i = 0; i < folderModel.count; i++) {
if (folderModel.get(i, "fileName") === fileName && !folderModel.get(i, "fileIsDir")) { if (folderModel.get(i, "fileName") === fileName && !folderModel.get(i, "fileIsDir")) {
exists = true exists = true
break break
} }
} }
if (exists) { if (exists) {
pendingFilePath = normalizedPath pendingFilePath = normalizedPath
showOverwriteConfirmation = true showOverwriteConfirmation = true
@@ -139,7 +139,7 @@ DankModal {
Component.onCompleted: { Component.onCompleted: {
currentPath = getLastPath() currentPath = getLastPath()
} }
property var steamPaths: [ property var steamPaths: [
StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/.steam/steam/steamapps/workshop/content/431960", StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/.steam/steam/steamapps/workshop/content/431960",
StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/.local/share/Steam/steamapps/workshop/content/431960", StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/.local/share/Steam/steamapps/workshop/content/431960",
@@ -147,17 +147,17 @@ DankModal {
StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/snap/steam/common/.local/share/Steam/steamapps/workshop/content/431960" StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/snap/steam/common/.local/share/Steam/steamapps/workshop/content/431960"
] ]
property int currentPathIndex: 0 property int currentPathIndex: 0
function discoverWallpaperEngine() { function discoverWallpaperEngine() {
currentPathIndex = 0 currentPathIndex = 0
checkNextPath() checkNextPath()
} }
function checkNextPath() { function checkNextPath() {
if (currentPathIndex >= steamPaths.length) { if (currentPathIndex >= steamPaths.length) {
return return
} }
const wePath = steamPaths[currentPathIndex] const wePath = steamPaths[currentPathIndex]
const cleanPath = wePath.replace(/^file:\/\//, '') const cleanPath = wePath.replace(/^file:\/\//, '')
weDiscoveryProcess.command = ["test", "-d", cleanPath] weDiscoveryProcess.command = ["test", "-d", cleanPath]
@@ -451,13 +451,13 @@ DankModal {
executeKeyboardSelection(targetIndex) executeKeyboardSelection(targetIndex)
} }
} }
Process { Process {
id: weDiscoveryProcess id: weDiscoveryProcess
property string wePath: "" property string wePath: ""
running: false running: false
onExited: exitCode => { onExited: exitCode => {
if (exitCode === 0) { if (exitCode === 0) {
fileBrowserModal.weAvailable = true fileBrowserModal.weAvailable = true
@@ -532,7 +532,7 @@ DankModal {
} }
} }
} }
DankActionButton { DankActionButton {
circular: false circular: false
iconName: "info" iconName: "info"
@@ -875,26 +875,26 @@ DankModal {
id: overwriteDialog id: overwriteDialog
anchors.fill: parent anchors.fill: parent
visible: showOverwriteConfirmation visible: showOverwriteConfirmation
Keys.onEscapePressed: { Keys.onEscapePressed: {
showOverwriteConfirmation = false showOverwriteConfirmation = false
pendingFilePath = "" pendingFilePath = ""
} }
Keys.onReturnPressed: { Keys.onReturnPressed: {
showOverwriteConfirmation = false showOverwriteConfirmation = false
fileSelected(pendingFilePath) fileSelected(pendingFilePath)
pendingFilePath = "" pendingFilePath = ""
Qt.callLater(() => fileBrowserModal.close()) Qt.callLater(() => fileBrowserModal.close())
} }
focus: showOverwriteConfirmation focus: showOverwriteConfirmation
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
color: Theme.shadowStrong color: Theme.shadowStrong
opacity: 0.8 opacity: 0.8
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
@@ -903,7 +903,7 @@ DankModal {
} }
} }
} }
StyledRect { StyledRect {
anchors.centerIn: parent anchors.centerIn: parent
width: 400 width: 400
@@ -912,12 +912,12 @@ DankModal {
radius: Theme.cornerRadius radius: Theme.cornerRadius
border.color: Theme.outlineMedium border.color: Theme.outlineMedium
border.width: 1 border.width: 1
Column { Column {
anchors.centerIn: parent anchors.centerIn: parent
width: parent.width - Theme.spacingL * 2 width: parent.width - Theme.spacingL * 2
spacing: Theme.spacingM spacing: Theme.spacingM
StyledText { StyledText {
text: I18n.tr("File Already Exists") text: I18n.tr("File Already Exists")
font.pixelSize: Theme.fontSizeLarge font.pixelSize: Theme.fontSizeLarge
@@ -925,7 +925,7 @@ DankModal {
color: Theme.surfaceText color: Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
} }
StyledText { StyledText {
text: I18n.tr("A file with this name already exists. Do you want to overwrite it?") text: I18n.tr("A file with this name already exists. Do you want to overwrite it?")
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
@@ -934,11 +934,11 @@ DankModal {
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
} }
Row { Row {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
spacing: Theme.spacingM spacing: Theme.spacingM
StyledRect { StyledRect {
width: 80 width: 80
height: 36 height: 36
@@ -946,7 +946,7 @@ DankModal {
color: cancelArea.containsMouse ? Theme.surfaceVariantHover : Theme.surfaceVariant color: cancelArea.containsMouse ? Theme.surfaceVariantHover : Theme.surfaceVariant
border.color: Theme.outline border.color: Theme.outline
border.width: 1 border.width: 1
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
text: I18n.tr("Cancel") text: I18n.tr("Cancel")
@@ -954,7 +954,7 @@ DankModal {
color: Theme.surfaceText color: Theme.surfaceText
font.weight: Font.Medium font.weight: Font.Medium
} }
MouseArea { MouseArea {
id: cancelArea id: cancelArea
anchors.fill: parent anchors.fill: parent
@@ -966,13 +966,13 @@ DankModal {
} }
} }
} }
StyledRect { StyledRect {
width: 90 width: 90
height: 36 height: 36
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: overwriteArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary color: overwriteArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
text: I18n.tr("Overwrite") text: I18n.tr("Overwrite")
@@ -980,7 +980,7 @@ DankModal {
color: Theme.background color: Theme.background
font.weight: Font.Medium font.weight: Font.Medium
} }
MouseArea { MouseArea {
id: overwriteArea id: overwriteArea
anchors.fill: parent anchors.fill: parent

View File

@@ -20,7 +20,7 @@ DankModal {
if (modalKeyboardController && notificationListRef) { if (modalKeyboardController && notificationListRef) {
modalKeyboardController.listView = notificationListRef modalKeyboardController.listView = notificationListRef
modalKeyboardController.rebuildFlatNavigation() modalKeyboardController.rebuildFlatNavigation()
Qt.callLater(() => { Qt.callLater(() => {
modalKeyboardController.keyboardNavigationActive = true modalKeyboardController.keyboardNavigationActive = true
modalKeyboardController.selectedFlatIndex = 0 modalKeyboardController.selectedFlatIndex = 0

View File

@@ -285,12 +285,12 @@ Item {
} }
const triggers = PluginService.getAllPluginTriggers() const triggers = PluginService.getAllPluginTriggers()
for (const trigger in triggers) { for (const trigger in triggers) {
if (query.startsWith(trigger)) { if (query.startsWith(trigger)) {
const pluginId = triggers[trigger] const pluginId = triggers[trigger]
const plugin = PluginService.getLauncherPlugin(pluginId) const plugin = PluginService.getLauncherPlugin(pluginId)
if (plugin) { if (plugin) {
const remainingQuery = query.substring(trigger.length).trim() const remainingQuery = query.substring(trigger.length).trim()
const result = { const result = {
@@ -304,7 +304,7 @@ Item {
} }
} }
} }
return { triggered: false, pluginCategory: "", query: "" } return { triggered: false, pluginCategory: "", query: "" }
} }

View File

@@ -17,7 +17,7 @@ Rectangle {
color: Theme.surfaceContainerHigh color: Theme.surfaceContainerHigh
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
border.width: 0 border.width: 0
Row { Row {
id: headerRow id: headerRow
anchors.left: parent.left anchors.left: parent.left
@@ -27,7 +27,7 @@ Rectangle {
anchors.rightMargin: Theme.spacingM anchors.rightMargin: Theme.spacingM
anchors.topMargin: Theme.spacingS anchors.topMargin: Theme.spacingS
height: 40 height: 40
StyledText { StyledText {
id: headerText id: headerText
text: I18n.tr("Input Devices") text: I18n.tr("Input Devices")
@@ -37,7 +37,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
} }
Row { Row {
id: volumeSlider id: volumeSlider
anchors.left: parent.left anchors.left: parent.left
@@ -105,7 +105,7 @@ Rectangle {
} }
} }
} }
DankFlickable { DankFlickable {
id: audioContent id: audioContent
anchors.top: hasInputVolumeSliderInCC ? headerRow.bottom : volumeSlider.bottom anchors.top: hasInputVolumeSliderInCC ? headerRow.bottom : volumeSlider.bottom
@@ -116,34 +116,34 @@ Rectangle {
anchors.topMargin: hasInputVolumeSliderInCC ? Theme.spacingM : Theme.spacingS anchors.topMargin: hasInputVolumeSliderInCC ? Theme.spacingM : Theme.spacingS
contentHeight: audioColumn.height contentHeight: audioColumn.height
clip: true clip: true
Column { Column {
id: audioColumn id: audioColumn
width: parent.width width: parent.width
spacing: Theme.spacingS spacing: Theme.spacingS
Repeater { Repeater {
model: Pipewire.nodes.values.filter(node => { model: Pipewire.nodes.values.filter(node => {
return node.audio && !node.isSink && !node.isStream return node.audio && !node.isSink && !node.isStream
}) })
delegate: Rectangle { delegate: Rectangle {
required property var modelData required property var modelData
required property int index required property int index
width: parent.width width: parent.width
height: 50 height: 50
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: deviceMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHighest color: deviceMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHighest
border.color: modelData === AudioService.source ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) border.color: modelData === AudioService.source ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
border.width: 0 border.width: 0
Row { Row {
anchors.left: parent.left anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Theme.spacingM anchors.leftMargin: Theme.spacingM
spacing: Theme.spacingS spacing: Theme.spacingS
DankIcon { DankIcon {
name: { name: {
if (modelData.name.includes("bluez")) if (modelData.name.includes("bluez"))
@@ -157,11 +157,11 @@ Rectangle {
color: modelData === AudioService.source ? Theme.primary : Theme.surfaceText color: modelData === AudioService.source ? Theme.primary : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Column { Column {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: parent.parent.width - parent.parent.anchors.leftMargin - parent.spacing - Theme.iconSize - Theme.spacingM width: parent.parent.width - parent.parent.anchors.leftMargin - parent.spacing - Theme.iconSize - Theme.spacingM
StyledText { StyledText {
text: AudioService.displayName(modelData) text: AudioService.displayName(modelData)
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
@@ -171,7 +171,7 @@ Rectangle {
width: parent.width width: parent.width
wrapMode: Text.NoWrap wrapMode: Text.NoWrap
} }
StyledText { StyledText {
text: modelData === AudioService.source ? "Active" : "Available" text: modelData === AudioService.source ? "Active" : "Available"
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
@@ -182,7 +182,7 @@ Rectangle {
} }
} }
} }
MouseArea { MouseArea {
id: deviceMouseArea id: deviceMouseArea
anchors.fill: parent anchors.fill: parent

View File

@@ -17,7 +17,7 @@ Rectangle {
color: Theme.surfaceContainerHigh color: Theme.surfaceContainerHigh
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
border.width: 0 border.width: 0
Row { Row {
id: headerRow id: headerRow
anchors.left: parent.left anchors.left: parent.left
@@ -27,7 +27,7 @@ Rectangle {
anchors.rightMargin: Theme.spacingM anchors.rightMargin: Theme.spacingM
anchors.topMargin: Theme.spacingS anchors.topMargin: Theme.spacingS
height: 40 height: 40
StyledText { StyledText {
id: headerText id: headerText
text: I18n.tr("Audio Devices") text: I18n.tr("Audio Devices")
@@ -121,34 +121,34 @@ Rectangle {
anchors.topMargin: volumeSlider.visible ? Theme.spacingS : Theme.spacingM anchors.topMargin: volumeSlider.visible ? Theme.spacingS : Theme.spacingM
contentHeight: audioColumn.height contentHeight: audioColumn.height
clip: true clip: true
Column { Column {
id: audioColumn id: audioColumn
width: parent.width width: parent.width
spacing: Theme.spacingS spacing: Theme.spacingS
Repeater { Repeater {
model: Pipewire.nodes.values.filter(node => { model: Pipewire.nodes.values.filter(node => {
return node.audio && node.isSink && !node.isStream return node.audio && node.isSink && !node.isStream
}) })
delegate: Rectangle { delegate: Rectangle {
required property var modelData required property var modelData
required property int index required property int index
width: parent.width width: parent.width
height: 50 height: 50
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: deviceMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHighest color: deviceMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHighest
border.color: modelData === AudioService.sink ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) border.color: modelData === AudioService.sink ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
border.width: 0 border.width: 0
Row { Row {
anchors.left: parent.left anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Theme.spacingM anchors.leftMargin: Theme.spacingM
spacing: Theme.spacingS spacing: Theme.spacingS
DankIcon { DankIcon {
name: { name: {
if (modelData.name.includes("bluez")) if (modelData.name.includes("bluez"))
@@ -164,11 +164,11 @@ Rectangle {
color: modelData === AudioService.sink ? Theme.primary : Theme.surfaceText color: modelData === AudioService.sink ? Theme.primary : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Column { Column {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: parent.parent.width - parent.parent.anchors.leftMargin - parent.spacing - Theme.iconSize - Theme.spacingM width: parent.parent.width - parent.parent.anchors.leftMargin - parent.spacing - Theme.iconSize - Theme.spacingM
StyledText { StyledText {
text: AudioService.displayName(modelData) text: AudioService.displayName(modelData)
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
@@ -178,7 +178,7 @@ Rectangle {
width: parent.width width: parent.width
wrapMode: Text.NoWrap wrapMode: Text.NoWrap
} }
StyledText { StyledText {
text: modelData === AudioService.sink ? "Active" : "Available" text: modelData === AudioService.sink ? "Active" : "Available"
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
@@ -189,7 +189,7 @@ Rectangle {
} }
} }
} }
MouseArea { MouseArea {
id: deviceMouseArea id: deviceMouseArea
anchors.fill: parent anchors.fill: parent

View File

@@ -83,12 +83,12 @@ Item {
hoverEnabled: true hoverEnabled: true
preventStealing: true preventStealing: true
propagateComposedEvents: false propagateComposedEvents: false
onClicked: root.hide() onClicked: root.hide()
onWheel: (wheel) => { wheel.accepted = true } onWheel: (wheel) => { wheel.accepted = true }
onPositionChanged: (mouse) => { mouse.accepted = true } onPositionChanged: (mouse) => { mouse.accepted = true }
} }
Rectangle { Rectangle {
id: modalBackground id: modalBackground
anchors.fill: parent anchors.fill: parent

View File

@@ -12,11 +12,11 @@ Rectangle {
color: Theme.surfaceContainerHigh color: Theme.surfaceContainerHigh
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
border.width: 0 border.width: 0
property var bluetoothCodecModalRef: null property var bluetoothCodecModalRef: null
signal showCodecSelector(var device) signal showCodecSelector(var device)
function updateDeviceCodecDisplay(deviceAddress, codecName) { function updateDeviceCodecDisplay(deviceAddress, codecName) {
for (let i = 0; i < pairedRepeater.count; i++) { for (let i = 0; i < pairedRepeater.count; i++) {
let item = pairedRepeater.itemAt(i) let item = pairedRepeater.itemAt(i)
@@ -26,7 +26,7 @@ Rectangle {
} }
} }
} }
Row { Row {
id: headerRow id: headerRow
anchors.left: parent.left anchors.left: parent.left
@@ -36,7 +36,7 @@ Rectangle {
anchors.rightMargin: Theme.spacingM anchors.rightMargin: Theme.spacingM
anchors.topMargin: Theme.spacingS anchors.topMargin: Theme.spacingS
height: 40 height: 40
StyledText { StyledText {
id: headerText id: headerText
text: I18n.tr("Bluetooth Settings") text: I18n.tr("Bluetooth Settings")
@@ -45,12 +45,12 @@ Rectangle {
font.weight: Font.Medium font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Item { Item {
width: Math.max(0, parent.width - headerText.implicitWidth - scanButton.width - Theme.spacingM) width: Math.max(0, parent.width - headerText.implicitWidth - scanButton.width - Theme.spacingM)
height: parent.height height: parent.height
} }
Rectangle { Rectangle {
id: scanButton id: scanButton
width: 100 width: 100
@@ -64,18 +64,18 @@ Rectangle {
border.color: BluetoothService.adapter && BluetoothService.adapter.enabled ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) border.color: BluetoothService.adapter && BluetoothService.adapter.enabled ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
border.width: 0 border.width: 0
visible: BluetoothService.adapter && BluetoothService.adapter.enabled visible: BluetoothService.adapter && BluetoothService.adapter.enabled
Row { Row {
anchors.centerIn: parent anchors.centerIn: parent
spacing: Theme.spacingXS spacing: Theme.spacingXS
DankIcon { DankIcon {
name: BluetoothService.adapter && BluetoothService.adapter.discovering ? "stop" : "bluetooth_searching" name: BluetoothService.adapter && BluetoothService.adapter.discovering ? "stop" : "bluetooth_searching"
size: 18 size: 18
color: BluetoothService.adapter && BluetoothService.adapter.enabled ? Theme.primary : Theme.surfaceVariantText color: BluetoothService.adapter && BluetoothService.adapter.enabled ? Theme.primary : Theme.surfaceVariantText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
StyledText { StyledText {
text: BluetoothService.adapter && BluetoothService.adapter.discovering ? "Scanning" : "Scan" text: BluetoothService.adapter && BluetoothService.adapter.discovering ? "Scanning" : "Scan"
color: BluetoothService.adapter && BluetoothService.adapter.enabled ? Theme.primary : Theme.surfaceVariantText color: BluetoothService.adapter && BluetoothService.adapter.enabled ? Theme.primary : Theme.surfaceVariantText
@@ -84,7 +84,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
} }
MouseArea { MouseArea {
id: scanMouseArea id: scanMouseArea
anchors.fill: parent anchors.fill: parent
@@ -98,7 +98,7 @@ Rectangle {
} }
} }
} }
DankFlickable { DankFlickable {
id: bluetoothContent id: bluetoothContent
anchors.top: headerRow.bottom anchors.top: headerRow.bottom
@@ -110,19 +110,19 @@ Rectangle {
visible: BluetoothService.adapter && BluetoothService.adapter.enabled visible: BluetoothService.adapter && BluetoothService.adapter.enabled
contentHeight: bluetoothColumn.height contentHeight: bluetoothColumn.height
clip: true clip: true
Column { Column {
id: bluetoothColumn id: bluetoothColumn
width: parent.width width: parent.width
spacing: Theme.spacingS spacing: Theme.spacingS
Repeater { Repeater {
id: pairedRepeater id: pairedRepeater
model: { model: {
if (!BluetoothService.adapter || !BluetoothService.adapter.devices) if (!BluetoothService.adapter || !BluetoothService.adapter.devices)
return [] return []
let devices = [...BluetoothService.adapter.devices.values.filter(dev => dev && (dev.paired || dev.trusted))] let devices = [...BluetoothService.adapter.devices.values.filter(dev => dev && (dev.paired || dev.trusted))]
devices.sort((a, b) => { devices.sort((a, b) => {
if (a.connected && !b.connected) return -1 if (a.connected && !b.connected) return -1
@@ -131,17 +131,17 @@ Rectangle {
}) })
return devices return devices
} }
delegate: Rectangle { delegate: Rectangle {
required property var modelData required property var modelData
required property int index required property int index
property string currentCodec: BluetoothService.deviceCodecs[modelData.address] || "" property string currentCodec: BluetoothService.deviceCodecs[modelData.address] || ""
width: parent.width width: parent.width
height: 50 height: 50
radius: Theme.cornerRadius radius: Theme.cornerRadius
Component.onCompleted: { Component.onCompleted: {
if (modelData.connected && BluetoothService.isAudioDevice(modelData)) { if (modelData.connected && BluetoothService.isAudioDevice(modelData)) {
BluetoothService.refreshDeviceCodec(modelData) BluetoothService.refreshDeviceCodec(modelData)
@@ -162,13 +162,13 @@ Rectangle {
return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
} }
border.width: 0 border.width: 0
Row { Row {
anchors.left: parent.left anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Theme.spacingM anchors.leftMargin: Theme.spacingM
spacing: Theme.spacingS spacing: Theme.spacingS
DankIcon { DankIcon {
name: BluetoothService.getDeviceIcon(modelData) name: BluetoothService.getDeviceIcon(modelData)
size: Theme.iconSize - 4 size: Theme.iconSize - 4
@@ -181,11 +181,11 @@ Rectangle {
} }
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Column { Column {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: 200 width: 200
StyledText { StyledText {
text: modelData.name || modelData.deviceName || "Unknown Device" text: modelData.name || modelData.deviceName || "Unknown Device"
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
@@ -194,10 +194,10 @@ Rectangle {
elide: Text.ElideRight elide: Text.ElideRight
width: parent.width width: parent.width
} }
Row { Row {
spacing: Theme.spacingXS spacing: Theme.spacingXS
StyledText { StyledText {
text: { text: {
if (modelData.state === BluetoothDeviceState.Connecting) if (modelData.state === BluetoothDeviceState.Connecting)
@@ -218,12 +218,12 @@ Rectangle {
return Theme.surfaceVariantText return Theme.surfaceVariantText
} }
} }
StyledText { StyledText {
text: { text: {
if (modelData.batteryAvailable && modelData.battery > 0) if (modelData.batteryAvailable && modelData.battery > 0)
return "• " + Math.round(modelData.battery * 100) + "%" return "• " + Math.round(modelData.battery * 100) + "%"
var btBattery = BatteryService.bluetoothDevices.find(dev => { var btBattery = BatteryService.bluetoothDevices.find(dev => {
return dev.name === (modelData.name || modelData.deviceName) || return dev.name === (modelData.name || modelData.deviceName) ||
dev.name.toLowerCase().includes((modelData.name || modelData.deviceName).toLowerCase()) || dev.name.toLowerCase().includes((modelData.name || modelData.deviceName).toLowerCase()) ||
@@ -235,7 +235,7 @@ Rectangle {
color: Theme.surfaceVariantText color: Theme.surfaceVariantText
visible: text.length > 0 visible: text.length > 0
} }
StyledText { StyledText {
text: modelData.signalStrength !== undefined && modelData.signalStrength > 0 ? "• " + modelData.signalStrength + "%" : "" text: modelData.signalStrength !== undefined && modelData.signalStrength > 0 ? "• " + modelData.signalStrength + "%" : ""
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
@@ -245,7 +245,7 @@ Rectangle {
} }
} }
} }
DankActionButton { DankActionButton {
id: pairedOptionsButton id: pairedOptionsButton
anchors.right: parent.right anchors.right: parent.right
@@ -262,7 +262,7 @@ Rectangle {
} }
} }
} }
MouseArea { MouseArea {
id: deviceMouseArea id: deviceMouseArea
anchors.fill: parent anchors.fill: parent
@@ -279,26 +279,26 @@ Rectangle {
} }
} }
} }
Rectangle { Rectangle {
width: parent.width width: parent.width
height: 1 height: 1
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
visible: pairedRepeater.count > 0 && availableRepeater.count > 0 visible: pairedRepeater.count > 0 && availableRepeater.count > 0
} }
Item { Item {
width: parent.width width: parent.width
height: 80 height: 80
visible: BluetoothService.adapter && BluetoothService.adapter.discovering && availableRepeater.count === 0 visible: BluetoothService.adapter && BluetoothService.adapter.discovering && availableRepeater.count === 0
DankIcon { DankIcon {
anchors.centerIn: parent anchors.centerIn: parent
name: "sync" name: "sync"
size: 24 size: 24
color: Qt.rgba(Theme.surfaceText.r || 0.8, Theme.surfaceText.g || 0.8, Theme.surfaceText.b || 0.8, 0.4) color: Qt.rgba(Theme.surfaceText.r || 0.8, Theme.surfaceText.g || 0.8, Theme.surfaceText.b || 0.8, 0.4)
RotationAnimation on rotation { RotationAnimation on rotation {
running: parent.visible && BluetoothService.adapter && BluetoothService.adapter.discovering && availableRepeater.count === 0 running: parent.visible && BluetoothService.adapter && BluetoothService.adapter.discovering && availableRepeater.count === 0
loops: Animation.Infinite loops: Animation.Infinite
@@ -308,27 +308,27 @@ Rectangle {
} }
} }
} }
Repeater { Repeater {
id: availableRepeater id: availableRepeater
model: { model: {
if (!BluetoothService.adapter || !BluetoothService.adapter.discovering || !Bluetooth.devices) if (!BluetoothService.adapter || !BluetoothService.adapter.discovering || !Bluetooth.devices)
return [] return []
var filtered = Bluetooth.devices.values.filter(dev => { var filtered = Bluetooth.devices.values.filter(dev => {
return dev && !dev.paired && !dev.pairing && !dev.blocked && return dev && !dev.paired && !dev.pairing && !dev.blocked &&
(dev.signalStrength === undefined || dev.signalStrength > 0) (dev.signalStrength === undefined || dev.signalStrength > 0)
}) })
return BluetoothService.sortDevices(filtered) return BluetoothService.sortDevices(filtered)
} }
delegate: Rectangle { delegate: Rectangle {
required property var modelData required property var modelData
required property int index required property int index
property bool canConnect: BluetoothService.canConnect(modelData) property bool canConnect: BluetoothService.canConnect(modelData)
property bool isBusy: BluetoothService.isDeviceBusy(modelData) property bool isBusy: BluetoothService.isDeviceBusy(modelData)
width: parent.width width: parent.width
height: 50 height: 50
radius: Theme.cornerRadius radius: Theme.cornerRadius
@@ -336,24 +336,24 @@ Rectangle {
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
border.width: 0 border.width: 0
opacity: canConnect ? 1 : 0.6 opacity: canConnect ? 1 : 0.6
Row { Row {
anchors.left: parent.left anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Theme.spacingM anchors.leftMargin: Theme.spacingM
spacing: Theme.spacingS spacing: Theme.spacingS
DankIcon { DankIcon {
name: BluetoothService.getDeviceIcon(modelData) name: BluetoothService.getDeviceIcon(modelData)
size: Theme.iconSize - 4 size: Theme.iconSize - 4
color: Theme.surfaceText color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Column { Column {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: 200 width: 200
StyledText { StyledText {
text: modelData.name || modelData.deviceName || "Unknown Device" text: modelData.name || modelData.deviceName || "Unknown Device"
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
@@ -361,10 +361,10 @@ Rectangle {
elide: Text.ElideRight elide: Text.ElideRight
width: parent.width width: parent.width
} }
Row { Row {
spacing: Theme.spacingXS spacing: Theme.spacingXS
StyledText { StyledText {
text: { text: {
if (modelData.pairing) return "Pairing..." if (modelData.pairing) return "Pairing..."
@@ -374,7 +374,7 @@ Rectangle {
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText color: Theme.surfaceVariantText
} }
StyledText { StyledText {
text: modelData.signalStrength !== undefined && modelData.signalStrength > 0 ? "• " + modelData.signalStrength + "%" : "" text: modelData.signalStrength !== undefined && modelData.signalStrength > 0 ? "• " + modelData.signalStrength + "%" : ""
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
@@ -384,7 +384,7 @@ Rectangle {
} }
} }
} }
StyledText { StyledText {
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Theme.spacingM anchors.rightMargin: Theme.spacingM
@@ -398,7 +398,7 @@ Rectangle {
color: canConnect ? Theme.primary : Theme.surfaceVariantText color: canConnect ? Theme.primary : Theme.surfaceVariantText
font.weight: Font.Medium font.weight: Font.Medium
} }
MouseArea { MouseArea {
id: availableMouseArea id: availableMouseArea
anchors.fill: parent anchors.fill: parent
@@ -411,15 +411,15 @@ Rectangle {
} }
} }
} }
} }
} }
Item { Item {
width: parent.width width: parent.width
height: 60 height: 60
visible: !BluetoothService.adapter visible: !BluetoothService.adapter
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
text: I18n.tr("No Bluetooth adapter found") text: I18n.tr("No Bluetooth adapter found")
@@ -429,25 +429,25 @@ Rectangle {
} }
} }
} }
Menu { Menu {
id: bluetoothContextMenu id: bluetoothContextMenu
width: 150 width: 150
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
property var currentDevice: null property var currentDevice: null
background: Rectangle { background: Rectangle {
color: Theme.popupBackground() color: Theme.popupBackground()
radius: Theme.cornerRadius radius: Theme.cornerRadius
border.width: 0 border.width: 0
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
} }
MenuItem { MenuItem {
text: bluetoothContextMenu.currentDevice && bluetoothContextMenu.currentDevice.connected ? "Disconnect" : "Connect" text: bluetoothContextMenu.currentDevice && bluetoothContextMenu.currentDevice.connected ? "Disconnect" : "Connect"
height: 32 height: 32
contentItem: StyledText { contentItem: StyledText {
text: parent.text text: parent.text
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
@@ -455,12 +455,12 @@ Rectangle {
leftPadding: Theme.spacingS leftPadding: Theme.spacingS
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
background: Rectangle { background: Rectangle {
color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent"
radius: Theme.cornerRadius / 2 radius: Theme.cornerRadius / 2
} }
onTriggered: { onTriggered: {
if (bluetoothContextMenu.currentDevice) { if (bluetoothContextMenu.currentDevice) {
if (bluetoothContextMenu.currentDevice.connected) { if (bluetoothContextMenu.currentDevice.connected) {
@@ -471,12 +471,12 @@ Rectangle {
} }
} }
} }
MenuItem { MenuItem {
text: I18n.tr("Audio Codec") text: I18n.tr("Audio Codec")
height: bluetoothContextMenu.currentDevice && BluetoothService.isAudioDevice(bluetoothContextMenu.currentDevice) && bluetoothContextMenu.currentDevice.connected ? 32 : 0 height: bluetoothContextMenu.currentDevice && BluetoothService.isAudioDevice(bluetoothContextMenu.currentDevice) && bluetoothContextMenu.currentDevice.connected ? 32 : 0
visible: bluetoothContextMenu.currentDevice && BluetoothService.isAudioDevice(bluetoothContextMenu.currentDevice) && bluetoothContextMenu.currentDevice.connected visible: bluetoothContextMenu.currentDevice && BluetoothService.isAudioDevice(bluetoothContextMenu.currentDevice) && bluetoothContextMenu.currentDevice.connected
contentItem: StyledText { contentItem: StyledText {
text: parent.text text: parent.text
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
@@ -484,23 +484,23 @@ Rectangle {
leftPadding: Theme.spacingS leftPadding: Theme.spacingS
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
background: Rectangle { background: Rectangle {
color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent"
radius: Theme.cornerRadius / 2 radius: Theme.cornerRadius / 2
} }
onTriggered: { onTriggered: {
if (bluetoothContextMenu.currentDevice) { if (bluetoothContextMenu.currentDevice) {
showCodecSelector(bluetoothContextMenu.currentDevice) showCodecSelector(bluetoothContextMenu.currentDevice)
} }
} }
} }
MenuItem { MenuItem {
text: I18n.tr("Forget Device") text: I18n.tr("Forget Device")
height: 32 height: 32
contentItem: StyledText { contentItem: StyledText {
text: parent.text text: parent.text
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
@@ -508,12 +508,12 @@ Rectangle {
leftPadding: Theme.spacingS leftPadding: Theme.spacingS
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
background: Rectangle { background: Rectangle {
color: parent.hovered ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.08) : "transparent" color: parent.hovered ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.08) : "transparent"
radius: Theme.cornerRadius / 2 radius: Theme.cornerRadius / 2
} }
onTriggered: { onTriggered: {
if (bluetoothContextMenu.currentDevice) { if (bluetoothContextMenu.currentDevice) {
bluetoothContextMenu.currentDevice.forget() bluetoothContextMenu.currentDevice.forget()
@@ -521,5 +521,5 @@ Rectangle {
} }
} }
} }
} }

View File

@@ -28,7 +28,7 @@ Rectangle {
Component.onDestruction: { Component.onDestruction: {
NetworkService.removeRef() NetworkService.removeRef()
} }
property int currentPreferenceIndex: { property int currentPreferenceIndex: {
if (DMSService.apiVersion < 5) { if (DMSService.apiVersion < 5) {
return 1 return 1
@@ -88,7 +88,7 @@ Rectangle {
} }
} }
} }
Item { Item {
id: wifiToggleContent id: wifiToggleContent
anchors.top: headerRow.bottom anchors.top: headerRow.bottom
@@ -127,7 +127,7 @@ Rectangle {
} }
} }
} }
Item { Item {
id: wifiOffContent id: wifiOffContent
anchors.top: headerRow.bottom anchors.top: headerRow.bottom
@@ -137,19 +137,19 @@ Rectangle {
anchors.topMargin: Theme.spacingM anchors.topMargin: Theme.spacingM
visible: currentPreferenceIndex === 1 && !NetworkService.wifiEnabled && !NetworkService.wifiToggling visible: currentPreferenceIndex === 1 && !NetworkService.wifiEnabled && !NetworkService.wifiToggling
height: visible ? 120 : 0 height: visible ? 120 : 0
Column { Column {
anchors.centerIn: parent anchors.centerIn: parent
spacing: Theme.spacingL spacing: Theme.spacingL
width: parent.width width: parent.width
DankIcon { DankIcon {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
name: "wifi_off" name: "wifi_off"
size: 48 size: 48
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5) color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
} }
StyledText { StyledText {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
text: I18n.tr("WiFi is off") text: I18n.tr("WiFi is off")
@@ -158,7 +158,7 @@ Rectangle {
font.weight: Font.Medium font.weight: Font.Medium
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
} }
Rectangle { Rectangle {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
width: 120 width: 120
@@ -167,7 +167,7 @@ Rectangle {
color: enableWifiButton.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) color: enableWifiButton.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08)
border.width: 0 border.width: 0
border.color: Theme.primary border.color: Theme.primary
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
text: I18n.tr("Enable WiFi") text: I18n.tr("Enable WiFi")
@@ -175,7 +175,7 @@ Rectangle {
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium font.weight: Font.Medium
} }
MouseArea { MouseArea {
id: enableWifiButton id: enableWifiButton
anchors.fill: parent anchors.fill: parent
@@ -257,7 +257,7 @@ Rectangle {
} }
} }
} }
DankActionButton { DankActionButton {
id: wiredOptionsButton id: wiredOptionsButton
anchors.right: parent.right anchors.right: parent.right
@@ -295,7 +295,7 @@ Rectangle {
} }
} }
} }
Menu { Menu {
id: wiredNetworkContextMenu id: wiredNetworkContextMenu
width: 150 width: 150
@@ -376,7 +376,7 @@ Rectangle {
id: wifiColumn id: wifiColumn
width: parent.width width: parent.width
spacing: Theme.spacingS spacing: Theme.spacingS
Item { Item {
width: parent.width width: parent.width
height: 200 height: 200
@@ -397,7 +397,7 @@ Rectangle {
} }
} }
} }
Repeater { Repeater {
model: sortedNetworks model: sortedNetworks
@@ -415,20 +415,20 @@ Rectangle {
delegate: Rectangle { delegate: Rectangle {
required property var modelData required property var modelData
required property int index required property int index
width: parent.width width: parent.width
height: 50 height: 50
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: networkMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHighest color: networkMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHighest
border.color: modelData.ssid === NetworkService.currentWifiSSID ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) border.color: modelData.ssid === NetworkService.currentWifiSSID ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
border.width: 0 border.width: 0
Row { Row {
anchors.left: parent.left anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Theme.spacingM anchors.leftMargin: Theme.spacingM
spacing: Theme.spacingS spacing: Theme.spacingS
DankIcon { DankIcon {
name: { name: {
let strength = modelData.signal || 0 let strength = modelData.signal || 0
@@ -440,11 +440,11 @@ Rectangle {
color: modelData.ssid === NetworkService.currentWifiSSID ? Theme.primary : Theme.surfaceText color: modelData.ssid === NetworkService.currentWifiSSID ? Theme.primary : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Column { Column {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: 200 width: 200
StyledText { StyledText {
text: modelData.ssid || "Unknown Network" text: modelData.ssid || "Unknown Network"
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
@@ -462,14 +462,14 @@ Rectangle {
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText color: Theme.surfaceVariantText
} }
StyledText { StyledText {
text: modelData.saved ? "Saved" : "" text: modelData.saved ? "Saved" : ""
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: Theme.primary color: Theme.primary
visible: text.length > 0 visible: text.length > 0
} }
StyledText { StyledText {
text: (modelData.saved ? "• " : "") + modelData.signal + "%" text: (modelData.saved ? "• " : "") + modelData.signal + "%"
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
@@ -478,7 +478,7 @@ Rectangle {
} }
} }
} }
DankActionButton { DankActionButton {
id: optionsButton id: optionsButton
anchors.right: parent.right anchors.right: parent.right
@@ -499,7 +499,7 @@ Rectangle {
} }
} }
} }
MouseArea { MouseArea {
id: networkMouseArea id: networkMouseArea
anchors.fill: parent anchors.fill: parent
@@ -517,34 +517,34 @@ Rectangle {
event.accepted = true event.accepted = true
} }
} }
} }
} }
} }
} }
Menu { Menu {
id: networkContextMenu id: networkContextMenu
width: 150 width: 150
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
property string currentSSID: "" property string currentSSID: ""
property bool currentSecured: false property bool currentSecured: false
property bool currentConnected: false property bool currentConnected: false
property bool currentSaved: false property bool currentSaved: false
property int currentSignal: 0 property int currentSignal: 0
background: Rectangle { background: Rectangle {
color: Theme.popupBackground() color: Theme.popupBackground()
radius: Theme.cornerRadius radius: Theme.cornerRadius
border.width: 0 border.width: 0
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
} }
MenuItem { MenuItem {
text: networkContextMenu.currentConnected ? "Disconnect" : "Connect" text: networkContextMenu.currentConnected ? "Disconnect" : "Connect"
height: 32 height: 32
contentItem: StyledText { contentItem: StyledText {
text: parent.text text: parent.text
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
@@ -552,12 +552,12 @@ Rectangle {
leftPadding: Theme.spacingS leftPadding: Theme.spacingS
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
background: Rectangle { background: Rectangle {
color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent"
radius: Theme.cornerRadius / 2 radius: Theme.cornerRadius / 2
} }
onTriggered: { onTriggered: {
if (networkContextMenu.currentConnected) { if (networkContextMenu.currentConnected) {
NetworkService.disconnectWifi() NetworkService.disconnectWifi()
@@ -570,11 +570,11 @@ Rectangle {
} }
} }
} }
MenuItem { MenuItem {
text: I18n.tr("Network Info") text: I18n.tr("Network Info")
height: 32 height: 32
contentItem: StyledText { contentItem: StyledText {
text: parent.text text: parent.text
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
@@ -582,23 +582,23 @@ Rectangle {
leftPadding: Theme.spacingS leftPadding: Theme.spacingS
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
background: Rectangle { background: Rectangle {
color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" color: parent.hovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent"
radius: Theme.cornerRadius / 2 radius: Theme.cornerRadius / 2
} }
onTriggered: { onTriggered: {
let networkData = NetworkService.getNetworkInfo(networkContextMenu.currentSSID) let networkData = NetworkService.getNetworkInfo(networkContextMenu.currentSSID)
networkInfoModal.showNetworkInfo(networkContextMenu.currentSSID, networkData) networkInfoModal.showNetworkInfo(networkContextMenu.currentSSID, networkData)
} }
} }
MenuItem { MenuItem {
text: I18n.tr("Forget Network") text: I18n.tr("Forget Network")
height: networkContextMenu.currentSaved || networkContextMenu.currentConnected ? 32 : 0 height: networkContextMenu.currentSaved || networkContextMenu.currentConnected ? 32 : 0
visible: networkContextMenu.currentSaved || networkContextMenu.currentConnected visible: networkContextMenu.currentSaved || networkContextMenu.currentConnected
contentItem: StyledText { contentItem: StyledText {
text: parent.text text: parent.text
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
@@ -606,18 +606,18 @@ Rectangle {
leftPadding: Theme.spacingS leftPadding: Theme.spacingS
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
background: Rectangle { background: Rectangle {
color: parent.hovered ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.08) : "transparent" color: parent.hovered ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.08) : "transparent"
radius: Theme.cornerRadius / 2 radius: Theme.cornerRadius / 2
} }
onTriggered: { onTriggered: {
NetworkService.forgetWifiNetwork(networkContextMenu.currentSSID) NetworkService.forgetWifiNetwork(networkContextMenu.currentSSID)
} }
} }
} }
WifiPasswordModal { WifiPasswordModal {
id: wifiPasswordModal id: wifiPasswordModal
} }
@@ -625,7 +625,7 @@ Rectangle {
NetworkInfoModal { NetworkInfoModal {
id: networkInfoModal id: networkInfoModal
} }
NetworkWiredInfoModal { NetworkWiredInfoModal {
id: networkWiredInfoModal id: networkWiredInfoModal
} }

View File

@@ -14,7 +14,7 @@ Rectangle {
property real maximumValue: 1.0 property real maximumValue: 1.0
property real minimumValue: 0.0 property real minimumValue: 0.0
property bool enabled: true property bool enabled: true
signal sliderValueChanged(real value) signal sliderValueChanged(real value)
width: parent ? parent.width : 200 width: parent ? parent.width : 200

View File

@@ -38,7 +38,7 @@ Item {
} }
return return
} }
root.clicked(); root.clicked();
if (popupTarget && popupTarget.setTriggerPosition) { if (popupTarget && popupTarget.setTriggerPosition) {
const globalPos = mapToGlobal(0, 0); const globalPos = mapToGlobal(0, 0);

View File

@@ -82,20 +82,20 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
acceptedButtons: Qt.NoButton acceptedButtons: Qt.NoButton
property real scrollAccumulator: 0 property real scrollAccumulator: 0
property real touchpadThreshold: 500 property real touchpadThreshold: 500
onWheel: (wheel) => { onWheel: (wheel) => {
const deltaY = wheel.angleDelta.y; const deltaY = wheel.angleDelta.y;
const isMouseWheel = Math.abs(deltaY) >= 120 const isMouseWheel = Math.abs(deltaY) >= 120
&& (Math.abs(deltaY) % 120) === 0; && (Math.abs(deltaY) % 120) === 0;
const windows = root.sortedToplevels; const windows = root.sortedToplevels;
if (windows.length < 2) { if (windows.length < 2) {
return; return;
} }
if (isMouseWheel) { if (isMouseWheel) {
// Direct mouse wheel action // Direct mouse wheel action
let currentIndex = -1; let currentIndex = -1;
@@ -128,7 +128,7 @@ Rectangle {
} else { } else {
// Touchpad - accumulate small deltas // Touchpad - accumulate small deltas
scrollAccumulator += deltaY; scrollAccumulator += deltaY;
if (Math.abs(scrollAccumulator) >= touchpadThreshold) { if (Math.abs(scrollAccumulator) >= touchpadThreshold) {
let currentIndex = -1; let currentIndex = -1;
for (let i = 0; i < windows.length; i++) { for (let i = 0; i < windows.length; i++) {
@@ -157,11 +157,11 @@ Rectangle {
if (nextWindow) { if (nextWindow) {
nextWindow.activate(); nextWindow.activate();
} }
scrollAccumulator = 0; scrollAccumulator = 0;
} }
} }
wheel.accepted = true; wheel.accepted = true;
} }
} }
@@ -640,51 +640,51 @@ Rectangle {
sourceComponent: DankTooltip {} sourceComponent: DankTooltip {}
} }
Loader { Loader {
id: windowContextMenuLoader id: windowContextMenuLoader
active: false active: false
sourceComponent: PanelWindow { sourceComponent: PanelWindow {
id: contextMenuWindow id: contextMenuWindow
property var currentWindow: null property var currentWindow: null
property bool isVisible: false property bool isVisible: false
property point anchorPos: Qt.point(0, 0) property point anchorPos: Qt.point(0, 0)
function showAt(x, y) { function showAt(x, y) {
screen = root.parentScreen; screen = root.parentScreen;
anchorPos = Qt.point(x, y); anchorPos = Qt.point(x, y);
isVisible = true; isVisible = true;
visible = true; visible = true;
} }
function close() { function close() {
isVisible = false; isVisible = false;
visible = false; visible = false;
windowContextMenuLoader.active = false; windowContextMenuLoader.active = false;
} }
implicitWidth: 100 implicitWidth: 100
implicitHeight: 40 implicitHeight: 40
visible: false visible: false
color: "transparent" color: "transparent"
WlrLayershell.layer: WlrLayershell.Overlay WlrLayershell.layer: WlrLayershell.Overlay
WlrLayershell.exclusiveZone: -1 WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
anchors { anchors {
top: true top: true
left: true left: true
right: true right: true
bottom: true bottom: true
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: contextMenuWindow.close(); onClicked: contextMenuWindow.close();
} }
Rectangle { Rectangle {
x: { x: {
const left = 10; const left = 10;
@@ -699,13 +699,13 @@ Rectangle {
radius: Theme.cornerRadius radius: Theme.cornerRadius
border.width: 1 border.width: 1
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
radius: parent.radius radius: parent.radius
color: closeMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" color: closeMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent"
} }
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
text: I18n.tr("Close") text: I18n.tr("Close")
@@ -713,7 +713,7 @@ Rectangle {
color: Theme.surfaceText color: Theme.surfaceText
font.weight: Font.Normal font.weight: Font.Normal
} }
MouseArea { MouseArea {
id: closeMouseArea id: closeMouseArea
anchors.fill: parent anchors.fill: parent

View File

@@ -290,7 +290,7 @@ Rectangle {
nextWindow.activate(); nextWindow.activate();
} }
} }
} else { } else {
scrollAccumulator += deltaY scrollAccumulator += deltaY
@@ -331,7 +331,7 @@ Rectangle {
nextWindow.activate(); nextWindow.activate();
} }
} }
scrollAccumulator = 0 scrollAccumulator = 0
} }
} }

View File

@@ -134,11 +134,11 @@ DankPopout {
{ icon: "dashboard", text: I18n.tr("Overview") }, { icon: "dashboard", text: I18n.tr("Overview") },
{ icon: "music_note", text: I18n.tr("Media") } { icon: "music_note", text: I18n.tr("Media") }
] ]
if (SettingsData.weatherEnabled) { if (SettingsData.weatherEnabled) {
tabs.push({ icon: "wb_sunny", text: I18n.tr("Weather") }) tabs.push({ icon: "wb_sunny", text: I18n.tr("Weather") })
} }
tabs.push({ icon: "settings", text: I18n.tr("Settings"), isAction: true }) tabs.push({ icon: "settings", text: I18n.tr("Settings"), isAction: true })
return tabs return tabs
} }

View File

@@ -128,9 +128,9 @@ Item {
function getAudioDeviceIcon(device) { function getAudioDeviceIcon(device) {
if (!device || !device.name) return "speaker" if (!device || !device.name) return "speaker"
const name = device.name.toLowerCase() const name = device.name.toLowerCase()
if (name.includes("bluez") || name.includes("bluetooth")) if (name.includes("bluez") || name.includes("bluetooth"))
return "headset" return "headset"
if (name.includes("hdmi")) if (name.includes("hdmi"))
@@ -139,10 +139,10 @@ Item {
return "headset" return "headset"
if (name.includes("analog") || name.includes("built-in")) if (name.includes("analog") || name.includes("built-in"))
return "speaker" return "speaker"
return "speaker" return "speaker"
} }
function getVolumeIcon(sink) { function getVolumeIcon(sink) {
if (!sink || !sink.audio) return "volume_off" if (!sink || !sink.audio) return "volume_off"
@@ -262,8 +262,8 @@ Item {
maybeFinishSwitch() maybeFinishSwitch()
} }
} }
property bool isSeeking: false property bool isSeeking: false
@@ -325,7 +325,7 @@ Item {
return mouse.x < item.x || mouse.x > item.x + item.width || return mouse.x < item.x || mouse.x > item.x + item.width ||
mouse.y < item.y || mouse.y > item.y + item.height mouse.y < item.y || mouse.y > item.y + item.height
} }
if (playerSelectorButton.playersExpanded && clickOutside(playerSelectorDropdown)) { if (playerSelectorButton.playersExpanded && clickOutside(playerSelectorDropdown)) {
playerSelectorButton.playersExpanded = false playerSelectorButton.playersExpanded = false
} }
@@ -400,11 +400,11 @@ Item {
easing.bezierCurve: Anims.standard easing.bezierCurve: Anims.standard
} }
} }
Column { Column {
anchors.fill: parent anchors.fill: parent
anchors.margins: Theme.spacingM anchors.margins: Theme.spacingM
StyledText { StyledText {
text: I18n.tr("Audio Output Devices (") + audioDevicesDropdown.availableDevices.length + ")" text: I18n.tr("Audio Output Devices (") + audioDevicesDropdown.availableDevices.length + ")"
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
@@ -414,49 +414,49 @@ Item {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
bottomPadding: Theme.spacingM bottomPadding: Theme.spacingM
} }
DankFlickable { DankFlickable {
width: parent.width width: parent.width
height: parent.height - 40 height: parent.height - 40
contentHeight: deviceColumn.height contentHeight: deviceColumn.height
clip: true clip: true
Column { Column {
id: deviceColumn id: deviceColumn
width: parent.width width: parent.width
spacing: Theme.spacingS spacing: Theme.spacingS
Repeater { Repeater {
model: audioDevicesDropdown.availableDevices model: audioDevicesDropdown.availableDevices
delegate: Rectangle { delegate: Rectangle {
required property var modelData required property var modelData
required property int index required property int index
width: parent.width width: parent.width
height: 48 height: 48
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: deviceMouseAreaLeft.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.surfaceContainerHigh color: deviceMouseAreaLeft.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.surfaceContainerHigh
border.color: modelData === AudioService.sink ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) border.color: modelData === AudioService.sink ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: modelData === AudioService.sink ? 2 : 1 border.width: modelData === AudioService.sink ? 2 : 1
Row { Row {
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: Theme.spacingM anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingM spacing: Theme.spacingM
width: parent.width - Theme.spacingM * 2 width: parent.width - Theme.spacingM * 2
DankIcon { DankIcon {
name: getAudioDeviceIcon(modelData) name: getAudioDeviceIcon(modelData)
size: 20 size: 20
color: modelData === AudioService.sink ? Theme.primary : Theme.surfaceText color: modelData === AudioService.sink ? Theme.primary : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Column { Column {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: parent.width - 20 - Theme.spacingM * 2 width: parent.width - 20 - Theme.spacingM * 2
StyledText { StyledText {
text: AudioService.displayName(modelData) text: AudioService.displayName(modelData)
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
@@ -466,7 +466,7 @@ Item {
width: parent.width width: parent.width
wrapMode: Text.NoWrap wrapMode: Text.NoWrap
} }
StyledText { StyledText {
text: modelData === AudioService.sink ? "Active" : "Available" text: modelData === AudioService.sink ? "Active" : "Available"
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
@@ -477,7 +477,7 @@ Item {
} }
} }
} }
MouseArea { MouseArea {
id: deviceMouseAreaLeft id: deviceMouseAreaLeft
anchors.fill: parent anchors.fill: parent
@@ -490,7 +490,7 @@ Item {
audioDevicesButton.devicesExpanded = false audioDevicesButton.devicesExpanded = false
} }
} }
Behavior on border.color { ColorAnimation { duration: Anims.durShort } } Behavior on border.color { ColorAnimation { duration: Anims.durShort } }
} }
} }
@@ -793,7 +793,7 @@ Item {
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText color: Theme.surfaceVariantText
} }
StyledText { StyledText {
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -812,7 +812,7 @@ Item {
Item { Item {
width: parent.width width: parent.width
height: 50 height: 50
Row { Row {
anchors.centerIn: parent anchors.centerIn: parent
spacing: Theme.spacingM spacing: Theme.spacingM

View File

@@ -92,12 +92,12 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
anchors.margins: Theme.spacingM anchors.margins: Theme.spacingM
spacing: Theme.spacingS spacing: Theme.spacingS
Item { Item {
width: parent.width width: parent.width
height: 40 height: 40
visible: showEventDetails visible: showEventDetails
Rectangle { Rectangle {
width: 32 width: 32
height: 32 height: 32
@@ -122,7 +122,7 @@ Rectangle {
onClicked: root.showEventDetails = false onClicked: root.showEventDetails = false
} }
} }
StyledText { StyledText {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@@ -149,7 +149,7 @@ Rectangle {
width: parent.width width: parent.width
height: 28 height: 28
visible: !showEventDetails visible: !showEventDetails
Rectangle { Rectangle {
width: 28 width: 28
height: 28 height: 28
@@ -215,7 +215,7 @@ Rectangle {
} }
} }
} }
Row { Row {
width: parent.width width: parent.width
height: 18 height: 18
@@ -248,14 +248,14 @@ Rectangle {
} }
} }
} }
Grid { Grid {
id: calendarGrid id: calendarGrid
visible: !showEventDetails visible: !showEventDetails
property date displayDate: systemClock.date property date displayDate: systemClock.date
property date selectedDate: systemClock.date property date selectedDate: systemClock.date
readonly property date firstDay: { readonly property date firstDay: {
const firstOfMonth = new Date(displayDate.getFullYear(), displayDate.getMonth(), 1) const firstOfMonth = new Date(displayDate.getFullYear(), displayDate.getMonth(), 1)
return startOfWeek(firstOfMonth) return startOfWeek(firstOfMonth)
@@ -341,7 +341,7 @@ Rectangle {
visible: showEventDetails visible: showEventDetails
clip: true clip: true
spacing: Theme.spacingXS spacing: Theme.spacingXS
delegate: Rectangle { delegate: Rectangle {
width: parent ? parent.width : 0 width: parent ? parent.width : 0
height: eventContent.implicitHeight + Theme.spacingS height: eventContent.implicitHeight + Theme.spacingS
@@ -377,7 +377,7 @@ Rectangle {
Column { Column {
id: eventContent id: eventContent
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -419,7 +419,7 @@ Rectangle {
MouseArea { MouseArea {
id: eventMouseArea id: eventMouseArea
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: modelData.url ? Qt.PointingHandCursor : Qt.ArrowCursor cursorShape: modelData.url ? Qt.PointingHandCursor : Qt.ArrowCursor

View File

@@ -4,9 +4,9 @@ import qs.Common
Rectangle { Rectangle {
id: card id: card
property int pad: Theme.spacingM property int pad: Theme.spacingM
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh color: Theme.surfaceContainerHigh
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)

View File

@@ -35,7 +35,7 @@ Card {
width: 28 width: 28
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
} }
StyledText { StyledText {
text: { text: {
if (SettingsData.use24HourClock) { if (SettingsData.use24HourClock) {
@@ -53,7 +53,7 @@ Card {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
} }
} }
Row { Row {
spacing: 0 spacing: 0
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
@@ -66,7 +66,7 @@ Card {
width: 28 width: 28
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
} }
StyledText { StyledText {
text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(1) text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(1)
font.pixelSize: 48 font.pixelSize: 48
@@ -102,7 +102,7 @@ Card {
} }
} }
StyledText { StyledText {
text: systemClock?.date?.toLocaleDateString(Qt.locale(), "MMM dd") text: systemClock?.date?.toLocaleDateString(Qt.locale(), "MMM dd")
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall

View File

@@ -92,7 +92,7 @@ Card {
} }
// Just using truncated is always true initially idk // Just using truncated is always true initially idk
property bool shouldUseShort: longTextWidth > availableWidth property bool shouldUseShort: longTextWidth > availableWidth
text: shouldUseShort ? UserInfoService.shortUptime : UserInfoService.uptime || "up 1h 23m" text: shouldUseShort ? UserInfoService.shortUptime : UserInfoService.uptime || "up 1h 23m"
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7) color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)

View File

@@ -47,18 +47,18 @@ Card {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingL spacing: Theme.spacingL
visible: WeatherService.weather.available && WeatherService.weather.temp !== 0 visible: WeatherService.weather.available && WeatherService.weather.temp !== 0
DankIcon { DankIcon {
name: WeatherService.getWeatherIcon(WeatherService.weather.wCode) name: WeatherService.getWeatherIcon(WeatherService.weather.wCode)
size: 48 size: 48
color: Theme.primary color: Theme.primary
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Column { Column {
spacing: Theme.spacingXS spacing: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
StyledText { StyledText {
text: { text: {
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp; const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
@@ -71,7 +71,7 @@ Card {
color: Theme.surfaceText color: Theme.surfaceText
font.weight: Font.Light font.weight: Font.Light
} }
StyledText { StyledText {
text: WeatherService.getWeatherCondition(WeatherService.weather.wCode) text: WeatherService.getWeatherCondition(WeatherService.weather.wCode)
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall

View File

@@ -132,7 +132,7 @@ Item {
anchors.left: tempText.right anchors.left: tempText.right
anchors.leftMargin: Theme.spacingXS anchors.leftMargin: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
@@ -540,7 +540,7 @@ Item {
width: (parent.width - Theme.spacingXS * 6) / 7 width: (parent.width - Theme.spacingXS * 6) / 7
height: parent.height height: parent.height
radius: Theme.cornerRadius radius: Theme.cornerRadius
property var dayDate: { property var dayDate: {
const date = new Date() const date = new Date()
date.setDate(date.getDate() + index) date.setDate(date.getDate() + index)

View File

@@ -75,14 +75,14 @@ Column {
property string lastTextForLineModel: "" property string lastTextForLineModel: ""
property var lineModel: [] property var lineModel: []
function updateLineModel() { function updateLineModel() {
if (!SettingsData.notepadShowLineNumbers) { if (!SettingsData.notepadShowLineNumbers) {
lineModel = [] lineModel = []
lastTextForLineModel = "" lastTextForLineModel = ""
return return
} }
if (textArea.text !== lastTextForLineModel || lineModel.length === 0) { if (textArea.text !== lastTextForLineModel || lineModel.length === 0) {
lastTextForLineModel = textArea.text lastTextForLineModel = textArea.text
lineModel = textArea.text.split('\n') lineModel = textArea.text.split('\n')
@@ -129,10 +129,10 @@ Column {
function highlightCurrentMatch() { function highlightCurrentMatch() {
if (currentMatchIndex >= 0 && currentMatchIndex < searchMatches.length) { if (currentMatchIndex >= 0 && currentMatchIndex < searchMatches.length) {
const match = searchMatches[currentMatchIndex] const match = searchMatches[currentMatchIndex]
textArea.cursorPosition = match.start textArea.cursorPosition = match.start
textArea.moveCursorSelection(match.end, TextEdit.SelectCharacters) textArea.moveCursorSelection(match.end, TextEdit.SelectCharacters)
const flickable = textArea.parent const flickable = textArea.parent
if (flickable && flickable.contentY !== undefined) { if (flickable && flickable.contentY !== undefined) {
const lineHeight = textArea.font.pixelSize * 1.5 const lineHeight = textArea.font.pixelSize * 1.5
@@ -219,11 +219,11 @@ Column {
verticalAlignment: TextInput.AlignVCenter verticalAlignment: TextInput.AlignVCenter
selectByMouse: true selectByMouse: true
clip: true clip: true
Component.onCompleted: { Component.onCompleted: {
text = root.searchQuery text = root.searchQuery
} }
Connections { Connections {
target: root target: root
function onSearchQueryChanged() { function onSearchQueryChanged() {
@@ -232,7 +232,7 @@ Column {
} }
} }
} }
onTextChanged: { onTextChanged: {
if (root.searchQuery !== text) { if (root.searchQuery !== text) {
root.searchQuery = text root.searchQuery = text
@@ -260,7 +260,7 @@ Column {
event.accepted = true event.accepted = true
} }
} }
// Placeholder text // Placeholder text
StyledText { StyledText {
Layout.fillWidth: true Layout.fillWidth: true

View File

@@ -366,7 +366,7 @@ Item {
Row { Row {
spacing: 4 spacing: 4
StyledText { StyledText {
text: `<a href="https://github.com/YaLTeR/niri" style="text-decoration:none; color:${Theme.primary};">niri</a>` text: `<a href="https://github.com/YaLTeR/niri" style="text-decoration:none; color:${Theme.primary};">niri</a>`
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
@@ -383,14 +383,14 @@ Item {
propagateComposedEvents: true propagateComposedEvents: true
} }
} }
StyledText { StyledText {
text: "&" text: "&"
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText color: Theme.surfaceVariantText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
StyledText { StyledText {
text: `<a href="https://github.com/hyprwm/Hyprland" style="text-decoration:none; color:${Theme.primary};">hyprland</a>` text: `<a href="https://github.com/hyprwm/Hyprland" style="text-decoration:none; color:${Theme.primary};">hyprland</a>`
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
@@ -418,7 +418,7 @@ Item {
Row { Row {
spacing: 4 spacing: 4
StyledText { StyledText {
text: `<a href="https://github.com/AvengeMedia/DankMaterialShell" style="text-decoration:none; color:${Theme.primary};">DankMaterialShell</a>` text: `<a href="https://github.com/AvengeMedia/DankMaterialShell" style="text-decoration:none; color:${Theme.primary};">DankMaterialShell</a>`
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
@@ -435,7 +435,7 @@ Item {
propagateComposedEvents: true propagateComposedEvents: true
} }
} }
StyledText { StyledText {
text: I18n.tr("- Support Us With a Star ⭐") text: I18n.tr("- Support Us With a Star ⭐")
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
@@ -453,7 +453,7 @@ Item {
Row { Row {
spacing: 4 spacing: 4
StyledText { StyledText {
text: `<a href="https://github.com/AvengeMedia/dgop" style="text-decoration:none; color:${Theme.primary};">dgop</a>` text: `<a href="https://github.com/AvengeMedia/dgop" style="text-decoration:none; color:${Theme.primary};">dgop</a>`
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
@@ -470,7 +470,7 @@ Item {
propagateComposedEvents: true propagateComposedEvents: true
} }
} }
StyledText { StyledText {
text: I18n.tr("- Stateless System Monitoring") text: I18n.tr("- Stateless System Monitoring")
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
@@ -488,7 +488,7 @@ Item {
Row { Row {
spacing: 4 spacing: 4
StyledText { StyledText {
text: `<a href="https://danklinux.com" style="text-decoration:none; color:${Theme.primary};">danklinux.com</a>` text: `<a href="https://danklinux.com" style="text-decoration:none; color:${Theme.primary};">danklinux.com</a>`
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium

View File

@@ -371,7 +371,7 @@ Item {
widgets = SettingsData.dankBarCenterWidgets.slice() widgets = SettingsData.dankBarCenterWidgets.slice()
else if (sectionId === "right") else if (sectionId === "right")
widgets = SettingsData.dankBarRightWidgets.slice() widgets = SettingsData.dankBarRightWidgets.slice()
if (widgetIndex >= 0 && widgetIndex < widgets.length) { if (widgetIndex >= 0 && widgetIndex < widgets.length) {
var widget = widgets[widgetIndex] var widget = widgets[widgetIndex]
var widgetId = typeof widget === "string" ? widget : widget.id var widgetId = typeof widget === "string" ? widget : widget.id
@@ -401,7 +401,7 @@ Item {
} }
} }
} }
if (sectionId === "left") if (sectionId === "left")
SettingsData.setDankBarLeftWidgets(widgets) SettingsData.setDankBarLeftWidgets(widgets)
else if (sectionId === "center") else if (sectionId === "center")

View File

@@ -734,11 +734,11 @@ Column {
modal: true modal: true
focus: true focus: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
onOpened: { onOpened: {
console.log("Control Center context menu opened") console.log("Control Center context menu opened")
} }
onClosed: { onClosed: {
console.log("Control Center context menu closed") console.log("Control Center context menu closed")
} }

View File

@@ -14,7 +14,7 @@ Item {
Component.onCompleted: { Component.onCompleted: {
console.log("LauncherExample: Plugin loaded") console.log("LauncherExample: Plugin loaded")
// Load custom trigger from settings // Load custom trigger from settings
if (pluginService) { if (pluginService) {
trigger = pluginService.loadPluginData("launcherExample", "trigger", "#") trigger = pluginService.loadPluginData("launcherExample", "trigger", "#")
@@ -119,7 +119,7 @@ Item {
function runScript(command) { function runScript(command) {
console.log("LauncherExample: Would run script:", command) console.log("LauncherExample: Would run script:", command)
showToast("Script executed: " + command) showToast("Script executed: " + command)
// In a real plugin, you might create a Process component here // In a real plugin, you might create a Process component here
// For demo purposes, we just show what would happen // For demo purposes, we just show what would happen
} }

View File

@@ -11,7 +11,7 @@ Singleton {
id: root id: root
property var applications: DesktopEntries.applications.values.filter(app => !app.noDisplay && !app.runInTerminal) property var applications: DesktopEntries.applications.values.filter(app => !app.noDisplay && !app.runInTerminal)
function searchApplications(query) { function searchApplications(query) {
@@ -266,7 +266,7 @@ Singleton {
function getPluginCategoryIcon(category) { function getPluginCategoryIcon(category) {
if (typeof PluginService === "undefined") return null if (typeof PluginService === "undefined") return null
const launchers = PluginService.getLauncherPlugins() const launchers = PluginService.getLauncherPlugins()
for (const pluginId in launchers) { for (const pluginId in launchers) {
const plugin = launchers[pluginId] const plugin = launchers[pluginId]
@@ -296,7 +296,7 @@ Singleton {
function getPluginItems(category, query) { function getPluginItems(category, query) {
if (typeof PluginService === "undefined") return [] if (typeof PluginService === "undefined") return []
const launchers = PluginService.getLauncherPlugins() const launchers = PluginService.getLauncherPlugins()
for (const pluginId in launchers) { for (const pluginId in launchers) {
const plugin = launchers[pluginId] const plugin = launchers[pluginId]
@@ -338,42 +338,42 @@ Singleton {
function executePluginItem(item, pluginId) { function executePluginItem(item, pluginId) {
if (typeof PluginService === "undefined") return false if (typeof PluginService === "undefined") return false
const component = PluginService.pluginLauncherComponents[pluginId] const component = PluginService.pluginLauncherComponents[pluginId]
if (!component) return false if (!component) return false
try { try {
const instance = component.createObject(root, { const instance = component.createObject(root, {
"pluginService": PluginService "pluginService": PluginService
}) })
if (instance && typeof instance.executeItem === "function") { if (instance && typeof instance.executeItem === "function") {
instance.executeItem(item) instance.executeItem(item)
instance.destroy() instance.destroy()
return true return true
} }
if (instance) { if (instance) {
instance.destroy() instance.destroy()
} }
} catch (e) { } catch (e) {
console.warn("AppSearchService: Error executing item from plugin", pluginId, ":", e) console.warn("AppSearchService: Error executing item from plugin", pluginId, ":", e)
} }
return false return false
} }
function searchPluginItems(query) { function searchPluginItems(query) {
if (typeof PluginService === "undefined") return [] if (typeof PluginService === "undefined") return []
let allItems = [] let allItems = []
const launchers = PluginService.getLauncherPlugins() const launchers = PluginService.getLauncherPlugins()
for (const pluginId in launchers) { for (const pluginId in launchers) {
const items = getPluginItemsForPlugin(pluginId, query) const items = getPluginItemsForPlugin(pluginId, query)
allItems = allItems.concat(items) allItems = allItems.concat(items)
} }
return allItems return allItems
} }
} }

View File

@@ -21,7 +21,7 @@ Singleton {
property string ethernetConnectionUuid: "" property string ethernetConnectionUuid: ""
property var wiredConnections: [] property var wiredConnections: []
property string wifiIP: "" property string wifiIP: ""
property string wifiInterface: "" property string wifiInterface: ""
property bool wifiConnected: false property bool wifiConnected: false
@@ -75,7 +75,7 @@ Singleton {
property string networkInfoSSID: "" property string networkInfoSSID: ""
property string networkInfoDetails: "" property string networkInfoDetails: ""
property bool networkInfoLoading: false property bool networkInfoLoading: false
property string networkWiredInfoUUID: "" property string networkWiredInfoUUID: ""
property string networkWiredInfoDetails: "" property string networkWiredInfoDetails: ""
property bool networkWiredInfoLoading: false property bool networkWiredInfoLoading: false
@@ -158,12 +158,12 @@ Singleton {
} }
return return
} }
if (line.includes("StateChanged") || if (line.includes("StateChanged") ||
line.includes("PrimaryConnectionChanged") || line.includes("PrimaryConnectionChanged") ||
line.includes("WirelessEnabled") || line.includes("WirelessEnabled") ||
(line.includes("ActiveConnection") && line.includes("State"))) { (line.includes("ActiveConnection") && line.includes("State"))) {
if (now - nmStateMonitor.lastRefreshTime > nmStateMonitor.minRefreshInterval) { if (now - nmStateMonitor.lastRefreshTime > nmStateMonitor.minRefreshInterval) {
nmStateMonitor.lastRefreshTime = now nmStateMonitor.lastRefreshTime = now
refreshNetworkState() refreshNetworkState()

View File

@@ -71,7 +71,7 @@ Singleton {
property string networkInfoSSID: "" property string networkInfoSSID: ""
property string networkInfoDetails: "" property string networkInfoDetails: ""
property bool networkInfoLoading: false property bool networkInfoLoading: false
property string networkWiredInfoUUID: "" property string networkWiredInfoUUID: ""
property string networkWiredInfoDetails: "" property string networkWiredInfoDetails: ""
property bool networkWiredInfoLoading: false property bool networkWiredInfoLoading: false
@@ -227,7 +227,7 @@ Singleton {
connectionChanged() connectionChanged()
} }
function connectToSpecificWiredConfig(uuid) { function connectToSpecificWiredConfig(uuid) {
if (!networkAvailable || isConnecting) return if (!networkAvailable || isConnecting) return
@@ -446,7 +446,7 @@ Singleton {
autoScan = false autoScan = false
autoRefreshEnabled = false autoRefreshEnabled = false
} }
function fetchWiredNetworkInfo(uuid) { function fetchWiredNetworkInfo(uuid) {
if (!networkAvailable) return if (!networkAvailable) return
@@ -475,18 +475,18 @@ Singleton {
details += "Driver: " + info.driver + "\\n" details += "Driver: " + info.driver + "\\n"
details += "MAC Addr: " + info.hwAddr + "\\n" details += "MAC Addr: " + info.hwAddr + "\\n"
details += "Speed: " + info.speed + " Mb/s\\n\\n" details += "Speed: " + info.speed + " Mb/s\\n\\n"
details += "IPv4 informations:\\n" details += "IPv4 informations:\\n"
for (const ip4 of info.IPv4s.ips) { for (const ip4 of info.IPv4s.ips) {
details += " IPv4 address: " + ip4 + "\\n" details += " IPv4 address: " + ip4 + "\\n"
} }
details += " Gateway: " + info.IPv4s.gateway + "\\n" details += " Gateway: " + info.IPv4s.gateway + "\\n"
details += " DNS: " + info.IPv4s.dns + "\\n" details += " DNS: " + info.IPv4s.dns + "\\n"
if (info.IPv6s.ips) { if (info.IPv6s.ips) {
details += "\\nIPv6 informations:\\n" details += "\\nIPv6 informations:\\n"
for (const ip6 of info.IPv6s.ips) { for (const ip6 of info.IPv6s.ips) {
details += " IPv6 address: " + ip6 + "\\n" details += " IPv6 address: " + ip6 + "\\n"
} }

View File

@@ -59,7 +59,7 @@ Singleton {
property string networkInfoSSID: activeService?.networkInfoSSID ?? "" property string networkInfoSSID: activeService?.networkInfoSSID ?? ""
property string networkInfoDetails: activeService?.networkInfoDetails ?? "" property string networkInfoDetails: activeService?.networkInfoDetails ?? ""
property bool networkInfoLoading: activeService?.networkInfoLoading ?? false property bool networkInfoLoading: activeService?.networkInfoLoading ?? false
property string networkWiredInfoUUID: activeService?.networkWiredInfoUUID ?? "" property string networkWiredInfoUUID: activeService?.networkWiredInfoUUID ?? ""
property string networkWiredInfoDetails: activeService?.networkWiredInfoDetails ?? "" property string networkWiredInfoDetails: activeService?.networkWiredInfoDetails ?? ""
property bool networkWiredInfoLoading: activeService?.networkWiredInfoLoading ?? false property bool networkWiredInfoLoading: activeService?.networkWiredInfoLoading ?? false
@@ -252,7 +252,7 @@ Singleton {
activeService.refreshNetworkState() activeService.refreshNetworkState()
} }
} }
function connectToSpecificWiredConfig(uuid) { function connectToSpecificWiredConfig(uuid) {
if (activeService && activeService.connectToSpecificWiredConfig) { if (activeService && activeService.connectToSpecificWiredConfig) {
activeService.connectToSpecificWiredConfig(uuid) activeService.connectToSpecificWiredConfig(uuid)

View File

@@ -538,7 +538,7 @@ Singleton {
// Launcher plugin helper functions // Launcher plugin helper functions
function getLauncherPlugins() { function getLauncherPlugins() {
const launchers = {} const launchers = {}
// Check plugins that have launcher components // Check plugins that have launcher components
for (const pluginId in pluginLauncherComponents) { for (const pluginId in pluginLauncherComponents) {
const plugin = availablePlugins[pluginId] const plugin = availablePlugins[pluginId]

View File

@@ -302,7 +302,7 @@ Singleton {
function cyclePrevForMonitor(screenName) { function cyclePrevForMonitor(screenName) {
if (!screenName) return if (!screenName) return
var currentWallpaper = SessionData.getMonitorWallpaper(screenName) var currentWallpaper = SessionData.getMonitorWallpaper(screenName)
if (currentWallpaper) { if (currentWallpaper) {
cycleToPrevWallpaper(screenName, currentWallpaper) cycleToPrevWallpaper(screenName, currentWallpaper)
@@ -370,10 +370,10 @@ Singleton {
Process { Process {
id: cyclingProcess id: cyclingProcess
property string targetScreenName: "" property string targetScreenName: ""
property string currentWallpaper: "" property string currentWallpaper: ""
running: false running: false
stdout: StdioCollector { stdout: StdioCollector {
@@ -404,10 +404,10 @@ Singleton {
Process { Process {
id: prevCyclingProcess id: prevCyclingProcess
property string targetScreenName: "" property string targetScreenName: ""
property string currentWallpaper: "" property string currentWallpaper: ""
running: false running: false
stdout: StdioCollector { stdout: StdioCollector {

View File

@@ -75,7 +75,7 @@ Singleton {
"96": "thunderstorm", "96": "thunderstorm",
"99": "thunderstorm" "99": "thunderstorm"
}) })
property var nightWeatherIcons: ({ property var nightWeatherIcons: ({
"0": "clear_night", "0": "clear_night",
"1": "clear_night", "1": "clear_night",
@@ -114,7 +114,7 @@ Singleton {
const iconMap = isDay ? weatherIcons : nightWeatherIcons const iconMap = isDay ? weatherIcons : nightWeatherIcons
return iconMap[String(code)] || "cloud" return iconMap[String(code)] || "cloud"
} }
function getWeatherCondition(code) { function getWeatherCondition(code) {
const conditions = { const conditions = {
"0": "Clear", "0": "Clear",
@@ -148,10 +148,10 @@ Singleton {
} }
return conditions[String(code)] || "Unknown" return conditions[String(code)] || "Unknown"
} }
function formatTime(isoString) { function formatTime(isoString) {
if (!isoString) return "--" if (!isoString) return "--"
try { try {
const date = new Date(isoString) const date = new Date(isoString)
const format = SettingsData.use24HourClock ? "HH:mm" : "h:mm AP" const format = SettingsData.use24HourClock ? "HH:mm" : "h:mm AP"
@@ -160,15 +160,15 @@ Singleton {
return "--" return "--"
} }
} }
function formatForecastDay(isoString, index) { function formatForecastDay(isoString, index) {
if (!isoString) return "--" if (!isoString) return "--"
try { try {
const date = new Date(isoString) const date = new Date(isoString)
if (index === 0) return I18n.tr("Today") if (index === 0) return I18n.tr("Today")
if (index === 1) return I18n.tr("Tomorrow") if (index === 1) return I18n.tr("Tomorrow")
const locale = Qt.locale() const locale = Qt.locale()
return locale.dayName(date.getDay(), Locale.ShortFormat) return locale.dayName(date.getDay(), Locale.ShortFormat)
} catch (e) { } catch (e) {
@@ -180,7 +180,7 @@ Singleton {
if (!location) { if (!location) {
return null return null
} }
const params = [ const params = [
"latitude=" + location.latitude, "latitude=" + location.latitude,
"longitude=" + location.longitude, "longitude=" + location.longitude,
@@ -189,14 +189,14 @@ Singleton {
"timezone=auto", "timezone=auto",
"forecast_days=7" "forecast_days=7"
] ]
if (SettingsData.useFahrenheit) { if (SettingsData.useFahrenheit) {
params.push("temperature_unit=fahrenheit") params.push("temperature_unit=fahrenheit")
} }
return "https://api.open-meteo.com/v1/forecast?" + params.join('&') return "https://api.open-meteo.com/v1/forecast?" + params.join('&')
} }
function getGeocodingUrl(query) { function getGeocodingUrl(query) {
return "https://geocoding-api.open-meteo.com/v1/search?name=" + encodeURIComponent(query) + "&count=1&language=en&format=json" return "https://geocoding-api.open-meteo.com/v1/search?name=" + encodeURIComponent(query) + "&count=1&language=en&format=json"
} }
@@ -229,25 +229,25 @@ Singleton {
} }
} }
} }
const cityName = SettingsData.weatherLocation const cityName = SettingsData.weatherLocation
if (cityName) { if (cityName) {
getLocationFromCity(cityName) getLocationFromCity(cityName)
} }
} }
} }
function getLocationFromCoords(lat, lon) { function getLocationFromCoords(lat, lon) {
const url = "https://nominatim.openstreetmap.org/reverse?lat=" + lat + "&lon=" + lon + "&format=json&addressdetails=1&accept-language=en" const url = "https://nominatim.openstreetmap.org/reverse?lat=" + lat + "&lon=" + lon + "&format=json&addressdetails=1&accept-language=en"
reverseGeocodeFetcher.command = lowPriorityCmd.concat(curlBaseCmd).concat(["-H", "User-Agent: DankMaterialShell Weather Widget", url]) reverseGeocodeFetcher.command = lowPriorityCmd.concat(curlBaseCmd).concat(["-H", "User-Agent: DankMaterialShell Weather Widget", url])
reverseGeocodeFetcher.running = true reverseGeocodeFetcher.running = true
} }
function getLocationFromCity(city) { function getLocationFromCity(city) {
cityGeocodeFetcher.command = lowPriorityCmd.concat(curlBaseCmd).concat([getGeocodingUrl(city)]) cityGeocodeFetcher.command = lowPriorityCmd.concat(curlBaseCmd).concat([getGeocodingUrl(city)])
cityGeocodeFetcher.running = true cityGeocodeFetcher.running = true
} }
function getLocationFromIP() { function getLocationFromIP() {
ipLocationFetcher.running = true ipLocationFetcher.running = true
} }
@@ -287,7 +287,7 @@ Singleton {
root.lastFetchTime = 0 // Reset throttle root.lastFetchTime = 0 // Reset throttle
fetchWeather() fetchWeather()
} }
function nextInterval() { function nextInterval() {
const jitter = Math.floor(Math.random() * 15000) - 7500 const jitter = Math.floor(Math.random() * 15000) - 7500
return Math.max(60000, root.updateInterval + jitter) return Math.max(60000, root.updateInterval + jitter)
@@ -324,7 +324,7 @@ Singleton {
id: ipLocationFetcher id: ipLocationFetcher
command: lowPriorityCmd.concat(curlBaseCmd).concat(["http://ipinfo.io/json"]) command: lowPriorityCmd.concat(curlBaseCmd).concat(["http://ipinfo.io/json"])
running: false running: false
stdout: StdioCollector { stdout: StdioCollector {
onStreamFinished: { onStreamFinished: {
const raw = text.trim() const raw = text.trim()
@@ -337,23 +337,23 @@ Singleton {
const data = JSON.parse(raw) const data = JSON.parse(raw)
const coords = data.loc const coords = data.loc
const city = data.city const city = data.city
if (!coords || !city) { if (!coords || !city) {
throw new Error("Missing location data") throw new Error("Missing location data")
} }
const coordsParts = coords.split(",") const coordsParts = coords.split(",")
if (coordsParts.length !== 2) { if (coordsParts.length !== 2) {
throw new Error("Invalid coordinates format") throw new Error("Invalid coordinates format")
} }
const lat = parseFloat(coordsParts[0]) const lat = parseFloat(coordsParts[0])
const lon = parseFloat(coordsParts[1]) const lon = parseFloat(coordsParts[1])
if (isNaN(lat) || isNaN(lon)) { if (isNaN(lat) || isNaN(lon)) {
throw new Error("Invalid coordinate values") throw new Error("Invalid coordinate values")
} }
root.location = { root.location = {
city: city, city: city,
latitude: lat, latitude: lat,
@@ -365,18 +365,18 @@ Singleton {
} }
} }
} }
onExited: exitCode => { onExited: exitCode => {
if (exitCode !== 0) { if (exitCode !== 0) {
root.handleWeatherFailure() root.handleWeatherFailure()
} }
} }
} }
Process { Process {
id: reverseGeocodeFetcher id: reverseGeocodeFetcher
running: false running: false
stdout: StdioCollector { stdout: StdioCollector {
onStreamFinished: { onStreamFinished: {
const raw = text.trim() const raw = text.trim()
@@ -388,32 +388,32 @@ Singleton {
try { try {
const data = JSON.parse(raw) const data = JSON.parse(raw)
const address = data.address || {} const address = data.address || {}
root.location = { root.location = {
city: address.hamlet || address.city || address.town || address.village || "Unknown", city: address.hamlet || address.city || address.town || address.village || "Unknown",
country: address.country || "Unknown", country: address.country || "Unknown",
latitude: parseFloat(data.lat), latitude: parseFloat(data.lat),
longitude: parseFloat(data.lon) longitude: parseFloat(data.lon)
} }
fetchWeather() fetchWeather()
} catch (e) { } catch (e) {
root.handleWeatherFailure() root.handleWeatherFailure()
} }
} }
} }
onExited: exitCode => { onExited: exitCode => {
if (exitCode !== 0) { if (exitCode !== 0) {
root.handleWeatherFailure() root.handleWeatherFailure()
} }
} }
} }
Process { Process {
id: cityGeocodeFetcher id: cityGeocodeFetcher
running: false running: false
stdout: StdioCollector { stdout: StdioCollector {
onStreamFinished: { onStreamFinished: {
const raw = text.trim() const raw = text.trim()
@@ -425,27 +425,27 @@ Singleton {
try { try {
const data = JSON.parse(raw) const data = JSON.parse(raw)
const results = data.results const results = data.results
if (!results || results.length === 0) { if (!results || results.length === 0) {
throw new Error("No results found") throw new Error("No results found")
} }
const result = results[0] const result = results[0]
root.location = { root.location = {
city: result.name, city: result.name,
country: result.country, country: result.country,
latitude: result.latitude, latitude: result.latitude,
longitude: result.longitude longitude: result.longitude
} }
fetchWeather() fetchWeather()
} catch (e) { } catch (e) {
root.handleWeatherFailure() root.handleWeatherFailure()
} }
} }
} }
onExited: exitCode => { onExited: exitCode => {
if (exitCode !== 0) { if (exitCode !== 0) {
root.handleWeatherFailure() root.handleWeatherFailure()
@@ -467,7 +467,7 @@ Singleton {
try { try {
const data = JSON.parse(raw) const data = JSON.parse(raw)
if (!data.current || !data.daily) { if (!data.current || !data.daily) {
throw new Error("Required weather data fields missing") throw new Error("Required weather data fields missing")
} }
@@ -475,12 +475,12 @@ Singleton {
const current = data.current const current = data.current
const daily = data.daily const daily = data.daily
const currentUnits = data.current_units || {} const currentUnits = data.current_units || {}
const tempC = current.temperature_2m || 0 const tempC = current.temperature_2m || 0
const tempF = SettingsData.useFahrenheit ? tempC : (tempC * 9/5 + 32) const tempF = SettingsData.useFahrenheit ? tempC : (tempC * 9/5 + 32)
const feelsLikeC = current.apparent_temperature || tempC const feelsLikeC = current.apparent_temperature || tempC
const feelsLikeF = SettingsData.useFahrenheit ? feelsLikeC : (feelsLikeC * 9/5 + 32) const feelsLikeF = SettingsData.useFahrenheit ? feelsLikeC : (feelsLikeC * 9/5 + 32)
const forecast = [] const forecast = []
if (daily.time && daily.time.length > 0) { if (daily.time && daily.time.length > 0) {
for (let i = 0; i < Math.min(daily.time.length, 7); i++) { for (let i = 0; i < Math.min(daily.time.length, 7); i++) {
@@ -488,7 +488,7 @@ Singleton {
const tempMaxC = daily.temperature_2m_max?.[i] || 0 const tempMaxC = daily.temperature_2m_max?.[i] || 0
const tempMinF = SettingsData.useFahrenheit ? tempMinC : (tempMinC * 9/5 + 32) const tempMinF = SettingsData.useFahrenheit ? tempMinC : (tempMinC * 9/5 + 32)
const tempMaxF = SettingsData.useFahrenheit ? tempMaxC : (tempMaxC * 9/5 + 32) const tempMaxF = SettingsData.useFahrenheit ? tempMaxC : (tempMaxC * 9/5 + 32)
forecast.push({ forecast.push({
"day": formatForecastDay(daily.time[i], i), "day": formatForecastDay(daily.time[i], i),
"wCode": daily.weather_code?.[i] || 0, "wCode": daily.weather_code?.[i] || 0,
@@ -502,7 +502,7 @@ Singleton {
}) })
} }
} }
root.weather = { root.weather = {
"available": true, "available": true,
"loading": false, "loading": false,
@@ -577,7 +577,7 @@ Singleton {
} }
Component.onCompleted: { Component.onCompleted: {
SettingsData.weatherCoordinatesChanged.connect(() => { SettingsData.weatherCoordinatesChanged.connect(() => {
root.location = null root.location = null
root.weather = { root.weather = {
@@ -635,7 +635,7 @@ Singleton {
root.lastFetchTime = 0 root.lastFetchTime = 0
root.forceRefresh() root.forceRefresh()
}) })
SettingsData.useFahrenheitChanged.connect(() => { SettingsData.useFahrenheitChanged.connect(() => {
root.lastFetchTime = 0 root.lastFetchTime = 0
root.forceRefresh() root.forceRefresh()

View File

@@ -42,91 +42,91 @@ Item {
preferredRendererType: Shape.CurveRenderer preferredRendererType: Shape.CurveRenderer
z: 0 z: 0
layer.enabled: false layer.enabled: false
readonly property real centerX: width / 2 readonly property real centerX: width / 2
readonly property real centerY: height / 2 readonly property real centerY: height / 2
readonly property real baseRadius: Math.min(width, height) * 0.41 * root.animationScale readonly property real baseRadius: Math.min(width, height) * 0.41 * root.animationScale
readonly property int segments: 28 readonly property int segments: 28
property var audioLevels: { property var audioLevels: {
if (!CavaService.cavaAvailable || CavaService.values.length === 0) { if (!CavaService.cavaAvailable || CavaService.values.length === 0) {
return [0.5, 0.3, 0.7, 0.4, 0.6, 0.5, 0.8, 0.2, 0.9, 0.6] return [0.5, 0.3, 0.7, 0.4, 0.6, 0.5, 0.8, 0.2, 0.9, 0.6]
} }
return CavaService.values return CavaService.values
} }
property var smoothedLevels: [0.5, 0.3, 0.7, 0.4, 0.6, 0.5, 0.8, 0.2, 0.9, 0.6] property var smoothedLevels: [0.5, 0.3, 0.7, 0.4, 0.6, 0.5, 0.8, 0.2, 0.9, 0.6]
property var cubics: [] property var cubics: []
onAudioLevelsChanged: updatePath() onAudioLevelsChanged: updatePath()
FrameAnimation { FrameAnimation {
running: morphingBlob.visible running: morphingBlob.visible
onTriggered: morphingBlob.updatePath() onTriggered: morphingBlob.updatePath()
} }
Component { Component {
id: cubicSegment id: cubicSegment
PathCubic {} PathCubic {}
} }
Component.onCompleted: { Component.onCompleted: {
shapePath.pathElements.push(Qt.createQmlObject( shapePath.pathElements.push(Qt.createQmlObject(
'import QtQuick; import QtQuick.Shapes; PathMove {}', shapePath 'import QtQuick; import QtQuick.Shapes; PathMove {}', shapePath
)) ))
for (let i = 0; i < segments; i++) { for (let i = 0; i < segments; i++) {
const seg = cubicSegment.createObject(shapePath) const seg = cubicSegment.createObject(shapePath)
shapePath.pathElements.push(seg) shapePath.pathElements.push(seg)
cubics.push(seg) cubics.push(seg)
} }
updatePath() updatePath()
} }
function expSmooth(prev, next, alpha) { function expSmooth(prev, next, alpha) {
return prev + alpha * (next - prev) return prev + alpha * (next - prev)
} }
function updatePath() { function updatePath() {
if (cubics.length === 0) return if (cubics.length === 0) return
for (let i = 0; i < Math.min(smoothedLevels.length, audioLevels.length); i++) { for (let i = 0; i < Math.min(smoothedLevels.length, audioLevels.length); i++) {
smoothedLevels[i] = expSmooth(smoothedLevels[i], audioLevels[i], 0.35) smoothedLevels[i] = expSmooth(smoothedLevels[i], audioLevels[i], 0.35)
} }
const points = [] const points = []
for (let i = 0; i < segments; i++) { for (let i = 0; i < segments; i++) {
const angle = (i / segments) * 2 * Math.PI const angle = (i / segments) * 2 * Math.PI
const audioIndex = i % Math.min(smoothedLevels.length, 10) const audioIndex = i % Math.min(smoothedLevels.length, 10)
const rawLevel = smoothedLevels[audioIndex] || 0 const rawLevel = smoothedLevels[audioIndex] || 0
const scaledLevel = Math.sqrt(Math.min(Math.max(rawLevel, 0), 100) / 100) * 100 const scaledLevel = Math.sqrt(Math.min(Math.max(rawLevel, 0), 100) / 100) * 100
const normalizedLevel = scaledLevel / 100 const normalizedLevel = scaledLevel / 100
const audioLevel = Math.max(0.15, normalizedLevel) * 0.5 const audioLevel = Math.max(0.15, normalizedLevel) * 0.5
const radius = baseRadius * (1.0 + audioLevel) const radius = baseRadius * (1.0 + audioLevel)
const x = centerX + Math.cos(angle) * radius const x = centerX + Math.cos(angle) * radius
const y = centerY + Math.sin(angle) * radius const y = centerY + Math.sin(angle) * radius
points.push({x: x, y: y}) points.push({x: x, y: y})
} }
const startMove = shapePath.pathElements[0] const startMove = shapePath.pathElements[0]
startMove.x = points[0].x startMove.x = points[0].x
startMove.y = points[0].y startMove.y = points[0].y
const tension = 0.5 const tension = 0.5
for (let i = 0; i < segments; i++) { for (let i = 0; i < segments; i++) {
const p0 = points[(i - 1 + segments) % segments] const p0 = points[(i - 1 + segments) % segments]
const p1 = points[i] const p1 = points[i]
const p2 = points[(i + 1) % segments] const p2 = points[(i + 1) % segments]
const p3 = points[(i + 2) % segments] const p3 = points[(i + 2) % segments]
const c1x = p1.x + (p2.x - p0.x) * tension / 3 const c1x = p1.x + (p2.x - p0.x) * tension / 3
const c1y = p1.y + (p2.y - p0.y) * tension / 3 const c1y = p1.y + (p2.y - p0.y) * tension / 3
const c2x = p2.x - (p3.x - p1.x) * tension / 3 const c2x = p2.x - (p3.x - p1.x) * tension / 3
const c2y = p2.y - (p3.y - p1.y) * tension / 3 const c2y = p2.y - (p3.y - p1.y) * tension / 3
const seg = cubics[i] const seg = cubics[i]
seg.control1X = c1x seg.control1X = c1x
seg.control1Y = c1y seg.control1Y = c1y
@@ -136,7 +136,7 @@ Item {
seg.y = p2.y seg.y = p2.y
} }
} }
ShapePath { ShapePath {
id: shapePath id: shapePath
fillColor: Theme.primary fillColor: Theme.primary

View File

@@ -98,10 +98,10 @@ Item {
bottomRightRadius: 0 bottomRightRadius: 0
color: Theme.primary color: Theme.primary
visible: false visible: false
property bool animationEnabled: false property bool animationEnabled: false
property bool initialSetupComplete: false property bool initialSetupComplete: false
Behavior on x { Behavior on x {
enabled: indicator.animationEnabled enabled: indicator.animationEnabled
NumberAnimation { NumberAnimation {
@@ -109,7 +109,7 @@ Item {
easing.type: Theme.standardEasing easing.type: Theme.standardEasing
} }
} }
Behavior on width { Behavior on width {
enabled: indicator.animationEnabled enabled: indicator.animationEnabled
NumberAnimation { NumberAnimation {
@@ -130,21 +130,21 @@ Item {
if (tabRepeater.count === 0 || currentIndex < 0 || currentIndex >= tabRepeater.count) { if (tabRepeater.count === 0 || currentIndex < 0 || currentIndex >= tabRepeater.count) {
return return
} }
const item = tabRepeater.itemAt(currentIndex) const item = tabRepeater.itemAt(currentIndex)
if (!item || item.isAction) { if (!item || item.isAction) {
return return
} }
const tabPos = item.mapToItem(tabBar, 0, 0) const tabPos = item.mapToItem(tabBar, 0, 0)
const tabCenterX = tabPos.x + item.width / 2 const tabCenterX = tabPos.x + item.width / 2
const indicatorWidth = 60 const indicatorWidth = 60
if (tabPos.x < 10 && currentIndex > 0) { if (tabPos.x < 10 && currentIndex > 0) {
Qt.callLater(() => updateIndicator(enableAnimation)) Qt.callLater(() => updateIndicator(enableAnimation))
return return
} }
indicator.animationEnabled = enableAnimation indicator.animationEnabled = enableAnimation
indicator.width = indicatorWidth indicator.width = indicatorWidth
indicator.x = tabCenterX - indicatorWidth / 2 indicator.x = tabCenterX - indicatorWidth / 2