Commit 8fe09b36 authored by Mike Sheldon's avatar Mike Sheldon

Beginnings of a Sailfish client

parent bf0465b1
[Desktop Entry]
Type=Application
X-Nemo-Application-Type=silica-qt5
Name=harbour-librefm
Icon=harbour-librefm
Exec=harbour-librefm
# The name of your app.
# NOTICE: name defined in TARGET has a corresponding QML filename.
# If name defined in TARGET is changed, following needs to be
# done to match new name:
# - corresponding QML filename must be changed
# - desktop icon filename must be changed
# - desktop filename must be changed
# - icon definition filename in desktop file must be changed
TARGET = harbour-librefm
CONFIG += sailfishapp
SOURCES += src/harbour-librefm.cpp \
src/settings.cpp
OTHER_FILES += qml/harbour-librefm.qml \
qml/cover/CoverPage.qml \
rpm/harbour-librefm.spec \
rpm/harbour-librefm.yaml \
harbour-librefm.desktop \
qml/pages/LoginPage.qml \
qml/images/love.png \
qml/images/librefm-tower.png \
qml/images/librefm-logo.png \
qml/images/librefm.svg \
qml/images/empty-album.png
HEADERS += \
src/settings.h
This diff is collapsed.
import QtQuick 2.0
import Sailfish.Silica 1.0
CoverBackground {
CoverActionList {
id: coverAction
CoverAction {
iconSource: "image://theme/icon-cover-next"
}
CoverAction {
iconSource: "image://theme/icon-cover-pause"
}
}
}
import QtQuick 2.0
import Sailfish.Silica 1.0
import "pages"
ApplicationWindow
{
property string wsUrl: "http://libre.fm/2.0/";
property string wsKey: "";
initialPage: LoginPage { }
cover: Qt.resolvedUrl("cover/CoverPage.qml")
Rectangle {
id: errorRect
color: Theme.highlightColor
width: parent.width
height: 32
visible: false
Label {
id: errorBanner
color: "black"
font.pixelSize: 20
anchors.centerIn: parent
text: ""
}
NumberAnimation on opacity {
id: errorRectFadeOut
from: 1
to: 0
duration: 10000
}
}
function request(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = (function(mxhr) {
return function() { if(mxhr.readyState === XMLHttpRequest.DONE) { callback(mxhr); } }
})(xhr);
xhr.open('GET', url, true);
xhr.send('');
}
function showError(e) {
console.log(e.text);
errorBanner.text = e.nodeValue;
errorRect.visible = true;
errorRectFadeOut.stop();
errorRectFadeOut.start();
console.log(e.nodeValue);
}
}
This diff is collapsed.
import QtQuick 2.0
import Sailfish.Silica 1.0
Page {
id: page
property bool loggingIn: false;
Component.onCompleted: {
if(settings.value("user", false) !== false) {
doLogin(settings.value("user"), settings.value("auth"));
}
}
Image {
id: logo
source: "../images/librefm-logo.png"
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 100
}
Column {
id: fields
visible: !loggingIn
spacing: 20
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 10
anchors.rightMargin: 10
anchors.top: logo.bottom
anchors.topMargin: 100
TextField {
id: username
placeholderText: "Username"
width: parent.width
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
Keys.onReturnPressed: {
if (username.text.length > 0 && password.text.length > 0) {
login()
} else {
password.forceActiveFocus()
}
}
}
TextField {
id: password
placeholderText: "Password"
echoMode: TextInput.Password
width: parent.width
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
Keys.onReturnPressed: {
if (username.text.length > 0 && password.text.length > 0) {
login()
} else {
username.forceActiveFocus()
}
}
}
Item {
height: 10
width: 1
}
Button {
id: button
text: "Log in"
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 10
anchors.rightMargin: 10
enabled: username.text.length > 0 && password.text.length > 0
onClicked: {
login()
}
}
Item {
height: 20
width: 1
}
Label {
width: parent.width
wrapMode: Text.WordWrap
font.pixelSize: 20
onLinkActivated: Qt.openUrlExternally(link)
horizontalAlignment: Text.AlignHCenter
textFormat: Text.RichText
text: "<style>a:link { color: " + Theme.highlightColor
+ "; }</style>Don't have a Libre.fm account?<br><a href='http://libre.fm'>Register for free</a>."
}
}
function doLogin(user, auth) {
loggingIn = true;
request(wsUrl + "?method=auth.getmobilesession&username=" + user + "&authToken=" + auth, function (doc) {
loggingIn = false;
console.log(doc.responseText)
var e = doc.responseXML.documentElement;
for(var i = 0; i < e.childNodes.length; i++) {
console.log(e.childNodes[i]);
if(e.childNodes[i].nodeName === "error") {
showError(e.childNodes[i]);
}
if(e.childNodes[i].nodeName === "key") {
settings.setValue("username", user);
settings.setValue("authToken", auth);
wsKey = e.childNodes[i].nodeValue;
}
}
})
password.text = ""
}
function login() {
var authToken = Qt.md5(username.text.toLowerCase() + Qt.md5(password.text))
doLogin(username.text, authToken)
}
Column {
anchors.centerIn: parent
anchors.verticalCenterOffset: 20
visible: loggingIn
spacing: 20
Label {
id: loggingText
anchors.horizontalCenter: parent.horizontalCenter
text: "Logging in"
}
BusyIndicator {
anchors.horizontalCenter: parent.horizontalCenter
running: parent.visible
}
}
}
Name: harbour-librefm
Summary: Libre.fm Radio
Version: 1.0
Release: 1
Group: Qt/Qt
URL: http://example.org/
License: LICENSE
Sources:
- '%{name}-%{version}.tar.bz2'
Description: |
Short description of my SailfishOS Application
Configure: none
Builder: qtc5
PkgConfigBR:
- Qt5Quick
- Qt5Qml
- Qt5Core
- sailfishapp >= 0.0.10
Requires:
- sailfishsilica-qt5 >= 0.10.9
Files:
- '%{_bindir}'
- '%{_datadir}/%{name}/qml'
- '%{_datadir}/applications/%{name}.desktop'
- '%{_datadir}/icons/hicolor/86x86/apps/%{name}.png'
- /usr/bin
- /usr/share/harbour-librefm
- /usr/share/applications
- /usr/share/icons/hicolor/86x86/apps
#include <sailfishapp.h>
#include <QSettings>
#include <QQuickWindow>
#include <QGuiApplication>
#include <QQuickView>
#include <QQmlContext>
#include <QDebug>
#include "settings.h"
int main(int argc, char *argv[])
{
QSettings::setPath(QSettings::NativeFormat, QSettings::UserScope, "/home/nemo/.local/share/harbour-librefm/");
Settings settings;
QGuiApplication *app = SailfishApp::application(argc, argv);
QQuickWindow::setDefaultAlphaBuffer(true);
QQuickView *view = SailfishApp::createView();
view->rootContext()->setContextProperty("settings", &settings);
view->setSource(QUrl("/usr/share/harbour-librefm/qml/harbour-librefm.qml"));
view->setResizeMode(QQuickView::SizeRootObjectToView);
view->show();
return app->exec();
}
#include "settings.h"
#include <QSettings>
#include <QDebug>
#include <QGuiApplication>
Settings::Settings(QObject *parent)
: QObject(parent)
{
}
Settings::Settings(const Settings &settings)
: QObject(0)
{
Q_UNUSED(settings)
}
void Settings::setValue(const QString &setting, const QVariant &value)
{
settings.setValue(setting, value);
emit valueChanged(setting, value);
}
QVariant Settings::value(const QString &setting, const QVariant &defaultValue)
{
return settings.value(setting, defaultValue);
}
QVariant Settings::value(const QString &setting)
{
return settings.value(setting);
}
bool Settings::remove(const QString &setting)
{
if (!settings.contains(setting)) {
return false;
}
settings.remove(setting);
return true;
}
void Settings::clear()
{
settings.clear();
}
#ifndef SETTINGS_H
#define SETTINGS_H
#include <QObject>
#include <QVariant>
#include <QSettings>
class Settings : public QObject
{
Q_OBJECT
public:
explicit Settings(QObject *parent = 0);
explicit Settings(const Settings &settings);
public slots:
void setValue(const QString &setting, const QVariant &value);
QVariant value(const QString &setting, const QVariant &defaultValue);
QVariant value(const QString &setting);
bool remove(const QString &setting);
void clear();
private:
QSettings settings;
signals:
void valueChanged(const QString &setting, const QVariant &value);
};
#endif // SETTINGS_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment