forked from Shinonome/dots-hyprland
overview: add music recognition button to search bar
This commit is contained in:
@@ -357,8 +357,8 @@ Singleton {
|
||||
property real mediaControlsHeight: 160
|
||||
property real notificationPopupWidth: 410
|
||||
property real osdWidth: 180
|
||||
property real searchWidthCollapsed: 260
|
||||
property real searchWidth: 400
|
||||
property real searchWidthCollapsed: 210
|
||||
property real searchWidth: 360
|
||||
property real sidebarWidth: 460
|
||||
property real sidebarWidthExtended: 750
|
||||
property real baseVerticalBarWidth: 46
|
||||
|
||||
@@ -9,6 +9,7 @@ ToolbarButton {
|
||||
colBackgroundToggled: Appearance.colors.colSecondaryContainer
|
||||
colBackgroundToggledHover: Appearance.colors.colSecondaryContainerHover
|
||||
colRippleToggled: Appearance.colors.colSecondaryContainerActive
|
||||
property color colText: toggled ? Appearance.colors.colOnSecondaryContainer : Appearance.colors.colOnSurfaceVariant
|
||||
|
||||
contentItem: MaterialSymbol {
|
||||
anchors.centerIn: parent
|
||||
@@ -16,6 +17,6 @@ ToolbarButton {
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
iconSize: 22
|
||||
text: iconBtn.text
|
||||
color: iconBtn.toggled ? Appearance.colors.colOnSecondaryContainer : Appearance.colors.colOnSurfaceVariant
|
||||
color: iconBtn.colText
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,8 +92,6 @@ RowLayout {
|
||||
}
|
||||
}
|
||||
|
||||
// background: null
|
||||
|
||||
cursorDelegate: Rectangle {
|
||||
width: 1
|
||||
color: searchInput.activeFocus ? Appearance.colors.colPrimary : "transparent"
|
||||
@@ -102,10 +100,58 @@ RowLayout {
|
||||
}
|
||||
|
||||
IconToolbarButton {
|
||||
Layout.topMargin: 4
|
||||
Layout.bottomMargin: 4
|
||||
onClicked: {
|
||||
GlobalStates.overviewOpen = false;
|
||||
Hyprland.dispatch("global quickshell:regionSearch")
|
||||
}
|
||||
text: "image_search"
|
||||
StyledToolTip {
|
||||
text: Translation.tr("Google Lens")
|
||||
}
|
||||
}
|
||||
|
||||
IconToolbarButton {
|
||||
id: songRecButton
|
||||
Layout.topMargin: 4
|
||||
Layout.bottomMargin: 4
|
||||
Layout.rightMargin: 4
|
||||
toggled: SongRec.running
|
||||
onClicked: SongRec.toggleRunning()
|
||||
text: "music_cast"
|
||||
|
||||
StyledToolTip {
|
||||
text: Translation.tr("Recognize music")
|
||||
}
|
||||
|
||||
colText: toggled ? Appearance.colors.colOnPrimary : Appearance.colors.colOnSurfaceVariant
|
||||
background: MaterialShape {
|
||||
RotationAnimation on rotation {
|
||||
running: songRecButton.toggled
|
||||
duration: 12000
|
||||
easing.type: Easing.Linear
|
||||
loops: Animation.Infinite
|
||||
from: 0
|
||||
to: 360
|
||||
}
|
||||
shape: {
|
||||
if (songRecButton.down) {
|
||||
return songRecButton.toggled ? MaterialShape.Shape.Circle : MaterialShape.Shape.Square
|
||||
} else {
|
||||
return songRecButton.toggled ? MaterialShape.Shape.SoftBurst : MaterialShape.Shape.Circle
|
||||
}
|
||||
}
|
||||
color: {
|
||||
if (songRecButton.toggled) {
|
||||
return songRecButton.hovered ? Appearance.colors.colPrimaryHover : Appearance.colors.colPrimary
|
||||
} else {
|
||||
return songRecButton.hovered ? Appearance.colors.colSurfaceContainerHigh : ColorUtils.transparentize(Appearance.colors.colSurfaceContainerHigh)
|
||||
}
|
||||
}
|
||||
Behavior on color {
|
||||
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-76
@@ -10,93 +10,23 @@ import qs.services
|
||||
AndroidQuickToggleButton {
|
||||
id: root
|
||||
|
||||
property int timeoutInterval: Config.options.musicRecognition.interval
|
||||
property int timeoutDuration: Config.options.musicRecognition.timeout
|
||||
|
||||
|
||||
property string monitorSource: "monitor" // "monitor" (system sound) , "input" (microphone)
|
||||
toggled: SongRec.running
|
||||
property bool sourceIsMonitor: SongRec.monitorSource === SongRec.MonitorSource.Monitor
|
||||
|
||||
name: Translation.tr("Identify Music")
|
||||
statusText: toggled ? Translation.tr("Listening...") : monitorSource === "monitor" ? Translation.tr("System sound") : Translation.tr("Microphone")
|
||||
toggled: false
|
||||
buttonIcon: toggled ? "music_cast" : (monitorSource === "monitor" ? "music_note" : "frame_person_mic")
|
||||
|
||||
property var recognizedTrack: ({ title:"", subtitle:"", url:""})
|
||||
|
||||
function handleRecognition(jsonText) {
|
||||
try {
|
||||
var obj = JSON.parse(jsonText)
|
||||
root.recognizedTrack = {
|
||||
title: obj.track.title,
|
||||
subtitle: obj.track.subtitle,
|
||||
url: obj.track.url
|
||||
}
|
||||
musicReconizedProc.running = true
|
||||
} catch(e) {
|
||||
Quickshell.execDetached(["notify-send", Translation.tr("Couldn't recognize music"), Translation.tr("Perhaps what you're listening to is too niche"), "-a", "Shell"])
|
||||
} finally {
|
||||
root.toggled = false
|
||||
}
|
||||
}
|
||||
|
||||
statusText: toggled ? Translation.tr("Listening...") : sourceIsMonitor ? Translation.tr("System sound") : Translation.tr("Microphone")
|
||||
buttonIcon: toggled ? "music_cast" : (sourceIsMonitor ? "music_note" : "frame_person_mic")
|
||||
|
||||
StyledToolTip {
|
||||
text: Translation.tr("Recognize music | Right-click to toggle source")
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
root.toggled = !root.toggled
|
||||
recognizeMusicProc.running = root.toggled
|
||||
musicReconizedProc.running = false
|
||||
SongRec.toggleRunning()
|
||||
}
|
||||
|
||||
altAction: () => {
|
||||
if (root.monitorSource === "monitor"){
|
||||
root.monitorSource = "input"
|
||||
return
|
||||
}else {
|
||||
root.monitorSource = "monitor"
|
||||
}
|
||||
|
||||
SongRec.toggleMonitorSource()
|
||||
}
|
||||
|
||||
Process {
|
||||
id: recognizeMusicProc
|
||||
running: false
|
||||
command: [`${Directories.scriptPath}/musicRecognition/recognize-music.sh`, "-i", root.timeoutInterval, "-t", root.timeoutDuration, "-s", root.monitorSource]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
handleRecognition(this.text)
|
||||
}
|
||||
}
|
||||
onExited: (exitCode, exitStatus) => {
|
||||
if (exitCode === 1) {
|
||||
Quickshell.execDetached(["notify-send", Translation.tr("Couldn't recognize music"), Translation.tr("Make sure you have songrec installed"), "-a", "Shell"])
|
||||
root.toggled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: musicReconizedProc
|
||||
running: false
|
||||
command: [
|
||||
"notify-send",
|
||||
Translation.tr("Music Recognized"),
|
||||
root.recognizedTrack.title + " - " + root.recognizedTrack.subtitle,
|
||||
"-A", "Shazam",
|
||||
"-A", "YouTube",
|
||||
"-a", "Shell"
|
||||
]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
if (this.text === "") return
|
||||
if (this.text == 0){
|
||||
Qt.openUrlExternally(root.recognizedTrack.url);
|
||||
} else {
|
||||
Qt.openUrlExternally("https://www.youtube.com/results?search_query=" + root.recognizedTrack.title + " - " + root.recognizedTrack.subtitle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.modules.common
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
enum MonitorSource { Monitor, Input }
|
||||
|
||||
property var monitorSource: SongRec.MonitorSource.Monitor
|
||||
property int timeoutInterval: Config.options.musicRecognition.interval
|
||||
property int timeoutDuration: Config.options.musicRecognition.timeout
|
||||
readonly property bool running: recognizeMusicProc.running
|
||||
|
||||
function toggleRunning(running) {
|
||||
if (recognizeMusicProc.running && !running === true) root.manuallyStopped = true;
|
||||
if (running != undefined) {
|
||||
recognizeMusicProc.running = running
|
||||
} else {
|
||||
recognizeMusicProc.running = !root.running
|
||||
}
|
||||
musicReconizedProc.running = false
|
||||
}
|
||||
|
||||
function toggleMonitorSource(source) {
|
||||
if (source !== undefined) {
|
||||
root.monitorSource = source
|
||||
return
|
||||
}
|
||||
root.monitorSource = (root.monitorSource === SongRec.MonitorSource.Monitor) ? SongRec.MonitorSource.Input : SongRec.MonitorSource.Monitor
|
||||
}
|
||||
function monitorSourceToString(source) {
|
||||
if (source === SongRec.MonitorSource.Monitor) {
|
||||
return "monitor"
|
||||
} else {
|
||||
return "input"
|
||||
}
|
||||
}
|
||||
readonly property string monitorSourceString: monitorSourceToString(monitorSource)
|
||||
property var recognizedTrack: ({ title:"", subtitle:"", url:""})
|
||||
property bool manuallyStopped: false
|
||||
|
||||
function handleRecognition(jsonText) {
|
||||
try {
|
||||
var obj = JSON.parse(jsonText)
|
||||
root.recognizedTrack = {
|
||||
title: obj.track.title,
|
||||
subtitle: obj.track.subtitle,
|
||||
url: obj.track.url
|
||||
}
|
||||
musicReconizedProc.running = true
|
||||
} catch(e) {
|
||||
Quickshell.execDetached(["notify-send", Translation.tr("Couldn't recognize music"), Translation.tr("Perhaps what you're listening to is too niche"), "-a", "Shell"])
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: recognizeMusicProc
|
||||
running: false
|
||||
command: [`${Directories.scriptPath}/musicRecognition/recognize-music.sh`, "-i", root.timeoutInterval, "-t", root.timeoutDuration, "-s", root.monitorSourceString]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
if (root.manuallyStopped) {
|
||||
root.manuallyStopped = false
|
||||
return
|
||||
}
|
||||
handleRecognition(this.text)
|
||||
}
|
||||
}
|
||||
onExited: (exitCode, exitStatus) => {
|
||||
if (exitCode === 1) {
|
||||
Quickshell.execDetached(["notify-send", Translation.tr("Couldn't recognize music"), Translation.tr("Make sure you have songrec installed"), "-a", "Shell"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: musicReconizedProc
|
||||
running: false
|
||||
command: [
|
||||
"notify-send",
|
||||
Translation.tr("Music Recognized"),
|
||||
root.recognizedTrack.title + " - " + root.recognizedTrack.subtitle,
|
||||
"-A", "Shazam",
|
||||
"-A", "YouTube",
|
||||
"-a", "Shell"
|
||||
]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
if (this.text === "") return
|
||||
if (this.text == 0) {
|
||||
Qt.openUrlExternally(root.recognizedTrack.url);
|
||||
} else {
|
||||
Qt.openUrlExternally("https://www.youtube.com/results?search_query=" + root.recognizedTrack.title + " - " + root.recognizedTrack.subtitle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user