feat: media controls

This commit is contained in:
end-4
2025-05-18 18:54:28 +02:00
parent 931b276d60
commit 314a6c67b6
6 changed files with 347 additions and 17 deletions
@@ -266,6 +266,8 @@ Singleton {
property real sidebarWidth: 450
property real sidebarWidthExtended: 750
property real osdWidth: 200
property real mediaControlsWidth: 430
property real mediaControlsHeight: 150
property real notificationPopupWidth: 410
property real searchWidthCollapsed: 260
property real searchWidth: 450
@@ -108,4 +108,32 @@ function wordWrap(str, maxLen) {
}
if (current.length > 0) lines.push(current);
return lines.join("\n");
}
function cleanMusicTitle(title) {
if (!title) return "";
// Brackets
title = title.replace(/ *\([^)]*\) */g, " "); // Round brackets
title = title.replace(/ *\[[^\]]*\] */g, " "); // Square brackets
title = title.replace(/ *\{[^\}]*\} */g, " "); // Curly brackets
// Japenis brackets
title = title.replace(/【[^】]*】/, "") // Touhou
title = title.replace(/《[^》]*》/, "") // ??
title = title.replace(/「[^」]*」/, "") // OP/ED
title = title.replace(/『[^』]*』/, "") // OP/ED
return title;
}
function friendlyTimeForSeconds(seconds) {
if (isNaN(seconds) || seconds < 0) return "0:00";
seconds = Math.floor(seconds);
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
const s = seconds % 60;
if (h > 0) {
return `${h}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
} else {
return `${m}:${s.toString().padStart(2, '0')}`;
}
}
@@ -16,8 +16,10 @@ Slider {
property real handleWidth: (slider.pressed ? 3 : 5) * scale
property real handleHeight: 44 * scale
property real handleLimit: slider.backgroundDotMargins * scale
property real trackHeight: 15 * scale
property real limitedHandleRangeWidth: (slider.availableWidth - handleWidth - slider.handleLimit * 2)
property string tooltipContent: `${Math.round(value * 100)}%`
Layout.fillWidth: true
from: 0
to: 1
@@ -44,13 +46,14 @@ Slider {
background: Item {
anchors.verticalCenter: parent.verticalCenter
implicitHeight: 12 // Somehow binding this makes it fill height. Must be set with a constant like this
implicitHeight: trackHeight
// Fill left
Rectangle {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
width: slider.handleLimit + slider.visualPosition * slider.limitedHandleRangeWidth - (slider.handleMargins + slider.handleWidth / 2)
height: parent.height
height: trackHeight
color: Appearance.m3colors.m3primary
topLeftRadius: Appearance.rounding.full
bottomLeftRadius: Appearance.rounding.full
@@ -60,9 +63,10 @@ Slider {
// Fill right
Rectangle {
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
width: slider.handleLimit + (1 - slider.visualPosition) * slider.limitedHandleRangeWidth - (slider.handleMargins + slider.handleWidth / 2)
height: parent.height
height: trackHeight
color: Appearance.m3colors.m3secondaryContainer
topLeftRadius: Appearance.rounding.unsharpen
bottomLeftRadius: Appearance.rounding.unsharpen
@@ -101,7 +105,7 @@ Slider {
StyledToolTip {
extraVisibleCondition: slider.pressed
content: `${Math.round(slider.value * 100)}%`
content: slider.tooltipContent
}
}
}