diff --git a/Main.qml b/Main.qml index 1e3da00..5c338b9 100755 --- a/Main.qml +++ b/Main.qml @@ -11,87 +11,87 @@ ApplicationWindow { height: 800 title: qsTr("QYouVideo") - ColumnLayout { - anchors.fill: parent + flags: Qt.Dialog + modality: Qt.ApplicationModal - Rectangle { - Layout.fillWidth: true - height: 43 + header: Rectangle { + Layout.fillWidth: true + height: 43 - color: Colors.surface0 + color: Colors.surface0 - RowLayout { - anchors.fill: parent - anchors.margins: 3 + RowLayout { + anchors.fill: parent + anchors.margins: 3 - Label { - Layout.leftMargin: 5 - text: "QYouVideo" - heading: "h1" - } + Label { + Layout.leftMargin: 5 + text: "QYouVideo" + heading: "h1" + } - Item { - Layout.fillWidth: true - } + Button { + visible: stack.currentItem.StackView.index > 0 + text: "Back" + onClicked: stack.popCurrentItem() + } - TabBar { - id: tabbar - spacing: 10 + Label { + heading: "h2" + text: stack.currentItem.StackView.index + } - background: Item{} + Label { + heading: "h2" + text: stack.depth + } - TabButton { - text: qsTr("Videos") - outlined: true - implicitWidth: 80 - } - TabButton { - text: qsTr("About") - outlined: true - implicitWidth: 80 - } - TabButton { - text: qsTr("Upload") - } - } + Item { + Layout.fillWidth: true + } + + Button { + text: qsTr("Videos") + outlined: true + implicitWidth: 80 + onClicked: if (stack.currentItem.StackView.index > 0) stack.push(stackVideoList) + } + Button { + text: qsTr("About") + outlined: true + implicitWidth: 80 + } + Button { + text: qsTr("Upload") } } + } - SwipeView { - Layout.fillWidth: true - Layout.fillHeight: true - Layout.margins: 20 + StackView { + id: stack - interactive: false - currentIndex: tabbar.currentIndex + anchors.fill: parent + anchors.margins: 20 - Loader { - // active: tabbar.currentIndex == 0 - active: true - asynchronous: true - visible: status == Loader.Ready - source: "ViewVideoList.qml" - } - Loader { - // active: tabbar.currentIndex == 1 - active: true - asynchronous: true - visible: status == Loader.Ready - source: "ViewAbout.qml" - } - Loader { - // active: tabbar.currentIndex == 2 - active: true - asynchronous: true - visible: status == Loader.Ready - sourceComponent: Label { - heading: "h1" - text: "No idea if I'll ever implement this so don't worry >w<" - font.bold: true - } - } + initialItem: ViewVideoList { + id: stackVideoList + } - Component.onCompleted: contentItem.highlightMoveDuration = 160; + function openVideo(id) { + // if (stack.find((item, index) => { + // // If found player instance + // if (item.id == id) { + // // stack.pop(index, StackView.Immediate); + // stack.push(item) + // return true; + // } + // return false; + // }) == null) { + // If didn't find player instance + const component = Qt.createComponent("VideoPlayer.qml"); + const item = component.createObject(stack, {id: id}) + stack.push(item); + // } } } } diff --git a/VideoEntry.qml b/VideoEntry.qml index 0577bfb..5beb162 100644 --- a/VideoEntry.qml +++ b/VideoEntry.qml @@ -75,6 +75,6 @@ Rectangle { anchors.fill: parent id: area hoverEnabled: true - onClicked: Player.loadVideo(parent.id) + onClicked: stack.openVideo(parent.id) } } diff --git a/VideoPlayer.qml b/VideoPlayer.qml index 688f219..074b97d 100644 --- a/VideoPlayer.qml +++ b/VideoPlayer.qml @@ -5,36 +5,34 @@ import QtQuick.Layouts 6.8 import QYRComponents 1.0 -Rectangle { - visible: Player.active - color: Colors.surface1 - radius: 10 +Item { + // color: Colors.surface1 + // radius: 10 - property bool unrolled: true + required property string id + property bool hasThumbnail: false + property bool loading: true + property bool failed: false + property string title + property string description + property string extension + property real position: 0 + property real duration: 0 + property real ratio - // width: childrenRect.width - height: unrolled ? 560 : 96 - - MouseArea { - anchors.fill: parent - height: 20 - hoverEnabled: true - propagateComposedEvents: true - - onClicked: unrolled = true; - onContainsMouseChanged: function() { - if (!containsMouse) { - unrolled = false; - } - } - } + anchors.fill: parent ColumnLayout { + visible: !loading && !failed anchors.fill: parent - Item { - visible: unrolled - Layout.fillHeight: true + Image { + Layout.fillWidth: true + height: width * parent.parent.ratio + asynchronous: true + cache: true + source: parent.parent.hasThumbnail ? ("https://youvideo.nonamesoft.xyz/thumbnails/" + parent.parent.id) : "https://youvideo.nonamesoft.xyz/thumbnails/audio.png" + fillMode: Image.PreserveAspectFit } RowLayout { @@ -64,15 +62,15 @@ Rectangle { Slider { Layout.fillWidth: true from: 0 - to: Player.duration - value: Player.position + to: parent.parent.parent.duration + value: parent.parent.parent.position buffered: Player.buffered onMoved: Player.position = value } Label { heading: "h4" - text: new Date(Player.duration).toISOString().slice(14, 19) + text: new Date(parent.parent.parent.duration).toISOString().slice(14, 19) } Label { @@ -91,19 +89,92 @@ Rectangle { Layout.fillWidth: true wrapMode: Text.WordWrap clip: true - text: Player.title + text: parent.parent.title heading: "h2" font.bold: true } Label { - visible: unrolled Layout.fillWidth: true wrapMode: Text.WordWrap clip: true - text: Player.description + text: parent.parent.description heading: "h4" font.bold: true } + + Item { + Layout.fillHeight: true + } + } + + BusyIndicator { + anchors.centerIn: parent + visible: loading + running: loading + } + + ColumnLayout { + Layout.alignment: Qt.AlignVCenter + anchors.centerIn: parent + visible: failed + + Label { + text: "Couldn't get video details!" + heading: "h2" + font.bold: true + } + + Label { + text: "This could mean that either your internet or YouVideo is down." + heading: "h4" + } + + Label { + Layout.bottomMargin: 25 + text: "Check your network connection and try again!" + heading: "h4" + } + + Button { + text: "Retry" + onClicked: parent.fetchData() + } + } + + Timer { + interval: 1000 + running: true + onTriggered: parent.fetchData() + } + + function fetchData() { + loading = true; + failed = false; + const xhr = new XMLHttpRequest; + xhr.open("GET", "https://youvideo.nonamesoft.xyz/youvideo/video/" + id); + xhr.onreadystatechange = function() { + if (xhr.readyState == XMLHttpRequest.DONE) { + loading = false; + if (xhr.status != 200) { + console.log("Invalid response"); + failed = true; + return; + } + const data = JSON.parse(xhr.responseText); + console.log("Received video metadata"); + title = data.name; + description = data.description; + extension = data.extension; + ratio = data.metadata.size[0] / data.metadata.size[1]; + console.log(ratio); + } + } + xhr.ontimeout = function() { + loading = false; + failed = true; + console.log("Request timed out"); + } + xhr.send(); } } diff --git a/ViewVideoList.qml b/ViewVideoList.qml index fcd7f0e..49f7b7d 100644 --- a/ViewVideoList.qml +++ b/ViewVideoList.qml @@ -7,14 +7,14 @@ import QYRComponents 1.0 Item { anchors.fill: parent - property bool loading: true property bool failed: false GridView { + width: Math.floor(cellWidth / parent.width) * cellWidth anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top - anchors.topMargin: Player.active ? 96 : 0 + // anchors.topMargin: Player.active ? 96 : 0 visible: !loading || !failed anchors.fill: parent model: ListModel { id: model } @@ -24,6 +24,8 @@ Item { cellHeight: 224 delegate: VideoEntry {} + + Component.onCompleted: console.log(cellWidth / parent.width) } BusyIndicator { @@ -71,7 +73,7 @@ Item { loading = true; failed = false; const xhr = new XMLHttpRequest; - xhr.open("GET", "http://youvideo.nonamesoft.xyz/youvideo/api/videos"); + xhr.open("GET", "https://youvideo.nonamesoft.xyz/youvideo/api/videos"); xhr.onreadystatechange = function() { if (xhr.readyState == XMLHttpRequest.DONE) { loading = false; @@ -94,11 +96,4 @@ Item { } xhr.send(); } - - VideoPlayer { - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - Layout.fillWidth: true - } }