diff --git a/harbour-tooter.desktop b/harbour-tooter.desktop
index 0488e61..213b20f 100644
--- a/harbour-tooter.desktop
+++ b/harbour-tooter.desktop
@@ -4,8 +4,3 @@ X-Nemo-Application-Type=silica-qt5
Icon=harbour-tooter
Exec=harbour-tooter
Name=Tooter
-# translation example:
-# your app name in German locale (de)
-#
-# Remember to comment out the following line, if you do not want to use
-# a different app name in German locale (de).
diff --git a/harbour-tooter.pro b/harbour-tooter.pro
index 6a1b13c..bd4e9d9 100644
--- a/harbour-tooter.pro
+++ b/harbour-tooter.pro
@@ -1,116 +1,116 @@
-# NOTICE:
-#
-# Application name defined in TARGET has a corresponding QML filename.
-# If name defined in TARGET is changed, the 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
-# - translation filenames have to be changed
-
-# The name of your application
-TARGET = harbour-tooter
-
-CONFIG += sailfishapp
-
-QT += network dbus sql
-CONFIG += link_pkgconfig
-PKGCONFIG += sailfishapp
-PKGCONFIG += \
- nemonotifications-qt5
-
-DEFINES += "APPVERSION=\\\"$${SPECVERSION}\\\""
-DEFINES += "APPNAME=\\\"$${TARGET}\\\""
-
-!exists( src/dbusAdaptor.h ) {
- system(qdbusxml2cpp config/ba.dysko.harbour.tooter.xml -i dbus.h -a src/dbusAdaptor)
-}
-
-config.path = /usr/share/$${TARGET}/config/
-config.files = config/icon-lock-harbour-tooter.png
-
-notification_categories.path = /usr/share/lipstick/notificationcategories
-notification_categories.files = config/x-harbour.tooter.activity.*
-
-dbus_services.path = /usr/share/dbus-1/services/
-dbus_services.files = config/ba.dysko.harbour.tooter.service
-
-interfaces.path = /usr/share/dbus-1/interfaces/
-interfaces.files = config/ba.dysko.harbour.tooter.xml
-
-SOURCES += src/harbour-tooter.cpp
-SOURCES += src/imageuploader.cpp
-SOURCES += src/filedownloader.cpp
-SOURCES += src/notifications.cpp
-SOURCES += src/dbusAdaptor.cpp
-SOURCES += src/dbus.cpp
-
-HEADERS += src/imageuploader.h
-HEADERS += src/filedownloader.h
-HEADERS += src/notifications.h
-HEADERS += src/dbusAdaptor.h
-HEADERS += src/dbus.h
-
-DISTFILES += qml/harbour-tooter.qml \
- qml/pages/components/VisualContainer.qml \
- qml/pages/components/MiniStatus.qml \
- qml/pages/components/MiniHeader.qml \
- qml/pages/components/ItemUser.qml \
- qml/pages/components/MyList.qml \
- qml/pages/components/Navigation.qml \
- qml/pages/components/ProfileHeader.qml \
- qml/pages/components/MediaBlock.qml \
- qml/pages/components/MyImage.qml \
- qml/pages/components/ImageFullScreen.qml \
- qml/cover/CoverPage.qml \
- qml/pages/MainPage.qml \
- qml/pages/LoginPage.qml \
- qml/pages/Conversation.qml \
- qml/pages/components/Toot.qml \
- qml/pages/Browser.qml \
- qml/pages/Profile.qml \
- qml/pages/Settings.qml \
- qml/lib/API.js \
- qml/images/notification.svg \
- qml/images/verified.svg \
- qml/images/boosted.svg \
- qml/images/tooter.svg \
- qml/images/emojiselect.svg \
- qml/images/icon-m-profile.svg \
- qml/images/icon-l-profile.svg \
- qml/lib/Mastodon.js \
- qml/lib/Worker.js \
- config/icon-lock-harbour-tooter.png \
- config/x-harbour.tooter.activity.conf \
- rpm/harbour-tooter.changes \
- rpm/harbour-tooter.changes.run.in \
- rpm/harbour-tooter.spec \
- rpm/harbour-tooter.yaml \
- translations/*.ts \
- harbour-tooter.desktop
-
-SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
-
-# to disable building translations every time, comment out the
-# following CONFIG line
-CONFIG += sailfishapp_i18n
-
-# German translation is enabled as an example. If you aren't
-# planning to localize your app, remember to comment out the
-# following TRANSLATIONS line. And also do not forget to
-# modify the localized app name in the the .desktop file.
-TRANSLATIONS += translations/harbour-tooter-de.ts
-TRANSLATIONS += translations/harbour-tooter-el.ts
-TRANSLATIONS += translations/harbour-tooter-es.ts
-TRANSLATIONS += translations/harbour-tooter-fi.ts
-TRANSLATIONS += translations/harbour-tooter-fr.ts
-TRANSLATIONS += translations/harbour-tooter-nl.ts
-TRANSLATIONS += translations/harbour-tooter-nl_BE.ts
-TRANSLATIONS += translations/harbour-tooter-oc.ts
-TRANSLATIONS += translations/harbour-tooter-pl.ts
-TRANSLATIONS += translations/harbour-tooter-ru.ts
-TRANSLATIONS += translations/harbour-tooter-sr.ts
-TRANSLATIONS += translations/harbour-tooter-sv.ts
-TRANSLATIONS += translations/harbour-tooter-zh_CN.ts
-TRANSLATIONS += translations/harbour-tooter-it.ts
+# NOTICE:
+#
+# Application name defined in TARGET has a corresponding QML filename.
+# If name defined in TARGET is changed, the 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
+# - translation filenames have to be changed
+
+# The name of your application
+TARGET = harbour-tooter
+
+CONFIG += sailfishapp
+
+QT += network dbus sql
+CONFIG += link_pkgconfig
+PKGCONFIG += sailfishapp
+PKGCONFIG += \
+ nemonotifications-qt5
+
+DEFINES += "APPVERSION=\\\"$${SPECVERSION}\\\""
+DEFINES += "APPNAME=\\\"$${TARGET}\\\""
+
+!exists( src/dbusAdaptor.h ) {
+ system(qdbusxml2cpp config/ba.dysko.harbour.tooter.xml -i dbus.h -a src/dbusAdaptor)
+}
+
+config.path = /usr/share/$${TARGET}/config/
+config.files = config/icon-lock-harbour-tooter.png
+
+notification_categories.path = /usr/share/lipstick/notificationcategories
+notification_categories.files = config/x-harbour.tooter.activity.*
+
+dbus_services.path = /usr/share/dbus-1/services/
+dbus_services.files = config/ba.dysko.harbour.tooter.service
+
+interfaces.path = /usr/share/dbus-1/interfaces/
+interfaces.files = config/ba.dysko.harbour.tooter.xml
+
+SOURCES += src/harbour-tooter.cpp
+SOURCES += src/imageuploader.cpp
+SOURCES += src/filedownloader.cpp
+SOURCES += src/notifications.cpp
+SOURCES += src/dbusAdaptor.cpp
+SOURCES += src/dbus.cpp
+
+HEADERS += src/imageuploader.h
+HEADERS += src/filedownloader.h
+HEADERS += src/notifications.h
+HEADERS += src/dbusAdaptor.h
+HEADERS += src/dbus.h
+
+DISTFILES += qml/harbour-tooter.qml \
+ qml/images/tooter-cover.svg \
+ qml/pages/ConversationPage.qml \
+ qml/pages/ProfilePage.qml \
+ qml/pages/SettingsPage.qml \
+ qml/pages/components/InfoBanner.qml \
+ qml/pages/components/MediaFullScreen.qml \
+ qml/pages/components/ProfileImage.qml \
+ qml/pages/components/VisualContainer.qml \
+ qml/pages/components/MiniStatus.qml \
+ qml/pages/components/MiniHeader.qml \
+ qml/pages/components/ItemUser.qml \
+ qml/pages/components/MyList.qml \
+ qml/pages/components/Navigation.qml \
+ qml/pages/components/ProfileHeader.qml \
+ qml/pages/components/MediaBlock.qml \
+ qml/pages/components/MyImage.qml \
+ qml/cover/CoverPage.qml \
+ qml/pages/MainPage.qml \
+ qml/pages/LoginPage.qml \
+ qml/pages/components/Toot.qml \
+ qml/pages/Browser.qml \
+ qml/lib/API.js \
+ qml/images/icon-s-following \
+ qml/images/icon-m-emoji.svg \
+ qml/images/icon-m-profile.svg \
+ qml/images/icon-l-profile.svg \
+ qml/lib/Mastodon.js \
+ qml/lib/Worker.js \
+ config/icon-lock-harbour-tooter.png \
+ config/x-harbour.tooter.activity.conf \
+ rpm/harbour-tooter.changes \
+ rpm/harbour-tooter.changes.run.in \
+ rpm/harbour-tooter.spec \
+ rpm/harbour-tooter.yaml \
+ translations/*.ts \
+ harbour-tooter.desktop
+
+SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172
+
+# to disable building translations every time, comment out the
+# following CONFIG line
+# CONFIG += sailfishapp_i18n
+
+# German translation is enabled as an example. If you aren't
+# planning to localize your app, remember to comment out the
+# following TRANSLATIONS line. And also do not forget to
+# modify the localized app name in the the .desktop file.
+TRANSLATIONS += translations/harbour-tooter-de.ts
+TRANSLATIONS += translations/harbour-tooter-el.ts
+TRANSLATIONS += translations/harbour-tooter-es.ts
+TRANSLATIONS += translations/harbour-tooter-fi.ts
+TRANSLATIONS += translations/harbour-tooter-fr.ts
+TRANSLATIONS += translations/harbour-tooter-nl.ts
+TRANSLATIONS += translations/harbour-tooter-nl_BE.ts
+TRANSLATIONS += translations/harbour-tooter-oc.ts
+TRANSLATIONS += translations/harbour-tooter-pl.ts
+TRANSLATIONS += translations/harbour-tooter-ru.ts
+TRANSLATIONS += translations/harbour-tooter-sr.ts
+TRANSLATIONS += translations/harbour-tooter-sv.ts
+TRANSLATIONS += translations/harbour-tooter-zh_CN.ts
+TRANSLATIONS += translations/harbour-tooter-it.ts
diff --git a/qml/cover/CoverPage.qml b/qml/cover/CoverPage.qml
index 770124c..70879fc 100644
--- a/qml/cover/CoverPage.qml
+++ b/qml/cover/CoverPage.qml
@@ -30,9 +30,9 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
-
import "../lib/API.js" as Logic
+
CoverBackground {
onStatusChanged: {
switch (status ){
@@ -46,20 +46,21 @@ CoverBackground {
break;
}
}
+
Image {
id: bg
+ source: "../images/tooter-cover.svg"
+ horizontalAlignment: Image.AlignLeft
+ verticalAlignment: Image.AlignBottom
+ fillMode: Image.PreserveAspectFit
anchors {
bottom : parent.bottom
left: parent.left
right: parent.right
top: parent.top
}
- horizontalAlignment: Image.AlignLeft
- verticalAlignment: Image.AlignBottom
- fillMode: Image.PreserveAspectFit
-
- source: "../images/tooter.svg"
}
+
Timer {
id: timer
interval: 60*1000
@@ -70,33 +71,34 @@ CoverBackground {
Image {
id: iconNot
+ source: "image://theme/icon-s-alarm?" + Theme.highlightColor
anchors {
left: parent.left
top: parent.top
leftMargin: Theme.paddingLarge
topMargin: Theme.paddingLarge
}
- source: "image://theme/icon-s-alarm?" + Theme.highlightColor
}
+
Label {
id: notificationsLbl
+ text: " "
+ color: Theme.highlightColor
anchors {
left: iconNot.right
leftMargin: Theme.paddingMedium
verticalCenter: iconNot.verticalCenter
}
- text: " "
- color: Theme.highlightColor
}
Label {
+ text: "Tooter"
+ color: Theme.secondaryColor
anchors {
right: parent.right
rightMargin: Theme.paddingLarge
verticalCenter: iconNot.verticalCenter
}
- text: "Tooter"
- color: Theme.primaryColor
}
signal activateapp(string person, string notice)
@@ -112,8 +114,11 @@ CoverBackground {
CoverAction {
iconSource: "image://theme/icon-cover-new"
onTriggered: {
- pageStack.push(Qt.resolvedUrl("./../pages/Conversation.qml"), {})
- appWindow.activate();
+ pageStack.push(Qt.resolvedUrl("./../pages/ConversationPage.qml"), {
+ headerTitle: qsTr("New Toot"),
+ type: "new"
+ })
+ appWindow.activate()
}
}
}
@@ -135,5 +140,5 @@ CoverBackground {
notificationsLbl.text = notificationsNum;
Logic.conf.notificationLastID = notificationLastID;
}
-}
+}
diff --git a/qml/harbour-tooter.qml b/qml/harbour-tooter.qml
index 7b23d5e..b0f9abd 100644
--- a/qml/harbour-tooter.qml
+++ b/qml/harbour-tooter.qml
@@ -33,41 +33,39 @@ import Sailfish.Silica 1.0
import "pages"
import "./lib/API.js" as Logic
-ApplicationWindow
-{
+ApplicationWindow {
id: appWindow
- //initialPage: Component { FirstPage { } }
cover: Qt.resolvedUrl("cover/CoverPage.qml")
allowedOrientations: defaultAllowedOrientations
Component.onCompleted: {
- var obj = {};
- Logic.mediator.installTo(obj);
- obj.subscribe('confLoaded', function(){
+ var obj = {}
+ Logic.mediator.installTo(obj)
+ obj.subscribe('confLoaded', function() {
console.log('confLoaded');
//console.log(JSON.stringify(Logic.conf))
if (!Logic.conf['notificationLastID'])
- Logic.conf['notificationLastID'] = 0;
+ Logic.conf['notificationLastID'] = 0
+
if (Logic.conf['instance']) {
- Logic.api = new Logic.MastodonAPI({ instance: Logic.conf['instance'], api_user_token: "" });
+ Logic.api = Logic.mastodonAPI({
+ "instance": Logic.conf['instance'],
+ "api_user_token": ""
+ })
}
+
if (Logic.conf['login']) {
- //Logic.conf['notificationLastID'] = 0
- Logic.api.setConfig("api_user_token", Logic.conf['api_user_token'])
- //accounts/verify_credentials
- Logic.api.get('instance', [], function(data) {
- console.log(JSON.stringify(data))
- pageStack.push(Qt.resolvedUrl("./pages/MainPage.qml"), {})
- });
-
- //
- //
- //pageStack.push(Qt.resolvedUrl("./pages/Conversation.qml"), {})
+ //Logic.conf['notificationLastID'] = 0
+ Logic.api.setConfig("api_user_token", Logic.conf['api_user_token'])
+ //accounts/verify_credentials
+ Logic.api.get('instance', [], function(data) {
+ console.log(JSON.stringify(data))
+ pageStack.push(Qt.resolvedUrl("./pages/MainPage.qml"), {})
+ })
+ //pageStack.push(Qt.resolvedUrl("./pages/Conversation.qml"), {})
} else {
- pageStack.push(Qt.resolvedUrl("./pages/LoginPage.qml"), {})
+ pageStack.push(Qt.resolvedUrl("./pages/LoginPage.qml"), {})
}
-
-
- });
+ })
Logic.init()
}
@@ -75,19 +73,18 @@ ApplicationWindow
//Logic.conf.notificationLastID = 0;
Logic.saveData()
}
- Connections
- {
- target: Dbus
- onViewtoot:
- {
- console.log(key, "dbus onViewtoot")
- }
- onActivateapp:
- {
- console.log ("dbus activate app")
- pageStack.pop(pageStack.find( function(page){ return (page._depth === 0) }))
- activate()
- }
+ Connections {
+ target: Dbus
+ onViewtoot: {
+ console.log(key, "dbus onViewtoot")
}
-}
+ onActivateapp: {
+ console.log ("dbus activate app")
+ pageStack.pop(pageStack.find( function(page) {
+ return (page._depth === 0)
+ }))
+ activate()
+ }
+ }
+}
diff --git a/qml/images/boosted.svg b/qml/images/boosted.svg
deleted file mode 100644
index 468e2da..0000000
--- a/qml/images/boosted.svg
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
diff --git a/qml/images/emojiselect.svg b/qml/images/icon-m-emoji.svg
similarity index 100%
rename from qml/images/emojiselect.svg
rename to qml/images/icon-m-emoji.svg
diff --git a/qml/images/icon-s-following.svg b/qml/images/icon-s-following.svg
new file mode 100644
index 0000000..ebcf5ee
--- /dev/null
+++ b/qml/images/icon-s-following.svg
@@ -0,0 +1,12 @@
+
diff --git a/qml/images/notification.svg b/qml/images/notification.svg
deleted file mode 100644
index 56f1b35..0000000
--- a/qml/images/notification.svg
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
diff --git a/qml/images/tooter.svg b/qml/images/tooter-cover.svg
similarity index 100%
rename from qml/images/tooter.svg
rename to qml/images/tooter-cover.svg
diff --git a/qml/images/verified.svg b/qml/images/verified.svg
deleted file mode 100644
index 65d529b..0000000
--- a/qml/images/verified.svg
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
diff --git a/qml/lib/API.js b/qml/lib/API.js
index 3dce882..ea84804 100644
--- a/qml/lib/API.js
+++ b/qml/lib/API.js
@@ -88,7 +88,6 @@ var tootParser = function(data){
ret.display_name = data.account.display_name
ret.avatar_static = data.account.avatar_static
-
ret.favourited = data.favourited ? true : false
ret.favourites_count = data.favourites_count ? data.favourites_count : 0
@@ -100,7 +99,6 @@ var tootParser = function(data){
ret.sensitive = data.sensitive ? true : false
ret.visibility = data.visibility ? data.visibility : false
-
console.log(ret)
}
var test = 1;
diff --git a/qml/lib/Mastodon.js b/qml/lib/Mastodon.js
index 8a8e4c6..55265be 100644
--- a/qml/lib/Mastodon.js
+++ b/qml/lib/Mastodon.js
@@ -3,7 +3,7 @@
// do whatever you want with it
// but please don't hurt it (and keep this header)
-var MastodonAPI = function(config) {
+var mastodonAPI = function(config) {
var apiBase = config.instance + "/api/v1/";
return {
setConfig: function (key, value) {
@@ -56,8 +56,8 @@ var MastodonAPI = function(config) {
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() { // Call a function when the state changes.
- if (http.readyState == 4) {
- if (http.status == 200) {
+ if (http.readyState === 4) {
+ if (http.status === 200) {
console.log("Successful GET API request to " +apiBase+endpoint);
callback(JSON.parse(http.response),http.status)
} else {
@@ -91,8 +91,8 @@ var MastodonAPI = function(config) {
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() { // Call a function when the state changes.
- if (http.readyState == 4) {
- if (http.status == 200) {
+ if (http.readyState === 4) {
+ if (http.status === 200) {
console.log("Successful POST API request to " +apiBase+endpoint);
callback(JSON.parse(http.response),http.status)
} else {
@@ -180,8 +180,8 @@ var MastodonAPI = function(config) {
http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
http.onreadystatechange = function() { // Call a function when the state changes.
- if (http.readyState == 4) {
- if (http.status == 200) {
+ if (http.readyState === 4) {
+ if (http.status === 200) {
console.log("Registered Application: " + http.response);
callback(http.response)
} else {
@@ -221,8 +221,8 @@ var MastodonAPI = function(config) {
http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
http.onreadystatechange = function() { // Call a function when the state changes.
- if (http.readyState == 4) {
- if (http.status == 200) {
+ if (http.readyState === 4) {
+ if (http.status === 200) {
console.log("Got Token: " + http.response);
callback(http.response)
} else {
@@ -236,7 +236,7 @@ var MastodonAPI = function(config) {
};
// node.js
-if (typeof module !== 'undefined') { module.exports = MastodonAPI; };
+if (typeof module !== 'undefined') { module.exports = mastodonAPI; };
String.prototype.replaceAll = function(search, replacement) {
var target = this;
diff --git a/qml/lib/Worker.js b/qml/lib/Worker.js
index 15c13fd..0317523 100644
--- a/qml/lib/Worker.js
+++ b/qml/lib/Worker.js
@@ -22,7 +22,7 @@ WorkerScript.onMessage = function(msg) {
if (typeof msg.conf['loadImages'] !== "undefined")
loadImages = msg.conf['loadImages']
- var API = MastodonAPI({ instance: msg.conf.instance, api_user_token: msg.conf.api_user_token});
+ var API = mastodonAPI({ instance: msg.conf.instance, api_user_token: msg.conf.api_user_token});
if (msg.method === "POST"){
API.post(msg.action, msg.params, function(data) {
if (msg.bgAction){
@@ -91,7 +91,7 @@ WorkerScript.onMessage = function(msg) {
addDataToModel (msg.model, "append", items);
items = [];
- } else if (data[i].hasOwnProperty("content")){
+ } else if (data[i].hasOwnProperty("content")){
//console.log("Is toot... parsing...")
item = parseToot(data[i]);
item['id'] = item['status_id']
@@ -132,11 +132,13 @@ function parseAccounts(collection, prefix, data){
res[prefix + 'account_username'] = data["username"]
res[prefix + 'account_acct'] = data["acct"]
res[prefix + 'account_display_name'] = data["display_name"]
+ res[prefix + 'account_discoverable'] = data["discoverable"]
res[prefix + 'account_locked'] = data["locked"]
res[prefix + 'account_created_at'] = data["created_at"]
res[prefix + 'account_avatar'] = data["avatar"]
+ res[prefix + 'account_header'] = data["header"]
- // /console.log(JSON.stringify(res))
+ // console.log(JSON.stringify(res))
return (res);
}
@@ -188,7 +190,7 @@ function parseNotification(data){
item = parseAccounts(item, "", data["account"])
item = parseAccounts(item, "reblog_", data["account"])
item['content'] = data['account']['note']
- item['typeIcon'] = "image://theme/icon-s-installed"
+ item['typeIcon'] = "../../images/icon-s-following.svg"
item['attachments'] = []
break;
@@ -226,6 +228,7 @@ function parseToot (data){
item['highlight'] = false
item['status_id'] = data["id"]
item['status_uri'] = data["uri"]
+ item['status_url'] = data["url"]
item['status_in_reply_to_id'] = data["in_reply_to_id"]
item['status_in_reply_to_account_id'] = data["in_reply_to_account_id"]
item['status_reblog'] = data["reblog"] ? true : false
@@ -236,6 +239,7 @@ function parseToot (data){
item['favourites_count'] = data["favourites_count"]
item['reblogged'] = data["reblogged"]
item['favourited'] = data["favourited"]
+ item['bookmarked'] = data["bookmarked"]
item['status_sensitive'] = data["sensitive"]
item['status_spoiler_text'] = data["spoiler_text"]
item['status_visibility'] = data["visibility"]
@@ -294,13 +298,13 @@ function addEmojis(item, data){
var emoji, i;
for (i = 0; i < data["emojis"].length; i++){
emoji = data["emojis"][i];
- item['content'] = item['content'].replaceAll(":"+emoji.shortcode+":", "")
+ item['content'] = item['content'].replaceAll(":"+emoji.shortcode+":", "")
//console.log(JSON.stringify(data["emojis"][i]))
}
if (data["reblog"])
for (i = 0; i < data["reblog"]["emojis"].length; i++){
emoji = data["reblog"]["emojis"][i];
- item['content'] = item['content'].replaceAll(":"+emoji.shortcode+":", "")
+ item['content'] = item['content'].replaceAll(":"+emoji.shortcode+":", "")
}
return item;
diff --git a/qml/pages/Conversation.qml b/qml/pages/ConversationPage.qml
similarity index 51%
rename from qml/pages/Conversation.qml
rename to qml/pages/ConversationPage.qml
index 3fed799..4218bea 100644
--- a/qml/pages/Conversation.qml
+++ b/qml/pages/ConversationPage.qml
@@ -4,17 +4,23 @@ import harbour.tooter.Uploader 1.0
import "../lib/API.js" as Logic
import "./components/"
+
Page {
id: conversationPage
- property string type
- property alias title: header.title
- property alias description: header.description
- property alias avatar: header.image
+
+ property string headerTitle: ""
+ property string type
+ property alias title: header.title
+ property alias description: header.description
+ property alias avatar: header.image
property string suggestedUser: ""
property ListModel suggestedModel
property string toot_id: ""
+ property string toot_url: ""
+ property string toot_uri: ""
property int tootMaxChar: 500;
- property ListModel mdl
+ property ListModel mdl
+
allowedOrientations: Orientation.All
onSuggestedUserChanged: {
console.log(suggestedUser)
@@ -59,18 +65,21 @@ Page {
id: header
visible: false
}
- SilicaListView {
- id: conversationList
+
+ SilicaListView {
+ id: myList
header: PageHeader {
- title: qsTr("Conversation")
+ title: headerTitle // pageTitle pushed from MainPage.qml or VisualContainer.qml
}
clip: true
- anchors {
- top: parent.top
- bottom: panel.top
- left: parent.left
- right: parent.right
- }
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: if (panel.open == true) {
+ panel.top
+ } else {
+ hiddenPanel.top
+ }
model: mdl
section {
property: 'section'
@@ -90,22 +99,53 @@ Page {
}
}
}
- }
+
+ PullDownMenu {
+ id: pulleyConversation
+ visible: type === "reply" //&& toot_url !== ""
+ MenuItem {
+ text: qsTr("Copy Link to Clipboard")
+ onClicked: if (toot_url === "") {
+
+ var test = toot_uri.split("/")
+ console.log(toot_uri)
+ console.log(JSON.stringify(test))
+ console.log(JSON.stringify(test.length))
+ if (test.length === 8 && (test[7] === "activity")) {
+ var urialt = toot_uri.replace("activity", "")
+ Clipboard.text = urialt
+ }
+ else Clipboard.text = toot_uri
+
+ } else onClicked: Clipboard.text = toot_url
+ }
+ }
+ }
+
Rectangle {
id: predictionList
visible: false
- anchors.bottom: panel.top
- anchors.left: parent.left
- anchors.right: panel.right
- height: suggestedModel.count > 6 ? Theme.itemSizeMedium * 6 : Theme.itemSizeMedium * suggestedModel.count
- color: Theme.highlightDimmerColor
+ color: Theme.highlightDimmerColor
+ height: parent.height - panel.height - (Theme.paddingLarge * 4.5)
+ anchors {
+ left: panel.left
+ right: panel.right
+ bottom: if (panel.open == true) {
+ panel.top
+ } else {
+ hiddenPanel.top
+ }
+ }
- SilicaListView {
- anchors.fill: parent
+ SilicaListView {
+ rotation: 180
+ anchors.fill: parent
model: suggestedModel
clip: true
-
+ quickScroll: false
+ VerticalScrollDecorator {}
delegate: ItemUser {
+ rotation: 180
onClicked: {
var start = toot.cursorPosition
while (toot.text[start] !== "@" && start > 0) {
@@ -124,26 +164,22 @@ Page {
}
}
onCountChanged: {
- positionViewAtIndex(suggestedModel.count - 1, ListView.End)
+ positionViewAtBeginning(suggestedModel.count - 1, ListView.Beginning)
}
}
}
DockedPanel {
id: panel
- open: true
- onExpandedChanged: {
- if (!expanded) {
- show()
- }
- }
-
width: parent.width
- height: progressBar.height + toot.height + (mediaModel.count ? uploadedImages.height : 0)
+ height: progressBar.height + toot.height + (mediaModel.count ? uploadedImages.height : 0)
+ btnContentWarning.height + Theme.paddingMedium
- + (warningContent.visible ? warningContent.height : 0)
- dock: Dock.Bottom
- Rectangle {
+ + (warningContent.visible ? warningContent.height : 0)
+ dock: Dock.Bottom
+ open: true
+ animationDuration: 200
+
+ Rectangle {
width: parent.width
height: progressBar.height
color: Theme.highlightBackgroundColor
@@ -154,15 +190,16 @@ Page {
top: parent.top
}
}
+
Rectangle {
id: progressBar
width: toot.text.length ? panel.width * (toot.text.length / tootMaxChar) : 0
- height: Theme.itemSizeSmall * 0.05
+ height: Theme.itemSizeSmall * 0.05
color: Theme.highlightBackgroundColor
opacity: 0.7
anchors {
left: parent.left
- top: parent.top
+ top: parent.top
}
}
@@ -171,7 +208,7 @@ Page {
visible: false
height: visible ? implicitHeight : 0
anchors {
- top: parent.top
+ top: parent.top
topMargin: Theme.paddingMedium
left: parent.left
right: parent.right
@@ -183,10 +220,9 @@ Page {
placeholderColor: palette.highlightColor
color: palette.highlightColor
horizontalAlignment: Text.AlignLeft
- EnterKey.onClicked: {
- //tweet()
- }
+ EnterKey.onClicked: {}
}
+
TextInput {
id: textOperations
visible: false
@@ -203,18 +239,19 @@ Page {
}
autoScrollEnabled: true
labelVisible: false
- //focus: true
- text: description !== "" && (description.charAt(0) == '@'
+ text: description !== "" && (description.charAt(0) === '@'
|| description.charAt(
- 0) == '#') ? description + ' ' : ''
- height: Math.max(270, Math.min(900, implicitHeight))
- //height: implicitHeight
+ 0) === '#') ? description + ' ' : ''
+ height: if (type !== "reply") {
+ Math.max(conversationPage.height / 3, Math.min(conversationPage.height * 0.65, implicitHeight))
+ }
+ else {
+ Math.max(conversationPage.height / 4, Math.min(conversationPage.height * 0.65, implicitHeight))
+ }
horizontalAlignment: Text.AlignLeft
placeholderText: qsTr("What's on your mind?")
font.pixelSize: Theme.fontSizeSmall
- EnterKey.onClicked: {
- //tweet()
- }
+ EnterKey.onClicked: {}
onTextChanged: {
textOperations.text = toot.text
textOperations.cursorPosition = toot.cursorPosition
@@ -230,45 +267,51 @@ Page {
}
}
}
+
IconButton {
id: btnSmileys
- property string selection
- onSelectionChanged: {
- console.log(selection)
- }
+ property string selection
+
+ opacity: 0.7
+ icon {
+ color: Theme.secondaryColor
+ width: Theme.iconSizeSmallPlus
+ fillMode: Image.PreserveAspectFit
+ source: "../../qml/images/icon-m-emoji.svg"
+ }
anchors {
top: warningContent.bottom
bottom: bottom.top
right: parent.right
rightMargin: Theme.paddingSmall
}
- opacity: 0.8
- icon.source: "../../qml/images/emojiselect.svg" + (pressed ? Theme.highlightColor : (warningContent.visible ? Theme.secondaryHighlightColor : Theme.primaryColor))
- onClicked: pageStack.push(firstWizardPage)
+ onSelectionChanged: { console.log(selection) }
+ onClicked: pageStack.push(emojiSelect)
}
+
SilicaGridView {
id: uploadedImages
width: parent.width
anchors.top: bottom.toot
anchors.bottom: parent.bottom
- height: mediaModel.count ? Theme.itemSizeSmall : 0
- model: mediaModel
+ height: mediaModel.count ? Theme.itemSizeExtraLarge : 0
+ model: mediaModel
cellWidth: uploadedImages.width / 4
- cellHeight: Theme.itemSizeSmall
+ cellHeight: Theme.itemSizeExtraLarge
delegate: BackgroundItem {
id: myDelegate
width: uploadedImages.cellWidth
height: uploadedImages.cellHeight
RemorseItem {
- id: remorse
+ id: remorse
}
+
Image {
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
source: model.preview_url
}
-
onClicked: {
var idx = index
console.log(idx)
@@ -286,7 +329,6 @@ Page {
duration: 800
}
}
-
remove: Transition {
NumberAnimation {
property: "opacity"
@@ -303,8 +345,8 @@ Page {
}
}
}
- IconButton {
+ IconButton {
id: btnContentWarning
anchors {
top: toot.bottom
@@ -316,6 +358,7 @@ Page {
+ (pressed ? Theme.highlightColor : (warningContent.visible ? Theme.secondaryHighlightColor : Theme.primaryColor))
onClicked: warningContent.visible = !warningContent.visible
}
+
IconButton {
id: btnAddImage
enabled: mediaModel.count < 4
@@ -341,21 +384,18 @@ Page {
})
}
}
+
ImageUploader {
id: imageUploader
-
onProgressChanged: {
console.log("progress " + progress)
uploadProgress.width = parent.width * progress
}
-
onSuccess: {
uploadProgress.width = 0
console.log(replyData)
-
mediaModel.append(JSON.parse(replyData))
}
-
onFailure: {
uploadProgress.width = 0
btnAddImage.enabled = true
@@ -363,15 +403,16 @@ Page {
console.log(statusText)
}
}
+
ComboBox {
- id: privacy
+ id: privacy
anchors {
top: toot.bottom
topMargin: -Theme.paddingSmall * 1.5
left: btnAddImage.right
- right: btnSend.left
- }
- menu: ContextMenu {
+ right: btnSend.left
+ }
+ menu: ContextMenu {
MenuItem {
text: qsTr("Public")
}
@@ -405,7 +446,6 @@ Page {
console.log(mediaModel.get(k).id)
media_ids.push(mediaModel.get(k).id)
}
-
var msg = {
"action": 'statuses',
"method": 'POST',
@@ -426,22 +466,23 @@ Page {
msg.params['spoiler_text'] = warningContent.text
}
- worker.sendMessage(msg)
- warningContent.text = ""
- toot.text = ""
- mediaModel.clear()
- pageStack.pop()
+ worker.sendMessage(msg)
+ warningContent.text = ""
+ toot.text = ""
+ mediaModel.clear()
+ sentBanner.showText(qsTr("Toot sent!"))
}
}
Rectangle {
id: uploadProgress
color: Theme.highlightBackgroundColor
- anchors.bottom: parent.bottom
+ anchors.bottom: parent.bottom
anchors.left: parent.left
- height: 3
+ height: Theme.itemSizeSmall * 0.05
}
}
+
Component.onCompleted: {
toot.cursorPosition = toot.text.length
if (mdl.count > 0) {
@@ -474,157 +515,66 @@ Page {
"conf": Logic.conf
})
}
- Component {
- id: firstWizardPage
- Dialog {
- id: emoticonsDialog
- canAccept: false //selector.currentIndex >= 0
+ BackgroundItem {
+ id: hiddenPanel
+ visible: !panel.open
+ height: Theme.paddingLarge * 0.5
+ width: parent.width
+ opacity: enabled ? 0.6 : 0.0
+ Behavior on opacity { FadeAnimator { duration: 400 } }
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ bottom: parent.bottom
+ }
- //acceptDestination: conversationPage
- onAcceptPendingChanged: {
- if (acceptPending) {
+ MouseArea {
+ anchors.fill: parent
+ onClicked: panel.open = !panel.open
+ }
- // Tell the destination page what the selected category is
- // acceptDestinationInstance.category = selector.value
- }
- }
+ Rectangle {
+ id: hiddenPanelBackground
+ width: parent.width
+ height: parent.height
+ color: Theme.highlightBackgroundColor
+ opacity: 0.4
+ anchors.fill: parent
+ }
- SilicaGridView {
- id: gridView
- anchors.fill: parent
- cellWidth: gridView.width / 6
- cellHeight: cellWidth
- header: PageHeader {
- title: qsTr("Emojis")
- description: qsTr("Tap to insert")
- }
- model: ListModel {
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐
" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐ " }
- ListElement { section: "smileys"; glyph: "๐ก" }
- ListElement { section: "smileys"; glyph: "๐ข" }
- ListElement { section: "smileys"; glyph: "๐ฃ" }
- ListElement { section: "smileys"; glyph: "๐ค" }
- ListElement { section: "smileys"; glyph: "๐ฅ" }
- ListElement { section: "smileys"; glyph: "๐จ" }
- ListElement { section: "smileys"; glyph: "๐ฉ" }
- ListElement { section: "smileys"; glyph: "๐ช" }
- ListElement { section: "smileys"; glyph: "๐ซ" }
- ListElement { section: "smileys"; glyph: "๐ญ" }
- ListElement { section: "smileys"; glyph: "๐ฐ" }
- ListElement { section: "smileys"; glyph: "๐ฑ" }
- ListElement { section: "smileys"; glyph: "๐ฒ" }
- ListElement { section: "smileys"; glyph: "๐ณ" }
- ListElement { section: "smileys"; glyph: "๐ต" }
- ListElement { section: "smileys"; glyph: "๐ท" }
- ListElement { section: "smileys"; glyph: "๐ธ" }
- ListElement { section: "smileys"; glyph: "๐น" }
- ListElement { section: "smileys"; glyph: "๐บ" }
- ListElement { section: "smileys"; glyph: "๐ป" }
- ListElement { section: "smileys"; glyph: "๐ผ" }
- ListElement { section: "smileys"; glyph: "๐ฝ" }
- ListElement { section: "smileys"; glyph: "๐พ" }
- ListElement { section: "smileys"; glyph: "๐ฟ" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐
" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
- ListElement { section: "smileys"; glyph: "๐" }
+ Rectangle {
+ id: progressBarBackground
+ width: parent.width
+ height: progressBarHiddenPanel.height
+ color: Theme.highlightBackgroundColor
+ opacity: 0.2
+ anchors {
+ left: parent.left
+ right: parent.right
+ top: parent.top
+ }
+ }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐
" }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐" }
- ListElement { section: "Transport and map"; glyph: "๐ข" }
- ListElement { section: "Transport and map"; glyph: "๐จ" }
- ListElement { section: "Transport and map"; glyph: "๐ฉ" }
- ListElement { section: "Transport and map"; glyph: "๐ช" }
- ListElement { section: "Transport and map"; glyph: "๐ซ" }
- ListElement { section: "Transport and map"; glyph: "๐ฌ" }
- ListElement { section: "Transport and map"; glyph: "๐ญ" }
- ListElement { section: "Transport and map"; glyph: "๐ฒ" }
- ListElement { section: "Transport and map"; glyph: "๐ถ" }
- ListElement { section: "Transport and map"; glyph: "๐น" }
- ListElement { section: "Transport and map"; glyph: "๐บ" }
- ListElement { section: "Transport and map"; glyph: "๐ป" }
- ListElement { section: "Transport and map"; glyph: "๐ผ" }
- ListElement { section: "Transport and map"; glyph: "๐ฝ" }
- ListElement { section: "Transport and map"; glyph: "๐พ" }
- ListElement { section: "Transport and map"; glyph: "๐" }
+ Rectangle {
+ id: progressBarHiddenPanel
+ width: toot.text.length ? panel.width * (toot.text.length / tootMaxChar) : 0
+ height: Theme.itemSizeSmall * 0.05
+ color: Theme.highlightBackgroundColor
+ opacity: 0.7
+ anchors {
+ left: parent.left
+ top: parent.top
+ }
+ }
- ListElement { section: "Horoscope Signs"; glyph: "โ" }
- ListElement { section: "Horoscope Signs"; glyph: "โ" }
- ListElement { section: "Horoscope Signs"; glyph: "โ" }
- ListElement { section: "Horoscope Signs"; glyph: "โ" }
- ListElement { section: "Horoscope Signs"; glyph: "โ" }
- ListElement { section: "Horoscope Signs"; glyph: "โ" }
- ListElement { section: "Horoscope Signs"; glyph: "โ" }
- ListElement { section: "Horoscope Signs"; glyph: "โ" }
- ListElement { section: "Horoscope Signs"; glyph: "โ" }
- ListElement { section: "Horoscope Signs"; glyph: "โ" }
- ListElement { section: "Horoscope Signs"; glyph: "โ" }
- ListElement { section: "Horoscope Signs"; glyph: "โ" }
- }
- delegate: BackgroundItem {
- width: gridView.cellWidth
- height: gridView.cellHeight
- Label {
- anchors.centerIn: parent
- color: (highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor)
- font.pixelSize: Theme.fontSizeLarge
- text: glyph
- }
- onClicked: {
- var cursorPosition = toot.cursorPosition
- toot.text = toot.text.substring(
- 0, cursorPosition) + model.glyph + toot.text.substring(
- cursorPosition)
- toot.cursorPosition = cursorPosition + model.glyph.length
- emoticonsDialog.canAccept = true
- emoticonsDialog.accept()
- }
- }
- }
- }
+ }
+
+ EmojiSelect {
+ id: emojiSelect
}
+
+ InfoBanner {
+ id: sentBanner
+ }
+
}
diff --git a/qml/pages/LoginPage.qml b/qml/pages/LoginPage.qml
index c3874fb..b35ad7a 100644
--- a/qml/pages/LoginPage.qml
+++ b/qml/pages/LoginPage.qml
@@ -1,48 +1,14 @@
-/*
- Copyright (C) 2013 Jolla Ltd.
- Contact: Thomas Perl
- All rights reserved.
-
- You may use this file under the terms of BSD license as follows:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the Jolla Ltd nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
import QtQuick 2.0
import QtWebKit 3.0
import Sailfish.Silica 1.0
import "../lib/API.js" as Logic
-
Page {
id: loginPage
-
// The effective value will be restricted by ApplicationWindow.allowedOrientations
allowedOrientations: Orientation.All
-
-
SilicaFlickable {
anchors.fill: parent
contentHeight: column.height + Theme.paddingLarge
@@ -52,8 +18,9 @@ Page {
Column {
id: column
width: parent.width
-
- PageHeader { title: qsTr("Login") }
+ PageHeader {
+ title: qsTr("Login")
+ }
SectionHeader {
text: qsTr("Instance")
@@ -64,14 +31,13 @@ Page {
focus: true
label: qsTr("Enter a valid Mastodon instance URL")
text: "https://"
- placeholderText: "https://mastodon.social"
width: parent.width
validator: RegExpValidator { regExp: /^(ftp|http|https):\/\/[^ "]+$/ }
EnterKey.enabled: instance.acceptableInput;
EnterKey.highlighted: instance.acceptableInput;
EnterKey.iconSource: "image://theme/icon-m-accept"
EnterKey.onClicked: {
- Logic.api = new Logic.MastodonAPI({ instance: instance.text, api_user_token: "" });
+ Logic.api = Logic.mastodonAPI({ instance: instance.text, api_user_token: "" });
Logic.api.registerApplication("Tooter",
'http://localhost/harbour-tooter', // redirect uri, we will need this later on
["read", "write", "follow"], //scopes
@@ -83,7 +49,6 @@ Page {
conf.instance = instance.text;
conf.login = false;
-
/*conf['login'] = false;
conf['mastodon_client_id'] = data['mastodon_client_id'];
conf['mastodon_client_secret'] = data['mastodon_client_secret'];
@@ -196,5 +161,5 @@ Page {
}
}
}
-}
+}
diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml
index e676870..2ff089f 100644
--- a/qml/pages/MainPage.qml
+++ b/qml/pages/MainPage.qml
@@ -1,33 +1,3 @@
-/*
- Copyright (C) 2013 Jolla Ltd.
- Contact: Thomas Perl
- All rights reserved.
-
- You may use this file under the terms of BSD license as follows:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the Jolla Ltd nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
import QtQuick 2.0
import Sailfish.Silica 1.0
import "../lib/API.js" as Logic
@@ -36,8 +6,9 @@ import "./components/"
Page {
id: mainPage
+
property bool isFirstPage: true
- property bool isTablet: true; //Screen.sizeCategory >= Screen.Large
+ property bool isTablet: true //Screen.sizeCategory >= Screen.Large
// The effective value will be restricted by ApplicationWindow.allowedOrientations
allowedOrientations: Orientation.All
@@ -57,10 +28,11 @@ Page {
}
}
}
+
VisualItemModel {
id: visualModel
MyList{
- id: tlHome;
+ id: tlHome
title: qsTr("Home")
type: "timelines/home"
mdl: Logic.modelTLhome
@@ -68,51 +40,62 @@ Page {
height: parent.itemHeight
onOpenDrawer: infoPanel.open = setDrawer
}
+
MyList{
- id: tlNotifications;
+ id: tlNotifications
title: qsTr("Notifications")
type: "notifications"
notifier: true
mdl: Logic.modelTLnotifications
width: parent.itemWidth
height: parent.itemHeight
- onOpenDrawer: infoPanel.open = setDrawer
+ onOpenDrawer: infoPanel.open = setDrawer
}
+
MyList{
- id: tlLocal;
+ id: tlLocal
title: qsTr("Local")
type: "timelines/public?local=true"
//params: ["local", true]
mdl: Logic.modelTLlocal
width: parent.itemWidth
height: parent.itemHeight
- onOpenDrawer: infoPanel.open = setDrawer
+ onOpenDrawer: infoPanel.open = setDrawer
}
+
MyList{
- id: tlPublic;
+ id: tlPublic
title: qsTr("Federated")
type: "timelines/public"
mdl: Logic.modelTLpublic
width: parent.itemWidth
height: parent.itemHeight
- onOpenDrawer: infoPanel.open = setDrawer
+ onOpenDrawer: infoPanel.open = setDrawer
}
+
Item {
- id: tlSearch;
+ id: tlSearch
+
+ property ListModel mdl: ListModel {}
+ property string search
+
width: parent.itemWidth
height: parent.itemHeight
- property ListModel mdl: ListModel {}
- property string search;
onSearchChanged: {
console.log(search)
loader.sourceComponent = loading
- loader.sourceComponent = search.charAt(0) === "@" ? userListComponent : tagListComponent
+ if (search.charAt(0) === "@") {
+ loader.sourceComponent = userListComponent
+ } else if (search.charAt(0) === "#") {
+ loader.sourceComponent = tagListComponent
+ } else { loader.sourceComponent = wordListComponent}
}
Loader {
id: loader
anchors.fill: parent
}
+
Column {
id: headerContainer
width: tlSearch.width
@@ -132,6 +115,7 @@ Page {
}
}
}
+
Component {
id: loading
BusyIndicator {
@@ -140,6 +124,7 @@ Page {
running: true
}
}
+
Component {
id: tagListComponent
MyList {
@@ -164,6 +149,7 @@ Page {
}
}
}
+
Component {
id: userListComponent
MyList {
@@ -184,11 +170,12 @@ Page {
delegate: ItemUser {
onClicked: {
- pageStack.push(Qt.resolvedUrl("Profile.qml"), {
+ pageStack.push(Qt.resolvedUrl("ProfilePage.qml"), {
"display_name": model.account_display_name,
"username": model.account_acct,
"user_id": model.account_id,
- "profileImage": model.account_avatar
+ "profileImage": model.account_avatar,
+ "profileBackground": model.account_header
})
}
}
@@ -201,11 +188,33 @@ Page {
}
}
+ Component {
+ id: wordListComponent
+ MyList {
+ id: view3
+ mdl: ListModel {}
+ width: parent.width
+ height: parent.height
+ onOpenDrawer: infoPanel.open = setDrawer
+ anchors.fill: parent
+ currentIndex: -1 // otherwise currentItem will steal focus
+ header: Item {
+ id: header
+ width: headerContainer.width
+ height: headerContainer.height
+ Component.onCompleted: headerContainer.parent = header
+ }
+
+ delegate: VisualContainer
+ Component.onCompleted: {
+ view3.type = "timelines/tag/"+tlSearch.search
+ view3.loadData("append")
+ }
+ }
+ }
}
-
}
-
SlideshowView {
id: slideshow
width: parent.width
@@ -216,12 +225,9 @@ Page {
onCurrentIndexChanged: {
navigation.slideshowIndexChanged(currentIndex)
}
-
anchors {
fill: parent
- leftMargin: 0
top: parent.top
- topMargin: 0
rightMargin: mainPage.isPortrait ? 0 : infoPanel.visibleSize
bottomMargin: mainPage.isPortrait ? infoPanel.visibleSize : 0
}
@@ -231,22 +237,22 @@ Page {
}
IconButton {
- anchors {
- right: (mainPage.isPortrait ? parent.right : infoPanel.left)
- bottom: (mainPage.isPortrait ? infoPanel.top : parent.bottom)
- margins: {
- left: Theme.paddingLarge
- bottom: Theme.paddingLarge
- }
- }
-
- id: newTweet
+ id: newToot
width: Theme.iconSizeLarge
height: width
visible: !isPortrait ? true : !infoPanel.open
icon.source: "image://theme/icon-l-add"
+ anchors {
+ right: (mainPage.isPortrait ? parent.right : infoPanel.left)
+ rightMargin: Theme.paddingLarge
+ bottom: (mainPage.isPortrait ? infoPanel.top : parent.bottom)
+ bottomMargin: Theme.paddingLarge
+ }
onClicked: {
- pageStack.push(Qt.resolvedUrl("Conversation.qml"), {title: qsTr("New Toot"), type: "new"})
+ pageStack.push(Qt.resolvedUrl("ConversationPage.qml"), {
+ headerTitle: qsTr("New Toot"),
+ type: "new"
+ })
}
}
@@ -266,11 +272,12 @@ Page {
navigation.navigateTo('search')
} else {
- Qt.openUrlExternally(href);
+ Qt.openUrlExternally(href)
}
}
+
Component.onCompleted: {
console.log("aaa")
}
-}
+}
diff --git a/qml/pages/Profile.qml b/qml/pages/Profile.qml
deleted file mode 100644
index 6d56f44..0000000
--- a/qml/pages/Profile.qml
+++ /dev/null
@@ -1,309 +0,0 @@
-import QtQuick 2.0
-import Sailfish.Silica 1.0
-import "../lib/API.js" as Logic
-import "./components/"
-import QtGraphicalEffects 1.0
-
-Page {
- property ListModel tweets;
- property string display_name : "";
- property string username : "";
- property string profileImage : "";
- property int user_id;
- property int statuses_count;
- property int following_count;
- property int followers_count;
- property int favourites_count;
- property int reblogs_count;
- property int count_moments;
- property string profile_background: "";
- property string note: "";
- property string url: "";
-
- property bool locked : false;
- property date created_at;
- property bool following : false;
- property bool requested : false;
- property bool followed_by : false;
- property bool blocking : false;
- property bool muting : false;
- property bool domain_blocking : false;
-
-
- WorkerScript {
- id: worker
- source: "../lib/Worker.js"
- onMessage: {
- console.log(JSON.stringify(messageObject))
- if(messageObject.action.indexOf("accounts/search") > -1 ){
- user_id = messageObject.data.id
- followers_count = messageObject.data.followers_count
- following_count = messageObject.data.following_count
- username = messageObject.data.acct
- display_name = messageObject.data.display_name
- profileImage = messageObject.data.avatar_static
-
- var msg = {
- 'action' : "accounts/relationships/",
- 'params' : [ {name: "id", data: user_id}],
- 'conf' : Logic.conf
- };
- worker.sendMessage(msg);
- list.loadData("prepend")
- }
-
- if(messageObject.action === "accounts/relationships/"){
- console.log(JSON.stringify(messageObject))
- following= messageObject.data.following
- requested= messageObject.data.requested
- followed_by= messageObject.data.followed_by
- blocking= messageObject.data.blocking
- muting= messageObject.data.muting
- domain_blocking= messageObject.data.domain_blocking
- }
- switch (messageObject.key) {
- case 'followers_count':
- followers_count = messageObject.data
- break;
- case 'following_count':
- following_count = messageObject.data
- break;
- case 'acct':
- // line below was commented out, reason unknown
- // username = messageObject.data
- break;
- case 'locked':
- locked = messageObject.data
- break;
- case 'created_at':
- created_at = messageObject.data
- break;
- case 'statuses_count':
- statuses_count = messageObject.data
- break;
- case 'note':
- note = messageObject.data
- break;
- case 'url':
- url = messageObject.data
- break;
- case 'following':
- following = messageObject.data
- followers_count = followers_count + (following ? 1 : - 1)
- break;
- case 'muting':
- muting = messageObject.data
- break;
- case 'muting':
- muting = messageObject.data
- break;
- case 'blocking':
- blocking = messageObject.data
- followers_count = followers_count + (blocking ? -1 : 0)
- break;
- case 'followed_by':
- followed_by = messageObject.data
- break;
- }
- }
- }
- // The effective value will be restricted by ApplicationWindow.allowedOrientations
- allowedOrientations: Orientation.All
- Component.onCompleted: {
- var msg;
-
- if (user_id) {
- msg = {
- 'action' : "accounts/relationships/",
- 'params' : [ {name: "id", data: user_id}],
- 'conf' : Logic.conf
- };
- worker.sendMessage(msg);
- msg = {
- 'action' : "accounts/"+user_id,
- 'conf' : Logic.conf
- };
- worker.sendMessage(msg);
- } else {
- var instance = Logic.conf['instance'].split("//")
- msg = {
- 'action' : "accounts/search?limit=1&q="+username.replace("@"+instance[1], ""),
- 'conf' : Logic.conf
- };
- worker.sendMessage(msg);
- }
- }
-
-
-
- MyList {
- id: list
- header: ProfileHeader {
- id: header
- title: display_name
- description: username
- image: profileImage
- }
-
- anchors {
- top: parent.top
- bottom: expander.top
- left: parent.left
- right: parent.right
- }
- clip: true
-
- mdl: ListModel {}
- type: "accounts/"+user_id+"/statuses"
- vars: {}
- conf: Logic.conf
- }
-
-
- ExpandingSectionGroup {
- id: expander
- //currentIndex: 0
- anchors {
- bottom: parent.bottom
- left: parent.left
- right: parent.right
- }
- ExpandingSection {
- title: qsTr("Summary")
- content.sourceComponent: Column {
- spacing: Theme.paddingMedium
- anchors.bottomMargin: Theme.paddingLarge
- DetailItem {
- visible: followers_count ? true : false
- label: qsTr("Followers")
- value: followers_count
- }
- DetailItem {
- visible: following_count ? true : false
- label: qsTr("Following")
- value: (following_count)
- }
- DetailItem {
- visible: statuses_count ? true : false
- label: qsTr("Statuses")
- value: (statuses_count)
- }
- DetailItem {
- visible: favourites_count ? true : false
- label: qsTr("Favourites")
- value: (favourites_count)
- }
-
- Column {
- spacing: Theme.paddingMedium
- anchors.horizontalCenter: parent.horizontalCenter
- Button {
- id: btnFollow
- text: (following ? qsTr("Unfollow") : (requested ? qsTr("Follow request sent!") : qsTr("Follow")))
- onClicked: {
- var msg = {
- 'method' : 'POST',
- 'params' : [],
- 'action' : "accounts/" + user_id + (following ? '/unfollow':'/follow'),
- 'conf' : Logic.conf
- };
- worker.sendMessage(msg);
- }
- }
- Button {
- id: btnMute
- text: (muting ? qsTr("Unmute") : qsTr("Mute"))
- onClicked: {
- var msg = {
- 'method' : 'POST',
- 'params' : [],
- 'action' : "accounts/" + user_id + (muting ? '/unmute':'/mute'),
- 'conf' : Logic.conf
- };
- worker.sendMessage(msg);
- }
- }
- Button {
- id: btnBlock
- text: (blocking ? qsTr("Unblock") : qsTr("Block") )
- onClicked: {
- var msg = {
- 'method' : 'POST',
- 'params' : [],
- 'action' : "accounts/" + user_id + (blocking ? '/unblock':'/block'),
- 'conf' : Logic.conf
- };
- worker.sendMessage(msg);
- }
- }
- }
- Label {
- text: " "
- }
- }
-
- }
- ExpandingSection {
- title: qsTr("Bio")
- content.sourceComponent: Column {
- spacing: Theme.paddingMedium
- anchors.bottomMargin: Theme.paddingLarge
- Text {
- x: Theme.horizontalPageMargin
- width: parent.width - ( 2 * Theme.horizontalPageMargin )
- id: txtnote
- text: note
- font.pixelSize: Theme.fontSizeExtraSmall
- color: Theme.secondaryColor
- linkColor: Theme.secondaryHighlightColor
- wrapMode: Text.Wrap
- anchors {
- horizontalCenter: parent.horizontalCenter
- }
- onLinkActivated: {
- var test = link.split("/")
- console.log(link)
- console.log(JSON.stringify(test))
- console.log(JSON.stringify(test.length))
-
- if (test.length === 5 && (test[3] === "tags" || test[3] === "tag") ) {
- pageStack.pop(pageStack.find(function(page) {
- var check = page.isFirstPage === true;
- if (check)
- page.onLinkActivated(link)
- return check;
- }));
- send(link)
-
- } else if (test.length === 4 && test[3][0] === "@" ) {
- tlSearch.search = decodeURIComponent("@"+test[3].substring(1)+"@"+test[2])
- slideshow.positionViewAtIndex(4, ListView.SnapToItem)
- navigation.navigateTo('search')
-
- } else {
- Qt.openUrlExternally(link);
- }
- }
-
- }
- Column {
- spacing: Theme.paddingMedium
- anchors.horizontalCenter: parent.horizontalCenter
- Button {
- id: btnUrl
- text: qsTr("Open Profile in Browser")
- onClicked: {
- Qt.openUrlExternally(url);
- }
- }
- }
- Label {
- text: " "
- }
- }
- }
- }
-
-
-
-}
diff --git a/qml/pages/ProfilePage.qml b/qml/pages/ProfilePage.qml
new file mode 100644
index 0000000..4478e4c
--- /dev/null
+++ b/qml/pages/ProfilePage.qml
@@ -0,0 +1,373 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+import QtGraphicalEffects 1.0
+import "../lib/API.js" as Logic
+import "./components/"
+
+
+Page {
+ id: profilePage
+
+ property ListModel tweets
+ property string display_name: ""
+ property string username: ""
+ property string profileImage: ""
+ property string profileBackground: ""
+ property string note: ""
+ property string url: ""
+ property string user_id: ""
+ property int statuses_count
+ property int following_count
+ property int followers_count
+ property int favourites_count
+ property int reblogs_count
+ property int count_moments
+ property bool locked: false
+ property bool bot: false
+ property bool following: false
+ property bool requested: false
+ property bool followed_by: false
+ property bool blocking: false
+ property bool muting: false
+ property bool domain_blocking: false
+ property date created_at
+
+ WorkerScript {
+ id: worker
+ source: "../lib/Worker.js"
+ onMessage: {
+ console.log(JSON.stringify(messageObject))
+ if(messageObject.action.indexOf("accounts/search") > -1 ){
+ user_id = messageObject.data.id
+ followers_count = messageObject.data.followers_count
+ following_count = messageObject.data.following_count
+ username = messageObject.data.acct
+ display_name = messageObject.data.display_name
+ profileImage = messageObject.data.avatar_static
+ profileBackground = messageObject.data.header_static
+
+ var msg = {
+ 'action' : "accounts/relationships/",
+ 'params' : [ {name: "id", data: user_id}],
+ 'conf' : Logic.conf
+ };
+ worker.sendMessage(msg);
+ list.loadData("prepend")
+ }
+
+ if(messageObject.action === "accounts/relationships/"){
+ console.log(JSON.stringify(messageObject))
+ following= messageObject.data.following
+ requested= messageObject.data.requested
+ followed_by= messageObject.data.followed_by
+ blocking= messageObject.data.blocking
+ muting= messageObject.data.muting
+ domain_blocking= messageObject.data.domain_blocking
+ }
+ switch (messageObject.key) {
+ case 'followers_count':
+ followers_count = messageObject.data
+ break;
+ case 'following_count':
+ following_count = messageObject.data
+ break;
+ case 'acct':
+ // line below was commented out, reason unknown
+ // username = messageObject.data
+ break;
+ case 'locked':
+ locked = messageObject.data
+ break;
+ case 'bot':
+ bot = messageObject.data
+ break;
+ case 'created_at':
+ created_at = messageObject.data
+ break;
+ case 'statuses_count':
+ statuses_count = messageObject.data
+ break;
+ case 'note':
+ note = messageObject.data
+ break;
+ case 'url':
+ url = messageObject.data
+ break;
+ case 'following':
+ following = messageObject.data
+ followers_count = followers_count + (following ? 1 : - 1)
+ break;
+ case 'muting':
+ muting = messageObject.data
+ break;
+ case 'blocking':
+ blocking = messageObject.data
+ followers_count = followers_count + (blocking ? -1 : 0)
+ break;
+ case 'followed_by':
+ followed_by = messageObject.data
+ break;
+ }
+ }
+ }
+
+ // The effective value will be restricted by ApplicationWindow.allowedOrientations
+ allowedOrientations: Orientation.All
+ Component.onCompleted: {
+ var msg
+
+ if (user_id) {
+ msg = {
+ 'action' : "accounts/relationships/",
+ 'params' : [ {name: "id", data: user_id}],
+ 'conf' : Logic.conf
+ }
+ worker.sendMessage(msg)
+ msg = {
+ 'action' : "accounts/"+user_id,
+ 'conf' : Logic.conf
+ }
+ worker.sendMessage(msg)
+ } else {
+ var instance = Logic.conf['instance'].split("//")
+ msg = {
+ 'action' : "accounts/search?limit=1&q="+username.replace("@"+instance[1], ""),
+ 'conf' : Logic.conf
+ }
+ worker.sendMessage(msg)
+ }
+ }
+
+ MyList {
+ id: list
+ header: ProfileHeader {
+ id: profileHeader
+ title: display_name
+ description: username
+ image: profileImage
+ bg: profileBackground
+ }
+ clip: true
+ mdl: ListModel {}
+ type: "accounts/"+user_id+"/statuses"
+ vars: {}
+ conf: Logic.conf
+ anchors {
+ top: parent.top
+ bottom: profileExpander.top
+ left: parent.left
+ right: parent.right
+ }
+ }
+
+ ExpandingSectionGroup { // ProfilePage ExpandingSection
+ id: profileExpander
+ anchors {
+ bottom: parent.bottom
+ left: parent.left
+ right: parent.right
+ }
+
+ ExpandingSection {
+ id: expandingSection1
+ title: qsTr("About")
+ content.sourceComponent: Column {
+ height: Math.min( txtContainer, parent.height * 0.7 )
+ spacing: Theme.paddingLarge
+
+ Item {
+ id: txtContainer
+ width: parent.width
+ height: Math.min( txtNote.height, parent.height * 0.55 )
+ visible: {
+ if ((note.text === "") || ( note.text === "" )) {
+ false
+ } else {
+ true
+ }
+ }
+
+ SilicaFlickable {
+ id: txtFlickable
+ contentWidth: parent.width
+ contentHeight: txtNote.height
+ anchors.fill: parent
+ clip: true
+
+ VerticalScrollDecorator {}
+
+ Label {
+ id: txtNote
+ text: note
+ textFormat: Text.StyledText
+ color: Theme.secondaryColor
+ font.pixelSize: Theme.fontSizeExtraSmall
+ linkColor: Theme.highlightColor
+ wrapMode: Text.Wrap
+ width: parent.width - ( 2 * Theme.horizontalPageMargin )
+ anchors.horizontalCenter: parent.horizontalCenter
+ onLinkActivated: {
+ var test = link.split("/")
+ console.log(link)
+ console.log(JSON.stringify(test))
+ console.log(JSON.stringify(test.length))
+ if (test.length === 5 && (test[3] === "tags" || test[3] === "tag") ) {
+ pageStack.pop(pageStack.find(function(page) {
+ var check = page.isFirstPage === true;
+ if (check)
+ page.onLinkActivated(link)
+ return check;
+ }));
+ send(link)
+ } else if (test.length === 4 && test[3][0] === "@" ) {
+ pageStack.pop(pageStack.find(function(page) {
+ var check = page.isFirstPage === true;
+ if (check)
+ page.onLinkActivated(link)
+ return check;
+ }));
+ } else {
+ Qt.openUrlExternally(link);
+ }
+ }
+ }
+ }
+ }
+
+ Item { // dummy item for spacing
+ height: Theme.paddingSmall
+ }
+
+ Row {
+ id: statsRow
+ spacing: Theme.paddingLarge
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.leftMargin: Theme.paddingLarge
+ anchors.rightMargin: Theme.paddingLarge
+
+ Text {
+ id: txtFollowers
+ visible: followers_count ? true : false
+ text: followers_count+" "+qsTr("Followers")
+ font.pixelSize: Theme.fontSizeExtraSmall
+ color: Theme.highlightColor
+ wrapMode: Text.Wrap
+ }
+
+ Text {
+ id: txtFollowing
+ visible: following_count ? true : false
+ text: following_count+" "+qsTr("Following")
+ font.pixelSize: Theme.fontSizeExtraSmall
+ color: Theme.highlightColor
+ wrapMode: Text.Wrap
+ }
+
+ Text {
+ id: txtStatuses
+ visible: statuses_count ? true : false
+ text: statuses_count+" "+qsTr("Statuses")
+ font.pixelSize: Theme.fontSizeExtraSmall
+ color: Theme.highlightColor
+ wrapMode: Text.Wrap
+ }
+
+ /*Text {
+ id: txtFavourites
+ visible: favourites_count ? true : false
+ text: favourites_count+" "+qsTr("Favourites")
+ font.pixelSize: Theme.fontSizeExtraSmall
+ color: Theme.highlightColor
+ wrapMode: Text.Wrap
+ } */
+ }
+
+ Item { // dummy item for spacing
+ height: Theme.paddingSmall
+ }
+
+ ButtonLayout {
+ id: btnLayout
+ Button {
+ id: btnMention
+ preferredWidth: Theme.buttonWidthSmall
+ text: "Mention"
+ onClicked: {
+ pageStack.push(Qt.resolvedUrl("ConversationPage.qml"), {
+ headerTitle: "Mention",
+ description: "@"+username,
+ type: "new"
+ })
+ }
+ }
+
+ Button {
+ id: btnFollow
+ preferredWidth: Theme.buttonWidthSmall
+ text: (following ? qsTr("Unfollow") : (requested ? qsTr("Requested") : qsTr("Follow")))
+ color: (following ? highlightColor : (requested ? palette.errorColor : palette.primaryColor))
+ onClicked: {
+ var msg = {
+ 'method' : 'POST',
+ 'params' : [],
+ 'action' : "accounts/" + user_id + (following ? '/unfollow':'/follow'),
+ 'conf' : Logic.conf
+ };
+ worker.sendMessage(msg);
+ // to-do: create notification banner "Follow request sent!"
+ }
+ }
+
+ Button {
+ id: btnMute
+ preferredWidth: Theme.buttonWidthSmall
+ text: (muting ? qsTr("Unmute") : qsTr("Mute"))
+ color: (muting ? palette.errorColor : palette.primaryColor)
+ onClicked: {
+ var msg = {
+ 'method' : 'POST',
+ 'params' : [],
+ 'action' : "accounts/" + user_id + (muting ? '/unmute':'/mute'),
+ 'conf' : Logic.conf
+ };
+ worker.sendMessage(msg);
+ }
+ }
+
+ Button {
+ id: btnBlock
+ preferredWidth: Theme.buttonWidthSmall
+ text: (blocking ? qsTr("Unblock") : qsTr("Block") )
+ color: (blocking ? palette.errorColor : palette.primaryColor)
+ onClicked: {
+ var msg = {
+ 'method' : 'POST',
+ 'params' : [],
+ 'action' : "accounts/" + user_id + (blocking ? '/unblock':'/block'),
+ 'conf' : Logic.conf
+ };
+ worker.sendMessage(msg);
+ }
+ }
+ }
+
+ Button {
+ id: btnBrowser
+ text: qsTr("Open in Browser")
+ preferredWidth: Theme.buttonWidthMedium
+ anchors.horizontalCenter: parent.horizontalCenter
+ onClicked: {
+ Qt.openUrlExternally(url)
+ }
+ }
+
+ Rectangle { // dummy item for spacing
+ height: Theme.paddingSmall
+ width: parent.width
+ opacity: 0
+ }
+ }
+ }
+ }
+
+}
diff --git a/qml/pages/Settings.qml b/qml/pages/SettingsPage.qml
similarity index 52%
rename from qml/pages/Settings.qml
rename to qml/pages/SettingsPage.qml
index 00d6874..876929c 100644
--- a/qml/pages/Settings.qml
+++ b/qml/pages/SettingsPage.qml
@@ -1,86 +1,131 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
-
import "../lib/API.js" as Logic
+
Page {
+ id: settingsPage
+ allowedOrientations: Orientation.All
+
SilicaFlickable {
- anchors.fill: parent
contentHeight: column.height + Theme.paddingLarge
contentWidth: parent.width
+ anchors.fill: parent
+
RemorsePopup { id: remorsePopup }
-
VerticalScrollDecorator {}
+
Column {
id: column
- spacing: Theme.paddingSmall
+ spacing: Theme.paddingMedium
width: parent.width
+
PageHeader {
title: qsTr("Settings")
}
- Column {
- // No spacing in this column
+
+ SectionHeader { text: qsTr("Options")}
+
+ IconTextSwitch {
+ text: qsTr("Load Images in Toots")
+ description: qsTr("Disable this option if you want to preserve your data connection")
+ icon.source: "image://theme/icon-m-image"
+ enabled: true
+ checked: typeof Logic.conf['loadImages'] !== "undefined" && Logic.conf['loadImages']
+ onClicked: {
+ Logic.conf['loadImages'] = checked
+ }
+ }
+
+ SectionHeader { text: qsTr("Account")}
+
+ Item {
+ id: removeAccount
width: parent.width
- IconTextSwitch {
- id: removeAccount
- text: Logic.conf['login'] ? qsTr("Remove Account") : qsTr("Add Account")
- description: Logic.conf['login'] ? qsTr("Deauthorize this app and remove your account") : qsTr("Authorize this app to access your Mastodon account")
- icon.source: Logic.conf['login'] ? "image://theme/icon-m-contact" : "image://theme/icon-m-add"
-
-
- onCheckedChanged: {
- remorsePopup.execute(removeAccount.text, function() {
- busy = true;
- checked = false;
- timer1.start();
- if (Logic.conf['login']) {
- Logic.conf['login'] = false
- Logic.conf['instance'] = null;
- Logic.conf['api_user_token'] = null;
- }
- pageStack.push(Qt.resolvedUrl("LoginPage.qml"))
- })
- }
-
- /* busy = true;
- checked = false;
- timer1.start()
-
- }*/
- Timer {
- id: timer1
- interval: 4700
- onTriggered: parent.busy = false
- }
+ height: txtRemoveAccount.height + btnRemoveAccount.height + Theme.paddingLarge
+ anchors {
+ left: parent.left
+ leftMargin: Theme.horizontalPageMargin
+ right: parent.right
+ rightMargin: Theme.paddingLarge
}
- IconTextSwitch {
- //enabled: false
- checked: typeof Logic.conf['loadImages'] !== "undefined" && Logic.conf['loadImages']
- text: qsTr("Load images in toots")
- description: qsTr("Disable this option if you want to preserve your data connection")
- icon.source: "image://theme/icon-m-image"
- onClicked: {
- Logic.conf['loadImages'] = checked
- }
+
+ Icon {
+ id: icnRemoveAccount
+ color: Theme.highlightColor
+ width: Theme.iconSizeMedium
+ fillMode: Image.PreserveAspectFit
+ source: Logic.conf['login'] ? "image://theme/icon-m-contact" : "image://theme/icon-m-add"
+ anchors.right: parent.right
}
- IconTextSwitch {
- text: qsTr("Translate")
- description: qsTr("Use Transifex to help with app translation to your language")
- icon.source: "image://theme/icon-m-font-size"
- onCheckedChanged: {
- busy = true;
- checked = false;
- Qt.openUrlExternally("https://www.transifex.com/dysko/tooter/");
- timer2.start()
+
+ Column {
+ id: clnRemoveAccount
+ spacing: Theme.paddingMedium
+ anchors {
+ left: parent.left
+ right: icnRemoveAccount.left
}
- Timer {
- id: timer2
- interval: 4700
- onTriggered: parent.busy = false
+
+ Button {
+ id: btnRemoveAccount
+ text: Logic.conf['login'] ? qsTr("Remove Account") : qsTr("Add Account")
+ width: Theme.buttonWidthMedium
+ anchors.horizontalCenter: parent.horizontalCenter
+ onClicked: {
+ remorsePopup.execute(btnRemoveAccount.text, function() {
+ if (Logic.conf['login']) {
+ Logic.conf['login'] = false
+ Logic.conf['instance'] = null;
+ Logic.conf['api_user_token'] = null;
+ }
+ pageStack.push(Qt.resolvedUrl("LoginPage.qml"))
+ })
+ }
+
+ Timer {
+ id: timer1
+ interval: 4700
+ onTriggered: parent.busy = false
+ }
+ }
+
+ Label {
+ id: txtRemoveAccount
+ text: Logic.conf['login'] ? qsTr("Deauthorize this app from using your account and remove account data from phone") : qsTr("Authorize this app to access your Mastodon account")
+ font.pixelSize: Theme.fontSizeExtraSmall
+ wrapMode: Text.Wrap
+ color: Theme.highlightColor
+ anchors {
+ left: parent.left
+ right: parent.right
+ rightMargin: Theme.paddingLarge + icnRemoveAccount
+ }
}
}
}
+
+ SectionHeader {
+ text: qsTr("Translate")
+ }
+
+ LinkedLabel {
+ text: qsTr("Use Transifex to help with app translation to your language.")
+ textFormat: Text.StyledText
+ color: Theme.highlightColor
+ linkColor: Theme.primaryColor
+ font.family: Theme.fontFamilyHeading
+ font.pixelSize: Theme.fontSizeExtraSmall
+ wrapMode: Text.Wrap
+ anchors {
+ left: parent.left
+ leftMargin: Theme.horizontalPageMargin
+ right: parent.right
+ rightMargin: Theme.paddingLarge
+ }
+ }
+
SectionHeader {
text: qsTr("Credits")
}
@@ -90,52 +135,61 @@ Page {
anchors {
left: parent.left
right: parent.right
- rightMargin: Theme.horizontalPageMargin
+ rightMargin: Theme.paddingLarge
}
+
Repeater {
model: ListModel {
+
ListElement {
name: "Duลกko Angireviฤ"
desc: qsTr("UI/UX design and development")
mastodon: "dysko@mastodon.social"
mail: ""
}
+
ListElement {
name: "Miodrag Nikoliฤ"
desc: qsTr("Visual identity")
mastodon: ""
mail: "micotakis@gmail.com"
}
+
ListElement {
name: "Molan"
desc: qsTr("Development and translations")
- mastodon: ""
- mail: "mol_an@sunrise.ch"
+ mastodon: "molan@fosstodon.org"
+ mail: ""
}
+
ListElement {
name: "Quentin PAGรS / Quenti โ"
desc: qsTr("Occitan & French translation")
mastodon: "Quenti@framapiaf.org"
mail: ""
}
+
ListElement {
name: "Luchy Kon / dashinfantry"
desc: qsTr("Chinese translation")
mastodon: ""
mail: "dashinfantry@gmail.com"
}
+
ListElement {
name: "Andrรฉ Koot"
desc: qsTr("Dutch translation")
mastodon: "meneer@mastodon.social"
mail: "https://twitter.com/meneer"
}
+
ListElement {
name: "CarmenFdez"
desc: qsTr("Spanish translation")
mastodon: ""
mail: ""
}
+
ListElement {
name: "Mohamed-Touhami MAHDI"
desc: qsTr("Added README file")
@@ -147,31 +201,29 @@ Page {
Item {
width: parent.width
height: Theme.itemSizeMedium
+
IconButton {
id: btn
+ icon.source: "image://theme/" + (model.mastodon !== "" ? "icon-m-outline-chat" : "icon-m-mail") + "?" + (pressed
+ ? Theme.highlightColor : Theme.primaryColor)
anchors {
verticalCenter: parent.verticalCenter
right: parent.right
}
- icon.source: "image://theme/" + (model.mastodon !== "" ? "icon-m-contact" : "icon-m-mail") + "?" + (pressed
- ? Theme.highlightColor
- : Theme.primaryColor)
onClicked: {
if (model.mastodon !== ""){
var m = Qt.createQmlObject('import QtQuick 2.0; ListModel { }', Qt.application, 'InternalQmlObject');
- pageStack.push(Qt.resolvedUrl("Conversation.qml"), {
- toot_id: 0,
- title: model.name,
+ pageStack.push(Qt.resolvedUrl("ConversationPage.qml"), {
+ headerTitle: "Mention",
description: '@'+model.mastodon,
- avatar: "",
- mdl: m,
- type: "reply"
+ type: "new"
})
} else {
Qt.openUrlExternally("mailto:"+model.mail);
}
}
}
+
Column {
anchors {
verticalCenter: parent.verticalCenter
@@ -184,9 +236,10 @@ Page {
Label {
id: lblName
text: model.name
- color: Theme.secondaryColor
+ color: Theme.highlightColor
font.pixelSize: Theme.fontSizeSmall
}
+
Label {
text: model.desc
color: Theme.secondaryHighlightColor
@@ -198,4 +251,5 @@ Page {
}
}
}
+
}
diff --git a/qml/pages/components/EmojiSelect.qml b/qml/pages/components/EmojiSelect.qml
new file mode 100644
index 0000000..45a6f10
--- /dev/null
+++ b/qml/pages/components/EmojiSelect.qml
@@ -0,0 +1,166 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+
+
+Component {
+ id: emojiComponent
+
+ Dialog {
+ id: emoticonsDialog
+ canAccept: false //selector.currentIndex >= 0
+ onAcceptPendingChanged: {
+ if (acceptPending) {
+ // Tell the destination page what the selected category is
+ // acceptDestinationInstance.category = selector.value
+ }
+ }
+
+ SilicaGridView {
+ id: gridView
+ header: PageHeader {
+ title: qsTr("Emojis")
+ description: qsTr("Tap to insert")
+ }
+ cellWidth: gridView.width / 6
+ cellHeight: cellWidth
+ anchors.fill: parent
+ model: ListModel {
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐
" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐" }
+ ListElement { section: "smileys"; glyph: "๐ " }
+ ListElement { section: "smileys"; glyph: "๐ก" }
+ ListElement { section: "smileys"; glyph: "๐ข" }
+ ListElement { section: "smileys"; glyph: "๐ฃ" }
+ ListElement { section: "smileys"; glyph: "๐ค" }
+ ListElement { section: "smileys"; glyph: "๐ฅ" }
+ ListElement { section: "smileys"; glyph: "๐จ" }
+ ListElement { section: "smileys"; glyph: "๐ฉ" }
+ ListElement { section: "smileys"; glyph: "๐ช" }
+ ListElement { section: "smileys"; glyph: "๐ซ" }
+ ListElement { section: "smileys"; glyph: "๐ญ" }
+ ListElement { section: "smileys"; glyph: "๐ฐ" }
+ ListElement { section: "smileys"; glyph: "๐ฑ" }
+ ListElement { section: "smileys"; glyph: "๐ฒ" }
+ ListElement { section: "smileys"; glyph: "๐ณ" }
+ ListElement { section: "smileys"; glyph: "๐ต" }
+ ListElement { section: "smileys"; glyph: "๐ท" }
+ ListElement { section: "smileys"; glyph: "๐ธ" }
+ ListElement { section: "smileys"; glyph: "๐น" }
+ ListElement { section: "smileys"; glyph: "๐บ" }
+ ListElement { section: "smileys"; glyph: "๐ป" }
+ ListElement { section: "smileys"; glyph: "๐ผ" }
+ ListElement { section: "smileys"; glyph: "๐ฝ" }
+ ListElement { section: "smileys"; glyph: "๐พ" }
+ ListElement { section: "smileys"; glyph: "๐ฟ" }
+ ListElement { section: "smileys"; glyph: "๐" }
+
+ ListElement { section: "People and Fantasy"; glyph: "๐
" }
+ ListElement { section: "People and Fantasy"; glyph: "๐" }
+ ListElement { section: "People and Fantasy"; glyph: "๐" }
+ ListElement { section: "People and Fantasy"; glyph: "๐" }
+ ListElement { section: "People and Fantasy"; glyph: "๐" }
+ ListElement { section: "People and Fantasy"; glyph: "๐" }
+ ListElement { section: "People and Fantasy"; glyph: "๐" }
+ ListElement { section: "People and Fantasy"; glyph: "๐" }
+ ListElement { section: "People and Fantasy"; glyph: "๐" }
+ ListElement { section: "People and Fantasy"; glyph: "๐" }
+ ListElement { section: "People and Fantasy"; glyph: "๐" }
+ ListElement { section: "People and Fantasy"; glyph: "๐" }
+ ListElement { section: "People and Fantasy"; glyph: "โ" }
+ ListElement { section: "People and Fantasy"; glyph: "๐ช" }
+ ListElement { section: "People and Fantasy"; glyph: "๐" }
+ ListElement { section: "People and Fantasy"; glyph: "๐" }
+
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐
" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+ ListElement { section: "Transport and Map"; glyph: "๐ข" }
+ ListElement { section: "Transport and Map"; glyph: "๐จ" }
+ ListElement { section: "Transport and Map"; glyph: "๐ฉ" }
+ ListElement { section: "Transport and Map"; glyph: "๐ช" }
+ ListElement { section: "Transport and Map"; glyph: "๐ซ" }
+ ListElement { section: "Transport and Map"; glyph: "๐ฌ" }
+ ListElement { section: "Transport and Map"; glyph: "๐ญ" }
+ ListElement { section: "Transport and Map"; glyph: "๐ฒ" }
+ ListElement { section: "Transport and Map"; glyph: "๐ถ" }
+ ListElement { section: "Transport and Map"; glyph: "๐น" }
+ ListElement { section: "Transport and Map"; glyph: "๐บ" }
+ ListElement { section: "Transport and Map"; glyph: "๐ป" }
+ ListElement { section: "Transport and Map"; glyph: "๐ผ" }
+ ListElement { section: "Transport and Map"; glyph: "๐ฝ" }
+ ListElement { section: "Transport and Map"; glyph: "๐พ" }
+ ListElement { section: "Transport and Map"; glyph: "๐" }
+
+ ListElement { section: "Horoscope Signs"; glyph: "โ" }
+ ListElement { section: "Horoscope Signs"; glyph: "โ" }
+ ListElement { section: "Horoscope Signs"; glyph: "โ" }
+ ListElement { section: "Horoscope Signs"; glyph: "โ" }
+ ListElement { section: "Horoscope Signs"; glyph: "โ" }
+ ListElement { section: "Horoscope Signs"; glyph: "โ" }
+ ListElement { section: "Horoscope Signs"; glyph: "โ" }
+ ListElement { section: "Horoscope Signs"; glyph: "โ" }
+ ListElement { section: "Horoscope Signs"; glyph: "โ" }
+ ListElement { section: "Horoscope Signs"; glyph: "โ" }
+ ListElement { section: "Horoscope Signs"; glyph: "โ" }
+ ListElement { section: "Horoscope Signs"; glyph: "โ" }
+ }
+ delegate: BackgroundItem {
+ width: gridView.cellWidth
+ height: gridView.cellHeight
+
+ Label {
+ text: glyph
+ font.pixelSize: Theme.fontSizeLarge
+ color: (highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor)
+ anchors.centerIn: parent
+ }
+ onClicked: {
+ var cursorPosition = toot.cursorPosition
+ toot.text = toot.text.substring(
+ 0, cursorPosition) + model.glyph + toot.text.substring(
+ cursorPosition)
+ toot.cursorPosition = cursorPosition + model.glyph.length
+ emoticonsDialog.canAccept = true
+ emoticonsDialog.accept()
+ }
+ }
+
+ VerticalScrollDecorator {flickable: listEmojis }
+ }
+ }
+
+
+}
diff --git a/qml/pages/components/InfoBanner.qml b/qml/pages/components/InfoBanner.qml
new file mode 100644
index 0000000..8d33b9a
--- /dev/null
+++ b/qml/pages/components/InfoBanner.qml
@@ -0,0 +1,59 @@
+import QtQuick 2.0
+import Sailfish.Silica 1.0
+
+
+DockedPanel {
+ id: root
+ dock: Dock.Top
+ width: parent.width
+ height: content.height
+
+ Rectangle {
+ id: content
+ color: Theme.highlightBackgroundColor
+ width: root.width
+ height: infoLabel.height + 2 * Theme.paddingMedium
+
+ Label {
+ id: infoLabel
+ text : ""
+ font.family: Theme.fontFamilyHeading
+ font.pixelSize: Theme.fontSizeMedium
+ color: Theme.primaryColor
+ wrapMode: Text.WrapAnywhere
+ width: parent.width
+ anchors {
+ left: parent.left
+ leftMargin: Theme.horizontalPageMargin*2
+ right: parent.right
+ rightMargin: Theme.horizontalPageMargin
+ verticalCenter: parent.verticalCenter
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ root.hide()
+ autoClose.stop()
+ }
+ }
+ }
+
+ function showText(text) {
+ infoLabel.text = text
+ root.show()
+ autoClose.start()
+ }
+
+ Timer {
+ id: autoClose
+ interval: 4500
+ running: false
+ onTriggered: {
+ root.hide()
+ stop()
+ }
+ }
+
+}
diff --git a/qml/pages/components/ItemUser.qml b/qml/pages/components/ItemUser.qml
index 809c97e..d1df686 100644
--- a/qml/pages/components/ItemUser.qml
+++ b/qml/pages/components/ItemUser.qml
@@ -4,9 +4,11 @@ import Sailfish.Silica 1.0
BackgroundItem {
id: delegate
+
signal openUser (string notice)
- height: Theme.itemSizeMedium
+
width: parent.width
+ height: Theme.itemSizeMedium
Rectangle {
id: avatar
@@ -23,6 +25,7 @@ BackgroundItem {
anchors.fill: parent
source: model.account_avatar
}
+
BusyIndicator {
size: BusyIndicatorSize.Small
opacity: img.status === Image.Ready ? 0.0 : 1.0
@@ -30,16 +33,19 @@ BackgroundItem {
running: avatar.status !== Image.Ready;
anchors.centerIn: parent
}
+
MouseArea {
anchors.fill: parent
- onClicked: pageStack.push(Qt.resolvedUrl("./../Profile.qml"), {
+ onClicked: pageStack.push(Qt.resolvedUrl("./../ProfilePage.qml"), {
"display_name": model.account_display_name,
"username": model.account_acct,
"user_id": model.account_id,
- "profileImage": model.account_avatar
+ "profileImage": model.account_avatar,
+ "profileBackground": model.account_header
})
}
}
+
Column {
anchors.left: avatar.right
anchors.leftMargin: Theme.paddingLarge
@@ -63,6 +69,8 @@ BackgroundItem {
"display_name": model.account_display_name,
"username": model.account_acct,
"user_id": model.account_id,
- "profileImage": model.account_avatar
+ "profileImage": model.account_avatar,
+ "profileBackground": model.account_header
})
+
}
diff --git a/qml/pages/components/MediaBlock.qml b/qml/pages/components/MediaBlock.qml
index e31af8d..bf3c047 100644
--- a/qml/pages/components/MediaBlock.qml
+++ b/qml/pages/components/MediaBlock.qml
@@ -4,10 +4,12 @@ import QtMultimedia 5.0
Item {
+ id: holder
+
property ListModel model
property double wRatio : 16/9
property double hRatio : 9/16
- id: holder
+
width: width
height: height
Component.onCompleted: {
@@ -74,8 +76,6 @@ Item {
}
}
-
-
MyImage {
id: placeholder1
width: 2
@@ -94,6 +94,7 @@ Item {
}
}
}
+
MyImage {
id: placeholder2
width: 2
@@ -112,6 +113,7 @@ Item {
}
}
}
+
MyImage {
id: placeholder3
width: 2
@@ -130,6 +132,7 @@ Item {
}
}
}
+
MyImage {
id: placeholder4
width: 2
@@ -148,8 +151,5 @@ Item {
}
}
}
+
}
-
-
-
-
diff --git a/qml/pages/components/ImageFullScreen.qml b/qml/pages/components/MediaFullScreen.qml
similarity index 78%
rename from qml/pages/components/ImageFullScreen.qml
rename to qml/pages/components/MediaFullScreen.qml
index dba23a8..324fa76 100644
--- a/qml/pages/components/ImageFullScreen.qml
+++ b/qml/pages/components/MediaFullScreen.qml
@@ -2,11 +2,14 @@ import QtQuick 2.0
import Sailfish.Silica 1.0
import QtMultimedia 5.0
-Page {
- id: imagePage
+
+FullscreenContentPage {
+ id: mediaPage
+
property string type: ""
property string previewURL: ""
property string mediaURL: ""
+
allowedOrientations: Orientation.All
Component.onCompleted: function(){
console.log(type)
@@ -14,31 +17,35 @@ Page {
console.log(mediaURL)
if (type != 'gifv' && type != 'video') {
imagePreview.source = mediaURL
- imageFlickable.visible = true;
+ imageFlickable.visible = true
} else {
video.source = mediaURL
video.fillMode = VideoOutput.PreserveAspectFit
video.play()
- videoFlickable.visible = true;
+ videoFlickable.visible = true
}
}
+
Flickable {
- id: videoFlickable
+ id: videoFlickable
visible: false
- anchors.fill: parent
- contentWidth: imageContainer.width; contentHeight: imageContainer.height
clip: true
+ contentWidth: imageContainer.width
+ contentHeight: imageContainer.height
+ anchors.fill: parent
+
Image {
id: videoPreview
fillMode: Image.PreserveAspectFit
anchors.fill: parent
source: previewURL
}
+
Video {
id: video
anchors.fill: parent
onErrorStringChanged: function(){
- videoError.visible = true;
+ videoError.visible = true
}
onStatusChanged: {
console.log(status)
@@ -49,10 +56,8 @@ Page {
case MediaPlayer.EndOfMedia:
console.log("EndOfMedia")
return;
-
}
}
-
onPlaybackStateChanged: {
console.log(playbackState)
switch (playbackState){
@@ -63,12 +68,10 @@ Page {
playerIcon.icon.source = "image://theme/icon-m-play"
return;
case MediaPlayer.StoppedState:
- playerIcon.icon.source = "image://theme/icon-m-stop"
+ playerIcon.icon.source = "image://theme/icon-m-reload"
return;
}
}
-
-
onPositionChanged: function(){
//console.log(duration)
//console.log(bufferProgress)
@@ -79,18 +82,23 @@ Page {
playerProgress.minimumValue = 0
playerProgress.value = position
}
+ }
+ onStopped: function() {
+ if (video.duration < 30000)
+ video.play()
+ else
+ video.stop()
+ }
- }
- onStopped: function(){
- play()
- }
IconButton {
id: playerIcon
- anchors.left: parent.left
- anchors.bottom: parent.bottom
- anchors.leftMargin: Theme.paddingLarge
- anchors.bottomMargin: Theme.paddingMedium
icon.source: "image://theme/icon-m-play"
+ anchors {
+ left: parent.left
+ bottom: parent.bottom
+ leftMargin: Theme.horizontalPageMargin
+ bottomMargin: Theme.horizontalPageMargin
+ }
onClicked: function() {
if (video.playbackState === MediaPlayer.PlayingState)
video.pause()
@@ -100,50 +108,17 @@ Page {
}
ProgressBar {
- indeterminate: true
id: playerProgress
- anchors.left: playerIcon.right
- anchors.right: videoDlBtn.left
-
- anchors.verticalCenter: playerIcon.verticalCenter
- anchors.leftMargin: 0
- anchors.bottomMargin: Theme.paddingMedium
- }
- IconButton {
- id: videoDlBtn
- visible: true
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- anchors.rightMargin: Theme.paddingLarge
- anchors.bottomMargin: Theme.paddingMedium
- //width: Theme.iconSizeMedium+Theme.paddingMedium*2
- icon.source: "image://theme/icon-m-cloud-download"
- onClicked: {
- var filename = mediaURL.split("/");
- FileDownloader.downloadFile(mediaURL, filename[filename.length-1]);
+ indeterminate: true
+ width: 400
+ anchors {
+ verticalCenter: playerIcon.verticalCenter
+ left: playerIcon.right
+ right: parent.right
+ rightMargin: Theme.horizontalPageMargin + Theme.iconSizeMedium
+ bottomMargin: Theme.horizontalPageMargin
}
}
- Rectangle {
- visible: videoError.text != ""
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- color: Theme.highlightDimmerColor
- height: videoError.height + 2*Theme.paddingMedium
- width: parent.width
- Label {
- anchors.centerIn: parent
- id: videoError
- width: parent.width - 2*Theme.paddingMedium
- wrapMode: Text.WordWrap
- height: contentHeight
- visible: false;
- font.pixelSize: Theme.fontSizeSmall;
- text: video.errorString
- color: Theme.highlightColor
- }
- }
-
MouseArea {
anchors.fill: parent
@@ -154,17 +129,43 @@ Page {
video.play()
}
}
+
+ Rectangle {
+ visible: videoError.text != ""
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ color: Theme.highlightDimmerColor
+ height: videoError.height + 2*Theme.paddingMedium
+ width: parent.width
+
+ Label {
+ id: videoError
+ visible: false
+ text: video.errorString
+ font.pixelSize: Theme.fontSizeSmall
+ color: Theme.highlightColor
+ wrapMode: Text.Wrap
+ width: parent.width - 2*Theme.paddingMedium
+ height: contentHeight
+ anchors.centerIn: parent
+ }
+ }
+
}
}
+
Flickable {
id: imageFlickable
visible: false
- anchors.fill: parent
- contentWidth: imageContainer.width; contentHeight: imageContainer.height
+ contentWidth: imageContainer.width
+ contentHeight: imageContainer.height
clip: true
- onHeightChanged: if (imagePreview.status === Image.Ready) imagePreview.fitToScreen();
-
+ anchors.fill: parent
+ onHeightChanged: if (imagePreview.status === Image.Ready) {
+ imagePreview.fitToScreen()
+ }
Item {
id: imageContainer
@@ -177,18 +178,17 @@ Page {
property real prevScale
function fitToScreen() {
- scale = Math.min(imageFlickable.width / width, imageFlickable.height / height, 1)
+ scale = Math.min(imageFlickable.width / width, imageFlickable.height / height, imageFlickable.width, imageFlickable.height)
pinchArea.minScale = scale
prevScale = scale
}
- anchors.centerIn: parent
fillMode: Image.PreserveAspectFit
cache: true
asynchronous: true
- sourceSize.height: 1000;
- smooth: false
-
+ sourceSize.width: mediaPage.width
+ smooth: true
+ anchors.centerIn: parent
onStatusChanged: {
if (status == Image.Ready) {
fitToScreen()
@@ -221,15 +221,16 @@ Page {
PinchArea {
id: pinchArea
- opacity: 0.3
+
property real minScale: 1.0
property real maxScale: 3.0
+ opacity: 0.3
anchors.fill: parent
enabled: imagePreview.status === Image.Ready
pinch.target: imagePreview
pinch.minimumScale: minScale * 0.5 // This is to create "bounce back effect"
- pinch.maximumScale: maxScale * 1.5 // when over zoomed
+ pinch.maximumScale: maxScale * 1.5 // when over zoomed}
onPinchFinished: {
imageFlickable.returnToBounds()
@@ -242,6 +243,7 @@ Page {
bounceBackAnimation.start()
}
}
+
NumberAnimation {
id: bounceBackAnimation
target: imagePreview
@@ -267,39 +269,57 @@ Page {
Component {
id: loadingIndicator
-
Item {
+ width: mediaPage.width
height: childrenRect.height
- width: imagePage.width
ProgressCircle {
id: imageLoadingIndicator
- anchors.horizontalCenter: parent.horizontalCenter
progressValue: imagePreview.progress
+ progressColor: inAlternateCycle ? Theme.highlightColor : Theme.highlightDimmerColor
+ backgroundColor: inAlternateCycle ? Theme.highlightDimmerColor : Theme.highlightColor
+ anchors.horizontalCenter: parent.horizontalCenter
}
}
}
}
+
Component {
id: failedLoading
Text {
- font.pixelSize: Theme.fontSizeSmall;
text: qsTr("Error loading")
+ font.pixelSize: Theme.fontSizeSmall;
color: Theme.highlightColor
}
}
+
IconButton {
- visible: true
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- anchors.rightMargin: Theme.paddingLarge
- anchors.bottomMargin: Theme.paddingMedium
- //width: Theme.iconSizeMedium+Theme.paddingMedium*2
+ id: dismissBtn
+ icon.source: "image://theme/icon-m-dismiss"
+ anchors {
+ top: parent.top
+ topMargin: Theme.horizontalPageMargin
+ right: parent.right
+ rightMargin: Theme.horizontalPageMargin
+ }
+ onClicked: pageStack.pop()
+ }
+
+ IconButton {
+ id: mediaDlBtn
+ anchors {
+ right: parent.right
+ rightMargin: Theme.horizontalPageMargin
+ bottom: parent.bottom
+ bottomMargin: Theme.horizontalPageMargin
+ }
icon.source: "image://theme/icon-m-cloud-download"
onClicked: {
var filename = mediaURL.split("/");
FileDownloader.downloadFile(mediaURL, filename[filename.length-1]);
}
}
+
VerticalScrollDecorator { flickable: imageFlickable }
}
+
diff --git a/qml/pages/components/MiniHeader.qml b/qml/pages/components/MiniHeader.qml
index 6a9f6f9..e227fd0 100644
--- a/qml/pages/components/MiniHeader.qml
+++ b/qml/pages/components/MiniHeader.qml
@@ -1,71 +1,72 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
+
Item {
- id: miniheader
+ id: miniHeader
height: lblName.height
width: parent.width
Label {
id: lblName
+ text:
+ if (account_display_name === "") {
+ account_username.split('@')[0]
+ }
+ else account_display_name
+ font.weight: Font.Bold
+ font.pixelSize: Theme.fontSizeSmall
+ color: if (myList.type === "notifications" && ( model.type === "favourite" || model.type === "reblog" )) {
+ (pressed ? Theme.secondaryHighlightColor : (!highlight ? Theme.secondaryColor : Theme.secondaryHighlightColor))
+ } else (pressed ? Theme.highlightColor : (!highlight ? Theme.primaryColor : Theme.secondaryColor))
+ truncationMode: TruncationMode.Fade
+ width: contentWidth > parent.width /2 ? parent.width /2 : contentWidth
anchors {
left: parent.left
leftMargin: Theme.paddingMedium
}
- text:
- if (account_display_name === "") {
- account_username.split('@')[0]
- }
- else account_display_name
- width: contentWidth > parent.width /2 ? parent.width /2 : contentWidth
- truncationMode: TruncationMode.Fade
- font.weight: Font.Bold
- font.pixelSize: Theme.fontSizeSmall
- color: (pressed ? Theme.highlightColor : Theme.primaryColor)
}
Image {
- id: iconVerified
+ id: icnLocked
+ visible: account_locked
+ opacity: 0.8
+ source: "image://theme/icon-s-secure?" + (pressed ? Theme.highlightColor : Theme.primaryColor)
+ width: account_locked ? Theme.iconSizeExtraSmall*0.8 : 0
+ height: width
y: Theme.paddingLarge
anchors {
left: lblName.right
leftMargin: Theme.paddingSmall
verticalCenter: lblName.verticalCenter
}
- visible: account_locked
- width: account_locked ? Theme.iconSizeExtraSmall*0.8 : 0
- opacity: 0.8
- height: width
- source: "image://theme/icon-s-secure?" + (pressed
- ? Theme.highlightColor
- : Theme.primaryColor)
}
-
Label {
id: lblScreenName
+ text: '@'+account_username
+ font.pixelSize: Theme.fontSizeExtraSmall
+ color: (pressed ? Theme.secondaryHighlightColor : Theme.secondaryColor)
+ truncationMode: TruncationMode.Fade
anchors {
- left: iconVerified.right
+ left: icnLocked.right
right: lblDate.left
leftMargin: Theme.paddingMedium
baseline: lblName.baseline
}
- truncationMode: TruncationMode.Fade
- text: '@'+account_username
- font.pixelSize: Theme.fontSizeExtraSmall
- color: (pressed ? Theme.secondaryHighlightColor : Theme.secondaryColor)
}
- Label {
+ Label {
id: lblDate
- color: (pressed ? Theme.highlightColor : Theme.primaryColor)
text: Format.formatDate(created_at, new Date() - created_at < 60*60*1000 ? Formatter.DurationElapsedShort : Formatter.TimeValueTwentyFourHours)
font.pixelSize: Theme.fontSizeExtraSmall
+ color: (pressed ? Theme.highlightColor : Theme.primaryColor)
horizontalAlignment: Text.AlignRight
anchors {
right: parent.right
- baseline: lblName.baseline
rightMargin: Theme.horizontalPageMargin
+ baseline: lblName.baseline
}
}
+
}
diff --git a/qml/pages/components/MiniStatus.qml b/qml/pages/components/MiniStatus.qml
index f7a57d0..d9dc96c 100644
--- a/qml/pages/components/MiniStatus.qml
+++ b/qml/pages/components/MiniStatus.qml
@@ -1,13 +1,19 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
+
Item {
- id: ministatus
+ id: miniStatus
visible: true
height: icon.height+Theme.paddingMedium
width: parent.width
- Image {
+ Icon {
id: icon
+ visible: type.length
+ color: Theme.highlightColor
+ width: Theme.iconSizeExtraSmall
+ height: width
+ source: typeof typeIcon !== "undefined" ? typeIcon : ""
anchors {
top: parent.top
topMargin: Theme.paddingMedium
@@ -15,12 +21,8 @@ Item {
left: parent.left
leftMargin: Theme.horizontalPageMargin + Theme.iconSizeMedium - width
}
- visible: type.length
- width: Theme.iconSizeExtraSmall
- height: width
- source: typeof typeIcon !== "undefined" ? typeIcon : ""
-
}
+
Label {
id: lblRtByName
visible: type.length
@@ -42,12 +44,11 @@ Item {
action = qsTr('followed you');
break;
default:
- ministatus.visible = false
+ miniStatus.visible = false
action = type;
}
return typeof reblog_account_username !== "undefined" ? '@' + reblog_account_username + ' ' + action : ''
}
-
font.pixelSize: Theme.fontSizeExtraSmall
color: Theme.highlightColor
}
diff --git a/qml/pages/components/MyImage.qml b/qml/pages/components/MyImage.qml
index 13cd278..8e0be74 100644
--- a/qml/pages/components/MyImage.qml
+++ b/qml/pages/components/MyImage.qml
@@ -2,34 +2,41 @@ import QtQuick 2.0
import Sailfish.Silica 1.0
import QtMultimedia 5.0
+
Item {
+ id: myImage
+
property string type : ""
property string previewURL: ""
property string mediaURL: ""
+
Rectangle {
opacity: 0.2
- anchors.fill: parent
color: Theme.highlightDimmerColor
+ anchors.fill: parent
}
+
Image {
- anchors.centerIn: parent
source: "image://theme/icon-m-image"
+ anchors.centerIn: parent
}
+
Rectangle {
id: progressRec
- anchors.bottom: parent.bottom
width: 0
height: Theme.paddingSmall
color: Theme.highlightBackgroundColor
+ anchors.bottom: parent.bottom
}
+
Image {
id: img
- anchors.fill: parent
- fillMode: Image.PreserveAspectCrop
asynchronous: true
opacity: status === Image.Ready ? 1.0 : 0.0
Behavior on opacity { FadeAnimator {} }
source: previewURL
+ fillMode: Image.PreserveAspectCrop
+ anchors.fill: parent
onProgressChanged: {
if (progress != 1)
progressRec.width = parent.width * progress
@@ -38,36 +45,47 @@ Item {
}
}
-
MouseArea {
anchors.fill: parent
onClicked: {
- pageStack.push(Qt.resolvedUrl("./ImageFullScreen.qml"), {"previewURL": previewURL, "mediaURL": mediaURL, "type": type})
+ pageStack.push(Qt.resolvedUrl("./MediaFullScreen.qml"), {
+ "previewURL": previewURL,
+ "mediaURL": mediaURL,
+ "type": type
+ })
}
}
+
Image {
+ id: videoIcon
visible: type === "video" || type === "gifv"
- anchors.centerIn: parent
source: "image://theme/icon-l-play"
+ anchors.centerIn: parent
}
+
BusyIndicator {
+ id: mediaLoader
size: BusyIndicatorSize.Large
running: img.status !== Image.Ready
opacity: img.status === Image.Ready ? 0.0 : 1.0
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
+
Rectangle {
- anchors.fill: parent
+ id: mediaWarning
color: Theme.highlightDimmerColor
visible: typeof status_sensitive != 'undefined' && status_sensitive ? true : false
+ anchors.fill: parent
+
Image {
source: "image://theme/icon-l-attention?"+Theme.highlightColor
anchors.centerIn: parent
}
+
MouseArea {
anchors.fill: parent
- onClicked: parent.visible = false;
+ onClicked: parent.visible = false
}
}
}
diff --git a/qml/pages/components/MyList.qml b/qml/pages/components/MyList.qml
index b2f0626..ce8f5e6 100644
--- a/qml/pages/components/MyList.qml
+++ b/qml/pages/components/MyList.qml
@@ -3,9 +3,11 @@ import Sailfish.Silica 1.0
import "../../lib/API.js" as Logic
import "."
+
SilicaListView {
id: myList
- property string type;
+
+ property string type
property string title
property string vwPlaceholderText: qsTr("Loading")
property string vwPlaceholderHint: qsTr("please wait...")
@@ -13,21 +15,21 @@ SilicaListView {
property ListModel mdl: []
property variant params: []
property var locale: Qt.locale()
- property bool autoLoadMore : true;
- property bool loadStarted : false;
- property int scrollOffset;
+ property bool autoLoadMore: true
+ property bool loadStarted: false
+ property int scrollOffset
property string action: ""
property variant vars
property variant conf
- property bool notifier : false;
+ property bool notifier: false
+
model: mdl
+
signal notify (string what, int num)
onNotify: {
console.log(what + " - " + num)
}
-
-
signal openDrawer (bool setDrawer)
onOpenDrawer: {
//console.log("Open drawer: " + setDrawer)
@@ -38,18 +40,16 @@ SilicaListView {
}
- BusyIndicator {
- size: BusyIndicatorSize.Large
- running: myList.model.count === 0 && !viewPlaceHolder.visible
- anchors.centerIn: parent
- }
-
header: PageHeader {
title: myList.title
description: myList.description
}
-
+ BusyIndicator {
+ size: BusyIndicatorSize.Large
+ running: myList.model.count === 0 && !viewPlaceHolder.visible
+ anchors.centerIn: parent
+ }
ViewPlaceholder {
id: viewPlaceHolder
@@ -62,7 +62,17 @@ SilicaListView {
MenuItem {
text: qsTr("Settings")
onClicked: {
- pageStack.push(Qt.resolvedUrl("../Settings.qml"), {})
+ pageStack.push(Qt.resolvedUrl("../SettingsPage.qml"), {})
+ }
+ }
+
+ MenuItem {
+ text: qsTr("New Toot")
+ onClicked: {
+ pageStack.push(Qt.resolvedUrl("../ConversationPage.qml"), {
+ //headerTitle: "New Toot",
+ type: "new"
+ })
}
}
@@ -73,14 +83,6 @@ SilicaListView {
}
}
}
- clip: true
- section {
- property: 'section'
- delegate: SectionHeader {
- height: Theme.itemSizeExtraSmall
- text: Format.formatDate(section, Formatter.DateMedium)
- }
- }
delegate: VisualContainer {
} //Toot {}
@@ -95,10 +97,9 @@ SilicaListView {
}
onCountChanged: {
- loadStarted = false;
+ loadStarted = false
/*contentY = scrollOffset
console.log("CountChanged!")*/
-
}
footer: Item{
@@ -114,6 +115,7 @@ SilicaListView {
loadData("append")
}
}
+
BusyIndicator {
size: BusyIndicatorSize.Small
running: loadStarted;
@@ -121,18 +123,18 @@ SilicaListView {
anchors.horizontalCenter: parent.horizontalCenter
}
}
- onContentYChanged: {
+ onContentYChanged: {
if (Math.abs(contentY - scrollOffset) > Theme.itemSizeMedium) {
openDrawer(contentY - scrollOffset > 0 ? false : true )
scrollOffset = contentY
}
-
if(contentY+height > footerItem.y && !loadStarted && autoLoadMore){
loadData("append")
- loadStarted = true;
+ loadStarted = true
}
}
+
VerticalScrollDecorator {}
WorkerScript {
@@ -145,7 +147,6 @@ SilicaListView {
if (messageObject.fireNotification && notifier){
Logic.notifier(messageObject.data)
}
-
}
}
@@ -160,17 +161,18 @@ SilicaListView {
loadData("prepend")
}
}
+
function loadData(mode){
- var p = [];
+ var p = []
if (params.length)
for(var i = 0; i 0 ? Theme.paddingLarge : 0 )+ lblName.paintedHeight + (type.length ? Theme.paddingLarge + iconRT.height : 0) + Theme.paddingLarge
+
Image {
id: iconRT
y: Theme.paddingLarge
- anchors {
- right: avatar.right
- }
+ anchors.right: avatar.right
visible: type.length
width: Theme.iconSizeExtraSmall
height: width
source: "../../images/boosted.svg"
}
+
Label {
id: lblRtByName
visible: type.length
- anchors {
- left: lblName.left
- bottom: iconRT.bottom
- }
+ anchors.left: lblName.left
+ anchors.bottom: iconRT.bottom
+ font.pixelSize: Theme.fontSizeExtraSmall
+ color: Theme.secondaryColor
text: {
var action;
switch(type){
@@ -45,10 +46,8 @@ BackgroundItem {
}
return '@' + retweetScreenName + ' ' + action
}
-
- font.pixelSize: Theme.fontSizeExtraSmall
- color: Theme.secondaryColor
}
+
Image {
id: avatar
x: Theme.horizontalPageMargin
@@ -62,71 +61,70 @@ BackgroundItem {
MouseArea {
anchors.fill: parent
onClicked: {
- pageStack.push(Qt.resolvedUrl("../Profile.qml"), {
+ pageStack.push(Qt.resolvedUrl("../ProfilePage.qml"), {
"display_name": account_display_name,
"username": account_username,
"profileImage": account_avatar
})
}
-
}
-
}
+
Label {
id: lblName
+ text: account_display_name
+ font.weight: Font.Bold
+ font.pixelSize: Theme.fontSizeSmall
+ color: (pressed ? Theme.highlightColor : Theme.primaryColor)
anchors {
top: avatar.top
topMargin: 0
left: avatar.right
leftMargin: Theme.paddingMedium
}
- text: account_display_name
- font.weight: Font.Bold
- font.pixelSize: Theme.fontSizeSmall
- color: (pressed ? Theme.highlightColor : Theme.primaryColor)
}
Image {
- id: iconVerified
+ id: iconLocked
+ visible: account_locked
y: Theme.paddingLarge
+ opacity: 0.8
+ source: "image://theme/icon-s-secure?" + (pressed
+ ? Theme.highlightColor
+ : Theme.primaryColor)
+ width: account_locked ? Theme.iconSizeExtraSmall*0.8 : 0
+ height: width
anchors {
left: lblName.right
leftMargin: Theme.paddingSmall
verticalCenter: lblName.verticalCenter
}
- visible: account_locked
- width: account_locked ? Theme.iconSizeExtraSmall*0.8 : 0
- opacity: 0.8
- height: width
- source: "image://theme/icon-s-secure?" + (pressed
- ? Theme.highlightColor
- : Theme.primaryColor)
}
-
Label {
id: lblScreenName
- anchors {
- left: iconVerified.right
- right: lblDate.left
- leftMargin: Theme.paddingMedium
- baseline: lblName.baseline
- }
truncationMode: TruncationMode.Fade
text: '@'+account_username
font.pixelSize: Theme.fontSizeExtraSmall
color: (pressed ? Theme.secondaryHighlightColor : Theme.secondaryColor)
+ anchors {
+ left: iconLocked.right
+ right: lblDate.left
+ leftMargin: Theme.paddingMedium
+ baseline: lblName.baseline
+ }
}
+
Label {
+ id: lblDate
function timestamp() {
var txt = Format.formatDate(created_at, Formatter.Timepoint)
var elapsed = Format.formatDate(created_at, Formatter.DurationElapsedShort)
return (elapsed ? elapsed : txt )
}
- id: lblDate
- color: (pressed ? Theme.highlightColor : Theme.primaryColor)
text: Format.formatDate(created_at, new Date() - created_at < 60*60*1000 ? Formatter.DurationElapsedShort : Formatter.TimeValueTwentyFourHours)
font.pixelSize: Theme.fontSizeExtraSmall
+ color: (pressed ? Theme.highlightColor : Theme.primaryColor)
horizontalAlignment: Text.AlignRight
anchors {
right: parent.right
@@ -135,15 +133,8 @@ BackgroundItem {
}
}
- Label {
+ Text {
id: lblText
- anchors {
- left: lblName.left
- right: parent.right
- top: lblScreenName.bottom
- topMargin: Theme.paddingSmall
- rightMargin: Theme.paddingLarge
- }
height: content.length ? paintedHeight : 0
onLinkActivated: {
console.log(link)
@@ -154,34 +145,40 @@ BackgroundItem {
"profileImage": ""
})
} else if (link[0] === "#") {
-
pageStack.pop(pageStack.find(function(page) {
var check = page.isFirstPage === true;
if (check)
page.onLinkActivated(link)
return check;
}));
-
send(link)
} else {
Qt.openUrlExternally(link);
}
-
-
}
text: content
textFormat: Text.RichText
+ font.pixelSize: Theme.fontSizeSmall
+ color: (pressed ? Theme.highlightColor : Theme.primaryColor)
linkColor : Theme.highlightColor
wrapMode: Text.Wrap
maximumLineCount: 6
- font.pixelSize: Theme.fontSizeSmall
- color: (pressed ? Theme.highlightColor : Theme.primaryColor)
+ anchors {
+ left: lblName.left
+ right: parent.right
+ top: lblScreenName.bottom
+ topMargin: Theme.paddingSmall
+ rightMargin: Theme.paddingLarge
+ }
}
+
onClicked: {
- pageStack.push(Qt.resolvedUrl("../Conversation.qml"), {
+ pageStack.push(Qt.resolvedUrl("../ConversationPage.qml"), {
+ headerTitle: "Conversation",
toot_id: id,
- title: account_display_name,
- description: '@'+account_username,
+ toot_url: status_url,
+ //title: account_display_name,
+ description: '@'+account_acc,
avatar: account_avatar,
type: "reply"
})
diff --git a/qml/pages/components/VisualContainer.qml b/qml/pages/components/VisualContainer.qml
index 072f816..2bb06a0 100644
--- a/qml/pages/components/VisualContainer.qml
+++ b/qml/pages/components/VisualContainer.qml
@@ -2,25 +2,48 @@ import QtQuick 2.2
import Sailfish.Silica 1.0
import "../../lib/API.js" as Logic
-BackgroundItem {
+BackgroundItem {
id: delegate
+
signal send (string notice)
signal navigateTo(string link)
+
width: parent.width
- height: mnu.height + miniHeader.height + (typeof attachments !== "undefined" && attachments.count ? media.height + Theme.paddingLarge + Theme.paddingMedium: Theme.paddingLarge) + lblContent.height + Theme.paddingLarge + (ministatus.visible ? ministatus.height : 0)
+ height: if (myList.type === "notifications" && ( model.type === "favourite" || model.type === "reblog" )) {
+ mnu.height + miniHeader.height + Theme.paddingLarge + lblContent.height + Theme.paddingLarge + (miniStatus.visible ? miniStatus.height : 0)
+ } else mnu.height + miniHeader.height + (typeof attachments !== "undefined" && attachments.count ? media.height + Theme.paddingLarge + Theme.paddingMedium: Theme.paddingLarge) + lblContent.height + Theme.paddingLarge + (miniStatus.visible ? miniStatus.height : 0) + (iconDirectMsg.visible ? iconDirectMsg.height : 0)
+
Rectangle {
- x: 0;
- y: 0;
- visible: status_visibility == 'direct'
+ id: bgDirect
+ x: 0
+ y: 0
+ visible: status_visibility === "direct"
width: parent.width
height: parent.height
opacity: 0.3
- color: Theme.highlightBackgroundColor;
+ gradient: Gradient {
+ GradientStop { position: -1.5; color: "transparent" }
+ GradientStop { position: 0.6; color: Theme.highlightBackgroundColor }
+ }
+ }
+
+ Rectangle {
+ id: bgNotifications
+ x: 0
+ y: 0
+ visible: myList.type === "notifications" && ( model.type === "favourite" || model.type === "reblog" )
+ width: parent.width
+ height: parent.height
+ opacity: 0.5
+ gradient: Gradient {
+ GradientStop { position: -0.5; color: "transparent" }
+ GradientStop { position: 0.4; color: Theme.highlightDimmerColor }
+ }
}
MiniStatus {
- id: ministatus
+ id: miniStatus
anchors {
leftMargin: Theme.horizontalPageMargin
rightMargin: Theme.horizontalPageMargin
@@ -28,22 +51,23 @@ BackgroundItem {
topMargin: Theme.paddingMedium
}
}
+
Image {
id: avatar
- anchors {
- top: ministatus.visible ? ministatus.bottom : parent.top
- topMargin: ministatus.visible ? Theme.paddingMedium : Theme.paddingLarge
- left: parent.left
- leftMargin: Theme.horizontalPageMargin
- }
+ visible: true
opacity: status === Image.Ready ? 1.0 : 0.0
Behavior on opacity { FadeAnimator {} }
asynchronous: true
- width: Theme.iconSizeMedium
- height: width
smooth: true
source: account_avatar
- visible: true
+ width: Theme.iconSizeMedium
+ height: width
+ anchors {
+ top: miniStatus.visible ? miniStatus.bottom : parent.top
+ topMargin: miniStatus.visible ? Theme.paddingMedium : Theme.paddingLarge
+ left: parent.left
+ leftMargin: Theme.horizontalPageMargin
+ }
onStatusChanged: {
if (avatar.status === Image.Error)
source = "../../images/icon-m-profile.svg?" + (pressed
@@ -54,30 +78,53 @@ BackgroundItem {
MouseArea {
anchors.fill: parent
onClicked: {
- pageStack.push(Qt.resolvedUrl("../Profile.qml"), {
+ pageStack.push(Qt.resolvedUrl("../ProfilePage.qml"), {
"display_name": model.account_display_name,
"username": model.account_acct,
"user_id": model.account_id,
- "profileImage": model.account_avatar
+ "profileImage": model.account_avatar,
+ "profileBackground": model.account_header
})
}
+ }
+ Rectangle {
+ visible: myList.type === "notifications" && ( model.type === "favourite" || model.type === "reblog" )
+ opacity: 0.5
+ color: Theme.highlightDimmerColor
+ anchors.fill: avatar
}
Image {
id: iconTR
+ visible: typeof status_reblogged !== "undefined" && status_reblogged
+ width: Theme.iconSizeExtraSmall
+ height: width
+ source: "image://theme/icon-s-retweet"
anchors {
top: avatar.bottom
topMargin: Theme.paddingMedium
left: avatar.left
}
- visible: typeof status_reblogged !== "undefined" && status_reblogged
- width: Theme.iconSizeExtraSmall
- height: width
- source: "image://theme/icon-s-retweet"
}
+
+ Image {
+ id: iconDirectMsg
+ visible: status_visibility === "direct"
+ width: Theme.iconSizeMedium
+ height: width
+ source: "image://theme/icon-m-mail"
+ anchors {
+ horizontalCenter: avatar.horizontalCenter
+ top: avatar.bottom
+ topMargin: Theme.paddingMedium
+ left: avatar.left
+ }
+ }
+
Rectangle {
- color: Theme.highlightDimmerColor
+ id: bgReblogAvatar
+ color: Theme.secondaryColor
width: Theme.iconSizeSmall
height: width
visible: typeof status_reblog !== "undefined" && status_reblog
@@ -87,18 +134,21 @@ BackgroundItem {
left: parent.left
leftMargin: -width/3
}
+
Image {
+ id: reblogAvatar
asynchronous: true
- width: Theme.iconSizeSmall
- height: width
smooth: true
opacity: status === Image.Ready ? 1.0 : 0.0
Behavior on opacity { FadeAnimator {} }
source: typeof reblog_account_avatar !== "undefined" ? reblog_account_avatar : ''
visible: typeof status_reblog !== "undefined" && status_reblog
+ width: Theme.iconSizeSmall
+ height: width
}
}
}
+
MiniHeader {
id: miniHeader
anchors {
@@ -107,8 +157,23 @@ BackgroundItem {
right: parent.right
}
}
+
Text {
id: lblContent
+ visible: model.type !== "follow"
+ text: content.replace(new RegExp(" paintedHeight ? contentWarningLabel.paintedHeight : paintedHeight) : 0
anchors {
left: miniHeader.left
leftMargin: Theme.paddingMedium
@@ -118,7 +183,6 @@ BackgroundItem {
topMargin: Theme.paddingSmall
bottomMargin: Theme.paddingLarge
}
- height: content.length ? (contentWarningLabel.paintedHeight > paintedHeight ? contentWarningLabel.paintedHeight : paintedHeight) : 0
onLinkActivated: {
var test = link.split("/")
console.log(link)
@@ -134,29 +198,32 @@ BackgroundItem {
}));
send(link)
} else if (test.length === 4 && test[3][0] === "@" ) {
- tlSearch.search = decodeURIComponent("@"+test[3].substring(1)+"@"+test[2])
- slideshow.positionViewAtIndex(4, ListView.SnapToItem)
- navigation.navigateTo('search')
-
+ pageStack.pop(pageStack.find(function(page) {
+ var check = page.isFirstPage === true;
+ if (check)
+ page.onLinkActivated(link)
+ return check;
+ }));
} else {
Qt.openUrlExternally(link);
}
}
- text: content.replace(new RegExp(" 0
+ anchors.fill: parent
+
Label {
id: contentWarningLabel
+ text: model.status_spoiler_text
font.pixelSize: Theme.fontSizeExtraSmall
+ color: Theme.highlightColor
+ truncationMode: TruncationMode.Fade
+ wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
+ width: parent.width
anchors {
topMargin: Theme.paddingSmall
left: parent.left
@@ -166,21 +233,21 @@ BackgroundItem {
rightMargin: Theme.paddingMedium
bottomMargin: Theme.paddingSmall
}
- width: parent.width
- truncationMode: TruncationMode.Fade
- color: Theme.highlightColor
- wrapMode: Text.WordWrap
- text: model.status_spoiler_text
}
+
MouseArea {
anchors.fill: parent
- onClicked: parent.visible = false;
+ onClicked: parent.visible = false
}
}
}
+
MediaBlock {
id: media
+ visible: myList.type !== "notifications" && ( model.type !== "favourite" || model.type !== "reblog" )
+ model: typeof attachments !== "undefined" ? attachments : Qt.createQmlObject('import QtQuick 2.0; ListModel { }', Qt.application, 'InternalQmlObject');
+ height: Theme.iconSizeExtraLarge * 2
anchors {
left: lblContent.left
right: lblContent.right
@@ -188,13 +255,15 @@ BackgroundItem {
topMargin: Theme.paddingSmall
bottomMargin: Theme.paddingLarge
}
- model: typeof attachments !== "undefined" ? attachments : Qt.createQmlObject('import QtQuick 2.0; ListModel { }', Qt.application, 'InternalQmlObject');
- height: 100
}
+
ContextMenu {
id: mnu
+
MenuItem {
- enabled: model.type !== "follow"
+ id: mnuBoost
+ visible: model.type !== "follow"
+ enabled: status_visibility !== "direct"
text: typeof model.reblogged !== "undefined" && model.reblogged ? qsTr("Unboost") : qsTr("Boost")
onClicked: {
var status = typeof model.reblogged !== "undefined" && model.reblogged
@@ -208,30 +277,34 @@ BackgroundItem {
model.reblogs_count = !status ? model.reblogs_count+1 : (model.reblogs_count > 0 ? model.reblogs_count-1 : model.reblogs_count);
model.reblogged = !model.reblogged
}
+
Image {
id: icRT
+ source: "image://theme/icon-s-retweet?" + (!model.reblogged ? Theme.highlightColor : Theme.primaryColor)
+ width: Theme.iconSizeExtraSmall
+ height: width
anchors {
leftMargin: Theme.horizontalPageMargin
left: parent.left
verticalCenter: parent.verticalCenter
}
- width: Theme.iconSizeExtraSmall
- height: width
- source: "image://theme/icon-s-retweet?" + (!model.reblogged ? Theme.highlightColor : Theme.primaryColor)
}
+
Label {
+ text: reblogs_count
+ font.pixelSize: Theme.fontSizeExtraSmall
+ color: !model.reblogged ? Theme.highlightColor : Theme.primaryColor
anchors {
left: icRT.right
leftMargin: Theme.paddingMedium
verticalCenter: parent.verticalCenter
}
- text: reblogs_count
- font.pixelSize: Theme.fontSizeExtraSmall
- color: !model.reblogged ? Theme.highlightColor : Theme.primaryColor
}
}
+
MenuItem {
- enabled: model.type !== "follow"
+ id: mnuFavourite
+ visible: model.type !== "follow" || model.status_visibility !== "direct"
text: typeof model.favourited !== "undefined" && model.favourited ? qsTr("Unfavorite") : qsTr("Favorite")
onClicked: {
var status = typeof model.favourited !== "undefined" && model.favourited
@@ -245,6 +318,7 @@ BackgroundItem {
model.favourites_count = !status ? model.favourites_count+1 : (model.favourites_count > 0 ? model.favourites_count-1 : model.favourites_count);
model.favourited = !model.favourited
}
+
Image {
id: icFA
anchors {
@@ -256,28 +330,54 @@ BackgroundItem {
height: width
source: "image://theme/icon-s-favorite?" + (!model.favourited ? Theme.highlightColor : Theme.primaryColor)
}
+
Label {
+ text: favourites_count
+ font.pixelSize: Theme.fontSizeExtraSmall
+ color: !model.favourited ? Theme.highlightColor : Theme.primaryColor
anchors {
left: icFA.right
leftMargin: Theme.paddingMedium
verticalCenter: parent.verticalCenter
}
- text: favourites_count
- font.pixelSize: Theme.fontSizeExtraSmall
- color: !model.favourited ? Theme.highlightColor : Theme.primaryColor
+ }
+ }
+
+ MenuItem {
+ id: mnuMention
+ visible: model.type === "follow"
+ text: qsTr("Mention")
+ onClicked: {
+ pageStack.push(Qt.resolvedUrl("../ConversationPage.qml"), {
+ headerTitle: "Mention",
+ description: "@"+reblog_account_acct,
+ type: "new"
+ })
+ }
+
+ Image {
+ id: icMT
+ anchors {
+ leftMargin: Theme.horizontalPageMargin
+ left: parent.left
+ verticalCenter: parent.verticalCenter
+ }
+ width: Theme.iconSizeExtraSmall
+ height: width
+ source: "image://theme/icon-s-chat?" + (!model.favourited ? Theme.highlightColor : Theme.primaryColor)
}
}
}
-
-
-
onClicked: {
var m = Qt.createQmlObject('import QtQuick 2.0; ListModel { }', Qt.application, 'InternalQmlObject');
if (typeof mdl !== "undefined")
m.append(mdl.get(index))
- pageStack.push(Qt.resolvedUrl("../Conversation.qml"), {
+ pageStack.push(Qt.resolvedUrl("../ConversationPage.qml"), {
+ headerTitle: "Conversation",
toot_id: status_id,
+ toot_url: status_url,
+ toot_uri: status_uri,
title: account_display_name,
description: '@'+account_acct,
avatar: account_avatar,
diff --git a/src/notifications.h b/src/notifications.h
index b22486a..524da9e 100644
--- a/src/notifications.h
+++ b/src/notifications.h
@@ -17,7 +17,7 @@ class Notifications : public QObject
{
Q_OBJECT
public:
- explicit Notifications(QObject *parent = 0);
+ explicit Notifications(QObject *parent = nullptr);
Q_INVOKABLE void notify(QString appName, QString summary, QString body, bool preview, QString ts, QString issuekey);
};
diff --git a/translations/harbour-tooter-de.ts b/translations/harbour-tooter-de.ts
index d2a2c44..0f08f63 100644
--- a/translations/harbour-tooter-de.ts
+++ b/translations/harbour-tooter-de.ts
@@ -22,10 +22,6 @@
Conversation
-
-
- Konversation
-
Lรถschen
@@ -62,12 +58,20 @@
Was gibt's Neues?
+
+
+ Toot gesendet!
+
+
+
+ Link kopieren
+
ImageFullScreen
- Fehler beim Laden
+ Ladefehler
diff --git a/translations/harbour-tooter-el.ts b/translations/harbour-tooter-el.ts
index 6f47211..df485eb 100644
--- a/translations/harbour-tooter-el.ts
+++ b/translations/harbour-tooter-el.ts
@@ -22,10 +22,6 @@
Conversation
-
-
- ฮฃฯ
ฮฝฮฟฮผฮนฮปฮฏฮฑ
-
ฮฮนฮฑฮณฯฮฑฯฮฎ
@@ -62,12 +58,20 @@
+
+
+
+
+
+
+
+
ImageFullScreen
- ฮฃฯฮฌฮปฮผฮฑ ฯฯฯฯฯฯฮทฯ
+
diff --git a/translations/harbour-tooter-es.ts b/translations/harbour-tooter-es.ts
index fe77cd8..195b8f5 100644
--- a/translations/harbour-tooter-es.ts
+++ b/translations/harbour-tooter-es.ts
@@ -22,10 +22,6 @@
Conversation
-
-
- Conversaciรณn
-
Borrar
@@ -62,12 +58,20 @@
ยฟEn quรฉ estรกs pensando?
+
+
+
+
+
+
+
+
ImageFullScreen
- Error al cargar
+
diff --git a/translations/harbour-tooter-fi.ts b/translations/harbour-tooter-fi.ts
index f1444ea..50a5f73 100644
--- a/translations/harbour-tooter-fi.ts
+++ b/translations/harbour-tooter-fi.ts
@@ -22,10 +22,6 @@
Conversation
-
-
-
-
@@ -62,6 +58,14 @@
+
+
+
+
+
+
+
+
ImageFullScreen
diff --git a/translations/harbour-tooter-fr.ts b/translations/harbour-tooter-fr.ts
index 341f2a4..baafe35 100644
--- a/translations/harbour-tooter-fr.ts
+++ b/translations/harbour-tooter-fr.ts
@@ -22,10 +22,6 @@
Conversation
-
-
- Conversation
-
Supprimer
@@ -62,12 +58,20 @@
Qu'avez-vous en tรชte?
+
+
+ Pouet envoyรฉ !
+
+
+
+ Copier le lien
+
ImageFullScreen
- Erreur de chargement
+
diff --git a/translations/harbour-tooter-it.ts b/translations/harbour-tooter-it.ts
index 6689a88..5b5be12 100644
--- a/translations/harbour-tooter-it.ts
+++ b/translations/harbour-tooter-it.ts
@@ -28,52 +28,57 @@
Conversation
-
-
- Conversazione
+
+
+ Copia link
-
+
Contenuto avviso
-
+
A cosa stai pensando?
-
+
Elimina
-
+
Pubblico
-
+
Non elencato
-
+
Solo ai seguaci
-
+
Diretto
-
+
+
+ Toot รจ stato pubblicato!
+
+
+
Emojis
-
+
Tap per inserire
@@ -81,9 +86,9 @@
ImageFullScreen
-
+
- Errore caricamento
+ Errore durante caricamento
@@ -97,27 +102,27 @@
LoginPage
-
+
Accesso
-
+
Istanza
-
+
Inserire URL di una istanza Mastodon valida
-
+
Mastodon รจ un servizio di rete sociale in software libero, costituito in una federazione d'istanze. Mastodon fa parte del piรน ampio Fediverso, permettendo ai suoi utenti di interagire anche con utenti su diverse piattaforme aperte che supportano lo stesso protocollo.
-
+
Ricarica
@@ -125,37 +130,37 @@
MainPage
-
+
Home
-
+
Notifiche
-
+
Locale
-
+
Federazione
-
+
Cerca
-
+
@utente o #termine
-
+
Nuovo toot
@@ -269,7 +274,7 @@
Biografia
-
+
Aprire profile nel browser
@@ -388,22 +393,22 @@
VisualContainer
-
+
Annulla condivisione
-
+
Condividi
-
+
Annulla apprezzamento
-
+
Apprezzato
diff --git a/translations/harbour-tooter-nl.ts b/translations/harbour-tooter-nl.ts
index 6ff67ed..9c3e4b0 100644
--- a/translations/harbour-tooter-nl.ts
+++ b/translations/harbour-tooter-nl.ts
@@ -22,10 +22,6 @@
Conversation
-
-
- Gesprek
-
Verwijderen
@@ -62,12 +58,20 @@
+
+
+
+
+
+
+
+
ImageFullScreen
- Fout bij laden
+
diff --git a/translations/harbour-tooter-nl_BE.ts b/translations/harbour-tooter-nl_BE.ts
index cf8d937..25d9369 100644
--- a/translations/harbour-tooter-nl_BE.ts
+++ b/translations/harbour-tooter-nl_BE.ts
@@ -22,10 +22,6 @@
Conversation
-
-
- Gesprek
-
Verwijderen
@@ -62,12 +58,20 @@
+
+
+
+
+
+
+
+
ImageFullScreen
- Fout bij laden
+
diff --git a/translations/harbour-tooter-oc.ts b/translations/harbour-tooter-oc.ts
index 2bb86d9..3319228 100644
--- a/translations/harbour-tooter-oc.ts
+++ b/translations/harbour-tooter-oc.ts
@@ -22,10 +22,6 @@
Conversation
-
-
- Discutida
-
Escafar
@@ -62,12 +58,20 @@
+
+
+
+
+
+
+
+
ImageFullScreen
- Error en cargar
+
diff --git a/translations/harbour-tooter-pl.ts b/translations/harbour-tooter-pl.ts
index 952b1b2..4d7fe81 100644
--- a/translations/harbour-tooter-pl.ts
+++ b/translations/harbour-tooter-pl.ts
@@ -22,10 +22,6 @@
Conversation
-
-
- Konwersacja
-
Usuล
@@ -62,12 +58,20 @@
+
+
+
+
+
+
+
+
ImageFullScreen
- Bลฤ
d ลadowania
+
diff --git a/translations/harbour-tooter-ru.ts b/translations/harbour-tooter-ru.ts
index 277a582..d47095f 100644
--- a/translations/harbour-tooter-ru.ts
+++ b/translations/harbour-tooter-ru.ts
@@ -22,10 +22,6 @@
Conversation
-
-
- ะะตัะตะดะฐ
-
ะฃะดะฐะปะธัั
@@ -62,12 +58,20 @@
+
+
+
+
+
+
+
+
ImageFullScreen
- ะัะธะฑะบะฐ ะฟัะธ ะทะฐะณััะทะบะต
+
diff --git a/translations/harbour-tooter-sr.ts b/translations/harbour-tooter-sr.ts
index 3091e3e..52a0d2c 100644
--- a/translations/harbour-tooter-sr.ts
+++ b/translations/harbour-tooter-sr.ts
@@ -22,10 +22,6 @@
Conversation
-
-
- ะ ะฐะทะณะพะฒะพั
-
ะะฑัะธัะธ
@@ -62,12 +58,20 @@
+
+
+
+
+
+
+
+
ImageFullScreen
- Greลกka u uฤitavanju
+
diff --git a/translations/harbour-tooter-sv.ts b/translations/harbour-tooter-sv.ts
index 43b1866..5cd3f54 100644
--- a/translations/harbour-tooter-sv.ts
+++ b/translations/harbour-tooter-sv.ts
@@ -22,10 +22,6 @@
Conversation
-
-
- Konversation
-
Radera
@@ -62,12 +58,20 @@
+
+
+
+
+
+
+
+
ImageFullScreen
- Problem att ladda
+
diff --git a/translations/harbour-tooter-zh_CN.ts b/translations/harbour-tooter-zh_CN.ts
index d25e9f9..b92289e 100644
--- a/translations/harbour-tooter-zh_CN.ts
+++ b/translations/harbour-tooter-zh_CN.ts
@@ -22,10 +22,6 @@
Conversation
-
-
- ๅฏน่ฏ
-
ๅ ้ค
@@ -62,12 +58,20 @@
ๆไฝๆณๆณ?
+
+
+
+
+
+
+ ๅคๅถ้พๆฅๅฐๅชๅๆฟ
+
ImageFullScreen
- ๅ ่ฝฝ้่ฏฏ
+
diff --git a/translations/harbour-tooter.ts b/translations/harbour-tooter.ts
index b119e7e..7e229a9 100644
--- a/translations/harbour-tooter.ts
+++ b/translations/harbour-tooter.ts
@@ -23,25 +23,21 @@
Conversation
-
- Conversation
-
-
-
- Delete
-
-
-
- Emojis
-
-
-
- Tap to insert
+
+
+
+
+
+
+
+
+
+
@@ -59,7 +55,18 @@
-
+
+
+
+
+
+ EmojiPage
+
+
+
+
+
+
@@ -67,7 +74,7 @@
ImageFullScreen
-
+