mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-06 05:25:41 -05:00
751 lines
32 KiB
QML
751 lines
32 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Effects
|
|
import QtQuick.Layouts
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import Quickshell.Wayland
|
|
import Quickshell.Widgets
|
|
import qs.Common
|
|
import qs.Modules.ControlCenter
|
|
import qs.Modules.ControlCenter.Widgets
|
|
import qs.Modules.ControlCenter.Details
|
|
import qs.Modules.ControlCenter.Details 1.0 as Details
|
|
import qs.Services
|
|
import qs.Widgets
|
|
|
|
DankPopout {
|
|
id: root
|
|
|
|
property string expandedSection: ""
|
|
property bool powerOptionsExpanded: false
|
|
property string triggerSection: "right"
|
|
property var triggerScreen: null
|
|
|
|
function setTriggerPosition(x, y, width, section, screen) {
|
|
triggerX = x
|
|
triggerY = y
|
|
triggerWidth = width
|
|
triggerSection = section
|
|
triggerScreen = screen
|
|
}
|
|
|
|
function openWithSection(section) {
|
|
if (shouldBeVisible) {
|
|
close()
|
|
} else {
|
|
expandedSection = section
|
|
open()
|
|
}
|
|
}
|
|
|
|
function toggleSection(section) {
|
|
if (expandedSection === section) {
|
|
expandedSection = ""
|
|
} else {
|
|
expandedSection = section
|
|
}
|
|
}
|
|
|
|
signal powerActionRequested(string action, string title, string message)
|
|
signal lockRequested
|
|
|
|
popupWidth: 550
|
|
popupHeight: Math.min((triggerScreen?.height ?? 1080) - 100, contentLoader.item && contentLoader.item.implicitHeight > 0 ? contentLoader.item.implicitHeight + 20 : 400)
|
|
triggerX: (triggerScreen?.width ?? 1920) - 600 - Theme.spacingL
|
|
triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingXS
|
|
triggerWidth: 80
|
|
positioning: "center"
|
|
screen: triggerScreen
|
|
shouldBeVisible: false
|
|
visible: shouldBeVisible
|
|
|
|
onShouldBeVisibleChanged: {
|
|
if (shouldBeVisible) {
|
|
Qt.callLater(() => {
|
|
NetworkService.autoRefreshEnabled = NetworkService.wifiEnabled
|
|
if (UserInfoService)
|
|
UserInfoService.getUptime()
|
|
})
|
|
} else {
|
|
Qt.callLater(() => {
|
|
NetworkService.autoRefreshEnabled = false
|
|
if (BluetoothService.adapter
|
|
&& BluetoothService.adapter.discovering)
|
|
BluetoothService.adapter.discovering = false
|
|
})
|
|
}
|
|
}
|
|
|
|
content: Component {
|
|
Rectangle {
|
|
id: controlContent
|
|
|
|
implicitHeight: mainColumn.implicitHeight + Theme.spacingM
|
|
property alias bluetoothCodecSelector: bluetoothCodecSelector
|
|
|
|
color: {
|
|
const transparency = Theme.popupTransparency || 0.92
|
|
const surface = Theme.surfaceContainer || Qt.rgba(0.1, 0.1, 0.1, 1)
|
|
return Qt.rgba(surface.r, surface.g, surface.b, transparency)
|
|
}
|
|
radius: Theme.cornerRadius
|
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
|
Theme.outline.b, 0.08)
|
|
border.width: 1
|
|
antialiasing: true
|
|
smooth: true
|
|
|
|
Column {
|
|
id: mainColumn
|
|
width: parent.width - Theme.spacingL * 2
|
|
x: Theme.spacingL
|
|
y: Theme.spacingL
|
|
spacing: Theme.spacingS
|
|
|
|
Rectangle {
|
|
width: parent.width
|
|
height: 90
|
|
radius: Theme.cornerRadius
|
|
color: Qt.rgba(Theme.surfaceVariant.r,
|
|
Theme.surfaceVariant.g,
|
|
Theme.surfaceVariant.b,
|
|
Theme.getContentBackgroundAlpha() * 0.4)
|
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
|
Theme.outline.b, 0.08)
|
|
border.width: 1
|
|
|
|
Row {
|
|
anchors.left: parent.left
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.leftMargin: Theme.spacingL
|
|
anchors.rightMargin: Theme.spacingL
|
|
spacing: Theme.spacingL
|
|
|
|
Item {
|
|
id: avatarContainer
|
|
|
|
property bool hasImage: profileImageLoader.status === Image.Ready
|
|
|
|
width: 64
|
|
height: 64
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
radius: width / 2
|
|
color: "transparent"
|
|
border.color: Theme.primary
|
|
border.width: 1
|
|
visible: parent.hasImage
|
|
}
|
|
|
|
Image {
|
|
id: profileImageLoader
|
|
|
|
source: {
|
|
if (PortalService.profileImage === "")
|
|
return ""
|
|
|
|
if (PortalService.profileImage.startsWith(
|
|
"/"))
|
|
return "file://" + PortalService.profileImage
|
|
|
|
return PortalService.profileImage
|
|
}
|
|
smooth: true
|
|
asynchronous: true
|
|
mipmap: true
|
|
cache: true
|
|
visible: false
|
|
}
|
|
|
|
MultiEffect {
|
|
anchors.fill: parent
|
|
anchors.margins: 5
|
|
source: profileImageLoader
|
|
maskEnabled: true
|
|
maskSource: circularMask
|
|
visible: avatarContainer.hasImage
|
|
maskThresholdMin: 0.5
|
|
maskSpreadAtMin: 1
|
|
}
|
|
|
|
Item {
|
|
id: circularMask
|
|
|
|
width: 64 - 10
|
|
height: 64 - 10
|
|
layer.enabled: true
|
|
layer.smooth: true
|
|
visible: false
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
radius: width / 2
|
|
color: "black"
|
|
antialiasing: true
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
radius: width / 2
|
|
color: Theme.primary
|
|
visible: !parent.hasImage
|
|
|
|
DankIcon {
|
|
anchors.centerIn: parent
|
|
name: "person"
|
|
size: Theme.iconSize + 8
|
|
color: Theme.primaryText
|
|
}
|
|
}
|
|
|
|
DankIcon {
|
|
anchors.centerIn: parent
|
|
name: "warning"
|
|
size: Theme.iconSize + 8
|
|
color: Theme.primaryText
|
|
visible: PortalService.profileImage !== ""
|
|
&& profileImageLoader.status === Image.Error
|
|
}
|
|
}
|
|
|
|
Column {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: Theme.spacingXS
|
|
|
|
StyledText {
|
|
text: UserInfoService.fullName
|
|
|| UserInfoService.username || "User"
|
|
font.pixelSize: Theme.fontSizeLarge
|
|
color: Theme.surfaceText
|
|
font.weight: Font.Medium
|
|
}
|
|
|
|
StyledText {
|
|
text: (UserInfoService.uptime
|
|
|| "Unknown")
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: Theme.surfaceVariantText
|
|
font.weight: Font.Normal
|
|
}
|
|
}
|
|
}
|
|
|
|
Row {
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.rightMargin: Theme.spacingL
|
|
spacing: Theme.spacingS
|
|
|
|
DankActionButton {
|
|
buttonSize: 40
|
|
iconName: "lock"
|
|
iconSize: Theme.iconSize - 2
|
|
iconColor: Theme.surfaceText
|
|
backgroundColor: Qt.rgba(
|
|
Theme.surfaceVariant.r,
|
|
Theme.surfaceVariant.g,
|
|
Theme.surfaceVariant.b,
|
|
0.5)
|
|
onClicked: {
|
|
root.close()
|
|
root.lockRequested()
|
|
}
|
|
}
|
|
|
|
DankActionButton {
|
|
buttonSize: 40
|
|
iconName: root.powerOptionsExpanded ? "expand_less" : "power_settings_new"
|
|
iconSize: Theme.iconSize - 2
|
|
iconColor: Theme.surfaceText
|
|
backgroundColor: Qt.rgba(
|
|
Theme.surfaceVariant.r,
|
|
Theme.surfaceVariant.g,
|
|
Theme.surfaceVariant.b,
|
|
0.5)
|
|
onClicked: {
|
|
root.powerOptionsExpanded = !root.powerOptionsExpanded
|
|
}
|
|
|
|
}
|
|
|
|
DankActionButton {
|
|
buttonSize: 40
|
|
iconName: "settings"
|
|
iconSize: Theme.iconSize - 2
|
|
iconColor: Theme.surfaceText
|
|
backgroundColor: Qt.rgba(
|
|
Theme.surfaceVariant.r,
|
|
Theme.surfaceVariant.g,
|
|
Theme.surfaceVariant.b,
|
|
0.5)
|
|
onClicked: {
|
|
root.close()
|
|
settingsModal.show()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
width: parent.width
|
|
implicitHeight: root.powerOptionsExpanded ? 60 : 0
|
|
height: implicitHeight
|
|
clip: true
|
|
|
|
Rectangle {
|
|
width: parent.width
|
|
height: 60
|
|
radius: Theme.cornerRadius
|
|
color: Qt.rgba(Theme.surfaceVariant.r,
|
|
Theme.surfaceVariant.g,
|
|
Theme.surfaceVariant.b,
|
|
Theme.getContentBackgroundAlpha() * 0.4)
|
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
|
Theme.outline.b, 0.08)
|
|
border.width: root.powerOptionsExpanded ? 1 : 0
|
|
opacity: root.powerOptionsExpanded ? 1 : 0
|
|
clip: true
|
|
|
|
Row {
|
|
anchors.centerIn: parent
|
|
spacing: Theme.spacingL
|
|
visible: root.powerOptionsExpanded
|
|
|
|
Rectangle {
|
|
width: 100
|
|
height: 34
|
|
radius: Theme.cornerRadius
|
|
color: logoutButton.containsMouse ? Qt.rgba(
|
|
Theme.primary.r,
|
|
Theme.primary.g,
|
|
Theme.primary.b,
|
|
0.12) : Qt.rgba(
|
|
Theme.surfaceVariant.r,
|
|
Theme.surfaceVariant.g,
|
|
Theme.surfaceVariant.b,
|
|
0.5)
|
|
|
|
Row {
|
|
anchors.centerIn: parent
|
|
spacing: Theme.spacingXS
|
|
|
|
DankIcon {
|
|
name: "logout"
|
|
size: Theme.fontSizeSmall
|
|
color: logoutButton.containsMouse ? Theme.primary : Theme.surfaceText
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: "Logout"
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: logoutButton.containsMouse ? Theme.primary : Theme.surfaceText
|
|
font.weight: Font.Medium
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
}
|
|
|
|
MouseArea {
|
|
id: logoutButton
|
|
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: Qt.PointingHandCursor
|
|
onPressed: {
|
|
root.powerOptionsExpanded = false
|
|
root.close()
|
|
root.powerActionRequested(
|
|
"logout", "Logout",
|
|
"Are you sure you want to logout?")
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: 100
|
|
height: 34
|
|
radius: Theme.cornerRadius
|
|
color: rebootButton.containsMouse ? Qt.rgba(
|
|
Theme.primary.r,
|
|
Theme.primary.g,
|
|
Theme.primary.b,
|
|
0.12) : Qt.rgba(
|
|
Theme.surfaceVariant.r,
|
|
Theme.surfaceVariant.g,
|
|
Theme.surfaceVariant.b,
|
|
0.5)
|
|
|
|
Row {
|
|
anchors.centerIn: parent
|
|
spacing: Theme.spacingXS
|
|
|
|
DankIcon {
|
|
name: "restart_alt"
|
|
size: Theme.fontSizeSmall
|
|
color: rebootButton.containsMouse ? Theme.primary : Theme.surfaceText
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: "Restart"
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: rebootButton.containsMouse ? Theme.primary : Theme.surfaceText
|
|
font.weight: Font.Medium
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
}
|
|
|
|
MouseArea {
|
|
id: rebootButton
|
|
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: Qt.PointingHandCursor
|
|
onPressed: {
|
|
root.powerOptionsExpanded = false
|
|
root.close()
|
|
root.powerActionRequested(
|
|
"reboot", "Restart",
|
|
"Are you sure you want to restart?")
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: 100
|
|
height: 34
|
|
radius: Theme.cornerRadius
|
|
color: suspendButton.containsMouse ? Qt.rgba(
|
|
Theme.primary.r,
|
|
Theme.primary.g,
|
|
Theme.primary.b,
|
|
0.12) : Qt.rgba(
|
|
Theme.surfaceVariant.r,
|
|
Theme.surfaceVariant.g,
|
|
Theme.surfaceVariant.b,
|
|
0.5)
|
|
|
|
Row {
|
|
anchors.centerIn: parent
|
|
spacing: Theme.spacingXS
|
|
|
|
DankIcon {
|
|
name: "bedtime"
|
|
size: Theme.fontSizeSmall
|
|
color: suspendButton.containsMouse ? Theme.primary : Theme.surfaceText
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: "Suspend"
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: suspendButton.containsMouse ? Theme.primary : Theme.surfaceText
|
|
font.weight: Font.Medium
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
}
|
|
|
|
MouseArea {
|
|
id: suspendButton
|
|
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: Qt.PointingHandCursor
|
|
onPressed: {
|
|
root.powerOptionsExpanded = false
|
|
root.close()
|
|
root.powerActionRequested(
|
|
"suspend", "Suspend",
|
|
"Are you sure you want to suspend?")
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: 100
|
|
height: 34
|
|
radius: Theme.cornerRadius
|
|
color: shutdownButton.containsMouse ? Qt.rgba(
|
|
Theme.primary.r,
|
|
Theme.primary.g,
|
|
Theme.primary.b,
|
|
0.12) : Qt.rgba(
|
|
Theme.surfaceVariant.r,
|
|
Theme.surfaceVariant.g,
|
|
Theme.surfaceVariant.b,
|
|
0.5)
|
|
|
|
Row {
|
|
anchors.centerIn: parent
|
|
spacing: Theme.spacingXS
|
|
|
|
DankIcon {
|
|
name: "power_settings_new"
|
|
size: Theme.fontSizeSmall
|
|
color: shutdownButton.containsMouse ? Theme.primary : Theme.surfaceText
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
StyledText {
|
|
text: "Shutdown"
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
color: shutdownButton.containsMouse ? Theme.primary : Theme.surfaceText
|
|
font.weight: Font.Medium
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
}
|
|
|
|
MouseArea {
|
|
id: shutdownButton
|
|
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
cursorShape: Qt.PointingHandCursor
|
|
onPressed: {
|
|
root.powerOptionsExpanded = false
|
|
root.close()
|
|
root.powerActionRequested(
|
|
"poweroff", "Shutdown",
|
|
"Are you sure you want to shutdown?")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
Item {
|
|
width: parent.width
|
|
height: audioSliderRow.implicitHeight
|
|
|
|
Row {
|
|
id: audioSliderRow
|
|
x: -Theme.spacingS
|
|
width: parent.width + Theme.spacingS * 2
|
|
spacing: Theme.spacingM
|
|
|
|
AudioSliderRow {
|
|
width: SettingsData.hideBrightnessSlider ? parent.width - Theme.spacingM : (parent.width - Theme.spacingM) / 2
|
|
}
|
|
|
|
Item {
|
|
width: (parent.width - Theme.spacingM) / 2
|
|
height: parent.height
|
|
visible: !SettingsData.hideBrightnessSlider
|
|
|
|
BrightnessSliderRow {
|
|
width: parent.width
|
|
height: parent.height
|
|
x: -Theme.spacingS
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Row {
|
|
width: parent.width
|
|
spacing: Theme.spacingM
|
|
|
|
NetworkPill {
|
|
width: (parent.width - Theme.spacingM) / 2
|
|
expanded: root.expandedSection === "network"
|
|
onClicked: {
|
|
if (NetworkService.wifiToggling) {
|
|
return
|
|
}
|
|
if (NetworkService.networkStatus === "ethernet") {
|
|
if (NetworkService.ethernetConnected && !NetworkService.wifiEnabled) {
|
|
NetworkService.toggleWifiRadio()
|
|
return
|
|
}
|
|
root.toggleSection("network")
|
|
return
|
|
}
|
|
if (NetworkService.networkStatus === "wifi") {
|
|
if (NetworkService.ethernetConnected) {
|
|
NetworkService.toggleWifiRadio()
|
|
return
|
|
}
|
|
NetworkService.disconnectWifi()
|
|
return
|
|
}
|
|
if (!NetworkService.wifiEnabled) {
|
|
NetworkService.toggleWifiRadio()
|
|
return
|
|
}
|
|
if (NetworkService.wifiEnabled && NetworkService.networkStatus === "disconnected") {
|
|
root.toggleSection("network")
|
|
}
|
|
}
|
|
onExpandClicked: root.toggleSection("network")
|
|
}
|
|
|
|
BluetoothPill {
|
|
width: (parent.width - Theme.spacingM) / 2
|
|
expanded: root.expandedSection === "bluetooth"
|
|
onClicked: {
|
|
if (BluetoothService.adapter)
|
|
BluetoothService.adapter.enabled = !BluetoothService.adapter.enabled
|
|
}
|
|
onExpandClicked: root.toggleSection("bluetooth")
|
|
visible: BluetoothService.available
|
|
}
|
|
}
|
|
|
|
Loader {
|
|
width: parent.width
|
|
active: root.expandedSection === "network" || root.expandedSection === "bluetooth"
|
|
visible: active
|
|
sourceComponent: DetailView {
|
|
width: parent.width
|
|
isVisible: true
|
|
title: {
|
|
switch (root.expandedSection) {
|
|
case "network": return "Network Settings"
|
|
case "bluetooth": return "Bluetooth Settings"
|
|
default: return ""
|
|
}
|
|
}
|
|
content: {
|
|
switch (root.expandedSection) {
|
|
case "network": return networkDetailComponent
|
|
case "bluetooth": return bluetoothDetailComponent
|
|
default: return null
|
|
}
|
|
}
|
|
contentHeight: 250
|
|
}
|
|
}
|
|
|
|
Row {
|
|
width: parent.width
|
|
spacing: Theme.spacingM
|
|
|
|
AudioOutputPill {
|
|
width: (parent.width - Theme.spacingM) / 2
|
|
expanded: root.expandedSection === "audio_output"
|
|
onClicked: {
|
|
if (AudioService.sink) {
|
|
AudioService.sink.audio.muted = !AudioService.sink.audio.muted
|
|
}
|
|
}
|
|
onExpandClicked: root.toggleSection("audio_output")
|
|
}
|
|
|
|
AudioInputPill {
|
|
width: (parent.width - Theme.spacingM) / 2
|
|
expanded: root.expandedSection === "audio_input"
|
|
onClicked: {
|
|
if (AudioService.source) {
|
|
AudioService.source.audio.muted = !AudioService.source.audio.muted
|
|
}
|
|
}
|
|
onExpandClicked: root.toggleSection("audio_input")
|
|
}
|
|
}
|
|
|
|
Loader {
|
|
width: parent.width
|
|
active: root.expandedSection === "audio_output" || root.expandedSection === "audio_input"
|
|
visible: active
|
|
sourceComponent: DetailView {
|
|
width: parent.width
|
|
isVisible: true
|
|
title: {
|
|
switch (root.expandedSection) {
|
|
case "audio_output": return "Audio Output"
|
|
case "audio_input": return "Audio Input"
|
|
default: return ""
|
|
}
|
|
}
|
|
content: {
|
|
switch (root.expandedSection) {
|
|
case "audio_output": return audioOutputDetailComponent
|
|
case "audio_input": return audioInputDetailComponent
|
|
default: return null
|
|
}
|
|
}
|
|
contentHeight: 250
|
|
}
|
|
}
|
|
|
|
Row {
|
|
width: parent.width
|
|
spacing: Theme.spacingM
|
|
|
|
ToggleButton {
|
|
width: (parent.width - Theme.spacingM) / 2
|
|
iconName: DisplayService.nightModeEnabled ? "nightlight" : "dark_mode"
|
|
text: "Night Mode"
|
|
secondaryText: SessionData.nightModeAutoEnabled ? "Auto" : (DisplayService.nightModeEnabled ? "On" : "Off")
|
|
isActive: DisplayService.nightModeEnabled
|
|
enabled: DisplayService.automationAvailable
|
|
onClicked: DisplayService.toggleNightMode()
|
|
|
|
DankIcon {
|
|
anchors.top: parent.top
|
|
anchors.right: parent.right
|
|
anchors.topMargin: Theme.spacingS
|
|
anchors.rightMargin: Theme.spacingS
|
|
name: "schedule"
|
|
size: 12
|
|
color: Theme.primary
|
|
visible: SessionData.nightModeAutoEnabled
|
|
opacity: 0.8
|
|
}
|
|
}
|
|
|
|
ToggleButton {
|
|
width: (parent.width - Theme.spacingM) / 2
|
|
iconName: SessionData.isLightMode ? "light_mode" : "palette"
|
|
text: "Theme"
|
|
secondaryText: SessionData.isLightMode ? "Light" : "Dark"
|
|
isActive: true
|
|
onClicked: Theme.toggleLightMode()
|
|
}
|
|
}
|
|
}
|
|
|
|
Details.BluetoothCodecSelector {
|
|
id: bluetoothCodecSelector
|
|
anchors.fill: parent
|
|
z: 10000
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: networkDetailComponent
|
|
NetworkDetail {}
|
|
}
|
|
|
|
Component {
|
|
id: bluetoothDetailComponent
|
|
BluetoothDetail {
|
|
id: bluetoothDetail
|
|
onShowCodecSelector: function(device) {
|
|
if (contentLoader.item && contentLoader.item.bluetoothCodecSelector) {
|
|
contentLoader.item.bluetoothCodecSelector.show(device)
|
|
contentLoader.item.bluetoothCodecSelector.codecSelected.connect(function(deviceAddress, codecName) {
|
|
bluetoothDetail.updateDeviceCodecDisplay(deviceAddress, codecName)
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: audioOutputDetailComponent
|
|
AudioOutputDetail {}
|
|
}
|
|
|
|
Component {
|
|
id: audioInputDetailComponent
|
|
AudioInputDetail {}
|
|
}
|
|
}
|