mirror of
https://github.com/HenkKalkwater/harbour-sailfin.git
synced 2024-11-22 09:15:18 +00:00
Update UI to bare minimum to allow for core lib testing
This commit is contained in:
parent
56d7c1486e
commit
3cd1fd3e23
|
@ -9,6 +9,10 @@ cmake_policy(SET CMP0048 NEW)
|
||||||
option(SAILFISHOS "Build SailfishOS version of application")
|
option(SAILFISHOS "Build SailfishOS version of application")
|
||||||
option(PLATFORM_QTQUICK "Build QtQuick version of application")
|
option(PLATFORM_QTQUICK "Build QtQuick version of application")
|
||||||
|
|
||||||
|
if (NOT SAILFIN_VERSION)
|
||||||
|
set(SAILFIN_VERSION "1.0.0")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(SAILFISHOS)
|
if(SAILFISHOS)
|
||||||
# Hardcode this less?
|
# Hardcode this less?
|
||||||
set(CMAKE_INSTALL_LIBDIR "${CMAKE_INSTALL_PREFIX}/share/harbour-sailfin/lib")
|
set(CMAKE_INSTALL_LIBDIR "${CMAKE_INSTALL_PREFIX}/share/harbour-sailfin/lib")
|
||||||
|
|
|
@ -184,7 +184,7 @@ void ApiClient::authenticate(QString username, QString password, bool storeCrede
|
||||||
|
|
||||||
requestData["Username"] = username;
|
requestData["Username"] = username;
|
||||||
requestData["Pw"] = password;
|
requestData["Pw"] = password;
|
||||||
QNetworkReply *rep = post("/Users/Authenticatebyname", QJsonDocument(requestData));
|
QNetworkReply *rep = post("/Users/authenticatebyname", QJsonDocument(requestData));
|
||||||
connect(rep, &QNetworkReply::finished, this, [rep, username, storeCredentials, this]() {
|
connect(rep, &QNetworkReply::finished, this, [rep, username, storeCredentials, this]() {
|
||||||
int status = rep->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
int status = rep->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
qDebug() << "Got reply with status code " << status;
|
qDebug() << "Got reply with status code " << status;
|
||||||
|
@ -202,6 +202,12 @@ void ApiClient::authenticate(QString username, QString password, bool storeCrede
|
||||||
if (storeCredentials) {
|
if (storeCredentials) {
|
||||||
m_credManager->store(this->m_baseUrl, this->m_userId, this->m_token);
|
m_credManager->store(this->m_baseUrl, this->m_userId, this->m_token);
|
||||||
}
|
}
|
||||||
|
} else if(status >= 400 && status < 500) {
|
||||||
|
if (status == 401) {
|
||||||
|
emit authenticationError(ApiError::INVALID_PASSWORD);
|
||||||
|
} else {
|
||||||
|
emit authenticationError(ApiError::UNEXPECTED_STATUS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rep->deleteLater();
|
rep->deleteLater();
|
||||||
});
|
});
|
||||||
|
|
|
@ -85,7 +85,7 @@ QJsonObject DeviceProfile::generateProfile() {
|
||||||
QJsonObject {
|
QJsonObject {
|
||||||
JsonPair("Property", "IsSecondaryAudio"),
|
JsonPair("Property", "IsSecondaryAudio"),
|
||||||
JsonPair("Condition", "Equals"),
|
JsonPair("Condition", "Equals"),
|
||||||
JsonPair("Value", false),
|
JsonPair("Value", "false"),
|
||||||
JsonPair("IsRequired", false)
|
JsonPair("IsRequired", false)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -97,7 +97,7 @@ QJsonObject DeviceProfile::generateProfile() {
|
||||||
QJsonObject {
|
QJsonObject {
|
||||||
JsonPair("Property", "IsAnamorphic"),
|
JsonPair("Property", "IsAnamorphic"),
|
||||||
JsonPair("Condition", "NotEquals"),
|
JsonPair("Condition", "NotEquals"),
|
||||||
JsonPair("Value", true),
|
JsonPair("Value", "true"),
|
||||||
JsonPair("IsRequired", false)
|
JsonPair("IsRequired", false)
|
||||||
},
|
},
|
||||||
QJsonObject {
|
QJsonObject {
|
||||||
|
@ -109,13 +109,13 @@ QJsonObject DeviceProfile::generateProfile() {
|
||||||
QJsonObject {
|
QJsonObject {
|
||||||
JsonPair("Property", "VideoLevel"),
|
JsonPair("Property", "VideoLevel"),
|
||||||
JsonPair("Condition", "LessThanEqual"),
|
JsonPair("Condition", "LessThanEqual"),
|
||||||
JsonPair("Value", 51),
|
JsonPair("Value", "51"),
|
||||||
JsonPair("IsRequired", false)
|
JsonPair("IsRequired", false)
|
||||||
},
|
},
|
||||||
QJsonObject {
|
QJsonObject {
|
||||||
JsonPair("Property", "IsInterlaced"),
|
JsonPair("Property", "IsInterlaced"),
|
||||||
JsonPair("Condition", "NotEquals"),
|
JsonPair("Condition", "NotEquals"),
|
||||||
JsonPair("Value", true),
|
JsonPair("Value", "true"),
|
||||||
JsonPair("IsRequired", false)
|
JsonPair("IsRequired", false)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -130,8 +130,8 @@ QJsonObject DeviceProfile::generateProfile() {
|
||||||
transcoding1["BreakOnNonKeyFrames"] =true;
|
transcoding1["BreakOnNonKeyFrames"] =true;
|
||||||
transcoding1["Container"] = "ts";
|
transcoding1["Container"] = "ts";
|
||||||
transcoding1["Context"] = "Streaming";
|
transcoding1["Context"] = "Streaming";
|
||||||
transcoding1["MaxAudioChannels"] = 2;
|
transcoding1["MaxAudioChannels"] = "2";
|
||||||
transcoding1["MinSegments"] = 1;
|
transcoding1["MinSegments"] = "1";
|
||||||
transcoding1["Protocol"] = "hls";
|
transcoding1["Protocol"] = "hls";
|
||||||
transcoding1["Type"] = "Audio";
|
transcoding1["Type"] = "Audio";
|
||||||
transcodingProfiles.append(transcoding1);
|
transcodingProfiles.append(transcoding1);
|
||||||
|
@ -142,7 +142,7 @@ QJsonObject DeviceProfile::generateProfile() {
|
||||||
JsonPair("BreakOnNonKeyFrames", true),
|
JsonPair("BreakOnNonKeyFrames", true),
|
||||||
JsonPair("Container", "ts"),
|
JsonPair("Container", "ts"),
|
||||||
JsonPair("Context", "Streaming"),
|
JsonPair("Context", "Streaming"),
|
||||||
JsonPair("MaxAudioChannels", 2),
|
JsonPair("MaxAudioChannels", "2"),
|
||||||
JsonPair("MinSegments", 1),
|
JsonPair("MinSegments", 1),
|
||||||
JsonPair("Protocol", "hls"),
|
JsonPair("Protocol", "hls"),
|
||||||
JsonPair("Type", "Video"),
|
JsonPair("Type", "Video"),
|
||||||
|
@ -168,8 +168,8 @@ QJsonObject DeviceProfile::generateProfile() {
|
||||||
JsonPair("VideoCodec", hlsVideoCodecs.join(",")),
|
JsonPair("VideoCodec", hlsVideoCodecs.join(",")),
|
||||||
JsonPair("Context", "Streaming"),
|
JsonPair("Context", "Streaming"),
|
||||||
JsonPair("Protocol", "hls"),
|
JsonPair("Protocol", "hls"),
|
||||||
JsonPair("MaxAudioChannels", 2),
|
JsonPair("MaxAudioChannels", "2"),
|
||||||
JsonPair("MinSegments", 1),
|
JsonPair("MinSegments", "1"),
|
||||||
JsonPair("BreakOnNonKeyFrames", true)
|
JsonPair("BreakOnNonKeyFrames", true)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,5 +14,7 @@
|
||||||
<file>qml/components/+sailfinstyle/Background.qml</file>
|
<file>qml/components/+sailfinstyle/Background.qml</file>
|
||||||
<file>qml/components/BusyDialog.qml</file>
|
<file>qml/components/BusyDialog.qml</file>
|
||||||
<file>qml/pages/setup/LoginPage.qml</file>
|
<file>qml/pages/setup/LoginPage.qml</file>
|
||||||
|
<file>qml/pages/MainPage.qml</file>
|
||||||
|
<file>qml/pages/DetailPage.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import QtQuick 2.12
|
import QtQuick 2.12
|
||||||
import QtQuick.Controls 2.12
|
import QtQuick.Controls 2.12
|
||||||
import QtGraphicalEffects 1.12
|
|
||||||
import QtQuick.Window 2.12
|
import QtQuick.Window 2.12
|
||||||
|
|
||||||
import nl.netsoj.chris.Jellyfin 1.0
|
import nl.netsoj.chris.Jellyfin 1.0
|
||||||
|
@ -31,11 +30,13 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
_oldDepth = depth
|
_oldDepth = depth
|
||||||
}
|
}
|
||||||
|
initialItem: Qt.resolvedUrl("pages/MainPage.qml")
|
||||||
|
Keys.onEscapePressed: pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: ApiClient
|
target: ApiClient
|
||||||
onSetupRequired: pageStack.push(Qt.resolvedUrl("pages/setup/ServerSelectPage.qml"));
|
onSetupRequired: pageStack.replace(Qt.resolvedUrl("pages/setup/ServerSelectPage.qml"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
|
37
qtquick/qml/pages/DetailPage.qml
Normal file
37
qtquick/qml/pages/DetailPage.qml
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Window 2.12
|
||||||
|
|
||||||
|
import nl.netsoj.chris.Jellyfin 1.0
|
||||||
|
|
||||||
|
import "../components"
|
||||||
|
import "../.."
|
||||||
|
|
||||||
|
Page {
|
||||||
|
property bool _modelsLoaded: false
|
||||||
|
property StackView stackView: StackView.view
|
||||||
|
property string itemId
|
||||||
|
property alias jellyfinItem: jellyfinItem
|
||||||
|
header: ToolBar {
|
||||||
|
Label {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
font.pixelSize: SailfinStyle.fontSizeLarge
|
||||||
|
text: jellyfinItem.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: stackView.pop()
|
||||||
|
}
|
||||||
|
JellyfinItem {
|
||||||
|
id: jellyfinItem
|
||||||
|
jellyfinId: itemId
|
||||||
|
apiClient: ApiClient
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
source: ApiClient.baseUrl + "/Items/" + itemId + "/Images/Primary?tag=" + jellyfinItem.tag
|
||||||
|
}
|
||||||
|
}
|
99
qtquick/qml/pages/MainPage.qml
Normal file
99
qtquick/qml/pages/MainPage.qml
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Window 2.12
|
||||||
|
|
||||||
|
import nl.netsoj.chris.Jellyfin 1.0
|
||||||
|
|
||||||
|
import "../components"
|
||||||
|
import "../.."
|
||||||
|
|
||||||
|
Page {
|
||||||
|
property bool _modelsLoaded: false
|
||||||
|
property StackView stackView: StackView.view
|
||||||
|
header: ToolBar {
|
||||||
|
Label {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
font.pixelSize: SailfinStyle.fontSizeLarge
|
||||||
|
text: qsTr("Main page")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UserViewModel {
|
||||||
|
id: mediaLibraryModel
|
||||||
|
apiClient: ApiClient
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
anchors.fill: parent
|
||||||
|
contentHeight: content.height
|
||||||
|
Column {
|
||||||
|
id: content
|
||||||
|
width: parent.width
|
||||||
|
Repeater {
|
||||||
|
model: mediaLibraryModel
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
UserItemLatestModel {
|
||||||
|
id: userItemModel
|
||||||
|
apiClient: ApiClient
|
||||||
|
parentId: model.id
|
||||||
|
limit: 16
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: model.name
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
width: parent.width
|
||||||
|
height: SailfinStyle.unit * 20
|
||||||
|
orientation: ListView.Horizontal
|
||||||
|
model: userItemModel
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
width: 12 * SailfinStyle.unit
|
||||||
|
height: 20 * SailfinStyle.unit
|
||||||
|
Image {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: ApiClient.baseUrl + "/Items/" + model.id + "/Images/Primary?tag=" + model.tag
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
text: model.name
|
||||||
|
}
|
||||||
|
onClicked: stackView.push(Qt.resolvedUrl("DetailPage.qml"), {"itemId": model.id})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: mediaLibraryModel
|
||||||
|
onStatusChanged: {
|
||||||
|
if (mediaLibraryModel.status == UserItemModel.Ready) {
|
||||||
|
userItemModel.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads models if not laoded. Set force to true to reload models
|
||||||
|
* even if loaded.
|
||||||
|
*/
|
||||||
|
function loadModels(force) {
|
||||||
|
if (force || (ApiClient.authenticated && !_modelsLoaded)) {
|
||||||
|
_modelsLoaded = true;
|
||||||
|
mediaLibraryModel.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ApiClient
|
||||||
|
onAuthenticatedChanged: {
|
||||||
|
if (authenticated) {
|
||||||
|
loadModels(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,14 @@
|
||||||
import QtQuick 2.12
|
import QtQuick 2.12
|
||||||
import QtQuick.Controls 2.12
|
import QtQuick.Controls 2.12
|
||||||
|
|
||||||
|
import nl.netsoj.chris.Jellyfin 1.0
|
||||||
|
|
||||||
|
import "../../components"
|
||||||
import "../../.."
|
import "../../.."
|
||||||
|
|
||||||
Page {
|
Page {
|
||||||
property string loginMessage
|
property string loginMessage
|
||||||
|
property StackView stackView: StackView.view
|
||||||
header: ToolBar {
|
header: ToolBar {
|
||||||
Label {
|
Label {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
@ -20,11 +24,27 @@ Page {
|
||||||
TextField {
|
TextField {
|
||||||
id: usernameField
|
id: usernameField
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
placeholderText: qsTr("Username")
|
||||||
EnterKey.type: Qt.EnterKeyNext
|
EnterKey.type: Qt.EnterKeyNext
|
||||||
}
|
}
|
||||||
TextField {
|
TextField {
|
||||||
id: passwordField
|
id: passwordField
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
placeholderText: qsTr("Password")
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: loginError
|
||||||
|
width: parent.width
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
text: qsTr("Invalid username/password")
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: qsTr("Login")
|
||||||
|
onClicked: login()
|
||||||
}
|
}
|
||||||
Label {
|
Label {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
@ -32,4 +52,29 @@ Page {
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BusyDialog {
|
||||||
|
id: busyDialog
|
||||||
|
anchors.centerIn: Overlay.overlay
|
||||||
|
title: qsTr("Logging in as %1").arg(usernameField.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
function login() {
|
||||||
|
busyDialog.open()
|
||||||
|
ApiClient.authenticate(usernameField.text, passwordField.text, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ApiClient
|
||||||
|
onAuthenticatedChanged: {
|
||||||
|
busyDialog.close()
|
||||||
|
if (authenticated) {
|
||||||
|
stackView.replace(null, Qt.resolvedUrl("../MainPage.qml"), {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onAuthenticationError: {
|
||||||
|
busyDialog.close()
|
||||||
|
loginError.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue