Implement smooth source select with Loaders, implement vertical tabbar for settings, add header
This commit is contained in:
106
Main.qml
106
Main.qml
@@ -2,6 +2,7 @@ import QtQuick 6.8
|
|||||||
import QtQuick.Controls 6.8
|
import QtQuick.Controls 6.8
|
||||||
import QtQuick.Controls.Basic 6.8
|
import QtQuick.Controls.Basic 6.8
|
||||||
import QtQuick.Layouts 6.8
|
import QtQuick.Layouts 6.8
|
||||||
|
import QtQuick.Dialogs 6.10
|
||||||
|
|
||||||
import QYRComponents 1.0
|
import QYRComponents 1.0
|
||||||
|
|
||||||
@@ -10,54 +11,105 @@ ApplicationWindow {
|
|||||||
height: 800
|
height: 800
|
||||||
title: qsTr("QYouRadio")
|
title: qsTr("QYouRadio")
|
||||||
|
|
||||||
|
Dialog {
|
||||||
|
id: dialogSettings
|
||||||
|
// modality: Qt.WindowModal
|
||||||
|
popupType: Popup.Window
|
||||||
|
title: qsTr("Settings")
|
||||||
|
|
||||||
|
ViewSettings {}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 10
|
anchors.margins: 10
|
||||||
|
|
||||||
TabBar {
|
RowLayout {
|
||||||
id: tabbar
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
spacing: 10
|
|
||||||
TabButton {
|
Label {
|
||||||
text: qsTr("Autoradio")
|
text: "QYR"
|
||||||
|
heading: "h3"
|
||||||
|
font.bold: true
|
||||||
}
|
}
|
||||||
// TabButton {
|
|
||||||
// text: qsTr("Live Mix")
|
Item {
|
||||||
// }
|
Layout.fillWidth: true
|
||||||
// TabButton {
|
}
|
||||||
// text: qsTr("Deep Bass")
|
|
||||||
// }
|
Label {
|
||||||
TabButton {
|
visible: Player.playing
|
||||||
text: qsTr("Settings")
|
text: "Playback active"
|
||||||
|
heading: "h4"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TabBar {
|
||||||
|
id: tabbar
|
||||||
|
spacing: 10
|
||||||
|
TabButton {
|
||||||
|
text: qsTr("Autoradio")
|
||||||
|
}
|
||||||
|
TabButton {
|
||||||
|
text: qsTr("Live Mix")
|
||||||
|
}
|
||||||
|
TabButton {
|
||||||
|
text: qsTr("Deep Bass")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: "S"
|
||||||
|
onClicked: function() {
|
||||||
|
dialogSettings.open()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StackLayout {
|
|
||||||
|
SwipeView {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.margins: 10
|
Layout.margins: 10
|
||||||
|
|
||||||
|
interactive: false
|
||||||
currentIndex: tabbar.currentIndex
|
currentIndex: tabbar.currentIndex
|
||||||
ViewPlayer {
|
|
||||||
title: qsTr("Autoradio")
|
Loader {
|
||||||
streamURL: "https://youradio.nonamesoft.xyz/api/autoradio"
|
active: tabbar.currentIndex == 0
|
||||||
|
asynchronous: true
|
||||||
|
visible: status == Loader.Ready
|
||||||
|
sourceComponent: ViewPlayer {
|
||||||
|
title: qsTr("Autoradio")
|
||||||
|
streamURL: "https://youradio.nonamesoft.xyz/api/autoradio"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// ViewPlayer {
|
Loader {
|
||||||
// title: qsTr("Live Radio")
|
active: tabbar.currentIndex == 1
|
||||||
// streamURL: "https://youradio.nonamesoft.xyz/api/live"
|
asynchronous: true
|
||||||
// }
|
visible: status == Loader.Ready
|
||||||
// ViewPlayer {
|
sourceComponent: ViewPlayer {
|
||||||
// title: qsTr("Deep Bass")
|
title: qsTr("Live Mix")
|
||||||
// streamURL: "https://youradio.nonamesoft.xyz/api/deepbass"
|
streamURL: "https://youradio.nonamesoft.xyz/api/live"
|
||||||
// }
|
}
|
||||||
ViewSettings {
|
}
|
||||||
|
Loader {
|
||||||
|
active: tabbar.currentIndex == 2
|
||||||
|
asynchronous: true
|
||||||
|
visible: status == Loader.Ready
|
||||||
|
sourceComponent: ViewPlayer {
|
||||||
|
title: qsTr("Deep Bass")
|
||||||
|
streamURL: "https://youradio.nonamesoft.xyz/api/deepbass"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
YouAds {
|
YouAds {
|
||||||
Layout.fillWidth: false
|
Layout.fillWidth: false
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
visible: tabbar.currentIndex != 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
Player.qml
14
Player.qml
@@ -6,25 +6,25 @@ MediaPlayer {
|
|||||||
source: ""
|
source: ""
|
||||||
|
|
||||||
function startPlaying(url) {
|
function startPlaying(url) {
|
||||||
if (player.playing) {
|
if (playing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("Starting playback from " + url);
|
console.log("Starting playback from " + url);
|
||||||
player.source = url;
|
source = url;
|
||||||
player.play();
|
play();
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopPlaying() {
|
function stopPlaying() {
|
||||||
console.log("Stopping playback...");
|
console.log("Stopping playback...");
|
||||||
player.source = "";
|
source = "";
|
||||||
player.stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
audioOutput: AudioOutput {
|
audioOutput: AudioOutput {
|
||||||
volume: 0.4
|
volume: 0.4
|
||||||
}
|
}
|
||||||
|
|
||||||
onErrorOccurred: function(error, errorString) {
|
onErrorOccurred: function(error, errorString) {
|
||||||
player.stopPlaying();
|
stopPlaying();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ import QtQuick.Controls 6.8
|
|||||||
import QtQuick.Controls.Basic 6.8
|
import QtQuick.Controls.Basic 6.8
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
|
property bool outlined: false
|
||||||
implicitHeight: 36
|
implicitHeight: 36
|
||||||
|
|
||||||
contentItem: Text {
|
contentItem: Text {
|
||||||
text: parent.text
|
text: parent.text
|
||||||
font.family: Colors.fontFamily
|
font.family: Colors.fontFamily
|
||||||
font.pointSize: Colors.fontSize.base
|
font.pointSize: Colors.fontSize.button
|
||||||
opacity: enabled ? 1.0 : 0.3
|
opacity: enabled ? 1.0 : 0.3
|
||||||
color: Colors.text;
|
color: Colors.text;
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
@@ -17,7 +18,9 @@ Button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: parent.hovered ? Colors.primaryAlt : Colors.primary
|
color: parent.outlined ? "transparent" : (parent.hovered ? Colors.primaryAlt : Colors.primary)
|
||||||
|
border.color: (parent.hovered ? "#555" : "#777")
|
||||||
|
border.width: parent.outlined ? 2 : 0
|
||||||
opacity: enabled ? 1 : 0.3
|
opacity: enabled ? 1 : 0.3
|
||||||
radius: 5
|
radius: 5
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,8 +37,9 @@ Item {
|
|||||||
h4: 16,
|
h4: 16,
|
||||||
h5: 13,
|
h5: 13,
|
||||||
h6: 10,
|
h6: 10,
|
||||||
p: 12,
|
p: 14,
|
||||||
base: 12
|
base: 14,
|
||||||
|
button: 12
|
||||||
})
|
})
|
||||||
|
|
||||||
property var currentTheme: themes.dark
|
property var currentTheme: themes.dark
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ TabButton {
|
|||||||
contentItem: Text {
|
contentItem: Text {
|
||||||
text: parent.text
|
text: parent.text
|
||||||
font.family: Colors.fontFamily
|
font.family: Colors.fontFamily
|
||||||
font.pointSize: Colors.fontSize.base
|
font.pointSize: Colors.fontSize.button
|
||||||
opacity: enabled ? 1.0 : 0.3
|
opacity: enabled ? 1.0 : 0.3
|
||||||
color: Colors.text;
|
color: Colors.text;
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|||||||
172
ViewSettings.qml
172
ViewSettings.qml
@@ -8,50 +8,168 @@ RowLayout {
|
|||||||
// Layout.leftMargin: parent.width * 2
|
// Layout.leftMargin: parent.width * 2
|
||||||
// Layout.rightMargin: parent.width * 2
|
// Layout.rightMargin: parent.width * 2
|
||||||
|
|
||||||
TabBar {
|
Container {
|
||||||
id: settingsCategory
|
id: settingsCategory
|
||||||
|
Layout.fillWidth: false
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
Layout.rightMargin: 15
|
||||||
|
|
||||||
spacing: 10
|
implicitWidth: 240
|
||||||
|
clip: true
|
||||||
|
|
||||||
contentItem: ListView {
|
contentItem: ListView {
|
||||||
|
spacing: 7.5
|
||||||
model: settingsCategory.contentModel
|
model: settingsCategory.contentModel
|
||||||
currentIndex: settingsCategory.currentIndex
|
snapMode: ListView.SnapOneItem
|
||||||
|
|
||||||
spacing: settingsCategory.spacing
|
|
||||||
orientation: ListView.Vertical
|
orientation: ListView.Vertical
|
||||||
boundsBehavior: Flickable.StopAtBounds
|
|
||||||
flickableDirection: Flickable.AutoFlickIfNeeded
|
|
||||||
snapMode: ListView.SnapToItem
|
|
||||||
|
|
||||||
highlightMoveDuration: 0
|
|
||||||
highlightRangeMode: ListView.ApplyRange
|
|
||||||
preferredHighlightBegin: 40
|
|
||||||
preferredHighlightEnd: width - 40
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TabButton {
|
|
||||||
|
Button {
|
||||||
text: qsTr("Appearance")
|
text: qsTr("Appearance")
|
||||||
width: 284
|
width: 240
|
||||||
|
outlined: true
|
||||||
|
onClicked: settingsCategory.currentIndex = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
TabButton {
|
Button {
|
||||||
|
text: qsTr("Language")
|
||||||
|
width: 240
|
||||||
|
outlined: true
|
||||||
|
onClicked: settingsCategory.currentIndex = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: qsTr("Playback Settings")
|
||||||
|
width: 240
|
||||||
|
outlined: true
|
||||||
|
onClicked: settingsCategory.currentIndex = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
text: qsTr("About")
|
text: qsTr("About")
|
||||||
width: 284
|
width: 240
|
||||||
|
outlined: true
|
||||||
|
onClicked: settingsCategory.currentIndex = 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
SwipeView {
|
||||||
Layout.fillHeight: true
|
|
||||||
width: 5
|
|
||||||
color: Colors.text
|
|
||||||
radius: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
StackLayout {
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
currentIndex: settingsCategory.currentIndex
|
orientation: Qt.Vertical
|
||||||
|
interactive: false
|
||||||
|
currentIndex: tabbar.currentIndex
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: tabbar.currentIndex == 0
|
||||||
|
asynchronous: true
|
||||||
|
visible: status == Loader.Ready
|
||||||
|
sourceComponent: ColumnLayout {
|
||||||
|
Label {
|
||||||
|
text: "Appearance"
|
||||||
|
heading: "h1"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: tabbar.currentIndex == 1
|
||||||
|
asynchronous: true
|
||||||
|
visible: status == Loader.Ready
|
||||||
|
sourceComponent: ColumnLayout {
|
||||||
|
Label {
|
||||||
|
text: "Language"
|
||||||
|
heading: "h1"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: tabbar.currentIndex == 2
|
||||||
|
asynchronous: true
|
||||||
|
visible: status == Loader.Ready
|
||||||
|
sourceComponent: ColumnLayout {
|
||||||
|
Label {
|
||||||
|
text: "Playback Settings"
|
||||||
|
heading: "h1"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: tabbar.currentIndex == 3
|
||||||
|
asynchronous: true
|
||||||
|
visible: status == Loader.Ready
|
||||||
|
sourceComponent: ColumnLayout {
|
||||||
|
Label {
|
||||||
|
text: "About"
|
||||||
|
heading: "h1"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "YouRadio"
|
||||||
|
heading: "h2"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "by Youpiter"
|
||||||
|
heading: "h3"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Music source"
|
||||||
|
heading: "base"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "QYouRadio"
|
||||||
|
heading: "h3"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: "by Ghostfox"
|
||||||
|
heading: "h3"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Client development"
|
||||||
|
heading: "base"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Attribution"
|
||||||
|
heading: "h1"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Qt"
|
||||||
|
heading: "h2"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "by Qt Group Inc."
|
||||||
|
heading: "h3"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Open-Source library on which QYouRadio is built uppon, licensed under LGPL-3.0"
|
||||||
|
heading: "base"
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6
flake.lock
generated
6
flake.lock
generated
@@ -20,11 +20,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1760036653,
|
"lastModified": 1760315168,
|
||||||
"narHash": "sha256-FJOwW7YMxtnMi3R+MxwiVsUsrOtm3ubIBo8Jdc1nH6w=",
|
"narHash": "sha256-qWDhFoiz6VSd+S+rVzC2m5u8xuAzxRsuDI8OojbPEZ4=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "b6bae5b8d26ef00d8df42206ac24d0665640286b",
|
"rev": "160e3dfce302bb2fcd03761b84248c7534f3b948",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
Reference in New Issue
Block a user