mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-25 05:52:50 -05:00
feat: Allow more pinned services in Control Center/Settings
This commit is contained in:
@@ -122,6 +122,21 @@ Rectangle {
|
||||
contentHeight: audioColumn.height
|
||||
clip: true
|
||||
|
||||
property int maxPinnedInputs: 3
|
||||
|
||||
function normalizePinList(value) {
|
||||
if (Array.isArray(value))
|
||||
return value.filter(v => v)
|
||||
if (typeof value === "string" && value.length > 0)
|
||||
return [value]
|
||||
return []
|
||||
}
|
||||
|
||||
function getPinnedInputs() {
|
||||
const pins = SettingsData.audioInputDevicePins || {}
|
||||
return normalizePinList(pins["preferredInput"])
|
||||
}
|
||||
|
||||
Column {
|
||||
id: audioColumn
|
||||
width: parent.width
|
||||
@@ -133,16 +148,20 @@ Rectangle {
|
||||
const nodes = Pipewire.nodes.values.filter(node => {
|
||||
return node.audio && !node.isSink && !node.isStream;
|
||||
});
|
||||
const pins = SettingsData.audioInputDevicePins || {};
|
||||
const pinnedName = pins["preferredInput"];
|
||||
const pinnedList = audioContent.getPinnedInputs();
|
||||
|
||||
let sorted = [...nodes];
|
||||
sorted.sort((a, b) => {
|
||||
// Pinned device first
|
||||
if (a.name === pinnedName && b.name !== pinnedName)
|
||||
return -1;
|
||||
if (b.name === pinnedName && a.name !== pinnedName)
|
||||
return 1;
|
||||
const aPinnedIndex = pinnedList.indexOf(a.name)
|
||||
const bPinnedIndex = pinnedList.indexOf(b.name)
|
||||
if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
|
||||
if (aPinnedIndex === -1)
|
||||
return 1
|
||||
if (bPinnedIndex === -1)
|
||||
return -1
|
||||
return aPinnedIndex - bPinnedIndex
|
||||
}
|
||||
// Then active device
|
||||
if (a === AudioService.source && b !== AudioService.source)
|
||||
return -1;
|
||||
@@ -224,7 +243,7 @@ Rectangle {
|
||||
height: 28
|
||||
radius: height / 2
|
||||
color: {
|
||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name;
|
||||
const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name);
|
||||
return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05);
|
||||
}
|
||||
|
||||
@@ -237,7 +256,7 @@ Rectangle {
|
||||
name: "push_pin"
|
||||
size: 16
|
||||
color: {
|
||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name;
|
||||
const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name);
|
||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@@ -245,12 +264,12 @@ Rectangle {
|
||||
|
||||
StyledText {
|
||||
text: {
|
||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name;
|
||||
const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name);
|
||||
return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin");
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: {
|
||||
const isThisDevicePinned = (SettingsData.audioInputDevicePins || {})["preferredInput"] === modelData.name;
|
||||
const isThisDevicePinned = audioContent.getPinnedInputs().includes(modelData.name);
|
||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@@ -261,16 +280,24 @@ Rectangle {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
const pins = JSON.parse(JSON.stringify(SettingsData.audioInputDevicePins || {}));
|
||||
const isCurrentlyPinned = pins["preferredInput"] === modelData.name;
|
||||
const pins = JSON.parse(JSON.stringify(SettingsData.audioInputDevicePins || {}))
|
||||
let pinnedList = audioContent.normalizePinList(pins["preferredInput"])
|
||||
const pinIndex = pinnedList.indexOf(modelData.name)
|
||||
|
||||
if (isCurrentlyPinned) {
|
||||
delete pins["preferredInput"];
|
||||
if (pinIndex !== -1) {
|
||||
pinnedList.splice(pinIndex, 1)
|
||||
} else {
|
||||
pins["preferredInput"] = modelData.name;
|
||||
pinnedList.unshift(modelData.name)
|
||||
if (pinnedList.length > audioContent.maxPinnedInputs)
|
||||
pinnedList = pinnedList.slice(0, audioContent.maxPinnedInputs)
|
||||
}
|
||||
|
||||
SettingsData.set("audioInputDevicePins", pins);
|
||||
if (pinnedList.length > 0)
|
||||
pins["preferredInput"] = pinnedList
|
||||
else
|
||||
delete pins["preferredInput"]
|
||||
|
||||
SettingsData.set("audioInputDevicePins", pins)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +132,21 @@ Rectangle {
|
||||
contentHeight: audioColumn.height
|
||||
clip: true
|
||||
|
||||
property int maxPinnedOutputs: 3
|
||||
|
||||
function normalizePinList(value) {
|
||||
if (Array.isArray(value))
|
||||
return value.filter(v => v)
|
||||
if (typeof value === "string" && value.length > 0)
|
||||
return [value]
|
||||
return []
|
||||
}
|
||||
|
||||
function getPinnedOutputs() {
|
||||
const pins = SettingsData.audioOutputDevicePins || {}
|
||||
return normalizePinList(pins["preferredOutput"])
|
||||
}
|
||||
|
||||
Column {
|
||||
id: audioColumn
|
||||
width: parent.width
|
||||
@@ -143,16 +158,20 @@ Rectangle {
|
||||
const nodes = Pipewire.nodes.values.filter(node => {
|
||||
return node.audio && node.isSink && !node.isStream;
|
||||
});
|
||||
const pins = SettingsData.audioOutputDevicePins || {};
|
||||
const pinnedName = pins["preferredOutput"];
|
||||
const pinnedList = audioContent.getPinnedOutputs();
|
||||
|
||||
let sorted = [...nodes];
|
||||
sorted.sort((a, b) => {
|
||||
// Pinned device first
|
||||
if (a.name === pinnedName && b.name !== pinnedName)
|
||||
return -1;
|
||||
if (b.name === pinnedName && a.name !== pinnedName)
|
||||
return 1;
|
||||
const aPinnedIndex = pinnedList.indexOf(a.name)
|
||||
const bPinnedIndex = pinnedList.indexOf(b.name)
|
||||
if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
|
||||
if (aPinnedIndex === -1)
|
||||
return 1
|
||||
if (bPinnedIndex === -1)
|
||||
return -1
|
||||
return aPinnedIndex - bPinnedIndex
|
||||
}
|
||||
// Then active device
|
||||
if (a === AudioService.sink && b !== AudioService.sink)
|
||||
return -1;
|
||||
@@ -236,7 +255,7 @@ Rectangle {
|
||||
height: 28
|
||||
radius: height / 2
|
||||
color: {
|
||||
const isThisDevicePinned = (SettingsData.audioOutputDevicePins || {})["preferredOutput"] === modelData.name;
|
||||
const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
|
||||
return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05);
|
||||
}
|
||||
|
||||
@@ -249,7 +268,7 @@ Rectangle {
|
||||
name: "push_pin"
|
||||
size: 16
|
||||
color: {
|
||||
const isThisDevicePinned = (SettingsData.audioOutputDevicePins || {})["preferredOutput"] === modelData.name;
|
||||
const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
|
||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@@ -257,12 +276,12 @@ Rectangle {
|
||||
|
||||
StyledText {
|
||||
text: {
|
||||
const isThisDevicePinned = (SettingsData.audioOutputDevicePins || {})["preferredOutput"] === modelData.name;
|
||||
const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
|
||||
return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin");
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: {
|
||||
const isThisDevicePinned = (SettingsData.audioOutputDevicePins || {})["preferredOutput"] === modelData.name;
|
||||
const isThisDevicePinned = audioContent.getPinnedOutputs().includes(modelData.name);
|
||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText;
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@@ -273,16 +292,24 @@ Rectangle {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
const pins = JSON.parse(JSON.stringify(SettingsData.audioOutputDevicePins || {}));
|
||||
const isCurrentlyPinned = pins["preferredOutput"] === modelData.name;
|
||||
const pins = JSON.parse(JSON.stringify(SettingsData.audioOutputDevicePins || {}))
|
||||
let pinnedList = audioContent.normalizePinList(pins["preferredOutput"])
|
||||
const pinIndex = pinnedList.indexOf(modelData.name)
|
||||
|
||||
if (isCurrentlyPinned) {
|
||||
delete pins["preferredOutput"];
|
||||
if (pinIndex !== -1) {
|
||||
pinnedList.splice(pinIndex, 1)
|
||||
} else {
|
||||
pins["preferredOutput"] = modelData.name;
|
||||
pinnedList.unshift(modelData.name)
|
||||
if (pinnedList.length > audioContent.maxPinnedOutputs)
|
||||
pinnedList = pinnedList.slice(0, audioContent.maxPinnedOutputs)
|
||||
}
|
||||
|
||||
SettingsData.set("audioOutputDevicePins", pins);
|
||||
if (pinnedList.length > 0)
|
||||
pins["preferredOutput"] = pinnedList
|
||||
else
|
||||
delete pins["preferredOutput"]
|
||||
|
||||
SettingsData.set("audioOutputDevicePins", pins)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +150,21 @@ Rectangle {
|
||||
contentHeight: bluetoothColumn.height
|
||||
clip: true
|
||||
|
||||
property int maxPinnedDevices: 3
|
||||
|
||||
function normalizePinList(value) {
|
||||
if (Array.isArray(value))
|
||||
return value.filter(v => v)
|
||||
if (typeof value === "string" && value.length > 0)
|
||||
return [value]
|
||||
return []
|
||||
}
|
||||
|
||||
function getPinnedDevices() {
|
||||
const pins = SettingsData.bluetoothDevicePins || {}
|
||||
return normalizePinList(pins["preferredDevice"])
|
||||
}
|
||||
|
||||
Column {
|
||||
id: bluetoothColumn
|
||||
width: parent.width
|
||||
@@ -162,14 +177,18 @@ Rectangle {
|
||||
if (!BluetoothService.adapter || !BluetoothService.adapter.devices)
|
||||
return []
|
||||
|
||||
const pins = SettingsData.bluetoothDevicePins || {}
|
||||
const pinnedAddr = pins["preferredDevice"]
|
||||
const pinnedList = bluetoothContent.getPinnedDevices()
|
||||
|
||||
let devices = [...BluetoothService.adapter.devices.values.filter(dev => dev && (dev.paired || dev.trusted))]
|
||||
devices.sort((a, b) => {
|
||||
// Pinned device first
|
||||
if (a.address === pinnedAddr && b.address !== pinnedAddr) return -1
|
||||
if (b.address === pinnedAddr && a.address !== pinnedAddr) return 1
|
||||
const aPinnedIndex = pinnedList.indexOf(a.address)
|
||||
const bPinnedIndex = pinnedList.indexOf(b.address)
|
||||
if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
|
||||
if (aPinnedIndex === -1) return 1
|
||||
if (bPinnedIndex === -1) return -1
|
||||
return aPinnedIndex - bPinnedIndex
|
||||
}
|
||||
// Then connected devices
|
||||
if (a.connected && !b.connected) return -1
|
||||
if (!a.connected && b.connected) return 1
|
||||
@@ -302,7 +321,7 @@ Rectangle {
|
||||
height: 28
|
||||
radius: height / 2
|
||||
color: {
|
||||
const isThisDevicePinned = (SettingsData.bluetoothDevicePins || {})["preferredDevice"] === modelData.address
|
||||
const isThisDevicePinned = bluetoothContent.getPinnedDevices().includes(modelData.address)
|
||||
return isThisDevicePinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05)
|
||||
}
|
||||
|
||||
@@ -315,7 +334,7 @@ Rectangle {
|
||||
name: "push_pin"
|
||||
size: 16
|
||||
color: {
|
||||
const isThisDevicePinned = (SettingsData.bluetoothDevicePins || {})["preferredDevice"] === modelData.address
|
||||
const isThisDevicePinned = bluetoothContent.getPinnedDevices().includes(modelData.address)
|
||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@@ -323,12 +342,12 @@ Rectangle {
|
||||
|
||||
StyledText {
|
||||
text: {
|
||||
const isThisDevicePinned = (SettingsData.bluetoothDevicePins || {})["preferredDevice"] === modelData.address
|
||||
const isThisDevicePinned = bluetoothContent.getPinnedDevices().includes(modelData.address)
|
||||
return isThisDevicePinned ? I18n.tr("Pinned") : I18n.tr("Pin")
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: {
|
||||
const isThisDevicePinned = (SettingsData.bluetoothDevicePins || {})["preferredDevice"] === modelData.address
|
||||
const isThisDevicePinned = bluetoothContent.getPinnedDevices().includes(modelData.address)
|
||||
return isThisDevicePinned ? Theme.primary : Theme.surfaceText
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@@ -340,14 +359,22 @@ Rectangle {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
const pins = JSON.parse(JSON.stringify(SettingsData.bluetoothDevicePins || {}))
|
||||
const isCurrentlyPinned = pins["preferredDevice"] === modelData.address
|
||||
let pinnedList = bluetoothContent.normalizePinList(pins["preferredDevice"])
|
||||
const pinIndex = pinnedList.indexOf(modelData.address)
|
||||
|
||||
if (isCurrentlyPinned) {
|
||||
delete pins["preferredDevice"]
|
||||
if (pinIndex !== -1) {
|
||||
pinnedList.splice(pinIndex, 1)
|
||||
} else {
|
||||
pins["preferredDevice"] = modelData.address
|
||||
pinnedList.unshift(modelData.address)
|
||||
if (pinnedList.length > bluetoothContent.maxPinnedDevices)
|
||||
pinnedList = pinnedList.slice(0, bluetoothContent.maxPinnedDevices)
|
||||
}
|
||||
|
||||
if (pinnedList.length > 0)
|
||||
pins["preferredDevice"] = pinnedList
|
||||
else
|
||||
delete pins["preferredDevice"]
|
||||
|
||||
SettingsData.set("bluetoothDevicePins", pins)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,20 +463,39 @@ Rectangle {
|
||||
contentHeight: wifiColumn.height
|
||||
clip: true
|
||||
|
||||
property int maxPinnedNetworks: 3
|
||||
|
||||
function normalizePinList(value) {
|
||||
if (Array.isArray(value))
|
||||
return value.filter(v => v)
|
||||
if (typeof value === "string" && value.length > 0)
|
||||
return [value]
|
||||
return []
|
||||
}
|
||||
|
||||
function getPinnedNetworks() {
|
||||
const pins = SettingsData.wifiNetworkPins || {}
|
||||
return normalizePinList(pins["preferredWifi"])
|
||||
}
|
||||
|
||||
property var frozenNetworks: []
|
||||
property bool menuOpen: false
|
||||
property var sortedNetworks: {
|
||||
const ssid = NetworkService.currentWifiSSID;
|
||||
const networks = NetworkService.wifiNetworks;
|
||||
const pins = SettingsData.wifiNetworkPins || {};
|
||||
const pinnedSSID = pins["preferredWifi"];
|
||||
const pinnedList = getPinnedNetworks()
|
||||
|
||||
let sorted = [...networks];
|
||||
sorted.sort((a, b) => {
|
||||
if (a.ssid === pinnedSSID && b.ssid !== pinnedSSID)
|
||||
return -1;
|
||||
if (b.ssid === pinnedSSID && a.ssid !== pinnedSSID)
|
||||
return 1;
|
||||
const aPinnedIndex = pinnedList.indexOf(a.ssid)
|
||||
const bPinnedIndex = pinnedList.indexOf(b.ssid)
|
||||
if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
|
||||
if (aPinnedIndex === -1)
|
||||
return 1
|
||||
if (bPinnedIndex === -1)
|
||||
return -1
|
||||
return aPinnedIndex - bPinnedIndex
|
||||
}
|
||||
if (a.ssid === ssid)
|
||||
return -1;
|
||||
if (b.ssid === ssid)
|
||||
@@ -625,7 +644,7 @@ Rectangle {
|
||||
height: 28
|
||||
radius: height / 2
|
||||
color: {
|
||||
const isThisNetworkPinned = (SettingsData.wifiNetworkPins || {})["preferredWifi"] === modelData.ssid;
|
||||
const isThisNetworkPinned = wifiContent.getPinnedNetworks().includes(modelData.ssid);
|
||||
return isThisNetworkPinned ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.surfaceText, 0.05);
|
||||
}
|
||||
|
||||
@@ -638,7 +657,7 @@ Rectangle {
|
||||
name: "push_pin"
|
||||
size: 16
|
||||
color: {
|
||||
const isThisNetworkPinned = (SettingsData.wifiNetworkPins || {})["preferredWifi"] === modelData.ssid;
|
||||
const isThisNetworkPinned = wifiContent.getPinnedNetworks().includes(modelData.ssid);
|
||||
return isThisNetworkPinned ? Theme.primary : Theme.surfaceText;
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@@ -646,12 +665,12 @@ Rectangle {
|
||||
|
||||
StyledText {
|
||||
text: {
|
||||
const isThisNetworkPinned = (SettingsData.wifiNetworkPins || {})["preferredWifi"] === modelData.ssid;
|
||||
const isThisNetworkPinned = wifiContent.getPinnedNetworks().includes(modelData.ssid);
|
||||
return isThisNetworkPinned ? I18n.tr("Pinned") : I18n.tr("Pin");
|
||||
}
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: {
|
||||
const isThisNetworkPinned = (SettingsData.wifiNetworkPins || {})["preferredWifi"] === modelData.ssid;
|
||||
const isThisNetworkPinned = wifiContent.getPinnedNetworks().includes(modelData.ssid);
|
||||
return isThisNetworkPinned ? Theme.primary : Theme.surfaceText;
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@@ -662,16 +681,24 @@ Rectangle {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {}));
|
||||
const isCurrentlyPinned = pins["preferredWifi"] === modelData.ssid;
|
||||
const pins = JSON.parse(JSON.stringify(SettingsData.wifiNetworkPins || {}))
|
||||
let pinnedList = wifiContent.normalizePinList(pins["preferredWifi"])
|
||||
const pinIndex = pinnedList.indexOf(modelData.ssid)
|
||||
|
||||
if (isCurrentlyPinned) {
|
||||
delete pins["preferredWifi"];
|
||||
if (pinIndex !== -1) {
|
||||
pinnedList.splice(pinIndex, 1)
|
||||
} else {
|
||||
pins["preferredWifi"] = modelData.ssid;
|
||||
pinnedList.unshift(modelData.ssid)
|
||||
if (pinnedList.length > wifiContent.maxPinnedNetworks)
|
||||
pinnedList = pinnedList.slice(0, wifiContent.maxPinnedNetworks)
|
||||
}
|
||||
|
||||
SettingsData.set("wifiNetworkPins", pins);
|
||||
if (pinnedList.length > 0)
|
||||
pins["preferredWifi"] = pinnedList
|
||||
else
|
||||
delete pins["preferredWifi"]
|
||||
|
||||
SettingsData.set("wifiNetworkPins", pins)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user