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:
22
CLAUDE.md
22
CLAUDE.md
@@ -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) {
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -1180,7 +1180,7 @@ Singleton {
|
|||||||
showWorkspaceIndex = enabled
|
showWorkspaceIndex = enabled
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setWorkspaceScrolling(enabled) {
|
function setWorkspaceScrolling(enabled) {
|
||||||
workspaceScrolling = enabled
|
workspaceScrolling = enabled
|
||||||
saveSettings()
|
saveSettings()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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: "" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user