aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--com.pelagicore.webradio/Main.qml57
-rw-r--r--com.pelagicore.webradio/assets/logo-dark.pngbin0 -> 17050 bytes
-rw-r--r--com.pelagicore.webradio/assets/logo.pngbin0 -> 21004 bytes
-rw-r--r--com.pelagicore.webradio/assets/onair.jpgbin0 -> 30284 bytes
-rw-r--r--com.pelagicore.webradio/com.pelagicore.webradio.pro19
-rw-r--r--com.pelagicore.webradio/icon.pngbin0 -> 878 bytes
-rw-r--r--com.pelagicore.webradio/info.yaml13
-rw-r--r--com.pelagicore.webradio/panels/CurrentStationScreen.qml107
-rw-r--r--com.pelagicore.webradio/panels/SelectionScreen.qml173
-rw-r--r--com.pelagicore.webradio/panels/StationCover.qml137
-rw-r--r--com.pelagicore.webradio/popups/AboutPopup.qml79
-rw-r--r--com.pelagicore.webradio/popups/MusicSourcesPopup.qml101
-rw-r--r--com.pelagicore.webradio/stores/RadioStore.qml244
-rw-r--r--com.pelagicore.webradio/views/WebRadioContent.qml85
-rw-r--r--qt-auto-extra-apps.pro3
15 files changed, 1017 insertions, 1 deletions
diff --git a/com.pelagicore.webradio/Main.qml b/com.pelagicore.webradio/Main.qml
new file mode 100644
index 0000000..00a20bf
--- /dev/null
+++ b/com.pelagicore.webradio/Main.qml
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Luxoft Sweden AB
+** Copyright (C) 2014-2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtAuto Extra Apps.
+**
+** $QT_BEGIN_LICENSE:GPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import shared.controls 1.0
+import shared.Sizes 1.0
+import shared.Style 1.0
+import application.windows 1.0
+
+import "stores"
+import "views"
+
+QtObject {
+ property var mainWindow: ApplicationCCWindow {
+ id: mainWindow
+
+ WebRadioContent {
+ x: mainWindow.exposedRect.x
+ y: mainWindow.exposedRect.y
+ width: mainWindow.exposedRect.width
+ height: mainWindow.exposedRect.height
+ anchors.top: parent.top
+ anchors.topMargin: Sizes.dp(200)
+ store: RadioStore { }
+ rootItem: mainWindow.contentItem
+ }
+ }
+}
diff --git a/com.pelagicore.webradio/assets/logo-dark.png b/com.pelagicore.webradio/assets/logo-dark.png
new file mode 100644
index 0000000..61bf203
--- /dev/null
+++ b/com.pelagicore.webradio/assets/logo-dark.png
Binary files differ
diff --git a/com.pelagicore.webradio/assets/logo.png b/com.pelagicore.webradio/assets/logo.png
new file mode 100644
index 0000000..847b054
--- /dev/null
+++ b/com.pelagicore.webradio/assets/logo.png
Binary files differ
diff --git a/com.pelagicore.webradio/assets/onair.jpg b/com.pelagicore.webradio/assets/onair.jpg
new file mode 100644
index 0000000..86364c2
--- /dev/null
+++ b/com.pelagicore.webradio/assets/onair.jpg
Binary files differ
diff --git a/com.pelagicore.webradio/com.pelagicore.webradio.pro b/com.pelagicore.webradio/com.pelagicore.webradio.pro
new file mode 100644
index 0000000..8eae043
--- /dev/null
+++ b/com.pelagicore.webradio/com.pelagicore.webradio.pro
@@ -0,0 +1,19 @@
+TEMPLATE = aux
+
+FILES += info.yaml \
+ icon.png \
+ Main.qml \
+ panels \
+ stores \
+ assets \
+ popups \
+ views \
+
+app.files = $$FILES
+app.path = /apps/com.pelagicore.webradio
+INSTALLS += app
+
+AM_MANIFEST = info.yaml
+AM_PACKAGE_DIR = $$app.path
+
+load(am-app)
diff --git a/com.pelagicore.webradio/icon.png b/com.pelagicore.webradio/icon.png
new file mode 100644
index 0000000..9b8ba23
--- /dev/null
+++ b/com.pelagicore.webradio/icon.png
Binary files differ
diff --git a/com.pelagicore.webradio/info.yaml b/com.pelagicore.webradio/info.yaml
new file mode 100644
index 0000000..326876d
--- /dev/null
+++ b/com.pelagicore.webradio/info.yaml
@@ -0,0 +1,13 @@
+formatVersion: 1
+formatType: am-application
+---
+id: 'com.pelagicore.webradio'
+icon: 'icon.png'
+code: 'Main.qml'
+runtime: 'qml'
+runtimeParameters: { importPaths: ['.'] }
+name:
+ en: 'WebRadio'
+ de: 'WebRadio'
+
+categories: [ 'media' ]
diff --git a/com.pelagicore.webradio/panels/CurrentStationScreen.qml b/com.pelagicore.webradio/panels/CurrentStationScreen.qml
new file mode 100644
index 0000000..49f38c3
--- /dev/null
+++ b/com.pelagicore.webradio/panels/CurrentStationScreen.qml
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Luxoft Sweden AB
+** Copyright (C) 2014-2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtAuto Extra Apps.
+**
+** $QT_BEGIN_LICENSE:GPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 2.2
+import shared.controls 1.0
+import shared.Sizes 1.0
+
+import shared.Style 1.0
+
+Item {
+ id: root
+
+ property string stationName: ""
+ property string stationImage: ""
+ property string bitRate: ""
+ property string streamingUrl: ""
+ property alias currentOperationStatus: stationInfo.status
+ property bool playing
+
+ signal nextStation()
+ signal prevStation()
+ signal playStation()
+ signal pauseStation()
+
+ StationCover {
+ id: stationInfo
+
+ anchors.left: parent.left
+ anchors.leftMargin: Sizes.dp(80)
+ source: root.stationImage === "" ? "../assets/onair.jpg" : root.stationImage
+ title: root.stationName
+ subTitle: qsTr("Bitrate: ") + root.bitRate
+ description: qsTr("Streaming: ") + root.streamingUrl
+ }
+
+ Image {
+ anchors.bottomMargin: -Sizes.dp(80)
+ anchors.bottom: controlsRow.top
+ anchors.left: stationInfo.right
+ height: Sizes.dp(278 / 3)
+ width: Sizes.dp(1000 / 3)
+ fillMode: Image.PreserveAspectCrop
+ source: Style.theme === Style.Dark ? "../assets/logo-dark.png" : "../assets/logo.png"
+ }
+
+ RowLayout {
+ id: controlsRow
+ anchors.top: parent.top
+ anchors.topMargin: Sizes.dp(52)
+ anchors.left: stationInfo.right
+ ToolButton {
+ Layout.preferredWidth: Sizes.dp(80)
+ Layout.preferredHeight: Sizes.dp(240)
+ icon.name: "ic_skipprevious"
+ onClicked: {
+ root.prevStation()
+ }
+ }
+
+ ToolButton {
+ Layout.preferredWidth: Sizes.dp(160)
+ Layout.preferredHeight: Sizes.dp(240)
+ icon.name: root.playing ? "ic-pause" : "ic_play"
+ onClicked: root.playing ? root.pauseStation() : root.playStation()
+ }
+
+ ToolButton {
+ Layout.preferredWidth: Sizes.dp(80)
+ Layout.preferredHeight: Sizes.dp(240)
+ icon.name: "ic_skipnext"
+ onClicked: {
+ root.nextStation()
+ }
+ }
+ }
+}
diff --git a/com.pelagicore.webradio/panels/SelectionScreen.qml b/com.pelagicore.webradio/panels/SelectionScreen.qml
new file mode 100644
index 0000000..48dcc7a
--- /dev/null
+++ b/com.pelagicore.webradio/panels/SelectionScreen.qml
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Luxoft Sweden AB
+** Copyright (C) 2014-2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtAuto Extra Apps.
+**
+** $QT_BEGIN_LICENSE:GPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 2.2
+
+import shared.controls 1.0
+import shared.Sizes 1.0
+import shared.Style 1.0
+import shared.utils 1.0
+import shared.animations 1.0
+
+import "../stores"
+import "../popups"
+
+
+Item {
+ id: root
+
+ property RadioStore store
+ property Item rootItem
+ signal chosenGenre(var genre)
+
+ Image {
+ width: root.width - Sizes.dp(80)
+ height: Sizes.dp(16)
+ anchors.horizontalCenter: root.horizontalCenter
+ anchors.bottom: genrelist.top
+ source: Style.image("list-divider")
+ opacity: genrelist.contentY > 0 ? 1.0 : 0.0
+ Behavior on opacity { DefaultNumberAnimation { duration: 100 } }
+ }
+
+ ToolsColumn {
+ id: toolsColumn
+ width: Sizes.dp(264)
+ anchors.left: parent.left
+ anchors.top: parent.top
+ model: root.store.toolsColumnModel
+
+ onClicked: {
+ if (currentText === "sources") {
+ //FIXME in multiprocess store.musicSourcesModel.length returns 1
+ //even though is more. When spotify and/or web radio are uninstalled
+ //and installed again, then it updates fine.
+ var pos = currentItem.mapToItem(root.rootItem
+ , currentItem.width/2, currentItem.height/2);
+
+ //set model each time to ensure data accuracy
+ musicSourcesPopup.model = root.store.musicSourcesModel
+ musicSourcesPopup.originItemX = pos.x;
+ musicSourcesPopup.originItemY = pos.y;
+ musicSourcesPopup.visible = true;
+ } else if (currentText === "ABOUT...") {
+ pos = currentItem.mapToItem(root.rootItem
+ , currentItem.width/2, currentItem.height/2);
+ aboutPopup.originItemX = pos.x;
+ aboutPopup.originItemY = pos.y;
+ aboutPopup.visible = true;
+ }
+
+ toolsColumn.currentIndex = 0;
+ }
+ }
+
+ MusicSourcesPopup {
+ id: musicSourcesPopup
+ width: root.Sizes.dp(910)
+ // caclulate popup height based on musicSources list items
+ // + 200 for header & margins
+ height: model ? root.Sizes.dp(200 + (model.count * 96)) : root.Sizes.dp(296)
+ popupY: root.Sizes.dp(Config.centerConsoleHeight / 4)
+ onSwitchSourceClicked: {
+ store.switchSource(source)
+ }
+ }
+
+ AboutPopup {
+ id: aboutPopup
+ width: root.Sizes.dp(910)
+ // caclulate popup height based on musicSources list items
+ // + 200 for header & margins
+ height: root.Sizes.dp(450)
+ popupY: root.Sizes.dp(Config.centerConsoleHeight / 4)
+ }
+
+ GridView {
+ id: genrelist
+
+ width: root.width - Sizes.dp(247.5)
+ height: root.height
+ anchors.centerIn: parent
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.horizontalCenterOffset: toolsColumn.width / 3
+
+ model: root.store.musicGenres
+ clip: true
+ cellWidth: Sizes.dp(202.5) ; cellHeight: cellWidth
+
+ ScrollIndicator.vertical: ScrollIndicator {
+ parent: genrelist.parent
+ anchors.top: genrelist.top
+ anchors.right: genrelist.right
+ anchors.rightMargin: - Sizes.dp(9)
+ anchors.bottom: genrelist.bottom
+ }
+
+ delegate: Item {
+ width: Sizes.dp(193,5)
+ height: Sizes.dp(180)
+
+ Rectangle {
+ anchors.fill: parent
+ opacity: 0.2
+ color: "black"
+ border.width: mouseArea.containsPress ? 2 : 1
+ border.color: "#888"
+ radius: 4
+ gradient: Gradient {
+ GradientStop { position: 0 ; color: mouseArea.containsPress ? "#ccc" : "#eee" }
+ GradientStop { position: 1 ; color: mouseArea.containsPress ? "#aaa" : "#ccc" }
+ }
+ }
+
+ Label {
+ anchors.centerIn: parent
+ width: Sizes.dp(157,5)
+ wrapMode: Text.WordWrap
+ horizontalAlignment: Text.AlignHCenter
+ font.pixelSize: Sizes.fontSizeS
+ text: model.name
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onClicked: {
+ root.chosenGenre(model.name)
+ }
+ }
+ }
+ }
+}
diff --git a/com.pelagicore.webradio/panels/StationCover.qml b/com.pelagicore.webradio/panels/StationCover.qml
new file mode 100644
index 0000000..364b473
--- /dev/null
+++ b/com.pelagicore.webradio/panels/StationCover.qml
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Luxoft Sweden AB
+** Copyright (C) 2014-2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtAuto Extra Apps.
+**
+** $QT_BEGIN_LICENSE:GPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import QtQuick.Layouts 1.0
+import QtGraphicalEffects 1.0
+import QtQuick.Controls 2.0
+
+import shared.Sizes 1.0
+import shared.controls 1.0
+import shared.Style 1.0
+
+Item {
+ id: root
+
+ width: Sizes.dp(607.5)
+ height: Sizes.dp(480)
+
+ property alias source: image.source
+ property alias title: title.text
+ property alias description: description.text
+ property alias subTitle: subTitle.text
+ property string status
+ signal clicked()
+
+ RowLayout {
+ id: currentRadio
+ anchors.left: parent.left
+ spacing: Sizes.dp(30)
+ Item {
+ Layout.preferredWidth: Sizes.dp(270)
+ Layout.preferredHeight: Sizes.dp(270)
+ Rectangle {
+ anchors.fill: parent
+ color: "white"
+ border.color: Qt.darker(color, 1.2)
+ }
+ Image {
+ id: image
+ anchors.fill: parent
+ anchors.margins: Sizes.dp(2)
+ fillMode: Image.PreserveAspectCrop
+ asynchronous: true
+ Image {
+ anchors.top: parent.bottom
+ width: Sizes.dp(270)
+ anchors.horizontalCenter: parent.horizontalCenter
+ source: Style.image("album-art-shadow-widget")
+ fillMode: Image.PreserveAspectFit
+ }
+ }
+ }
+
+ Label {
+ id: titelPlaceholder
+ Layout.preferredWidth: Sizes.dp(306)
+ horizontalAlignment: Text.AlignLeft
+ font.pixelSize: Sizes.fontSizeM
+ wrapMode: Text.WordWrap
+ visible: title.text === ""
+ text: qsTr("No Stream Selected")
+ }
+
+ Label {
+ id: title
+ Layout.preferredWidth: Sizes.dp(306)
+ horizontalAlignment: Text.AlignLeft
+ font.pixelSize: Sizes.fontSizeM
+ wrapMode: Text.WordWrap
+ }
+ }
+
+ ColumnLayout {
+ anchors.top: currentRadio.bottom
+ anchors.topMargin: Sizes.dp(80)
+ anchors.left: currentRadio.left
+ spacing: Sizes.dp(5)
+
+ Label {
+ id: subTitle
+ font.pixelSize: Sizes.fontSizeS
+ font.weight: Font.Light
+ }
+
+ Label {
+ id: description
+ Layout.preferredWidth: root.width
+ Layout.preferredHeight: Sizes.dp(70)
+ font.pixelSize: Sizes.fontSizeS
+ font.weight: Font.Light
+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+ }
+
+ Label {
+ visible: root.status !== ""
+ text: root.status
+ font.pixelSize: Sizes.fontSizeM
+ font.weight: Font.Light
+ Layout.preferredWidth: root.width
+ Layout.alignment: Qt.AlignCenter
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: root.clicked()
+ }
+}
diff --git a/com.pelagicore.webradio/popups/AboutPopup.qml b/com.pelagicore.webradio/popups/AboutPopup.qml
new file mode 100644
index 0000000..a8ec0cc
--- /dev/null
+++ b/com.pelagicore.webradio/popups/AboutPopup.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Luxoft Sweden AB
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtAuto Extra Apps.
+**
+** $QT_BEGIN_LICENSE:GPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Controls 2.2
+import QtApplicationManager 2.0
+import QtQuick.Layouts 1.14
+import shared.utils 1.0
+import application.windows 1.0
+
+import shared.Style 1.0
+import shared.controls 1.0
+import shared.Sizes 1.0
+
+PopupWindow {
+ id: root
+
+ Item {
+ id: popupContent
+
+ anchors.fill: parent
+
+ Label {
+ id: header
+ anchors.baseline: parent.top
+ anchors.baselineOffset: Sizes.dp(75)
+ width: parent.width
+ text: qsTr("About com.pelagicore.webradio")
+ horizontalAlignment: Text.AlignHCenter
+ font.pixelSize: Sizes.fontSizeM
+ }
+ Image {
+ id: shadow
+ anchors.top: parent.top
+ anchors.topMargin: Sizes.dp(120)
+ width: parent.width
+ height: Sizes.dp(sourceSize.height)
+ source: Style.image("popup-title-shadow")
+ }
+
+ TextArea {
+ anchors.topMargin: Sizes.dp(200)
+ anchors.fill: parent
+ readOnly: true
+ font.pixelSize: Sizes.fontSizeM
+ text: qsTr("The integration of the Shoutcast is provided for demonstration purposes only. This does not imply any sub-licensing of Shoutcast technologies. A final customer product using the code of this app should be covered by a dedicated license from Shoutcast")
+ wrapMode: TextEdit.WordWrap
+ color: Style.contrastColor
+ }
+ }
+}
diff --git a/com.pelagicore.webradio/popups/MusicSourcesPopup.qml b/com.pelagicore.webradio/popups/MusicSourcesPopup.qml
new file mode 100644
index 0000000..71c2257
--- /dev/null
+++ b/com.pelagicore.webradio/popups/MusicSourcesPopup.qml
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Luxoft Sweden AB
+** Copyright (C) 2014-2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtAuto Extra Apps.
+**
+** $QT_BEGIN_LICENSE:GPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+import QtQuick 2.6
+import QtQuick.Controls 2.2
+import QtApplicationManager 2.0
+import shared.utils 1.0
+import application.windows 1.0
+
+import shared.Style 1.0
+import shared.Sizes 1.0
+
+PopupWindow {
+ id: root
+
+ property alias model: listView.model
+ signal switchSourceClicked(string source)
+
+ Item {
+ id: popupContent
+
+ anchors.fill: parent
+
+ Label {
+ id: header
+ anchors.baseline: parent.top
+ anchors.baselineOffset: Sizes.dp(75)
+ width: parent.width
+ text: qsTr("Choose Source")
+ horizontalAlignment: Text.AlignHCenter
+ font.pixelSize: Sizes.fontSizeM
+ }
+ Image {
+ id: shadow
+ anchors.top: parent.top
+ anchors.topMargin: Sizes.dp(120)
+ width: parent.width
+ height: Sizes.dp(sourceSize.height)
+ source: Style.image("popup-title-shadow")
+ }
+
+ ListView {
+ id: listView
+ anchors {
+ top: shadow.bottom
+ left: parent.left
+ leftMargin: Sizes.dp(40)
+ right: parent.right
+ rightMargin: Sizes.dp(40)
+ bottom: parent.bottom
+ bottomMargin: Sizes.dp(40)
+ }
+ interactive: false
+ delegate: RadioButton {
+ checked: appId == "com.pelagicore.webradio"
+ width: parent.width
+ height: Sizes.dp(96)
+ font.pixelSize: Sizes.fontSizeS
+ indicator.implicitHeight: Sizes.dp(30)
+ indicator.implicitWidth: Sizes.dp(30)
+ text: model.text
+ spacing: Sizes.dp(20)
+ onClicked: {
+ root.switchSourceClicked(appId)
+ root.close();
+ }
+
+ checkable: false
+ }
+ }
+ }
+}
diff --git a/com.pelagicore.webradio/stores/RadioStore.qml b/com.pelagicore.webradio/stores/RadioStore.qml
new file mode 100644
index 0000000..ff9c9d6
--- /dev/null
+++ b/com.pelagicore.webradio/stores/RadioStore.qml
@@ -0,0 +1,244 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Luxoft Sweden AB
+** Copyright (C) 2017-2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Neptune 3 IVI UI.
+**
+** $QT_BEGIN_LICENSE:GPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import QtMultimedia 5.9
+import QtQuick.XmlListModel 2.14
+import QtApplicationManager.Application 2.0
+import QtApplicationManager 2.0
+
+import shared.utils 1.0
+import shared.Sizes 1.0
+
+Store {
+ id: root
+
+ property bool nextStation: true
+ Component.onCompleted: {
+ getAllGenres();
+ }
+
+ property ListModel musicGenres: ListModel {}
+ property ListModel currentStations: ListModel {}
+
+ property Audio player: Audio {
+ id: player
+ source: url
+ }
+
+ property alias volume: player.volume
+ property bool playing: player.playbackState === Audio.PlayingState
+
+ property var station
+ property int currentIndex
+ property string url
+ property string currentOperationStatus
+
+ property ListModel toolsColumnModel: ListModel {
+ id: toolsColumnModel
+
+ ListElement { icon: "ic-installed"; text: "genres"; greyedOut: false }
+ ListElement { icon: "ic-toolbar-sources-tuner"; text: "sources"; greyedOut: false }
+ ListElement { icon: ""; text: "ABOUT..."; greyedOut: false }
+ }
+
+ property ListModel musicSourcesModel: ListModel {
+ id: musicSourcesModel
+ ListElement {
+ text: "AM/FM Radio"
+ appId: "com.pelagicore.tuner"
+ }
+ ListElement {
+ text: "Music"
+ appId: "com.pelagicore.music"
+ }
+ }
+
+ QtObject {
+ id: d
+ readonly property string devID: "5ClwKdIfc6j5Nitn"
+ readonly property string base_tuneIN: "/sbin/tunein-station.pls"
+ readonly property var xmlGenresParser: XmlListModel {
+ query: "/genrelist/genre"
+ XmlRole { name: "name"; query: "@name/string()" }
+ XmlRole { name: "count"; query: "@count/number()" }
+ onStatusChanged: {
+ if (status === XmlListModel.Ready) {
+ musicGenres.clear();
+ root.currentOperationStatus = "";
+ var tmpAr = []
+ for (var i = 0; i < count; ++i) {
+ var obj = get(i);
+ if (obj.count > 0) {
+ tmpAr.push({'name': obj.name});
+ }
+ }
+
+ // append array is not documented
+ // see qt5/qtdeclarative/src/qml/types/qqmllistmodel.cpp
+ musicGenres.append(tmpAr);
+ } else if (status === XmlListModel.Error) {
+ root.currentOperationStatus =
+ qsTr("Failed to load genres list, try to restart the app later");
+ }
+ }
+ }
+
+ readonly property var xmlStationsParser: XmlListModel {
+ query: "/stationlist/station"
+ XmlRole { name: "name"; query: "@name/string()" }
+ XmlRole { name: "mt"; query: "@mt/string()" }
+ XmlRole { name: "id"; query: "@id/string()" }
+ XmlRole { name: "br"; query: "@br/string()" }
+ XmlRole { name: "logo"; query: "@logo/string()" }
+ onStatusChanged: {
+ if (status === XmlListModel.Ready) {
+ currentStations.clear();
+ root.currentOperationStatus = "";
+ var tmpAr = []
+ for (var i = 0; i < count; ++i) {
+ var obj = get(i);
+ tmpAr.push(
+ {'name': obj.name
+ , "id": obj.id
+ , "logo": obj.logo
+ , "br": obj.br
+ });
+ }
+
+ currentStations.append(tmpAr);
+ playFirst();
+ } else if (status === XmlListModel.Error) {
+ root.currentOperationStatus =
+ qsTr("Failed to get stations for the given genre");
+ }
+ }
+ }
+ }
+
+ function playFirst() {
+ if (currentStations.count > 0) {
+ currentIndex = 0;
+ var station = currentStations.get(currentIndex);
+ getSourceForStation(station.id);
+ root.station = station;
+ }
+ }
+
+ function next() {
+ if (currentStations.count > 0) {
+ currentIndex = (currentIndex + 1) % currentStations.count;
+ var station = currentStations.get(currentIndex);
+ getSourceForStation(station.id);
+ root.station = station;
+ }
+ }
+
+ function previous() {
+ if (currentStations.count > 0) {
+ currentIndex = currentIndex == 0 ? currentStations.count - 1 : currentIndex - 1;
+ var station = currentStations.get(currentIndex);
+ getSourceForStation(station.id);
+ root.station = station;
+ }
+ }
+
+ function play() {
+ player.autoPlay = true
+ player.play()
+ }
+
+ function pause() {
+ player.autoPlay = false
+ player.pause()
+ }
+
+ function switchSource(source) {
+ root.pause()
+ if (source === "com.pelagicore.music" || source === "com.pelagicore.tuner") {
+ var request = IntentClient.sendIntentRequest("activate-app", source, {})
+ request.onReplyReceived.connect(function() {
+ if (request.succeeded) {
+ var result = request.result
+ console.log(Logging.apps, "Intent result: " + result.done)
+ } else {
+ console.log(Logging.apps, "Intent request failed: " + request.errorMessage)
+ }
+ })
+ }
+ }
+
+ // A SHOUTcast Radio Directory API is used with the devId
+ function getAllGenres() {
+ root.currentOperationStatus = qsTr("Trying to load genres");
+ var xhr = new XMLHttpRequest;
+ xhr.open("GET", "http://api.shoutcast.com/legacy/genrelist?k=" + d.devID)
+ xhr.responseType = "document";
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState === XMLHttpRequest.DONE) {
+ d.xmlGenresParser.xml = xhr.responseText;
+ }
+ }
+ xhr.send()
+ }
+
+ //http://api.shoutcast.com/legacy/genresearch?k=5ClwKdIfc6j5Nitn&genre=50s
+ //http://api.shoutcast.com/legacy/genresearch?k=[Your Dev ID]&genre=<genre>
+ function getStationsForGenre(genre) {
+ root.currentOperationStatus = qsTr("Trying to load stations for ") + genre;
+ var xhr = new XMLHttpRequest;
+ xhr.open("GET"
+ , "http://api.shoutcast.com/legacy/genresearch?k="
+ + d.devID + "&genre=" + genre.replace("&","%26")
+ );
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState === XMLHttpRequest.DONE) {
+ d.xmlStationsParser.xml = xhr.responseText;
+ }
+ }
+ xhr.send();
+ }
+
+ //http://yp.shoutcast.com/sbin/tunein-station.pls?id=1513982
+ function getSourceForStation(id) {
+ root.currentOperationStatus = qsTr("Trying to get url for the given station");
+ var xhr = new XMLHttpRequest;
+ xhr.open("GET", "http://yp.shoutcast.com/sbin/tunein-station.pls?id=" + id);
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState === XMLHttpRequest.DONE) {
+ root.url = xhr.responseText.match("File1=(.*)")[1];
+ root.currentOperationStatus = "";
+ }
+ }
+ xhr.send();
+ }
+}
diff --git a/com.pelagicore.webradio/views/WebRadioContent.qml b/com.pelagicore.webradio/views/WebRadioContent.qml
new file mode 100644
index 0000000..32661d5
--- /dev/null
+++ b/com.pelagicore.webradio/views/WebRadioContent.qml
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Luxoft Sweden AB
+** Copyright (C) 2014-2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtAuto Extra Apps.
+**
+** $QT_BEGIN_LICENSE:GPL-QTAS$
+** Commercial License Usage
+** Licensees holding valid commercial Qt Automotive Suite licenses may use
+** this file in accordance with the commercial license agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and The Qt Company. For
+** licensing terms and conditions see https://www.qt.io/terms-conditions.
+** For further information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+** SPDX-License-Identifier: GPL-3.0
+**
+****************************************************************************/
+
+import QtQuick 2.2
+
+import shared.controls 1.0
+import shared.Sizes 1.0
+import shared.Style 1.0
+
+import "../stores"
+import "../panels"
+
+Item {
+ id: root
+
+ property RadioStore store
+ property var station: store.station
+ property alias rootItem: selectionScreen.rootItem
+ property bool playerVisible: false
+
+ CurrentStationScreen {
+ id: currentStation
+
+ width: parent.width
+ height: Sizes.dp(560)
+ stationName: root.station && root.station.name ? root.station.name : ""
+ stationImage: root.station && root.station.logo ? root.station.logo : ""
+ bitRate: root.station && root.station.br? root.station.br : ""
+ streamingUrl: root.store.url
+ currentOperationStatus: root.store.currentOperationStatus
+ playing: root.store.playing
+
+ onNextStation: {
+ root.store.next();
+ }
+
+ onPrevStation: {
+ root.store.previous();
+ }
+
+ onPlayStation: root.store.play()
+ onPauseStation: root.store.pause()
+ }
+
+ SelectionScreen {
+ id: selectionScreen
+ width: parent.width
+ height: parent.height - currentStation.height
+ anchors.top: currentStation.bottom
+ store: root.store
+
+ onChosenGenre: {
+ store.getStationsForGenre(genre);
+ }
+ }
+}
diff --git a/qt-auto-extra-apps.pro b/qt-auto-extra-apps.pro
index 37b8856..4ceed54 100644
--- a/qt-auto-extra-apps.pro
+++ b/qt-auto-extra-apps.pro
@@ -3,7 +3,8 @@ SUBDIRS = com.pelagicore.camera \
com.pelagicore.spotify \
com.pelagicore.netflix \
com.luxoft.webbrowser \
- com.luxoft.videoplayer
+ com.luxoft.videoplayer \
+ com.pelagicore.webradio \
# Top-level package target
QMAKE_EXTRA_TARGETS += package