mirror of
https://github.com/HenkKalkwater/harbour-sailfin.git
synced 2024-11-25 10:25:17 +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(PLATFORM_QTQUICK "Build QtQuick version of application")
|
||||
|
||||
if (NOT SAILFIN_VERSION)
|
||||
set(SAILFIN_VERSION "1.0.0")
|
||||
endif()
|
||||
|
||||
if(SAILFISHOS)
|
||||
# Hardcode this less?
|
||||
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["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]() {
|
||||
int status = rep->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
qDebug() << "Got reply with status code " << status;
|
||||
|
@ -202,6 +202,12 @@ void ApiClient::authenticate(QString username, QString password, bool storeCrede
|
|||
if (storeCredentials) {
|
||||
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();
|
||||
});
|
||||
|
|
|
@ -85,7 +85,7 @@ QJsonObject DeviceProfile::generateProfile() {
|
|||
QJsonObject {
|
||||
JsonPair("Property", "IsSecondaryAudio"),
|
||||
JsonPair("Condition", "Equals"),
|
||||
JsonPair("Value", false),
|
||||
JsonPair("Value", "false"),
|
||||
JsonPair("IsRequired", false)
|
||||
}
|
||||
}),
|
||||
|
@ -97,7 +97,7 @@ QJsonObject DeviceProfile::generateProfile() {
|
|||
QJsonObject {
|
||||
JsonPair("Property", "IsAnamorphic"),
|
||||
JsonPair("Condition", "NotEquals"),
|
||||
JsonPair("Value", true),
|
||||
JsonPair("Value", "true"),
|
||||
JsonPair("IsRequired", false)
|
||||
},
|
||||
QJsonObject {
|
||||
|
@ -109,13 +109,13 @@ QJsonObject DeviceProfile::generateProfile() {
|
|||
QJsonObject {
|
||||
JsonPair("Property", "VideoLevel"),
|
||||
JsonPair("Condition", "LessThanEqual"),
|
||||
JsonPair("Value", 51),
|
||||
JsonPair("Value", "51"),
|
||||
JsonPair("IsRequired", false)
|
||||
},
|
||||
QJsonObject {
|
||||
JsonPair("Property", "IsInterlaced"),
|
||||
JsonPair("Condition", "NotEquals"),
|
||||
JsonPair("Value", true),
|
||||
JsonPair("Value", "true"),
|
||||
JsonPair("IsRequired", false)
|
||||
}
|
||||
}),
|
||||
|
@ -130,8 +130,8 @@ QJsonObject DeviceProfile::generateProfile() {
|
|||
transcoding1["BreakOnNonKeyFrames"] =true;
|
||||
transcoding1["Container"] = "ts";
|
||||
transcoding1["Context"] = "Streaming";
|
||||
transcoding1["MaxAudioChannels"] = 2;
|
||||
transcoding1["MinSegments"] = 1;
|
||||
transcoding1["MaxAudioChannels"] = "2";
|
||||
transcoding1["MinSegments"] = "1";
|
||||
transcoding1["Protocol"] = "hls";
|
||||
transcoding1["Type"] = "Audio";
|
||||
transcodingProfiles.append(transcoding1);
|
||||
|
@ -142,7 +142,7 @@ QJsonObject DeviceProfile::generateProfile() {
|
|||
JsonPair("BreakOnNonKeyFrames", true),
|
||||
JsonPair("Container", "ts"),
|
||||
JsonPair("Context", "Streaming"),
|
||||
JsonPair("MaxAudioChannels", 2),
|
||||
JsonPair("MaxAudioChannels", "2"),
|
||||
JsonPair("MinSegments", 1),
|
||||
JsonPair("Protocol", "hls"),
|
||||
JsonPair("Type", "Video"),
|
||||
|
@ -168,8 +168,8 @@ QJsonObject DeviceProfile::generateProfile() {
|
|||
JsonPair("VideoCodec", hlsVideoCodecs.join(",")),
|
||||
JsonPair("Context", "Streaming"),
|
||||
JsonPair("Protocol", "hls"),
|
||||
JsonPair("MaxAudioChannels", 2),
|
||||
JsonPair("MinSegments", 1),
|
||||
JsonPair("MaxAudioChannels", "2"),
|
||||
JsonPair("MinSegments", "1"),
|
||||
JsonPair("BreakOnNonKeyFrames", true)
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,5 +14,7 @@
|
|||
<file>qml/components/+sailfinstyle/Background.qml</file>
|
||||
<file>qml/components/BusyDialog.qml</file>
|
||||
<file>qml/pages/setup/LoginPage.qml</file>
|
||||
<file>qml/pages/MainPage.qml</file>
|
||||
<file>qml/pages/DetailPage.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtGraphicalEffects 1.12
|
||||
import QtQuick.Window 2.12
|
||||
|
||||
import nl.netsoj.chris.Jellyfin 1.0
|
||||
|
@ -31,11 +30,13 @@ ApplicationWindow {
|
|||
}
|
||||
_oldDepth = depth
|
||||
}
|
||||
initialItem: Qt.resolvedUrl("pages/MainPage.qml")
|
||||
Keys.onEscapePressed: pop()
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ApiClient
|
||||
onSetupRequired: pageStack.push(Qt.resolvedUrl("pages/setup/ServerSelectPage.qml"));
|
||||
onSetupRequired: pageStack.replace(Qt.resolvedUrl("pages/setup/ServerSelectPage.qml"));
|
||||
}
|
||||
|
||||
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.Controls 2.12
|
||||
|
||||
import nl.netsoj.chris.Jellyfin 1.0
|
||||
|
||||
import "../../components"
|
||||
import "../../.."
|
||||
|
||||
Page {
|
||||
property string loginMessage
|
||||
property StackView stackView: StackView.view
|
||||
header: ToolBar {
|
||||
Label {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
@ -20,11 +24,27 @@ Page {
|
|||
TextField {
|
||||
id: usernameField
|
||||
width: parent.width
|
||||
placeholderText: qsTr("Username")
|
||||
EnterKey.type: Qt.EnterKeyNext
|
||||
}
|
||||
TextField {
|
||||
id: passwordField
|
||||
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 {
|
||||
width: parent.width
|
||||
|
@ -32,4 +52,29 @@ Page {
|
|||
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