From c8ad3f02cc12da45fd3c6b5c73f1306622551452 Mon Sep 17 00:00:00 2001 From: molan-git Date: Sun, 24 May 2020 19:54:46 +0200 Subject: [PATCH 01/22] sentBanner Adds a confirmation banner when sending a Toot --- harbour-tooter.pro | 233 ++++++++++--------- qml/pages/Conversation.qml | 22 +- qml/pages/MainPage.qml | 2 +- qml/pages/components/InfoBanner.qml | 62 +++++ qml/pages/components/InfoBanner.qml.autosave | 61 +++++ qml/pages/components/VisualContainer.qml | 1 + translations/harbour-tooter-de.ts | 8 +- translations/harbour-tooter-el.ts | 8 +- translations/harbour-tooter-es.ts | 8 +- translations/harbour-tooter-fi.ts | 8 +- translations/harbour-tooter-fr.ts | 8 +- translations/harbour-tooter-it.ts | 28 +-- translations/harbour-tooter-nl.ts | 8 +- translations/harbour-tooter-nl_BE.ts | 8 +- translations/harbour-tooter-oc.ts | 8 +- translations/harbour-tooter-pl.ts | 8 +- translations/harbour-tooter-ru.ts | 8 +- translations/harbour-tooter-sr.ts | 8 +- translations/harbour-tooter-sv.ts | 8 +- translations/harbour-tooter-zh_CN.ts | 8 +- translations/harbour-tooter.ts | 8 +- 21 files changed, 325 insertions(+), 196 deletions(-) create mode 100644 qml/pages/components/InfoBanner.qml create mode 100644 qml/pages/components/InfoBanner.qml.autosave diff --git a/harbour-tooter.pro b/harbour-tooter.pro index 6a1b13c..026fe41 100644 --- a/harbour-tooter.pro +++ b/harbour-tooter.pro @@ -1,116 +1,117 @@ -# 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/pages/components/InfoBanner.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 diff --git a/qml/pages/Conversation.qml b/qml/pages/Conversation.qml index 3fed799..2aac1ad 100644 --- a/qml/pages/Conversation.qml +++ b/qml/pages/Conversation.qml @@ -4,9 +4,11 @@ import harbour.tooter.Uploader 1.0 import "../lib/API.js" as Logic import "./components/" + Page { id: conversationPage - property string type + property string headerTitle: "" + property string type property alias title: header.title property alias description: header.description property alias avatar: header.image @@ -40,6 +42,10 @@ Page { } } + InfoBanner { + id: sentBanner + } + ListModel { id: mediaModel onCountChanged: { @@ -62,7 +68,7 @@ Page { SilicaListView { id: conversationList header: PageHeader { - title: qsTr("Conversation") + title: headerTitle // pageTitle pushed from MainPage.qml or VisualContainer.qml } clip: true anchors { @@ -208,7 +214,6 @@ Page { || description.charAt( 0) == '#') ? description + ' ' : '' height: Math.max(270, Math.min(900, implicitHeight)) - //height: implicitHeight horizontalAlignment: Text.AlignLeft placeholderText: qsTr("What's on your mind?") font.pixelSize: Theme.fontSizeSmall @@ -304,7 +309,6 @@ Page { } } IconButton { - id: btnContentWarning anchors { top: toot.bottom @@ -426,11 +430,11 @@ 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!")) } } diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml index e676870..463b305 100644 --- a/qml/pages/MainPage.qml +++ b/qml/pages/MainPage.qml @@ -246,7 +246,7 @@ Page { visible: !isPortrait ? true : !infoPanel.open icon.source: "image://theme/icon-l-add" onClicked: { - pageStack.push(Qt.resolvedUrl("Conversation.qml"), {title: qsTr("New Toot"), type: "new"}) + pageStack.push(Qt.resolvedUrl("Conversation.qml"), {headerTitle: qsTr("New Toot"), type: "new"}) } } diff --git a/qml/pages/components/InfoBanner.qml b/qml/pages/components/InfoBanner.qml new file mode 100644 index 0000000..3696c59 --- /dev/null +++ b/qml/pages/components/InfoBanner.qml @@ -0,0 +1,62 @@ +import QtQuick 2.0 +import Sailfish.Silica 1.0 + + +DockedPanel { + id: root + z: 100; + width: parent.width //- Theme.paddingLarge*4 + //x: Theme.paddingLarge*2 + height: content.height + dock: Dock.Bottom + + Rectangle { + id: content + width: root.width + height: infoLabel.height + 4*Theme.paddingMedium + //anchors.topMargin: 20 + color: Theme.highlightBackgroundColor + opacity: 1.0 + + Label { + id: infoLabel + text : "" + color: Theme.primaryColor + font.family: Theme.fontFamilyHeading + font.pixelSize: Theme.fontSizeMedium + //font.weight: Font.Bold + width: parent.width + wrapMode: Text.WrapAnywhere + anchors { + left: parent.left + leftMargin: Theme.horizontalPageMargin + 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: 6000 + running: false + onTriggered: { + root.hide() + stop() + } + } +} diff --git a/qml/pages/components/InfoBanner.qml.autosave b/qml/pages/components/InfoBanner.qml.autosave new file mode 100644 index 0000000..7921d05 --- /dev/null +++ b/qml/pages/components/InfoBanner.qml.autosave @@ -0,0 +1,61 @@ +import QtQuick 2.0 +import Sailfish.Silica 1.0 + + +DockedPanel { + id: root + z: 100; + width: parent.width + height: content.height + dock: Dock.Bottom + + Rectangle { + id: content + width: root.width + height: infoLabel.height + 4*Theme.paddingMedium + //anchors.topMargin: 20 + color: Theme.highlightBackgroundColor + opacity: 1.0 + + Label { + id: infoLabel + text : "" + color: Theme.primaryColor + font.family: Theme.fontFamilyHeading + font.pixelSize: Theme.fontSizeMedium + //font.weight: Font.Bold + width: parent.width + wrapMode: Text.WrapAnywhere + anchors { + left: parent.left + leftMargin: Theme.horizontalPageMargin + right: parent.right + rightMargin: Theme.ho rizontalPageMargin + 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: 6000 + running: false + onTriggered: { + root.hide() + stop() + } + } +} diff --git a/qml/pages/components/VisualContainer.qml b/qml/pages/components/VisualContainer.qml index 072f816..d3a06e2 100644 --- a/qml/pages/components/VisualContainer.qml +++ b/qml/pages/components/VisualContainer.qml @@ -277,6 +277,7 @@ BackgroundItem { if (typeof mdl !== "undefined") m.append(mdl.get(index)) pageStack.push(Qt.resolvedUrl("../Conversation.qml"), { + headerTitle: "Conversation", toot_id: status_id, title: account_display_name, description: '@'+account_acct, diff --git a/translations/harbour-tooter-de.ts b/translations/harbour-tooter-de.ts index d2a2c44..210e07b 100644 --- a/translations/harbour-tooter-de.ts +++ b/translations/harbour-tooter-de.ts @@ -22,10 +22,6 @@ Conversation - - Conversation - Konversation - Delete Löschen @@ -62,6 +58,10 @@ What's on your mind? Was gibt's Neues? + + Toot sent! + + ImageFullScreen diff --git a/translations/harbour-tooter-el.ts b/translations/harbour-tooter-el.ts index 6f47211..c926c14 100644 --- a/translations/harbour-tooter-el.ts +++ b/translations/harbour-tooter-el.ts @@ -22,10 +22,6 @@ Conversation - - Conversation - Συνομιλία - Delete Διαγραφή @@ -62,6 +58,10 @@ What's on your mind? + + Toot sent! + + ImageFullScreen diff --git a/translations/harbour-tooter-es.ts b/translations/harbour-tooter-es.ts index fe77cd8..c52d603 100644 --- a/translations/harbour-tooter-es.ts +++ b/translations/harbour-tooter-es.ts @@ -22,10 +22,6 @@ Conversation - - Conversation - Conversación - Delete Borrar @@ -62,6 +58,10 @@ What's on your mind? ¿En qué estás pensando? + + Toot sent! + + ImageFullScreen diff --git a/translations/harbour-tooter-fi.ts b/translations/harbour-tooter-fi.ts index f1444ea..a1ec939 100644 --- a/translations/harbour-tooter-fi.ts +++ b/translations/harbour-tooter-fi.ts @@ -22,10 +22,6 @@ Conversation - - Conversation - - Delete @@ -62,6 +58,10 @@ What's on your mind? + + Toot sent! + + ImageFullScreen diff --git a/translations/harbour-tooter-fr.ts b/translations/harbour-tooter-fr.ts index 341f2a4..b3835ab 100644 --- a/translations/harbour-tooter-fr.ts +++ b/translations/harbour-tooter-fr.ts @@ -22,10 +22,6 @@ Conversation - - Conversation - Conversation - Delete Supprimer @@ -62,6 +58,10 @@ What's on your mind? Qu'avez-vous en tête? + + Toot sent! + + ImageFullScreen diff --git a/translations/harbour-tooter-it.ts b/translations/harbour-tooter-it.ts index 6689a88..e62798d 100644 --- a/translations/harbour-tooter-it.ts +++ b/translations/harbour-tooter-it.ts @@ -28,52 +28,52 @@ Conversation - - Conversation - Conversazione - - - + Write your warning here Contenuto avviso - + What's on your mind? A cosa stai pensando? - + Delete Elimina - + Public Pubblico - + Unlisted Non elencato - + Followers-only Solo ai seguaci - + Direct Diretto - + + Toot sent! + + + + Emojis Emojis - + Tap to insert Tap per inserire diff --git a/translations/harbour-tooter-nl.ts b/translations/harbour-tooter-nl.ts index 6ff67ed..768c5a8 100644 --- a/translations/harbour-tooter-nl.ts +++ b/translations/harbour-tooter-nl.ts @@ -22,10 +22,6 @@ Conversation - - Conversation - Gesprek - Delete Verwijderen @@ -62,6 +58,10 @@ What's on your mind? + + Toot sent! + + ImageFullScreen diff --git a/translations/harbour-tooter-nl_BE.ts b/translations/harbour-tooter-nl_BE.ts index cf8d937..035f8b9 100644 --- a/translations/harbour-tooter-nl_BE.ts +++ b/translations/harbour-tooter-nl_BE.ts @@ -22,10 +22,6 @@ Conversation - - Conversation - Gesprek - Delete Verwijderen @@ -62,6 +58,10 @@ What's on your mind? + + Toot sent! + + ImageFullScreen diff --git a/translations/harbour-tooter-oc.ts b/translations/harbour-tooter-oc.ts index 2bb86d9..cf6f401 100644 --- a/translations/harbour-tooter-oc.ts +++ b/translations/harbour-tooter-oc.ts @@ -22,10 +22,6 @@ Conversation - - Conversation - Discutida - Delete Escafar @@ -62,6 +58,10 @@ What's on your mind? + + Toot sent! + + ImageFullScreen diff --git a/translations/harbour-tooter-pl.ts b/translations/harbour-tooter-pl.ts index 952b1b2..7e97caa 100644 --- a/translations/harbour-tooter-pl.ts +++ b/translations/harbour-tooter-pl.ts @@ -22,10 +22,6 @@ Conversation - - Conversation - Konwersacja - Delete Usuń @@ -62,6 +58,10 @@ What's on your mind? + + Toot sent! + + ImageFullScreen diff --git a/translations/harbour-tooter-ru.ts b/translations/harbour-tooter-ru.ts index 277a582..724ec09 100644 --- a/translations/harbour-tooter-ru.ts +++ b/translations/harbour-tooter-ru.ts @@ -22,10 +22,6 @@ Conversation - - Conversation - Беседа - Delete Удалить @@ -62,6 +58,10 @@ What's on your mind? + + Toot sent! + + ImageFullScreen diff --git a/translations/harbour-tooter-sr.ts b/translations/harbour-tooter-sr.ts index 3091e3e..6080c74 100644 --- a/translations/harbour-tooter-sr.ts +++ b/translations/harbour-tooter-sr.ts @@ -22,10 +22,6 @@ Conversation - - Conversation - Разговор - Delete Обриши @@ -62,6 +58,10 @@ What's on your mind? + + Toot sent! + + ImageFullScreen diff --git a/translations/harbour-tooter-sv.ts b/translations/harbour-tooter-sv.ts index 43b1866..3e411bf 100644 --- a/translations/harbour-tooter-sv.ts +++ b/translations/harbour-tooter-sv.ts @@ -22,10 +22,6 @@ Conversation - - Conversation - Konversation - Delete Radera @@ -62,6 +58,10 @@ What's on your mind? + + Toot sent! + + ImageFullScreen diff --git a/translations/harbour-tooter-zh_CN.ts b/translations/harbour-tooter-zh_CN.ts index d25e9f9..fa8b314 100644 --- a/translations/harbour-tooter-zh_CN.ts +++ b/translations/harbour-tooter-zh_CN.ts @@ -22,10 +22,6 @@ Conversation - - Conversation - 对话 - Delete 删除 @@ -62,6 +58,10 @@ What's on your mind? 有何想法? + + Toot sent! + + ImageFullScreen diff --git a/translations/harbour-tooter.ts b/translations/harbour-tooter.ts index b119e7e..bf8ce75 100644 --- a/translations/harbour-tooter.ts +++ b/translations/harbour-tooter.ts @@ -22,10 +22,6 @@ Conversation - - Conversation - Conversation - Delete Delete @@ -62,6 +58,10 @@ What's on your mind? + + Toot sent! + + ImageFullScreen From 41041a77aa35a92f0df906078c70b3660b1166f3 Mon Sep 17 00:00:00 2001 From: molan-git Date: Mon, 25 May 2020 17:54:02 +0200 Subject: [PATCH 02/22] ui-improvements New image/video viewer Send-message Profile background images --- qml/lib/Worker.js | 6 +- qml/pages/Conversation.qml | 16 ++++- qml/pages/LoginPage.qml | 10 +-- qml/pages/MainPage.qml | 4 +- qml/pages/Profile.qml | 13 ++-- qml/pages/components/ImageFullScreen.qml | 52 +++++++++------- qml/pages/components/InfoBanner.qml | 11 ++-- qml/pages/components/InfoBanner.qml.autosave | 61 ------------------ qml/pages/components/MediaBlock.qml | 2 - qml/pages/components/MiniHeader.qml | 1 - qml/pages/components/Navigation.qml | 2 - qml/pages/components/ProfileHeader.qml | 19 +++--- qml/pages/components/VisualContainer.qml | 26 ++++---- translations/harbour-tooter-de.ts | 8 ++- translations/harbour-tooter-el.ts | 6 +- translations/harbour-tooter-es.ts | 6 +- translations/harbour-tooter-fi.ts | 4 ++ translations/harbour-tooter-fr.ts | 8 ++- translations/harbour-tooter-it.ts | 65 +++++++++++--------- translations/harbour-tooter-nl.ts | 6 +- translations/harbour-tooter-nl_BE.ts | 6 +- translations/harbour-tooter-oc.ts | 6 +- translations/harbour-tooter-pl.ts | 6 +- translations/harbour-tooter-ru.ts | 6 +- translations/harbour-tooter-sr.ts | 6 +- translations/harbour-tooter-sv.ts | 6 +- translations/harbour-tooter-zh_CN.ts | 6 +- translations/harbour-tooter.ts | 6 +- 28 files changed, 197 insertions(+), 177 deletions(-) delete mode 100644 qml/pages/components/InfoBanner.qml.autosave diff --git a/qml/lib/Worker.js b/qml/lib/Worker.js index 15c13fd..8b53e8c 100644 --- a/qml/lib/Worker.js +++ b/qml/lib/Worker.js @@ -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); } @@ -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"] diff --git a/qml/pages/Conversation.qml b/qml/pages/Conversation.qml index 2aac1ad..0fb4c91 100644 --- a/qml/pages/Conversation.qml +++ b/qml/pages/Conversation.qml @@ -15,6 +15,7 @@ Page { property string suggestedUser: "" property ListModel suggestedModel property string toot_id: "" + property string toot_url: "" property int tootMaxChar: 500; property ListModel mdl allowedOrientations: Orientation.All @@ -96,6 +97,18 @@ Page { } } } + PullDownMenu { + visible: type == "reply" && toot_url != "" + /* MenuItem { + text: qsTr("Open in Browser") + onClicked: Qt.openUrlExternally(toot_url); + } */ + // ! url isn't always fetched. Needs a solution. + MenuItem { + text: qsTr("Copy Link to Clipboard") + onClicked: Clipboard.text = toot_url; + } + } } Rectangle { id: predictionList @@ -110,7 +123,6 @@ Page { anchors.fill: parent model: suggestedModel clip: true - delegate: ItemUser { onClicked: { var start = toot.cursorPosition @@ -433,7 +445,7 @@ Page { worker.sendMessage(msg) warningContent.text = "" toot.text = "" - mediaModel.clear() + mediaModel.clear(); sentBanner.showText(qsTr("Toot sent!")) } } diff --git a/qml/pages/LoginPage.qml b/qml/pages/LoginPage.qml index c3874fb..b1d2064 100644 --- a/qml/pages/LoginPage.qml +++ b/qml/pages/LoginPage.qml @@ -34,15 +34,11 @@ 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 +48,9 @@ Page { Column { id: column width: parent.width - - PageHeader { title: qsTr("Login") } + PageHeader { + title: qsTr("Login") + } SectionHeader { text: qsTr("Instance") @@ -83,7 +80,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']; diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml index 463b305..e273c23 100644 --- a/qml/pages/MainPage.qml +++ b/qml/pages/MainPage.qml @@ -57,6 +57,7 @@ Page { } } } + VisualItemModel { id: visualModel MyList{ @@ -188,7 +189,8 @@ Page { "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/Profile.qml b/qml/pages/Profile.qml index 6d56f44..3f39db7 100644 --- a/qml/pages/Profile.qml +++ b/qml/pages/Profile.qml @@ -16,7 +16,7 @@ Page { property int favourites_count; property int reblogs_count; property int count_moments; - property string profile_background: ""; + property string profileBackground: ""; property string note: ""; property string url: ""; @@ -42,6 +42,7 @@ Page { 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/", @@ -135,7 +136,6 @@ Page { } - MyList { id: list header: ProfileHeader { @@ -143,6 +143,7 @@ Page { title: display_name description: username image: profileImage + bg: profileBackground } anchors { @@ -159,7 +160,6 @@ Page { conf: Logic.conf } - ExpandingSectionGroup { id: expander //currentIndex: 0 @@ -275,10 +275,8 @@ Page { })); 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') + // function still missing for user accounts + // } else if (test.length === 4 && test[3][0] === "@" ) { } else { Qt.openUrlExternally(link); @@ -290,7 +288,6 @@ Page { spacing: Theme.paddingMedium anchors.horizontalCenter: parent.horizontalCenter Button { - id: btnUrl text: qsTr("Open Profile in Browser") onClicked: { Qt.openUrlExternally(url); diff --git a/qml/pages/components/ImageFullScreen.qml b/qml/pages/components/ImageFullScreen.qml index dba23a8..5384804 100644 --- a/qml/pages/components/ImageFullScreen.qml +++ b/qml/pages/components/ImageFullScreen.qml @@ -2,7 +2,7 @@ import QtQuick 2.0 import Sailfish.Silica 1.0 import QtMultimedia 5.0 -Page { +FullscreenContentPage { id: imagePage property string type: "" property string previewURL: "" @@ -22,6 +22,26 @@ Page { videoFlickable.visible = true; } } + + Item { + id: overlay + z: 100 + property bool active: true + enabled: active + anchors.fill: parent + opacity: active ? 1.0 : 0.0 + Behavior on opacity { FadeAnimator {}} + IconButton { + y: Theme.paddingLarge + anchors { + right: parent.right + rightMargin: Theme.horizontalPageMargin + } + icon.source: "image://theme/icon-m-dismiss" + onClicked: pageStack.pop() + } + } + Flickable { id: videoFlickable visible: false @@ -49,7 +69,6 @@ Page { case MediaPlayer.EndOfMedia: console.log("EndOfMedia") return; - } } @@ -68,7 +87,6 @@ Page { } } - onPositionChanged: function(){ //console.log(duration) //console.log(bufferProgress) @@ -81,15 +99,17 @@ Page { } } + onStopped: function(){ play() } + IconButton { id: playerIcon anchors.left: parent.left anchors.bottom: parent.bottom anchors.leftMargin: Theme.paddingLarge - anchors.bottomMargin: Theme.paddingMedium + anchors.bottomMargin: Theme.paddingLarge*1.5 icon.source: "image://theme/icon-m-play" onClicked: function() { if (video.playbackState === MediaPlayer.PlayingState) @@ -104,10 +124,9 @@ Page { id: playerProgress anchors.left: playerIcon.right anchors.right: videoDlBtn.left - anchors.verticalCenter: playerIcon.verticalCenter anchors.leftMargin: 0 - anchors.bottomMargin: Theme.paddingMedium + anchors.bottomMargin: Theme.paddingLarge*1.5 } IconButton { id: videoDlBtn @@ -115,9 +134,9 @@ Page { 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" + anchors.bottomMargin: Theme.paddingLarge*1.5 + icon.source: "image://theme/icon-m-device-download" + icon.opacity: 0.0 onClicked: { var filename = mediaURL.split("/"); FileDownloader.downloadFile(mediaURL, filename[filename.length-1]); @@ -135,7 +154,7 @@ Page { anchors.centerIn: parent id: videoError width: parent.width - 2*Theme.paddingMedium - wrapMode: Text.WordWrap + wrapMode: Text.Wrap height: contentHeight visible: false; font.pixelSize: Theme.fontSizeSmall; @@ -165,7 +184,6 @@ Page { clip: true onHeightChanged: if (imagePreview.status === Image.Ready) imagePreview.fitToScreen(); - Item { id: imageContainer width: Math.max(imagePreview.width * imagePreview.scale, imageFlickable.width) @@ -173,22 +191,18 @@ Page { Image { id: imagePreview - property real prevScale - function fitToScreen() { scale = Math.min(imageFlickable.width / width, imageFlickable.height / height, 1) pinchArea.minScale = scale prevScale = scale } - anchors.centerIn: parent fillMode: Image.PreserveAspectFit cache: true asynchronous: true sourceSize.height: 1000; smooth: false - onStatusChanged: { if (status == Image.Ready) { fitToScreen() @@ -224,7 +238,6 @@ Page { opacity: 0.3 property real minScale: 1.0 property real maxScale: 3.0 - anchors.fill: parent enabled: imagePreview.status === Image.Ready pinch.target: imagePreview @@ -267,11 +280,9 @@ Page { Component { id: loadingIndicator - Item { height: childrenRect.height width: imagePage.width - ProgressCircle { id: imageLoadingIndicator anchors.horizontalCenter: parent.horizontalCenter @@ -293,9 +304,8 @@ Page { 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" + anchors.bottomMargin: Theme.paddingLarge*1.5 + icon.source: "image://theme/icon-m-device-download" onClicked: { var filename = mediaURL.split("/"); FileDownloader.downloadFile(mediaURL, filename[filename.length-1]); diff --git a/qml/pages/components/InfoBanner.qml b/qml/pages/components/InfoBanner.qml index 3696c59..a9a0148 100644 --- a/qml/pages/components/InfoBanner.qml +++ b/qml/pages/components/InfoBanner.qml @@ -4,16 +4,15 @@ import Sailfish.Silica 1.0 DockedPanel { id: root - z: 100; - width: parent.width //- Theme.paddingLarge*4 - //x: Theme.paddingLarge*2 + z: 100 + width: parent.width height: content.height - dock: Dock.Bottom + dock: Dock.Top Rectangle { id: content width: root.width - height: infoLabel.height + 4*Theme.paddingMedium + height: infoLabel.height + 5*Theme.paddingMedium //anchors.topMargin: 20 color: Theme.highlightBackgroundColor opacity: 1.0 @@ -29,7 +28,7 @@ DockedPanel { wrapMode: Text.WrapAnywhere anchors { left: parent.left - leftMargin: Theme.horizontalPageMargin + leftMargin: Theme.horizontalPageMargin*2 right: parent.right rightMargin: Theme.horizontalPageMargin verticalCenter: parent.verticalCenter diff --git a/qml/pages/components/InfoBanner.qml.autosave b/qml/pages/components/InfoBanner.qml.autosave deleted file mode 100644 index 7921d05..0000000 --- a/qml/pages/components/InfoBanner.qml.autosave +++ /dev/null @@ -1,61 +0,0 @@ -import QtQuick 2.0 -import Sailfish.Silica 1.0 - - -DockedPanel { - id: root - z: 100; - width: parent.width - height: content.height - dock: Dock.Bottom - - Rectangle { - id: content - width: root.width - height: infoLabel.height + 4*Theme.paddingMedium - //anchors.topMargin: 20 - color: Theme.highlightBackgroundColor - opacity: 1.0 - - Label { - id: infoLabel - text : "" - color: Theme.primaryColor - font.family: Theme.fontFamilyHeading - font.pixelSize: Theme.fontSizeMedium - //font.weight: Font.Bold - width: parent.width - wrapMode: Text.WrapAnywhere - anchors { - left: parent.left - leftMargin: Theme.horizontalPageMargin - right: parent.right - rightMargin: Theme.ho rizontalPageMargin - 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: 6000 - running: false - onTriggered: { - root.hide() - stop() - } - } -} diff --git a/qml/pages/components/MediaBlock.qml b/qml/pages/components/MediaBlock.qml index e31af8d..069f954 100644 --- a/qml/pages/components/MediaBlock.qml +++ b/qml/pages/components/MediaBlock.qml @@ -74,8 +74,6 @@ Item { } } - - MyImage { id: placeholder1 width: 2 diff --git a/qml/pages/components/MiniHeader.qml b/qml/pages/components/MiniHeader.qml index 6a9f6f9..06c420a 100644 --- a/qml/pages/components/MiniHeader.qml +++ b/qml/pages/components/MiniHeader.qml @@ -41,7 +41,6 @@ Item { : Theme.primaryColor) } - Label { id: lblScreenName anchors { diff --git a/qml/pages/components/Navigation.qml b/qml/pages/components/Navigation.qml index 30e5e81..b054e76 100644 --- a/qml/pages/components/Navigation.qml +++ b/qml/pages/components/Navigation.qml @@ -169,7 +169,5 @@ SilicaGridView { } - - VerticalScrollDecorator {} } diff --git a/qml/pages/components/ProfileHeader.qml b/qml/pages/components/ProfileHeader.qml index c1b53ae..f2a4ddf 100644 --- a/qml/pages/components/ProfileHeader.qml +++ b/qml/pages/components/ProfileHeader.qml @@ -10,21 +10,22 @@ Item { property string bg: ""; width: parent.width height: icon.height + Theme.paddingLarge*2 - /*Image { - anchors.fill: parent - asynchronous: true - fillMode: Image.PreserveAspectCrop - source: bg - opacity: 0.3 - }*/ + Rectangle { + id: bgImage anchors.fill: parent opacity: 0.2 gradient: Gradient { GradientStop { position: 0.0; color: Theme.highlightBackgroundColor } - GradientStop { position: 1.0; color: Theme.highlightBackgroundColor } + GradientStop { position: 1.0; color: Theme.highlightBackgroundColor } + } + Image { + anchors.fill: bgImage + asynchronous: true + fillMode: Image.PreserveAspectCrop + source: bg + opacity: 0.8 } - } Image { id: icon diff --git a/qml/pages/components/VisualContainer.qml b/qml/pages/components/VisualContainer.qml index d3a06e2..d05f36a 100644 --- a/qml/pages/components/VisualContainer.qml +++ b/qml/pages/components/VisualContainer.qml @@ -3,7 +3,6 @@ import Sailfish.Silica 1.0 import "../../lib/API.js" as Logic BackgroundItem { - id: delegate signal send (string notice) signal navigateTo(string link) @@ -28,6 +27,7 @@ BackgroundItem { topMargin: Theme.paddingMedium } } + Image { id: avatar anchors { @@ -50,7 +50,6 @@ BackgroundItem { ? Theme.highlightColor : Theme.primaryColor) } - MouseArea { anchors.fill: parent onClicked: { @@ -58,12 +57,12 @@ 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 }) } } - Image { id: iconTR anchors { @@ -75,7 +74,7 @@ BackgroundItem { width: Theme.iconSizeExtraSmall height: width source: "image://theme/icon-s-retweet" - } + } Rectangle { color: Theme.highlightDimmerColor width: Theme.iconSizeSmall @@ -137,14 +136,19 @@ BackgroundItem { tlSearch.search = decodeURIComponent("@"+test[3].substring(1)+"@"+test[2]) slideshow.positionViewAtIndex(4, ListView.SnapToItem) navigation.navigateTo('search') - + // Original component + /* pageStack.push(Qt.resolvedUrl("../Profile.qml"), { + "name": "", + "username": test[3].substring(1)+"@"+test[2], + "profileImage": "" + }) */ } else { Qt.openUrlExternally(link); } } text: content.replace(new RegExp(" Toot sent! - + Toot gesendet! + + + Copy Link to Clipboard + Link kopieren ImageFullScreen Error loading - Fehler beim Laden + Ladefehler diff --git a/translations/harbour-tooter-el.ts b/translations/harbour-tooter-el.ts index c926c14..df485eb 100644 --- a/translations/harbour-tooter-el.ts +++ b/translations/harbour-tooter-el.ts @@ -62,12 +62,16 @@ Toot sent! + + Copy Link to Clipboard + + ImageFullScreen Error loading - Σφάλμα φόρτωσης + diff --git a/translations/harbour-tooter-es.ts b/translations/harbour-tooter-es.ts index c52d603..195b8f5 100644 --- a/translations/harbour-tooter-es.ts +++ b/translations/harbour-tooter-es.ts @@ -62,12 +62,16 @@ Toot sent! + + Copy Link to Clipboard + + ImageFullScreen Error loading - Error al cargar + diff --git a/translations/harbour-tooter-fi.ts b/translations/harbour-tooter-fi.ts index a1ec939..50a5f73 100644 --- a/translations/harbour-tooter-fi.ts +++ b/translations/harbour-tooter-fi.ts @@ -62,6 +62,10 @@ Toot sent! + + Copy Link to Clipboard + + ImageFullScreen diff --git a/translations/harbour-tooter-fr.ts b/translations/harbour-tooter-fr.ts index b3835ab..baafe35 100644 --- a/translations/harbour-tooter-fr.ts +++ b/translations/harbour-tooter-fr.ts @@ -60,14 +60,18 @@ Toot sent! - + Pouet envoyé ! + + + Copy Link to Clipboard + Copier le lien ImageFullScreen Error loading - Erreur de chargement + diff --git a/translations/harbour-tooter-it.ts b/translations/harbour-tooter-it.ts index e62798d..5b5be12 100644 --- a/translations/harbour-tooter-it.ts +++ b/translations/harbour-tooter-it.ts @@ -28,52 +28,57 @@ Conversation - + + Copy Link to Clipboard + Copia link + + + Write your warning here Contenuto avviso - + What's on your mind? A cosa stai pensando? - + Delete Elimina - + Public Pubblico - + Unlisted Non elencato - + Followers-only Solo ai seguaci - + Direct Diretto - + Toot sent! - + Toot è stato pubblicato! - + Emojis Emojis - + Tap to insert Tap per inserire @@ -81,9 +86,9 @@ ImageFullScreen - + Error loading - Errore caricamento + Errore durante caricamento @@ -97,27 +102,27 @@ LoginPage - + Login Accesso - + Instance Istanza - + Enter a valid Mastodon instance URL Inserire URL di una istanza Mastodon valida - + Mastodon is a free, open-source social network. A decentralized alternative to commercial platforms, it avoids the risks of a single company monopolizing your communication. Pick a server that you trust — whichever you choose, you can interact with everyone else. Anyone can run their own Mastodon instance and participate in the social network seamlessly. 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. - + Reload Ricarica @@ -125,37 +130,37 @@ MainPage - + Home Home - + Notifications Notifiche - + Local Locale - + Federated Federazione - + Search Cerca - + @user or #term @utente o #termine - + New Toot Nuovo toot @@ -269,7 +274,7 @@ Biografia - + Open Profile in Browser Aprire profile nel browser @@ -388,22 +393,22 @@ VisualContainer - + Unboost Annulla condivisione - + Boost Condividi - + Unfavorite Annulla apprezzamento - + Favorite Apprezzato diff --git a/translations/harbour-tooter-nl.ts b/translations/harbour-tooter-nl.ts index 768c5a8..9c3e4b0 100644 --- a/translations/harbour-tooter-nl.ts +++ b/translations/harbour-tooter-nl.ts @@ -62,12 +62,16 @@ Toot sent! + + Copy Link to Clipboard + + ImageFullScreen Error loading - Fout bij laden + diff --git a/translations/harbour-tooter-nl_BE.ts b/translations/harbour-tooter-nl_BE.ts index 035f8b9..25d9369 100644 --- a/translations/harbour-tooter-nl_BE.ts +++ b/translations/harbour-tooter-nl_BE.ts @@ -62,12 +62,16 @@ Toot sent! + + Copy Link to Clipboard + + ImageFullScreen Error loading - Fout bij laden + diff --git a/translations/harbour-tooter-oc.ts b/translations/harbour-tooter-oc.ts index cf6f401..3319228 100644 --- a/translations/harbour-tooter-oc.ts +++ b/translations/harbour-tooter-oc.ts @@ -62,12 +62,16 @@ Toot sent! + + Copy Link to Clipboard + + ImageFullScreen Error loading - Error en cargar + diff --git a/translations/harbour-tooter-pl.ts b/translations/harbour-tooter-pl.ts index 7e97caa..4d7fe81 100644 --- a/translations/harbour-tooter-pl.ts +++ b/translations/harbour-tooter-pl.ts @@ -62,12 +62,16 @@ Toot sent! + + Copy Link to Clipboard + + ImageFullScreen Error loading - Błąd ładowania + diff --git a/translations/harbour-tooter-ru.ts b/translations/harbour-tooter-ru.ts index 724ec09..d47095f 100644 --- a/translations/harbour-tooter-ru.ts +++ b/translations/harbour-tooter-ru.ts @@ -62,12 +62,16 @@ Toot sent! + + Copy Link to Clipboard + + ImageFullScreen Error loading - Ошибка при загрузке + diff --git a/translations/harbour-tooter-sr.ts b/translations/harbour-tooter-sr.ts index 6080c74..52a0d2c 100644 --- a/translations/harbour-tooter-sr.ts +++ b/translations/harbour-tooter-sr.ts @@ -62,12 +62,16 @@ Toot sent! + + Copy Link to Clipboard + + ImageFullScreen Error loading - Greška u učitavanju + diff --git a/translations/harbour-tooter-sv.ts b/translations/harbour-tooter-sv.ts index 3e411bf..5cd3f54 100644 --- a/translations/harbour-tooter-sv.ts +++ b/translations/harbour-tooter-sv.ts @@ -62,12 +62,16 @@ Toot sent! + + Copy Link to Clipboard + + ImageFullScreen Error loading - Problem att ladda + diff --git a/translations/harbour-tooter-zh_CN.ts b/translations/harbour-tooter-zh_CN.ts index fa8b314..b92289e 100644 --- a/translations/harbour-tooter-zh_CN.ts +++ b/translations/harbour-tooter-zh_CN.ts @@ -62,12 +62,16 @@ Toot sent! + + Copy Link to Clipboard + 复制链接到剪切板 + ImageFullScreen Error loading - 加载错误 + diff --git a/translations/harbour-tooter.ts b/translations/harbour-tooter.ts index bf8ce75..0bf8406 100644 --- a/translations/harbour-tooter.ts +++ b/translations/harbour-tooter.ts @@ -62,12 +62,16 @@ Toot sent! + + Copy Link to Clipboard + + ImageFullScreen Error loading - + From fd2f317f254ecb1e16f9ecbef0fddc45c389b240 Mon Sep 17 00:00:00 2001 From: molan-git Date: Fri, 29 May 2020 20:05:05 +0200 Subject: [PATCH 03/22] Add / improve UI elements - new ProfilePage expander - flexible UI elements for various screensizes - various UI changes - code refactoring --- harbour-tooter.desktop | 5 - harbour-tooter.pro | 8 +- qml/cover/CoverPage.qml | 4 +- qml/harbour-tooter.qml | 71 ++-- qml/lib/Mastodon.js | 16 +- ...{Conversation.qml => ConversationPage.qml} | 314 ++++++--------- qml/pages/LoginPage.qml | 32 +- qml/pages/MainPage.qml | 53 +-- qml/pages/Profile.qml | 306 -------------- qml/pages/ProfilePage.qml | 374 ++++++++++++++++++ qml/pages/{Settings.qml => SettingsPage.qml} | 22 +- qml/pages/components/EmojiSelect.qml | 165 ++++++++ qml/pages/components/ImageFullScreen.qml | 70 ++-- qml/pages/components/InfoBanner.qml | 3 +- qml/pages/components/ItemUser.qml | 10 +- qml/pages/components/MediaBlock.qml | 5 +- qml/pages/components/MiniHeader.qml | 4 +- qml/pages/components/MiniStatus.qml | 5 +- qml/pages/components/MyImage.qml | 4 +- qml/pages/components/MyList.qml | 42 +- qml/pages/components/Navigation.qml | 17 +- qml/pages/components/ProfileHeader.qml | 13 +- qml/pages/components/Toot.qml | 44 +-- qml/pages/components/VisualContainer.qml | 27 +- translations/harbour-tooter.ts | 33 +- 25 files changed, 868 insertions(+), 779 deletions(-) rename qml/pages/{Conversation.qml => ConversationPage.qml} (56%) delete mode 100644 qml/pages/Profile.qml create mode 100644 qml/pages/ProfilePage.qml rename qml/pages/{Settings.qml => SettingsPage.qml} (97%) create mode 100644 qml/pages/components/EmojiSelect.qml 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 026fe41..5242229 100644 --- a/harbour-tooter.pro +++ b/harbour-tooter.pro @@ -53,6 +53,9 @@ HEADERS += src/dbusAdaptor.h HEADERS += src/dbus.h DISTFILES += qml/harbour-tooter.qml \ + qml/pages/ConversationPage.qml \ + qml/pages/ProfilePage.qml \ + qml/pages/SettingsPage.qml \ qml/pages/components/InfoBanner.qml \ qml/pages/components/VisualContainer.qml \ qml/pages/components/MiniStatus.qml \ @@ -67,11 +70,8 @@ DISTFILES += qml/harbour-tooter.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 \ @@ -95,7 +95,7 @@ SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172 # to disable building translations every time, comment out the # following CONFIG line -CONFIG += sailfishapp_i18n +# CONFIG += sailfishapp_i18n # German translation is enabled as an example. If you aren't # planning to localize your app, remember to comment out the diff --git a/qml/cover/CoverPage.qml b/qml/cover/CoverPage.qml index 770124c..4080b51 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 ){ @@ -135,5 +135,5 @@ CoverBackground { notificationsLbl.text = notificationsNum; Logic.conf.notificationLastID = notificationLastID; } -} +} diff --git a/qml/harbour-tooter.qml b/qml/harbour-tooter.qml index 7b23d5e..60b34c8 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 = new 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/lib/Mastodon.js b/qml/lib/Mastodon.js index 8a8e4c6..03cfb17 100644 --- a/qml/lib/Mastodon.js +++ b/qml/lib/Mastodon.js @@ -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 { diff --git a/qml/pages/Conversation.qml b/qml/pages/ConversationPage.qml similarity index 56% rename from qml/pages/Conversation.qml rename to qml/pages/ConversationPage.qml index 0fb4c91..c39f9d3 100644 --- a/qml/pages/Conversation.qml +++ b/qml/pages/ConversationPage.qml @@ -9,9 +9,9 @@ Page { id: conversationPage property string headerTitle: "" property string type - property alias title: header.title - property alias description: header.description - property alias avatar: header.image + 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: "" @@ -66,6 +66,7 @@ Page { id: header visible: false } + SilicaListView { id: conversationList header: PageHeader { @@ -97,6 +98,7 @@ Page { } } } + PullDownMenu { visible: type == "reply" && toot_url != "" /* MenuItem { @@ -110,19 +112,24 @@ Page { } } } + 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 + anchors.top: parent.top + height: implicitHeight + //height: suggestedModel.count > 6 ? Theme.itemSizeMedium * 6 : Theme.itemSizeMedium * suggestedModel.count color: Theme.highlightDimmerColor SilicaListView { anchors.fill: parent model: suggestedModel clip: true + quickScroll: false + VerticalScrollDecorator {} delegate: ItemUser { onClicked: { var start = toot.cursorPosition @@ -149,19 +156,19 @@ Page { DockedPanel { id: panel - open: true - onExpandedChanged: { - if (!expanded) { - show() - } - } - + 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 + + Rectangle { width: parent.width height: progressBar.height color: Theme.highlightBackgroundColor @@ -172,15 +179,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 } } @@ -189,7 +197,7 @@ Page { visible: false height: visible ? implicitHeight : 0 anchors { - top: parent.top + top: parent.top topMargin: Theme.paddingMedium left: parent.left right: parent.right @@ -201,10 +209,9 @@ Page { placeholderColor: palette.highlightColor color: palette.highlightColor horizontalAlignment: Text.AlignLeft - EnterKey.onClicked: { - //tweet() - } + EnterKey.onClicked: {} } + TextInput { id: textOperations visible: false @@ -221,17 +228,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)) + 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 @@ -247,45 +256,46 @@ Page { } } } + IconButton { id: btnSmileys - property string selection + property string selection onSelectionChanged: { - console.log(selection) - } - + console.log(selection) + } 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) + opacity: 0.6 + icon.source: "../../qml/images/emojiselect.svg" + 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) @@ -303,7 +313,6 @@ Page { duration: 800 } } - remove: Transition { NumberAnimation { property: "opacity" @@ -320,6 +329,7 @@ Page { } } } + IconButton { id: btnContentWarning anchors { @@ -332,6 +342,7 @@ Page { + (pressed ? Theme.highlightColor : (warningContent.visible ? Theme.secondaryHighlightColor : Theme.primaryColor)) onClicked: warningContent.visible = !warningContent.visible } + IconButton { id: btnAddImage enabled: mediaModel.count < 4 @@ -357,21 +368,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 @@ -379,15 +387,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") } @@ -421,7 +430,6 @@ Page { console.log(mediaModel.get(k).id) media_ids.push(mediaModel.get(k).id) } - var msg = { "action": 'statuses', "method": 'POST', @@ -445,7 +453,7 @@ Page { worker.sendMessage(msg) warningContent.text = "" toot.text = "" - mediaModel.clear(); + mediaModel.clear() sentBanner.showText(qsTr("Toot sent!")) } } @@ -453,11 +461,12 @@ Page { 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) { @@ -490,157 +499,64 @@ Page { "conf": Logic.conf }) } - Component { - id: firstWizardPage - Dialog { - id: emoticonsDialog - canAccept: false //selector.currentIndex >= 0 + BackgroundItem { + id: showPanel + visible: !panel.open + height: Theme.paddingMedium + width: parent.width + opacity: enabled ? 1.0 : 0.0 + Behavior on opacity { FadeAnimator {} } + 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 { + width: parent.width + height: progressBarShowPanel.height + color: Theme.highlightBackgroundColor + opacity: 0.2 + anchors { + left: parent.left + right: parent.right + top: parent.top + } + } - 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 { + color: Theme.highlightBackgroundColor + opacity: 0.2 + height: showPanel.height + width: showPanel.width + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top + bottom: parent.bottom + } + } - 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: progressBarShowPanel + 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 } + } diff --git a/qml/pages/LoginPage.qml b/qml/pages/LoginPage.qml index b1d2064..7751cdf 100644 --- a/qml/pages/LoginPage.qml +++ b/qml/pages/LoginPage.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 QtWebKit 3.0 import Sailfish.Silica 1.0 @@ -192,5 +162,5 @@ Page { } } } -} +} diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml index e273c23..9dcff9a 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 @@ -37,7 +7,7 @@ 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 @@ -185,7 +155,7 @@ 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, @@ -207,7 +177,6 @@ Page { } - SlideshowView { id: slideshow width: parent.width @@ -233,6 +202,11 @@ Page { } IconButton { + id: newTweet + 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) bottom: (mainPage.isPortrait ? infoPanel.top : parent.bottom) @@ -241,14 +215,11 @@ Page { bottom: Theme.paddingLarge } } - - id: newTweet - width: Theme.iconSizeLarge - height: width - visible: !isPortrait ? true : !infoPanel.open - icon.source: "image://theme/icon-l-add" onClicked: { - pageStack.push(Qt.resolvedUrl("Conversation.qml"), {headerTitle: qsTr("New Toot"), type: "new"}) + pageStack.push(Qt.resolvedUrl("ConversationPage.qml"), { + headerTitle: qsTr("New Toot"), + type: "new" + }) } } @@ -274,5 +245,5 @@ Page { Component.onCompleted: { console.log("aaa") } -} +} diff --git a/qml/pages/Profile.qml b/qml/pages/Profile.qml deleted file mode 100644 index 3f39db7..0000000 --- a/qml/pages/Profile.qml +++ /dev/null @@ -1,306 +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 profileBackground: ""; - 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 - 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 '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 - bg: profileBackground - } - - 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) - - // function still missing for user accounts - // } else if (test.length === 4 && test[3][0] === "@" ) { - - } else { - Qt.openUrlExternally(link); - } - } - - } - Column { - spacing: Theme.paddingMedium - anchors.horizontalCenter: parent.horizontalCenter - Button { - 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..0247b72 --- /dev/null +++ b/qml/pages/ProfilePage.qml @@ -0,0 +1,374 @@ +import QtQuick 2.0 +import Sailfish.Silica 1.0 +import "../lib/API.js" as Logic +import "./components/" +import QtGraphicalEffects 1.0 + + +Page { + id: profilePage + 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 profileBackground: "" + 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 + 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 '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 + } + 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 + } + + // ProfilePage ExpandingSection + ExpandingSectionGroup { + id: expander + 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.paddingSmall + anchors.bottomMargin: Theme.paddingLarge + + Rectangle { + id: txtContainer + width: expander.width + height: Math.min(txtNote.height, parent.height*0.488) + color: "transparent" + visible: { + if ((note.text === "") && (note.text === "

") ) { + false + } else { + true + } + } + SilicaListView { + id: txtFlickable + anchors.fill: txtContainer + clip: true + quickScroll: false + VerticalScrollDecorator { flickable: txtNote } + + Text { + id: txtNote + text: note + textFormat: Text.StyledText + wrapMode: Text.Wrap + font.pixelSize: Theme.fontSizeExtraSmall + color: Theme.secondaryColor + linkColor: Theme.highlightColor + 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) + /* Function still missing for user accounts */ + // } else if (test.length === 4 && test[3][0] === "@" ) { + } else { + Qt.openUrlExternally(link); + } + } + } + } + } + + 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 + } */ + } + + Label { + id: separatorLabel1 + x: Theme.horizontalPageMargin + width: parent.width - ( 2 * Theme.horizontalPageMargin ) + font.pixelSize: Theme.fontSizeExtraSmall + wrapMode: Text.Wrap + anchors { + horizontalCenter: parent.horizontalCenter + } + } + + 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 ? highlightColor : 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); + } + } + } + + Separator { + id: btnSeparator + width: parent.width + height: Theme.paddingMedium + color: Theme.primaryColor + opacity: 0.0 + horizontalAlignment: Qt.AlignHCenter + } + + Button { + id: btnBrowser + text: qsTr("Open in Browser") + preferredWidth: Theme.buttonWidthMedium + anchors { + horizontalCenter: parent.horizontalCenter + } + onClicked: { + Qt.openUrlExternally(url); + } + } + + Label { + id: separatorLabel2 + x: Theme.horizontalPageMargin + width: parent.width - ( 2 * Theme.horizontalPageMargin ) + font.pixelSize: Theme.fontSizeExtraSmall + wrapMode: Text.Wrap + anchors { + horizontalCenter: parent.horizontalCenter + } + } + + } + } + } +} diff --git a/qml/pages/Settings.qml b/qml/pages/SettingsPage.qml similarity index 97% rename from qml/pages/Settings.qml rename to qml/pages/SettingsPage.qml index 00d6874..d844bff 100644 --- a/qml/pages/Settings.qml +++ b/qml/pages/SettingsPage.qml @@ -1,16 +1,15 @@ import QtQuick 2.0 import Sailfish.Silica 1.0 - import "../lib/API.js" as Logic + Page { + id: settingsPage SilicaFlickable { anchors.fill: parent contentHeight: column.height + Theme.paddingLarge contentWidth: parent.width RemorsePopup { id: remorsePopup } - - VerticalScrollDecorator {} Column { id: column @@ -22,13 +21,12 @@ Page { Column { // No spacing in this column 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; @@ -42,18 +40,17 @@ Page { pageStack.push(Qt.resolvedUrl("LoginPage.qml")) }) } - /* busy = true; checked = false; timer1.start() - - }*/ + }*/ Timer { id: timer1 interval: 4700 onTriggered: parent.busy = false } } + IconTextSwitch { //enabled: false checked: typeof Logic.conf['loadImages'] !== "undefined" && Logic.conf['loadImages'] @@ -64,6 +61,7 @@ Page { Logic.conf['loadImages'] = checked } } + IconTextSwitch { text: qsTr("Translate") description: qsTr("Use Transifex to help with app translation to your language") @@ -81,6 +79,7 @@ Page { } } } + SectionHeader { text: qsTr("Credits") } @@ -109,8 +108,8 @@ Page { 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 ♏" @@ -159,7 +158,7 @@ Page { onClicked: { if (model.mastodon !== ""){ var m = Qt.createQmlObject('import QtQuick 2.0; ListModel { }', Qt.application, 'InternalQmlObject'); - pageStack.push(Qt.resolvedUrl("Conversation.qml"), { + pageStack.push(Qt.resolvedUrl("ConversationPage.qml"), { toot_id: 0, title: model.name, description: '@'+model.mastodon, @@ -198,4 +197,5 @@ Page { } } } + } diff --git a/qml/pages/components/EmojiSelect.qml b/qml/pages/components/EmojiSelect.qml new file mode 100644 index 0000000..ce8548e --- /dev/null +++ b/qml/pages/components/EmojiSelect.qml @@ -0,0 +1,165 @@ +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 + anchors.fill: parent + //anchors.rightMargin: Theme.paddingLarge + //anchors.leftMargin: Theme.paddingLarge + cellWidth: gridView.width / 6 + cellHeight: cellWidth + VerticalScrollDecorator {flickable: listEmojis } + header: PageHeader { + title: qsTr("Emojis") + description: qsTr("Tap to insert") + } + model: ListModel { + id: listEmojis + 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 { + 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() + } + } + } + } + +} + diff --git a/qml/pages/components/ImageFullScreen.qml b/qml/pages/components/ImageFullScreen.qml index 5384804..f27da61 100644 --- a/qml/pages/components/ImageFullScreen.qml +++ b/qml/pages/components/ImageFullScreen.qml @@ -2,11 +2,13 @@ import QtQuick 2.0 import Sailfish.Silica 1.0 import QtMultimedia 5.0 + FullscreenContentPage { - id: imagePage property string type: "" property string previewURL: "" property string mediaURL: "" + + id: imagePage allowedOrientations: Orientation.All Component.onCompleted: function(){ console.log(type) @@ -14,31 +16,12 @@ FullscreenContentPage { 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; - } - } - - Item { - id: overlay - z: 100 - property bool active: true - enabled: active - anchors.fill: parent - opacity: active ? 1.0 : 0.0 - Behavior on opacity { FadeAnimator {}} - IconButton { - y: Theme.paddingLarge - anchors { - right: parent.right - rightMargin: Theme.horizontalPageMargin - } - icon.source: "image://theme/icon-m-dismiss" - onClicked: pageStack.pop() + videoFlickable.visible = true } } @@ -46,14 +29,17 @@ FullscreenContentPage { id: videoFlickable visible: false anchors.fill: parent - contentWidth: imageContainer.width; contentHeight: imageContainer.height + contentWidth: imageContainer.width + contentHeight: imageContainer.height clip: true + Image { id: videoPreview fillMode: Image.PreserveAspectFit anchors.fill: parent source: previewURL } + Video { id: video anchors.fill: parent @@ -82,7 +68,7 @@ FullscreenContentPage { 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; } } @@ -97,11 +83,10 @@ FullscreenContentPage { playerProgress.minimumValue = 0 playerProgress.value = position } - } onStopped: function(){ - play() + stop() } IconButton { @@ -128,20 +113,20 @@ FullscreenContentPage { anchors.leftMargin: 0 anchors.bottomMargin: Theme.paddingLarge*1.5 } + IconButton { id: videoDlBtn - visible: true anchors.right: parent.right anchors.bottom: parent.bottom anchors.rightMargin: Theme.paddingLarge anchors.bottomMargin: Theme.paddingLarge*1.5 - icon.source: "image://theme/icon-m-device-download" - icon.opacity: 0.0 + icon.source: "image://theme/icon-m-cloud-download" onClicked: { var filename = mediaURL.split("/"); FileDownloader.downloadFile(mediaURL, filename[filename.length-1]); } } + Rectangle { visible: videoError.text != "" anchors.left: parent.left @@ -163,7 +148,6 @@ FullscreenContentPage { } } - MouseArea { anchors.fill: parent onClicked: function() { @@ -180,7 +164,8 @@ FullscreenContentPage { 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(); @@ -201,8 +186,8 @@ FullscreenContentPage { fillMode: Image.PreserveAspectFit cache: true asynchronous: true - sourceSize.height: 1000; - smooth: false + sourceSize.height: 2000; + smooth: true // might slower performance onStatusChanged: { if (status == Image.Ready) { fitToScreen() @@ -255,6 +240,7 @@ FullscreenContentPage { bounceBackAnimation.start() } } + NumberAnimation { id: bounceBackAnimation target: imagePreview @@ -280,17 +266,22 @@ FullscreenContentPage { Component { id: loadingIndicator + Item { height: childrenRect.height width: imagePage.width + ProgressCircle { id: imageLoadingIndicator + progressColor: inAlternateCycle ? Theme.highlightColor : Theme.highlightDimmerColor + backgroundColor: inAlternateCycle ? Theme.highlightDimmerColor : Theme.highlightColor anchors.horizontalCenter: parent.horizontalCenter progressValue: imagePreview.progress } } } } + Component { id: failedLoading Text { @@ -299,17 +290,26 @@ FullscreenContentPage { color: Theme.highlightColor } } + + IconButton { + y: Theme.paddingLarge + anchors.right: parent.right + anchors.rightMargin: Theme.horizontalPageMargin + icon.source: "image://theme/icon-m-dismiss" + onClicked: pageStack.pop() + } + IconButton { - visible: true anchors.right: parent.right anchors.bottom: parent.bottom anchors.rightMargin: Theme.paddingLarge anchors.bottomMargin: Theme.paddingLarge*1.5 - icon.source: "image://theme/icon-m-device-download" + 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/InfoBanner.qml b/qml/pages/components/InfoBanner.qml index a9a0148..923face 100644 --- a/qml/pages/components/InfoBanner.qml +++ b/qml/pages/components/InfoBanner.qml @@ -51,11 +51,12 @@ DockedPanel { Timer { id: autoClose - interval: 6000 + interval: 4500 running: false onTriggered: { root.hide() stop() } } + } diff --git a/qml/pages/components/ItemUser.qml b/qml/pages/components/ItemUser.qml index 809c97e..56e11b3 100644 --- a/qml/pages/components/ItemUser.qml +++ b/qml/pages/components/ItemUser.qml @@ -32,14 +32,16 @@ BackgroundItem { } 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 +65,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 069f954..2a7717c 100644 --- a/qml/pages/components/MediaBlock.qml +++ b/qml/pages/components/MediaBlock.qml @@ -146,8 +146,5 @@ Item { } } } + } - - - - diff --git a/qml/pages/components/MiniHeader.qml b/qml/pages/components/MiniHeader.qml index 06c420a..6922f39 100644 --- a/qml/pages/components/MiniHeader.qml +++ b/qml/pages/components/MiniHeader.qml @@ -1,8 +1,9 @@ import QtQuick 2.0 import Sailfish.Silica 1.0 + Item { - id: miniheader + id: miniHeader height: lblName.height width: parent.width @@ -67,4 +68,5 @@ Item { rightMargin: Theme.horizontalPageMargin } } + } diff --git a/qml/pages/components/MiniStatus.qml b/qml/pages/components/MiniStatus.qml index f7a57d0..4dd559b 100644 --- a/qml/pages/components/MiniStatus.qml +++ b/qml/pages/components/MiniStatus.qml @@ -1,8 +1,9 @@ import QtQuick 2.0 import Sailfish.Silica 1.0 + Item { - id: ministatus + id: miniStatus visible: true height: icon.height+Theme.paddingMedium width: parent.width @@ -42,7 +43,7 @@ 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 : '' diff --git a/qml/pages/components/MyImage.qml b/qml/pages/components/MyImage.qml index 13cd278..0e0775f 100644 --- a/qml/pages/components/MyImage.qml +++ b/qml/pages/components/MyImage.qml @@ -2,7 +2,9 @@ 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: "" @@ -37,8 +39,6 @@ Item { progressRec.width = 0; } } - - MouseArea { anchors.fill: parent onClicked: { diff --git a/qml/pages/components/MyList.qml b/qml/pages/components/MyList.qml index b2f0626..135df3c 100644 --- a/qml/pages/components/MyList.qml +++ b/qml/pages/components/MyList.qml @@ -3,9 +3,10 @@ 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 +14,19 @@ 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) @@ -37,7 +36,6 @@ SilicaListView { console.log("LIST send signal emitted with notice: " + notice) } - BusyIndicator { size: BusyIndicatorSize.Large running: myList.model.count === 0 && !viewPlaceHolder.visible @@ -49,8 +47,6 @@ SilicaListView { description: myList.description } - - ViewPlaceholder { id: viewPlaceHolder enabled: model.count === 0 @@ -62,10 +58,16 @@ SilicaListView { MenuItem { text: qsTr("Settings") onClicked: { - pageStack.push(Qt.resolvedUrl("../Settings.qml"), {}) + pageStack.push(Qt.resolvedUrl("../SettingsPage.qml"), {}) } } - + /* MenuItem { + text: qsTr("Open in Browser") + visible: profile_url != "" + onClicked: { + Clipboard.text = profile_url + } + } */ MenuItem { text: qsTr("Load more") onClicked: { @@ -95,10 +97,9 @@ SilicaListView { } onCountChanged: { - loadStarted = false; + loadStarted = false /*contentY = scrollOffset console.log("CountChanged!")*/ - } footer: Item{ @@ -122,17 +123,16 @@ SilicaListView { } } 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 { @@ -161,16 +161,16 @@ SilicaListView { } } 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 text: { var action; switch(type){ @@ -45,10 +43,10 @@ BackgroundItem { } return '@' + retweetScreenName + ' ' + action } - font.pixelSize: Theme.fontSizeExtraSmall color: Theme.secondaryColor } + Image { id: avatar x: Theme.horizontalPageMargin @@ -62,28 +60,28 @@ 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 { @@ -103,7 +101,6 @@ BackgroundItem { : Theme.primaryColor) } - Label { id: lblScreenName anchors { @@ -117,6 +114,7 @@ BackgroundItem { font.pixelSize: Theme.fontSizeExtraSmall color: (pressed ? Theme.secondaryHighlightColor : Theme.secondaryColor) } + Label { function timestamp() { var txt = Format.formatDate(created_at, Formatter.Timepoint) @@ -135,7 +133,7 @@ BackgroundItem { } } - Label { + Text { id: lblText anchors { left: lblName.left @@ -154,20 +152,16 @@ 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 @@ -178,10 +172,12 @@ BackgroundItem { color: (pressed ? Theme.highlightColor : Theme.primaryColor) } 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 d05f36a..8765456 100644 --- a/qml/pages/components/VisualContainer.qml +++ b/qml/pages/components/VisualContainer.qml @@ -2,12 +2,13 @@ import QtQuick 2.2 import Sailfish.Silica 1.0 import "../../lib/API.js" as Logic + 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: 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) Rectangle { x: 0; y: 0; @@ -15,11 +16,11 @@ BackgroundItem { width: parent.width height: parent.height opacity: 0.3 - color: Theme.highlightBackgroundColor; + color: Theme.highlightBackgroundColor } MiniStatus { - id: ministatus + id: miniStatus anchors { leftMargin: Theme.horizontalPageMargin rightMargin: Theme.horizontalPageMargin @@ -31,8 +32,8 @@ BackgroundItem { Image { id: avatar anchors { - top: ministatus.visible ? ministatus.bottom : parent.top - topMargin: ministatus.visible ? Theme.paddingMedium : Theme.paddingLarge + top: miniStatus.visible ? miniStatus.bottom : parent.top + topMargin: miniStatus.visible ? Theme.paddingMedium : Theme.paddingLarge left: parent.left leftMargin: Theme.horizontalPageMargin } @@ -50,10 +51,11 @@ BackgroundItem { ? Theme.highlightColor : Theme.primaryColor) } + 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, @@ -63,6 +65,7 @@ BackgroundItem { } } + Image { id: iconTR anchors { @@ -74,7 +77,8 @@ BackgroundItem { width: Theme.iconSizeExtraSmall height: width source: "image://theme/icon-s-retweet" - } + } + Rectangle { color: Theme.highlightDimmerColor width: Theme.iconSizeSmall @@ -98,6 +102,7 @@ BackgroundItem { } } } + MiniHeader { id: miniHeader anchors { @@ -106,6 +111,7 @@ BackgroundItem { right: parent.right } } + Text { id: lblContent anchors { @@ -176,6 +182,7 @@ BackgroundItem { wrapMode: Text.Wrap text: model.status_spoiler_text } + MouseArea { anchors.fill: parent onClicked: parent.visible = false; @@ -225,6 +232,7 @@ BackgroundItem { height: width source: "image://theme/icon-s-retweet?" + (!model.reblogged ? Theme.highlightColor : Theme.primaryColor) } + Label { anchors { left: icRT.right @@ -236,6 +244,7 @@ BackgroundItem { color: !model.reblogged ? Theme.highlightColor : Theme.primaryColor } } + MenuItem { enabled: model.type !== "follow" text: typeof model.favourited !== "undefined" && model.favourited ? qsTr("Unfavorite") : qsTr("Favorite") @@ -251,6 +260,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 { @@ -262,6 +272,7 @@ BackgroundItem { height: width source: "image://theme/icon-s-favorite?" + (!model.favourited ? Theme.highlightColor : Theme.primaryColor) } + Label { anchors { left: icFA.right @@ -279,7 +290,7 @@ BackgroundItem { 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, diff --git a/translations/harbour-tooter.ts b/translations/harbour-tooter.ts index 0bf8406..7e229a9 100644 --- a/translations/harbour-tooter.ts +++ b/translations/harbour-tooter.ts @@ -23,21 +23,21 @@ Conversation - Delete - Delete - - - Emojis - Emojis - - - Tap to insert - Tap to insert + Copy Link to Clipboard + Write your warning here + + What's on your mind? + + + + Delete + + Public @@ -54,16 +54,19 @@ Direct - - What's on your mind? - - Toot sent! + + + EmojiPage - Copy Link to Clipboard + Emojis + + + + Tap to insert From 16e211ddb971d6d4c5a1e09d1f4ed26bbe6e1175 Mon Sep 17 00:00:00 2001 From: molan-git Date: Wed, 3 Jun 2020 07:34:33 +0200 Subject: [PATCH 04/22] ui-improvements - open profile picture - improved media viewer - improved user suggestion - better responsive UI design - code refactoring - updated settings page --- harbour-tooter.pro | 3 +- qml/cover/CoverPage.qml | 9 +- qml/harbour-tooter.qml | 2 +- qml/lib/Mastodon.js | 4 +- qml/lib/Worker.js | 8 +- qml/pages/ConversationPage.qml | 89 ++++--- qml/pages/MainPage.qml | 21 +- qml/pages/ProfilePage.qml | 33 ++- qml/pages/SettingsPage.qml | 192 ++++++++++----- qml/pages/components/EmojiSelect.qml | 21 +- qml/pages/components/InfoBanner.qml | 15 +- qml/pages/components/ItemUser.qml | 6 +- qml/pages/components/MediaBlock.qml | 7 +- ...mageFullScreen.qml => MediaFullScreen.qml} | 230 +++++++++--------- qml/pages/components/MiniHeader.qml | 16 +- qml/pages/components/MiniStatus.qml | 11 +- qml/pages/components/MyImage.qml | 36 ++- qml/pages/components/MyList.qml | 8 +- qml/pages/components/Navigation.qml | 92 +++---- qml/pages/components/ProfileHeader.qml | 57 +++-- qml/pages/components/ProfileImage.qml | 27 ++ qml/pages/components/Toot.qml | 6 +- src/notifications.h | 2 +- 23 files changed, 525 insertions(+), 370 deletions(-) rename qml/pages/components/{ImageFullScreen.qml => MediaFullScreen.qml} (64%) create mode 100644 qml/pages/components/ProfileImage.qml diff --git a/harbour-tooter.pro b/harbour-tooter.pro index 5242229..a7c61ae 100644 --- a/harbour-tooter.pro +++ b/harbour-tooter.pro @@ -57,6 +57,8 @@ DISTFILES += qml/harbour-tooter.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 \ @@ -66,7 +68,6 @@ DISTFILES += qml/harbour-tooter.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 \ diff --git a/qml/cover/CoverPage.qml b/qml/cover/CoverPage.qml index 4080b51..63b9d01 100644 --- a/qml/cover/CoverPage.qml +++ b/qml/cover/CoverPage.qml @@ -57,7 +57,6 @@ CoverBackground { horizontalAlignment: Image.AlignLeft verticalAlignment: Image.AlignBottom fillMode: Image.PreserveAspectFit - source: "../images/tooter.svg" } Timer { @@ -78,6 +77,7 @@ CoverBackground { } source: "image://theme/icon-s-alarm?" + Theme.highlightColor } + Label { id: notificationsLbl anchors { @@ -112,8 +112,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() } } } diff --git a/qml/harbour-tooter.qml b/qml/harbour-tooter.qml index 60b34c8..b0f9abd 100644 --- a/qml/harbour-tooter.qml +++ b/qml/harbour-tooter.qml @@ -47,7 +47,7 @@ ApplicationWindow { Logic.conf['notificationLastID'] = 0 if (Logic.conf['instance']) { - Logic.api = new Logic.MastodonAPI({ + Logic.api = Logic.mastodonAPI({ "instance": Logic.conf['instance'], "api_user_token": "" }) diff --git a/qml/lib/Mastodon.js b/qml/lib/Mastodon.js index 03cfb17..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) { @@ -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 8b53e8c..19469c6 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'] @@ -298,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/ConversationPage.qml b/qml/pages/ConversationPage.qml index c39f9d3..611329f 100644 --- a/qml/pages/ConversationPage.qml +++ b/qml/pages/ConversationPage.qml @@ -43,10 +43,6 @@ Page { } } - InfoBanner { - id: sentBanner - } - ListModel { id: mediaModel onCountChanged: { @@ -73,12 +69,14 @@ Page { 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' @@ -100,12 +98,7 @@ Page { } PullDownMenu { - visible: type == "reply" && toot_url != "" - /* MenuItem { - text: qsTr("Open in Browser") - onClicked: Qt.openUrlExternally(toot_url); - } */ - // ! url isn't always fetched. Needs a solution. + visible: type === "reply" && toot_url !== "" MenuItem { text: qsTr("Copy Link to Clipboard") onClicked: Clipboard.text = toot_url; @@ -121,16 +114,17 @@ Page { anchors.right: panel.right anchors.top: parent.top height: implicitHeight - //height: suggestedModel.count > 6 ? Theme.itemSizeMedium * 6 : Theme.itemSizeMedium * suggestedModel.count color: Theme.highlightDimmerColor 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) { @@ -149,24 +143,20 @@ 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) + btnContentWarning.height + Theme.paddingMedium + (warningContent.visible ? warningContent.height : 0) dock: Dock.Bottom + open: true + animationDuration: 200 Rectangle { width: parent.width @@ -260,8 +250,12 @@ Page { IconButton { id: btnSmileys property string selection - onSelectionChanged: { - console.log(selection) + opacity: 0.7 + icon { + color: Theme.highlightColor + width: Theme.iconSizeSmallPlus + fillMode: Image.PreserveAspectFit + source: "../../qml/images/emojiselect.svg" } anchors { top: warningContent.bottom @@ -269,8 +263,9 @@ Page { right: parent.right rightMargin: Theme.paddingSmall } - opacity: 0.6 - icon.source: "../../qml/images/emojiselect.svg" + onSelectionChanged: { + console.log(selection) + } onClicked: pageStack.push(emojiSelect) } @@ -501,12 +496,12 @@ Page { } BackgroundItem { - id: showPanel + id: hiddenPanel visible: !panel.open - height: Theme.paddingMedium + height: Theme.paddingLarge * 0.5 width: parent.width - opacity: enabled ? 1.0 : 0.0 - Behavior on opacity { FadeAnimator {} } + opacity: enabled ? 0.6 : 0.0 + Behavior on opacity { FadeAnimator { duration: 400 } } anchors { horizontalCenter: parent.horizontalCenter bottom: parent.bottom @@ -518,8 +513,18 @@ Page { } Rectangle { + id: hiddenPanelBackground width: parent.width - height: progressBarShowPanel.height + height: parent.height + color: Theme.highlightBackgroundColor + opacity: 0.4 + anchors.fill: parent + } + + Rectangle { + id: progressBarBackground + width: parent.width + height: progressBarHiddenPanel.height color: Theme.highlightBackgroundColor opacity: 0.2 anchors { @@ -530,19 +535,7 @@ Page { } Rectangle { - color: Theme.highlightBackgroundColor - opacity: 0.2 - height: showPanel.height - width: showPanel.width - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top - bottom: parent.bottom - } - } - - Rectangle { - id: progressBarShowPanel + id: progressBarHiddenPanel width: toot.text.length ? panel.width * (toot.text.length / tootMaxChar) : 0 height: Theme.itemSizeSmall * 0.05 color: Theme.highlightBackgroundColor @@ -559,4 +552,8 @@ Page { id: emojiSelect } + InfoBanner { + id: sentBanner + } + } diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml index 9dcff9a..b254496 100644 --- a/qml/pages/MainPage.qml +++ b/qml/pages/MainPage.qml @@ -6,6 +6,7 @@ import "./components/" Page { id: mainPage + property bool isFirstPage: true property bool isTablet: true //Screen.sizeCategory >= Screen.Large @@ -39,6 +40,7 @@ Page { height: parent.itemHeight onOpenDrawer: infoPanel.open = setDrawer } + MyList{ id: tlNotifications; title: qsTr("Notifications") @@ -49,6 +51,7 @@ Page { height: parent.itemHeight onOpenDrawer: infoPanel.open = setDrawer } + MyList{ id: tlLocal; title: qsTr("Local") @@ -59,6 +62,7 @@ Page { height: parent.itemHeight onOpenDrawer: infoPanel.open = setDrawer } + MyList{ id: tlPublic; title: qsTr("Federated") @@ -68,6 +72,7 @@ Page { height: parent.itemHeight onOpenDrawer: infoPanel.open = setDrawer } + Item { id: tlSearch; width: parent.itemWidth @@ -84,6 +89,7 @@ Page { id: loader anchors.fill: parent } + Column { id: headerContainer width: tlSearch.width @@ -103,6 +109,7 @@ Page { } } } + Component { id: loading BusyIndicator { @@ -111,6 +118,7 @@ Page { running: true } } + Component { id: tagListComponent MyList { @@ -135,6 +143,7 @@ Page { } } } + Component { id: userListComponent MyList { @@ -172,9 +181,7 @@ Page { } } } - } - } SlideshowView { @@ -187,12 +194,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 } @@ -209,11 +213,9 @@ Page { 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) - margins: { - left: Theme.paddingLarge - bottom: Theme.paddingLarge - } + bottomMargin: Theme.paddingLarge } onClicked: { pageStack.push(Qt.resolvedUrl("ConversationPage.qml"), { @@ -242,6 +244,7 @@ Page { Qt.openUrlExternally(href); } } + Component.onCompleted: { console.log("aaa") } diff --git a/qml/pages/ProfilePage.qml b/qml/pages/ProfilePage.qml index 0247b72..a0316e4 100644 --- a/qml/pages/ProfilePage.qml +++ b/qml/pages/ProfilePage.qml @@ -7,6 +7,7 @@ import QtGraphicalEffects 1.0 Page { id: profilePage + property ListModel tweets property string display_name: "" property string username: "" @@ -141,27 +142,28 @@ Page { image: profileImage bg: profileBackground } - 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 + anchors { + top: parent.top + bottom: profileExpander.top + left: parent.left + right: parent.right + } } // ProfilePage ExpandingSection ExpandingSectionGroup { - id: expander + id: profileExpander anchors { bottom: parent.bottom left: parent.left right: parent.right } + ExpandingSection { id: expandingSection1 title: qsTr("About") @@ -172,22 +174,23 @@ Page { Rectangle { id: txtContainer - width: expander.width + width: parent.width height: Math.min(txtNote.height, parent.height*0.488) color: "transparent" visible: { - if ((note.text === "") && (note.text === "

") ) { + if ((note.text === "") || (note.text === "

") ) { false } else { true } } + SilicaListView { id: txtFlickable - anchors.fill: txtContainer + anchors.fill: parent clip: true quickScroll: false - VerticalScrollDecorator { flickable: txtNote } + VerticalScrollDecorator {} Text { id: txtNote @@ -228,6 +231,7 @@ Page { anchors.horizontalCenter: parent.horizontalCenter anchors.leftMargin: Theme.paddingLarge anchors.rightMargin: Theme.paddingLarge + Text { id: txtFollowers visible: followers_count ? true : false @@ -236,6 +240,7 @@ Page { color: Theme.highlightColor wrapMode: Text.Wrap } + Text { id: txtFollowing visible: following_count ? true : false @@ -244,6 +249,7 @@ Page { color: Theme.highlightColor wrapMode: Text.Wrap } + Text { id: txtStatuses visible: statuses_count ? true : false @@ -252,6 +258,7 @@ Page { color: Theme.highlightColor wrapMode: Text.Wrap } + /*Text { id: txtFavourites visible: favourites_count ? true : false @@ -304,11 +311,12 @@ Page { // to-do: create notification banner "Follow request sent!" } } + Button { id: btnMute preferredWidth: Theme.buttonWidthSmall text: (muting ? qsTr("Unmute") : qsTr("Mute")) - color: (muting ? highlightColor : palette.primaryColor) + color: (muting ? palette.errorColor : palette.primaryColor) onClicked: { var msg = { 'method' : 'POST', @@ -319,6 +327,7 @@ Page { worker.sendMessage(msg); } } + Button { id: btnBlock preferredWidth: Theme.buttonWidthSmall diff --git a/qml/pages/SettingsPage.qml b/qml/pages/SettingsPage.qml index d844bff..cf13abd 100644 --- a/qml/pages/SettingsPage.qml +++ b/qml/pages/SettingsPage.qml @@ -5,81 +5,137 @@ 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: "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 + } + } + + IconTextSwitch { + text: qsTr("Use smaller Font Size in Toots") + description: qsTr("Enable this option if you prefer to use a smaller font size in displayed Toots") + icon.source: "image://theme/icon-m-font-size" + enabled: false + //checked: typeof Logic.conf['loadImages'] !== "undefined" && Logic.conf['loadImages'] + //onClicked: { + // Logic.conf['loadImages'] = checked + //} + } + + SectionHeader { text: "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.paddingLarge + 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.secondaryColor + 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") + 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.secondaryColor + anchors { + left: parent.left + leftMargin: Theme.paddingLarge * 1.9 + right: parent.right + rightMargin: Theme.paddingLarge * 1.2 + } } } } + /* SectionHeader { text: "Support"} + + 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() + } + Timer { + id: timer2 + interval: 4700 + onTriggered: parent.busy = false + } + } */ + SectionHeader { text: qsTr("Credits") } @@ -89,52 +145,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: "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") @@ -146,31 +211,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("ConversationPage.qml"), { - toot_id: 0, - title: model.name, + headerTitle: "Mention", description: '@'+model.mastodon, - avatar: "", - mdl: m, - type: "reply" + type: "new" }) } else { Qt.openUrlExternally("mailto:"+model.mail); } } } + Column { anchors { verticalCenter: parent.verticalCenter @@ -183,9 +246,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 diff --git a/qml/pages/components/EmojiSelect.qml b/qml/pages/components/EmojiSelect.qml index ce8548e..3e4f8fa 100644 --- a/qml/pages/components/EmojiSelect.qml +++ b/qml/pages/components/EmojiSelect.qml @@ -4,6 +4,7 @@ import Sailfish.Silica 1.0 Component { id: emojiComponent + Dialog { id: emoticonsDialog canAccept: false //selector.currentIndex >= 0 @@ -13,20 +14,17 @@ Component { // acceptDestinationInstance.category = selector.value } } + SilicaGridView { id: gridView - anchors.fill: parent - //anchors.rightMargin: Theme.paddingLarge - //anchors.leftMargin: Theme.paddingLarge - cellWidth: gridView.width / 6 - cellHeight: cellWidth - VerticalScrollDecorator {flickable: listEmojis } header: PageHeader { title: qsTr("Emojis") description: qsTr("Tap to insert") } + cellWidth: gridView.width / 6 + cellHeight: cellWidth + anchors.fill: parent model: ListModel { - id: listEmojis ListElement { section: "smileys"; glyph: "😁" } ListElement { section: "smileys"; glyph: "😂" } ListElement { section: "smileys"; glyph: "😃" } @@ -142,11 +140,12 @@ Component { delegate: BackgroundItem { width: gridView.cellWidth height: gridView.cellHeight + Label { - anchors.centerIn: parent - color: (highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor) - font.pixelSize: Theme.fontSizeLarge text: glyph + font.pixelSize: Theme.fontSizeLarge + color: (highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor) + anchors.centerIn: parent } onClicked: { var cursorPosition = toot.cursorPosition @@ -158,6 +157,8 @@ Component { emoticonsDialog.accept() } } + + VerticalScrollDecorator {flickable: listEmojis } } } diff --git a/qml/pages/components/InfoBanner.qml b/qml/pages/components/InfoBanner.qml index 923face..a6a444e 100644 --- a/qml/pages/components/InfoBanner.qml +++ b/qml/pages/components/InfoBanner.qml @@ -4,28 +4,24 @@ import Sailfish.Silica 1.0 DockedPanel { id: root - z: 100 + dock: Dock.Top width: parent.width height: content.height - dock: Dock.Top Rectangle { id: content - width: root.width - height: infoLabel.height + 5*Theme.paddingMedium - //anchors.topMargin: 20 color: Theme.highlightBackgroundColor - opacity: 1.0 + width: root.width + height: infoLabel.height + 3*Theme.paddingMedium Label { id: infoLabel text : "" - color: Theme.primaryColor font.family: Theme.fontFamilyHeading font.pixelSize: Theme.fontSizeMedium - //font.weight: Font.Bold - width: parent.width + color: Theme.highlightColor wrapMode: Text.WrapAnywhere + width: parent.width anchors { left: parent.left leftMargin: Theme.horizontalPageMargin*2 @@ -34,6 +30,7 @@ DockedPanel { verticalCenter: parent.verticalCenter } } + MouseArea { anchors.fill: parent onClicked: { diff --git a/qml/pages/components/ItemUser.qml b/qml/pages/components/ItemUser.qml index 56e11b3..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,6 +33,7 @@ BackgroundItem { running: avatar.status !== Image.Ready; anchors.centerIn: parent } + MouseArea { anchors.fill: parent onClicked: pageStack.push(Qt.resolvedUrl("./../ProfilePage.qml"), { diff --git a/qml/pages/components/MediaBlock.qml b/qml/pages/components/MediaBlock.qml index 2a7717c..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: { @@ -92,6 +94,7 @@ Item { } } } + MyImage { id: placeholder2 width: 2 @@ -110,6 +113,7 @@ Item { } } } + MyImage { id: placeholder3 width: 2 @@ -128,6 +132,7 @@ Item { } } } + MyImage { id: placeholder4 width: 2 diff --git a/qml/pages/components/ImageFullScreen.qml b/qml/pages/components/MediaFullScreen.qml similarity index 64% rename from qml/pages/components/ImageFullScreen.qml rename to qml/pages/components/MediaFullScreen.qml index f27da61..3378cac 100644 --- a/qml/pages/components/ImageFullScreen.qml +++ b/qml/pages/components/MediaFullScreen.qml @@ -4,12 +4,13 @@ import QtMultimedia 5.0 FullscreenContentPage { + id: mediaPage + allowedOrientations: Orientation.All + property string type: "" property string previewURL: "" property string mediaURL: "" - id: imagePage - allowedOrientations: Orientation.All Component.onCompleted: function(){ console.log(type) console.log(previewURL) @@ -29,8 +30,6 @@ FullscreenContentPage { id: videoFlickable visible: false anchors.fill: parent - contentWidth: imageContainer.width - contentHeight: imageContainer.height clip: true Image { @@ -57,7 +56,6 @@ FullscreenContentPage { return; } } - onPlaybackStateChanged: { console.log(playbackState) switch (playbackState){ @@ -72,7 +70,6 @@ FullscreenContentPage { return; } } - onPositionChanged: function(){ //console.log(duration) //console.log(bufferProgress) @@ -84,17 +81,18 @@ FullscreenContentPage { playerProgress.value = position } } - onStopped: function(){ stop() } IconButton { id: playerIcon - anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.leftMargin: Theme.paddingLarge - anchors.bottomMargin: Theme.paddingLarge*1.5 + anchors { + left: parent.left + bottom: parent.bottom + leftMargin: Theme.horizontalPageMargin + bottomMargin: Theme.horizontalPageMargin + } icon.source: "image://theme/icon-m-play" onClicked: function() { if (video.playbackState === MediaPlayer.PlayingState) @@ -105,56 +103,47 @@ FullscreenContentPage { } ProgressBar { - indeterminate: true id: playerProgress - anchors.left: playerIcon.right - anchors.right: videoDlBtn.left - anchors.verticalCenter: playerIcon.verticalCenter - anchors.leftMargin: 0 - anchors.bottomMargin: Theme.paddingLarge*1.5 - } - - IconButton { - id: videoDlBtn - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.rightMargin: Theme.paddingLarge - anchors.bottomMargin: Theme.paddingLarge*1.5 - 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.Wrap - height: contentHeight - visible: false; - font.pixelSize: Theme.fontSizeSmall; - text: video.errorString - color: Theme.highlightColor + 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 + } } - } - MouseArea { - anchors.fill: parent - onClicked: function() { - if (video.playbackState === MediaPlayer.PlayingState) - video.pause() - else - video.play() + MouseArea { + anchors.fill: parent + onClicked: function() { + if (video.playbackState === MediaPlayer.PlayingState) + video.pause() + else + video.play() + } } } } @@ -163,11 +152,12 @@ FullscreenContentPage { 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 @@ -176,18 +166,21 @@ FullscreenContentPage { Image { id: imagePreview + 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: 2000; - smooth: true // might slower performance + sourceSize.width: mediaPage.width + smooth: false + anchors.centerIn: parent onStatusChanged: { if (status == Image.Ready) { fitToScreen() @@ -195,15 +188,6 @@ FullscreenContentPage { } } - NumberAnimation { - id: loadedAnimation - target: imagePreview - property: "opacity" - duration: 250 - from: 0; to: 1 - easing.type: Easing.InOutQuad - } - onScaleChanged: { if ((width * scale) > imageFlickable.width) { var xoff = (imageFlickable.width / 2 + imageFlickable.contentX) * scale / prevScale; @@ -215,19 +199,30 @@ FullscreenContentPage { } prevScale = scale } + + NumberAnimation { + id: loadedAnimation + target: imagePreview + property: "opacity" + duration: 250 + from: 0; to: 1 + easing.type: Easing.InOutQuad + } } } PinchArea { id: pinchArea opacity: 0.3 + property real minScale: 1.0 property real maxScale: 3.0 + 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() @@ -249,67 +244,74 @@ FullscreenContentPage { from: imagePreview.scale } } - } - Loader { - anchors.centerIn: parent - sourceComponent: { - switch (imagePreview.status) { - case Image.Loading: - return loadingIndicator - case Image.Error: - return failedLoading - default: - return undefined + Loader { + anchors.centerIn: parent + sourceComponent: { + switch (imagePreview.status) { + case Image.Loading: + return loadingIndicator + case Image.Error: + return failedLoading + default: + return undefined + } } - } - Component { - id: loadingIndicator + Component { + id: loadingIndicator + Item { + width: mediaPage.width + height: childrenRect.height - Item { - height: childrenRect.height - width: imagePage.width + ProgressCircle { + id: imageLoadingIndicator + progressValue: imagePreview.progress + progressColor: inAlternateCycle ? Theme.highlightColor : Theme.highlightDimmerColor + backgroundColor: inAlternateCycle ? Theme.highlightDimmerColor : Theme.highlightColor + anchors.horizontalCenter: parent.horizontalCenter + } + } + } - ProgressCircle { - id: imageLoadingIndicator - progressColor: inAlternateCycle ? Theme.highlightColor : Theme.highlightDimmerColor - backgroundColor: inAlternateCycle ? Theme.highlightDimmerColor : Theme.highlightColor - anchors.horizontalCenter: parent.horizontalCenter - progressValue: imagePreview.progress + Component { + id: failedLoading + Text { + text: qsTr("Error loading") + font.pixelSize: Theme.fontSizeSmall; + color: Theme.highlightColor } } } - } - Component { - id: failedLoading - Text { - font.pixelSize: Theme.fontSizeSmall; - text: qsTr("Error loading") - color: Theme.highlightColor - } + VerticalScrollDecorator { flickable: imageFlickable } } IconButton { - y: Theme.paddingLarge - anchors.right: parent.right - anchors.rightMargin: Theme.horizontalPageMargin + 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 { - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.rightMargin: Theme.paddingLarge - anchors.bottomMargin: Theme.paddingLarge*1.5 + 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 6922f39..af5c608 100644 --- a/qml/pages/components/MiniHeader.qml +++ b/qml/pages/components/MiniHeader.qml @@ -37,26 +37,24 @@ Item { width: account_locked ? Theme.iconSizeExtraSmall*0.8 : 0 opacity: 0.8 height: width - source: "image://theme/icon-s-secure?" + (pressed - ? Theme.highlightColor - : Theme.primaryColor) + source: "image://theme/icon-s-secure?" + (pressed ? Theme.highlightColor : Theme.primaryColor) } Label { id: lblScreenName + truncationMode: TruncationMode.Fade + text: '@'+account_username + font.pixelSize: Theme.fontSizeExtraSmall + color: (pressed ? Theme.secondaryHighlightColor : Theme.secondaryColor) 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) } - 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) @@ -64,8 +62,8 @@ Item { 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 4dd559b..a38dfca 100644 --- a/qml/pages/components/MiniStatus.qml +++ b/qml/pages/components/MiniStatus.qml @@ -9,6 +9,10 @@ Item { width: parent.width Image { id: icon + visible: type.length + width: Theme.iconSizeExtraSmall + height: width + source: typeof typeIcon !== "undefined" ? typeIcon : "" anchors { top: parent.top topMargin: Theme.paddingMedium @@ -16,12 +20,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 @@ -48,7 +48,6 @@ Item { } 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 0e0775f..8e0be74 100644 --- a/qml/pages/components/MyImage.qml +++ b/qml/pages/components/MyImage.qml @@ -5,33 +5,38 @@ 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 @@ -39,35 +44,48 @@ Item { progressRec.width = 0; } } + 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 135df3c..d3dc318 100644 --- a/qml/pages/components/MyList.qml +++ b/qml/pages/components/MyList.qml @@ -61,13 +61,7 @@ SilicaListView { pageStack.push(Qt.resolvedUrl("../SettingsPage.qml"), {}) } } - /* MenuItem { - text: qsTr("Open in Browser") - visible: profile_url != "" - onClicked: { - Clipboard.text = profile_url - } - } */ + MenuItem { text: qsTr("Load more") onClicked: { diff --git a/qml/pages/components/Navigation.qml b/qml/pages/components/Navigation.qml index 1d721b1..c4af981 100644 --- a/qml/pages/components/Navigation.qml +++ b/qml/pages/components/Navigation.qml @@ -4,13 +4,16 @@ import QtGraphicalEffects 1.0 SilicaGridView { + id: gridView + + property bool isPortrait: false signal slideshowShow(int vIndex) signal slideshowIndexChanged(int vIndex) + onSlideshowIndexChanged: { navigateTo(vIndex) } - id: gridView - property bool isPortrait: false + ListModel { id: listModel ListElement { @@ -20,12 +23,14 @@ SilicaGridView { active: true unread: false } + ListElement { icon: "image://theme/icon-m-alarm" slug: "notifications" name: "Notifications" active: false } + ListElement { icon: "image://theme/icon-m-whereami" slug: "local" @@ -33,6 +38,7 @@ SilicaGridView { active: false unread: false } + ListElement { icon: "image://theme/icon-m-website" slug: "federated" @@ -40,6 +46,7 @@ SilicaGridView { active: false unread: false } + ListElement { icon: "image://theme/icon-m-search" slug: "search" @@ -49,15 +56,13 @@ SilicaGridView { } } model: listModel - anchors.fill: parent currentIndex: -1 - cellWidth: isPortrait ? gridView.width : gridView.width / model.count cellHeight: isPortrait ? gridView.height/model.count : gridView.height - + anchors.fill: parent delegate: BackgroundItem { - clip: true id: rectangle + clip: true width: gridView.cellWidth height: gridView.cellHeight GridView.onAdd: AddAnimation { @@ -66,88 +71,93 @@ SilicaGridView { GridView.onRemove: RemoveAnimation { target: rectangle } + GlassItem { id: effect visible: !isPortrait && unread + dimmed: true + color: Theme.highlightColor width: Theme.itemSizeMedium height: Theme.itemSizeMedium - dimmed: true - anchors.bottom: parent.bottom - anchors.bottomMargin: -height/2 - anchors.horizontalCenter: parent.horizontalCenter - color: Theme.highlightColor + anchors { + bottom: parent.bottom + bottomMargin: -height/2 + horizontalCenter: parent.horizontalCenter + } } + GlassItem { id: effect2 visible: isPortrait && unread + dimmed: false + color: Theme.highlightColor width: Theme.itemSizeMedium height: Theme.itemSizeMedium - dimmed: false - anchors.right: parent.right; - anchors.rightMargin: -height/2; - anchors.verticalCenter: parent.verticalCenter - color: Theme.highlightColor + anchors { + right: parent.right + rightMargin: -height/2 + verticalCenter: parent.verticalCenter + } } + OpacityRampEffect { sourceItem: label offset: 0.5 } + ColorOverlay { - anchors.fill: image - source: image - color: (highlighted ? Theme.highlightColor : (model.active ? Theme.primaryColor : Theme.secondaryHighlightColor)) - } + source: image + color: (highlighted ? Theme.highlightColor : (model.active ? Theme.primaryColor : Theme.secondaryHighlightColor)) + anchors.fill: image + } + Image { id: image + visible: false + source: model.icon // +'?'+ (highlighted ? Theme.highlightColor : (model.active ? Theme.primaryColor : Theme.secondaryHighlightColor)) sourceSize.width: Theme.iconSizeMedium sourceSize.height: Theme.iconSizeMedium - source: model.icon// +'?'+ (highlighted ? Theme.highlightColor : (model.active ? Theme.primaryColor : Theme.secondaryHighlightColor)) anchors.centerIn: parent - visible: false - // smooth: true } Text { - anchors.bottom: parent.bottom - anchors.bottomMargin: Theme.paddingSmall - anchors.left: parent.left - anchors.right: parent.right - horizontalAlignment: Text.AlignHCenter visible: false text: model.name font.pixelSize: Theme.fontSizeExtraSmall/2 color: (highlighted ? Theme.highlightColor : (model.active ? Theme.primaryColor : Theme.secondaryHighlightColor)) + horizontalAlignment: Text.AlignHCenter + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + bottomMargin: Theme.paddingSmall + } } Label { id: label visible: false - anchors { - bottom: parent.bottom - } - horizontalAlignment : Text.AlignHCente - width: parent.width color: (highlighted ? Theme.highlightColor : Theme.secondaryHighlightColor) - text: { return model.name.toUpperCase(); } - - font { - pixelSize: Theme.fontSizeExtraSmall - family: Theme.fontFamilyHeading - } + font.pixelSize: Theme.fontSizeExtraSmall + font.family: Theme.fontFamilyHeading + width: parent.width + horizontalAlignment : Text.AlignHCenter + anchors.bottom: parent.bottom } + onClicked: { slideshowShow(index) console.log(index) navigateTo(model.slug) effect.state = "right" } - } + function navigateTo(slug){ for(var i = 0; i < listModel.count; i++){ if (listModel.get(i).slug === slug || i===slug) @@ -156,9 +166,9 @@ SilicaGridView { listModel.setProperty(i, 'active', false); } console.log(slug) - } VerticalScrollDecorator {} + } diff --git a/qml/pages/components/ProfileHeader.qml b/qml/pages/components/ProfileHeader.qml index a4fd987..af2126d 100644 --- a/qml/pages/components/ProfileHeader.qml +++ b/qml/pages/components/ProfileHeader.qml @@ -4,48 +4,69 @@ import Sailfish.Silica 1.0 Item { id: profileHeader + property int value: 0 property string title: "" property string description: "" property string image: "" property string bg: "" + width: parent.width height: icon.height + Theme.paddingLarge*2 Rectangle { id: bgImage - anchors.fill: parent opacity: 0.2 gradient: Gradient { GradientStop { position: 0.0; color: Theme.highlightBackgroundColor } GradientStop { position: 1.0; color: Theme.highlightBackgroundColor } } + anchors.fill: parent + Image { - anchors.fill: bgImage asynchronous: true fillMode: Image.PreserveAspectCrop source: bg opacity: 0.8 + anchors.fill: parent } } + Image { id: icon + asynchronous: true + source: + if (icon.status === Image.Error) + source = "../../images/icon-l-profile.svg?" + (pressed + ? Theme.highlightColor + : Theme.primaryColor) + else image + width: description === "" ? Theme.iconSizeMedium : Theme.iconSizeLarge + height: width anchors { left: parent.left leftMargin: Theme.paddingLarge top: parent.top topMargin: Theme.paddingLarge } - asynchronous: true - width: description === "" ? Theme.iconSizeMedium : Theme.iconSizeLarge - height: width - source: - if (icon.status === Image.Error) - source = "../../images/icon-l-profile.svg?" + (pressed - ? Theme.highlightColor - : Theme.primaryColor) - else image + + Button { + id: imageButton + opacity: 0 + width: Theme.iconSizeExtraLarge * 1.2 + anchors { + top: parent.top + left: parent.left + bottom: parent.bottom + } + onClicked: { + pageStack.push(Qt.resolvedUrl("ProfileImage.qml"), { + "image": image + }) + } + } } + Column { anchors { left: icon.right @@ -54,6 +75,7 @@ Item { rightMargin: Theme.paddingLarge verticalCenter: parent.verticalCenter } + Label { id: ttl text: @@ -61,23 +83,24 @@ Item { description.split('@')[0] } else title - height: contentHeight - color: Theme.highlightColor font.pixelSize: Theme.fontSizeLarge font.family: Theme.fontFamilyHeading - horizontalAlignment: Text.AlignRight + color: Theme.highlightColor truncationMode: TruncationMode.Fade width: parent.width + height: contentHeight + horizontalAlignment: Text.AlignRight } + Label { - height: description === "" ? 0 : contentHeight text: "@"+description - color: Theme.secondaryHighlightColor font.pixelSize: Theme.fontSizeSmall font.family: Theme.fontFamilyHeading - horizontalAlignment: Text.AlignRight + color: Theme.secondaryHighlightColor truncationMode: TruncationMode.Fade width: parent.width + height: description === "" ? 0 : contentHeight + horizontalAlignment: Text.AlignRight } } diff --git a/qml/pages/components/ProfileImage.qml b/qml/pages/components/ProfileImage.qml new file mode 100644 index 0000000..38fdde0 --- /dev/null +++ b/qml/pages/components/ProfileImage.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 +import Sailfish.Silica 1.0 + +FullscreenContentPage { + id: profileImage + allowedOrientations: Orientation.All + + property string image: "" + + Image { + source: image + fillMode: Image.PreserveAspectFit + anchors.fill: parent + } + + IconButton { + icon.source: "image://theme/icon-m-dismiss" + anchors { + top: profileImage.top + topMargin: Theme.horizontalPageMargin + right: parent.right + rightMargin: Theme.horizontalPageMargin + } + onClicked: pageStack.pop() + } + +} diff --git a/qml/pages/components/Toot.qml b/qml/pages/components/Toot.qml index fbd9190..43de76b 100644 --- a/qml/pages/components/Toot.qml +++ b/qml/pages/components/Toot.qml @@ -26,6 +26,8 @@ BackgroundItem { visible: type.length anchors.left: lblName.left anchors.bottom: iconRT.bottom + font.pixelSize: Theme.fontSizeExtraSmall + color: Theme.secondaryColor text: { var action; switch(type){ @@ -43,8 +45,6 @@ BackgroundItem { } return '@' + retweetScreenName + ' ' + action } - font.pixelSize: Theme.fontSizeExtraSmall - color: Theme.secondaryColor } Image { @@ -116,12 +116,12 @@ BackgroundItem { } 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 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); }; From eac5aac326bd5bad0a50bb15bf61ce21c48c30be Mon Sep 17 00:00:00 2001 From: molan-git Date: Wed, 3 Jun 2020 11:52:07 +0200 Subject: [PATCH 05/22] ui-improvements-fixes Fixes new UI elements New responsive UI items --- qml/pages/ConversationPage.qml | 25 ++++++++++++++-------- qml/pages/ProfilePage.qml | 9 ++++++-- qml/pages/SettingsPage.qml | 12 +---------- qml/pages/components/MediaFullScreen.qml | 27 ++++++++++++------------ qml/pages/components/VisualContainer.qml | 4 ++-- 5 files changed, 40 insertions(+), 37 deletions(-) diff --git a/qml/pages/ConversationPage.qml b/qml/pages/ConversationPage.qml index 611329f..8e6d197 100644 --- a/qml/pages/ConversationPage.qml +++ b/qml/pages/ConversationPage.qml @@ -7,6 +7,7 @@ import "./components/" Page { id: conversationPage + property string headerTitle: "" property string type property alias title: header.title @@ -18,6 +19,7 @@ Page { property string toot_url: "" property int tootMaxChar: 500; property ListModel mdl + allowedOrientations: Orientation.All onSuggestedUserChanged: { console.log(suggestedUser) @@ -101,7 +103,7 @@ Page { visible: type === "reply" && toot_url !== "" MenuItem { text: qsTr("Copy Link to Clipboard") - onClicked: Clipboard.text = toot_url; + onClicked: Clipboard.text = toot_url } } } @@ -109,16 +111,21 @@ Page { Rectangle { id: predictionList visible: false - anchors.bottom: panel.top - anchors.left: parent.left - anchors.right: panel.right - anchors.top: parent.top - height: implicitHeight - 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 { + SilicaListView { rotation: 180 - anchors.fill: parent + anchors.fill: parent model: suggestedModel clip: true quickScroll: false diff --git a/qml/pages/ProfilePage.qml b/qml/pages/ProfilePage.qml index a0316e4..d0aa2d8 100644 --- a/qml/pages/ProfilePage.qml +++ b/qml/pages/ProfilePage.qml @@ -175,7 +175,7 @@ Page { Rectangle { id: txtContainer width: parent.width - height: Math.min(txtNote.height, parent.height*0.488) + height: Math.min(txtNote.height, parent.height*0.5) color: "transparent" visible: { if ((note.text === "") || (note.text === "

") ) { @@ -185,9 +185,13 @@ Page { } } - SilicaListView { + SilicaFlickable { id: txtFlickable anchors.fill: parent + contentWidth: parent.width + contentHeight: txtNote.height + anchors.topMargin: Theme.paddingMedium + anchors.bottomMargin: Theme.paddingMedium clip: true quickScroll: false VerticalScrollDecorator {} @@ -229,6 +233,7 @@ Page { id: statsRow spacing: Theme.paddingLarge anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: Theme.paddingMedium anchors.leftMargin: Theme.paddingLarge anchors.rightMargin: Theme.paddingLarge diff --git a/qml/pages/SettingsPage.qml b/qml/pages/SettingsPage.qml index cf13abd..3eec6a6 100644 --- a/qml/pages/SettingsPage.qml +++ b/qml/pages/SettingsPage.qml @@ -38,17 +38,6 @@ Page { } } - IconTextSwitch { - text: qsTr("Use smaller Font Size in Toots") - description: qsTr("Enable this option if you prefer to use a smaller font size in displayed Toots") - icon.source: "image://theme/icon-m-font-size" - enabled: false - //checked: typeof Logic.conf['loadImages'] !== "undefined" && Logic.conf['loadImages'] - //onClicked: { - // Logic.conf['loadImages'] = checked - //} - } - SectionHeader { text: "Account"} Item { @@ -82,6 +71,7 @@ Page { 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() { diff --git a/qml/pages/components/MediaFullScreen.qml b/qml/pages/components/MediaFullScreen.qml index 3378cac..b19f5e0 100644 --- a/qml/pages/components/MediaFullScreen.qml +++ b/qml/pages/components/MediaFullScreen.qml @@ -114,6 +114,16 @@ FullscreenContentPage { bottomMargin: Theme.horizontalPageMargin } + MouseArea { + anchors.fill: parent + onClicked: function() { + if (video.playbackState === MediaPlayer.PlayingState) + video.pause() + else + video.play() + } + } + Rectangle { visible: videoError.text != "" anchors.left: parent.left @@ -136,15 +146,6 @@ FullscreenContentPage { } } - MouseArea { - anchors.fill: parent - onClicked: function() { - if (video.playbackState === MediaPlayer.PlayingState) - video.pause() - else - video.play() - } - } } } } @@ -152,7 +153,8 @@ FullscreenContentPage { Flickable { id: imageFlickable visible: false - contentWidth: imageContainer.width; contentHeight: imageContainer.height + contentWidth: imageContainer.width + contentHeight: imageContainer.height clip: true anchors.fill: parent onHeightChanged: if (imagePreview.status === Image.Ready) { @@ -178,8 +180,8 @@ FullscreenContentPage { fillMode: Image.PreserveAspectFit cache: true asynchronous: true - sourceSize.width: mediaPage.width - smooth: false + sourceSize.width: mediaPage.width + smooth: true anchors.centerIn: parent onStatusChanged: { if (status == Image.Ready) { @@ -197,7 +199,6 @@ FullscreenContentPage { var yoff = (imageFlickable.height / 2 + imageFlickable.contentY) * scale / prevScale; imageFlickable.contentY = yoff - imageFlickable.height / 2 } - prevScale = scale } NumberAnimation { diff --git a/qml/pages/components/VisualContainer.qml b/qml/pages/components/VisualContainer.qml index 8765456..8c2f3ed 100644 --- a/qml/pages/components/VisualContainer.qml +++ b/qml/pages/components/VisualContainer.qml @@ -153,7 +153,7 @@ BackgroundItem { } } text: content.replace(new RegExp("
Date: Thu, 4 Jun 2020 11:17:06 +0200 Subject: [PATCH 06/22] issue #38 fix + ui-improvements --- qml/pages/MainPage.qml | 10 +- qml/pages/ProfilePage.qml | 94 ++++++------- qml/pages/SettingsPage.qml | 41 +++--- qml/pages/components/InfoBanner.qml | 6 +- qml/pages/components/MediaFullScreen.qml | 163 ++++++++++++----------- qml/pages/components/MyList.qml | 6 +- qml/pages/components/Toot.qml | 45 ++++--- qml/pages/components/VisualContainer.qml | 106 ++++++++------- 8 files changed, 234 insertions(+), 237 deletions(-) diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml index b254496..f275b8d 100644 --- a/qml/pages/MainPage.qml +++ b/qml/pages/MainPage.qml @@ -74,11 +74,13 @@ Page { } 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 @@ -241,7 +243,7 @@ Page { navigation.navigateTo('search') } else { - Qt.openUrlExternally(href); + Qt.openUrlExternally(href) } } diff --git a/qml/pages/ProfilePage.qml b/qml/pages/ProfilePage.qml index d0aa2d8..b6e9d78 100644 --- a/qml/pages/ProfilePage.qml +++ b/qml/pages/ProfilePage.qml @@ -1,8 +1,8 @@ import QtQuick 2.0 import Sailfish.Silica 1.0 +import QtGraphicalEffects 1.0 import "../lib/API.js" as Logic import "./components/" -import QtGraphicalEffects 1.0 Page { @@ -12,6 +12,9 @@ Page { property string display_name: "" property string username: "" property string profileImage: "" + property string profileBackground: "" + property string note: "" + property string url: "" property int user_id property int statuses_count property int following_count @@ -19,17 +22,14 @@ Page { property int favourites_count property int reblogs_count property int count_moments - property string profileBackground: "" - 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 + property date created_at WorkerScript { id: worker @@ -106,6 +106,7 @@ Page { } } } + // The effective value will be restricted by ApplicationWindow.allowedOrientations allowedOrientations: Orientation.All Component.onCompleted: { @@ -155,8 +156,7 @@ Page { } } - // ProfilePage ExpandingSection - ExpandingSectionGroup { + ExpandingSectionGroup { // ProfilePage ExpandingSection id: profileExpander anchors { bottom: parent.bottom @@ -168,17 +168,16 @@ Page { id: expandingSection1 title: qsTr("About") content.sourceComponent: Column { - height: Math.min(txtContainer, parent.height*0.7) - spacing: Theme.paddingSmall - anchors.bottomMargin: Theme.paddingLarge + height: Math.min( txtContainer, parent.height * 0.7 ) + spacing: Theme.paddingLarge - Rectangle { + Item { id: txtContainer width: parent.width - height: Math.min(txtNote.height, parent.height*0.5) - color: "transparent" + height: Math.min( txtNote.height, parent.height * 0.55 ) + //color: "transparent" visible: { - if ((note.text === "") || (note.text === "

") ) { + if ((note.text === "") || ( note.text === "

" )) { false } else { true @@ -187,23 +186,21 @@ Page { SilicaFlickable { id: txtFlickable - anchors.fill: parent contentWidth: parent.width contentHeight: txtNote.height - anchors.topMargin: Theme.paddingMedium - anchors.bottomMargin: Theme.paddingMedium + anchors.fill: parent clip: true - quickScroll: false + VerticalScrollDecorator {} - Text { + Label { id: txtNote text: note textFormat: Text.StyledText - wrapMode: Text.Wrap - font.pixelSize: Theme.fontSizeExtraSmall color: Theme.secondaryColor + font.pixelSize: Theme.fontSizeExtraSmall linkColor: Theme.highlightColor + wrapMode: Text.Wrap width: parent.width - ( 2 * Theme.horizontalPageMargin ) anchors.horizontalCenter: parent.horizontalCenter onLinkActivated: { @@ -219,8 +216,13 @@ Page { return check; })); send(link) - /* Function still missing for user accounts */ - // } else if (test.length === 4 && test[3][0] === "@" ) { + } 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); } @@ -229,11 +231,14 @@ Page { } } + Item { // dummy item for spacing + height: Theme.paddingSmall + } + Row { id: statsRow spacing: Theme.paddingLarge anchors.horizontalCenter: parent.horizontalCenter - anchors.topMargin: Theme.paddingMedium anchors.leftMargin: Theme.paddingLarge anchors.rightMargin: Theme.paddingLarge @@ -274,15 +279,8 @@ Page { } */ } - Label { - id: separatorLabel1 - x: Theme.horizontalPageMargin - width: parent.width - ( 2 * Theme.horizontalPageMargin ) - font.pixelSize: Theme.fontSizeExtraSmall - wrapMode: Text.Wrap - anchors { - horizontalCenter: parent.horizontalCenter - } + Item { // dummy item for spacing + height: Theme.paddingSmall } ButtonLayout { @@ -350,39 +348,23 @@ Page { } } - Separator { - id: btnSeparator - width: parent.width - height: Theme.paddingMedium - color: Theme.primaryColor - opacity: 0.0 - horizontalAlignment: Qt.AlignHCenter - } - Button { id: btnBrowser text: qsTr("Open in Browser") preferredWidth: Theme.buttonWidthMedium - anchors { - horizontalCenter: parent.horizontalCenter - } + anchors.horizontalCenter: parent.horizontalCenter onClicked: { - Qt.openUrlExternally(url); + Qt.openUrlExternally(url) } } - Label { - id: separatorLabel2 - x: Theme.horizontalPageMargin - width: parent.width - ( 2 * Theme.horizontalPageMargin ) - font.pixelSize: Theme.fontSizeExtraSmall - wrapMode: Text.Wrap - anchors { - horizontalCenter: parent.horizontalCenter - } + Rectangle { // dummy item for spacing + height: Theme.paddingSmall + width: parent.width + opacity: 0 } - } } } + } diff --git a/qml/pages/SettingsPage.qml b/qml/pages/SettingsPage.qml index 3eec6a6..70a6dd6 100644 --- a/qml/pages/SettingsPage.qml +++ b/qml/pages/SettingsPage.qml @@ -25,7 +25,7 @@ Page { title: qsTr("Settings") } - SectionHeader { text: "Options"} + SectionHeader { text: qsTr("Options")} IconTextSwitch { text: qsTr("Load Images in Toots") @@ -38,7 +38,7 @@ Page { } } - SectionHeader { text: "Account"} + SectionHeader { text: qsTr("Account")} Item { id: removeAccount @@ -53,7 +53,7 @@ Page { Icon { id: icnRemoveAccount - color: Theme.secondaryColor + color: Theme.highlightColor width: Theme.iconSizeMedium fillMode: Image.PreserveAspectFit source: Logic.conf['login'] ? "image://theme/icon-m-contact" : "image://theme/icon-m-add" @@ -96,7 +96,7 @@ Page { 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.secondaryColor + color: Theme.highlightColor anchors { left: parent.left leftMargin: Theme.paddingLarge * 1.9 @@ -107,24 +107,25 @@ Page { } } - /* SectionHeader { text: "Support"} + SectionHeader { + text: qsTr("Translate") + } - 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() + 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 } - Timer { - id: timer2 - interval: 4700 - onTriggered: parent.busy = false - } - } */ + } SectionHeader { text: qsTr("Credits") diff --git a/qml/pages/components/InfoBanner.qml b/qml/pages/components/InfoBanner.qml index a6a444e..8d33b9a 100644 --- a/qml/pages/components/InfoBanner.qml +++ b/qml/pages/components/InfoBanner.qml @@ -3,7 +3,7 @@ import Sailfish.Silica 1.0 DockedPanel { - id: root + id: root dock: Dock.Top width: parent.width height: content.height @@ -12,14 +12,14 @@ DockedPanel { id: content color: Theme.highlightBackgroundColor width: root.width - height: infoLabel.height + 3*Theme.paddingMedium + height: infoLabel.height + 2 * Theme.paddingMedium Label { id: infoLabel text : "" font.family: Theme.fontFamilyHeading font.pixelSize: Theme.fontSizeMedium - color: Theme.highlightColor + color: Theme.primaryColor wrapMode: Text.WrapAnywhere width: parent.width anchors { diff --git a/qml/pages/components/MediaFullScreen.qml b/qml/pages/components/MediaFullScreen.qml index b19f5e0..fda8df1 100644 --- a/qml/pages/components/MediaFullScreen.qml +++ b/qml/pages/components/MediaFullScreen.qml @@ -30,6 +30,8 @@ FullscreenContentPage { id: videoFlickable visible: false anchors.fill: parent + contentWidth: imageContainer.width + contentHeight: imageContainer.height clip: true Image { @@ -113,43 +115,44 @@ FullscreenContentPage { rightMargin: Theme.horizontalPageMargin + Theme.iconSizeMedium bottomMargin: Theme.horizontalPageMargin } - - MouseArea { - anchors.fill: parent - onClicked: function() { - if (video.playbackState === MediaPlayer.PlayingState) - video.pause() - else - 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 - } - } - } + + MouseArea { + anchors.fill: parent + onClicked: function() { + if (video.playbackState === MediaPlayer.PlayingState) + video.pause() + else + 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 @@ -158,7 +161,7 @@ FullscreenContentPage { clip: true anchors.fill: parent onHeightChanged: if (imagePreview.status === Image.Ready) { - imagePreview.fitToScreen() + imagePreview.fitToScreen(); } Item { @@ -190,6 +193,15 @@ FullscreenContentPage { } } + NumberAnimation { + id: loadedAnimation + target: imagePreview + property: "opacity" + duration: 250 + from: 0; to: 1 + easing.type: Easing.InOutQuad + } + onScaleChanged: { if ((width * scale) > imageFlickable.width) { var xoff = (imageFlickable.width / 2 + imageFlickable.contentX) * scale / prevScale; @@ -199,15 +211,7 @@ FullscreenContentPage { var yoff = (imageFlickable.height / 2 + imageFlickable.contentY) * scale / prevScale; imageFlickable.contentY = yoff - imageFlickable.height / 2 } - } - - NumberAnimation { - id: loadedAnimation - target: imagePreview - property: "opacity" - duration: 250 - from: 0; to: 1 - easing.type: Easing.InOutQuad + prevScale = scale } } } @@ -245,47 +249,45 @@ FullscreenContentPage { from: imagePreview.scale } } + } - Loader { - anchors.centerIn: parent - sourceComponent: { - switch (imagePreview.status) { - case Image.Loading: - return loadingIndicator - case Image.Error: - return failedLoading - default: - return undefined - } - } - - Component { - id: loadingIndicator - Item { - width: mediaPage.width - height: childrenRect.height - - ProgressCircle { - id: imageLoadingIndicator - progressValue: imagePreview.progress - progressColor: inAlternateCycle ? Theme.highlightColor : Theme.highlightDimmerColor - backgroundColor: inAlternateCycle ? Theme.highlightDimmerColor : Theme.highlightColor - anchors.horizontalCenter: parent.horizontalCenter - } - } - } - - Component { - id: failedLoading - Text { - text: qsTr("Error loading") - font.pixelSize: Theme.fontSizeSmall; - color: Theme.highlightColor - } + Loader { + anchors.centerIn: parent + sourceComponent: { + switch (imagePreview.status) { + case Image.Loading: + return loadingIndicator + case Image.Error: + return failedLoading + default: + return undefined } } - VerticalScrollDecorator { flickable: imageFlickable } + Component { + id: loadingIndicator + Item { + width: mediaPage.width + height: childrenRect.height + + ProgressCircle { + id: imageLoadingIndicator + progressValue: imagePreview.progress + progressColor: inAlternateCycle ? Theme.highlightColor : Theme.highlightDimmerColor + backgroundColor: inAlternateCycle ? Theme.highlightDimmerColor : Theme.highlightColor + anchors.horizontalCenter: parent.horizontalCenter + } + } + } + } + + Component { + id: failedLoading + Text { + text: qsTr("Error loading") + font.pixelSize: Theme.fontSizeSmall; + color: Theme.highlightColor + } } IconButton { @@ -314,5 +316,6 @@ FullscreenContentPage { FileDownloader.downloadFile(mediaURL, filename[filename.length-1]); } } + VerticalScrollDecorator { flickable: imageFlickable } } diff --git a/qml/pages/components/MyList.qml b/qml/pages/components/MyList.qml index d3dc318..adad1ea 100644 --- a/qml/pages/components/MyList.qml +++ b/qml/pages/components/MyList.qml @@ -6,6 +6,7 @@ import "." SilicaListView { id: myList + property string type property string title property string vwPlaceholderText: qsTr("Loading") @@ -22,6 +23,7 @@ SilicaListView { property variant conf property bool notifier: false model: mdl + signal notify (string what, int num) onNotify: { console.log(what + " - " + num) @@ -109,6 +111,7 @@ SilicaListView { loadData("append") } } + BusyIndicator { size: BusyIndicatorSize.Small running: loadStarted; @@ -116,6 +119,7 @@ SilicaListView { anchors.horizontalCenter: parent.horizontalCenter } } + onContentYChanged: { if (Math.abs(contentY - scrollOffset) > Theme.itemSizeMedium) { openDrawer(contentY - scrollOffset > 0 ? false : true ) @@ -139,7 +143,6 @@ SilicaListView { if (messageObject.fireNotification && notifier){ Logic.notifier(messageObject.data) } - } } @@ -154,6 +157,7 @@ SilicaListView { loadData("prepend") } } + function loadData(mode){ var p = [] if (params.length) diff --git a/qml/pages/components/Toot.qml b/qml/pages/components/Toot.qml index 43de76b..5a705e1 100644 --- a/qml/pages/components/Toot.qml +++ b/qml/pages/components/Toot.qml @@ -11,6 +11,7 @@ BackgroundItem { //property string text: "0" width: parent.width height: lblText.paintedHeight + (lblText.text.length > 0 ? Theme.paddingLarge : 0 )+ lblName.paintedHeight + (type.length ? Theme.paddingLarge + iconRT.height : 0) + Theme.paddingLarge + Image { id: iconRT y: Theme.paddingLarge @@ -67,7 +68,6 @@ BackgroundItem { }) } } - } Label { @@ -86,33 +86,33 @@ BackgroundItem { Image { id: iconVerified + 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 + truncationMode: TruncationMode.Fade + text: '@'+account_username + font.pixelSize: Theme.fontSizeExtraSmall + color: (pressed ? Theme.secondaryHighlightColor : Theme.secondaryColor) 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) } Label { @@ -122,9 +122,9 @@ BackgroundItem { var elapsed = Format.formatDate(created_at, Formatter.DurationElapsedShort) return (elapsed ? elapsed : txt ) } - 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,13 +135,6 @@ BackgroundItem { 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) @@ -165,12 +158,20 @@ BackgroundItem { } 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("../ConversationPage.qml"), { headerTitle: "Conversation", diff --git a/qml/pages/components/VisualContainer.qml b/qml/pages/components/VisualContainer.qml index 8c2f3ed..5382131 100644 --- a/qml/pages/components/VisualContainer.qml +++ b/qml/pages/components/VisualContainer.qml @@ -5,13 +5,16 @@ import "../../lib/API.js" as Logic 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) + Rectangle { - x: 0; - y: 0; + x: 0 + y: 0 visible: status_visibility == 'direct' width: parent.width height: parent.height @@ -31,20 +34,20 @@ BackgroundItem { Image { id: avatar + visible: true + opacity: status === Image.Ready ? 1.0 : 0.0 + Behavior on opacity { FadeAnimator {} } + asynchronous: true + smooth: true + source: account_avatar + 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 } - 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 onStatusChanged: { if (avatar.status === Image.Error) source = "../../images/icon-m-profile.svg?" + (pressed @@ -63,20 +66,19 @@ BackgroundItem { "profileBackground": model.account_header }) } - } 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" } Rectangle { @@ -90,15 +92,16 @@ BackgroundItem { left: parent.left leftMargin: -width/3 } + Image { 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 } } } @@ -114,6 +117,13 @@ BackgroundItem { Text { id: lblContent + text: content.replace(new RegExp(" paintedHeight ? contentWarningLabel.paintedHeight : paintedHeight) : 0 anchors { left: miniHeader.left leftMargin: Theme.paddingMedium @@ -123,7 +133,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) @@ -139,34 +148,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') - // Original component - /* pageStack.push(Qt.resolvedUrl("../Profile.qml"), { - "name": "", - "username": test[3].substring(1)+"@"+test[2], - "profileImage": "" - }) */ + 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 @@ -176,16 +183,11 @@ BackgroundItem { rightMargin: Theme.paddingMedium bottomMargin: Theme.paddingSmall } - width: parent.width - truncationMode: TruncationMode.Fade - color: Theme.highlightColor - wrapMode: Text.Wrap - text: model.status_spoiler_text } MouseArea { anchors.fill: parent - onClicked: parent.visible = false; + onClicked: parent.visible = false } } @@ -193,6 +195,8 @@ BackgroundItem { MediaBlock { id: media + 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 @@ -200,12 +204,11 @@ BackgroundItem { topMargin: Theme.paddingSmall bottomMargin: Theme.paddingLarge } - model: typeof attachments !== "undefined" ? attachments : Qt.createQmlObject('import QtQuick 2.0; ListModel { }', Qt.application, 'InternalQmlObject'); - height: Theme.iconSizeExtraLarge * 2 } ContextMenu { id: mnu + MenuItem { enabled: model.type !== "follow" text: typeof model.reblogged !== "undefined" && model.reblogged ? qsTr("Unboost") : qsTr("Boost") @@ -221,27 +224,28 @@ 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 } } @@ -274,14 +278,14 @@ BackgroundItem { } 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 } } } From 99b070124b3a0df48e03a47bfcad42e7fb284525 Mon Sep 17 00:00:00 2001 From: molan-git Date: Thu, 4 Jun 2020 19:44:12 +0200 Subject: [PATCH 07/22] small ui-adjustments --- qml/lib/API.js | 2 - qml/pages/ConversationPage.qml | 2 +- qml/pages/LoginPage.qml | 3 +- qml/pages/MainPage.qml | 14 +++---- qml/pages/ProfilePage.qml | 3 +- qml/pages/SettingsPage.qml | 5 +-- qml/pages/components/MyList.qml | 1 + qml/pages/components/VisualContainer.qml | 48 ++++++++++++++++++++++-- 8 files changed, 58 insertions(+), 20 deletions(-) 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/pages/ConversationPage.qml b/qml/pages/ConversationPage.qml index 8e6d197..db97654 100644 --- a/qml/pages/ConversationPage.qml +++ b/qml/pages/ConversationPage.qml @@ -259,7 +259,7 @@ Page { property string selection opacity: 0.7 icon { - color: Theme.highlightColor + color: Theme.secondaryColor width: Theme.iconSizeSmallPlus fillMode: Image.PreserveAspectFit source: "../../qml/images/emojiselect.svg" diff --git a/qml/pages/LoginPage.qml b/qml/pages/LoginPage.qml index 7751cdf..b35ad7a 100644 --- a/qml/pages/LoginPage.qml +++ b/qml/pages/LoginPage.qml @@ -31,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 diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml index f275b8d..acd1a89 100644 --- a/qml/pages/MainPage.qml +++ b/qml/pages/MainPage.qml @@ -32,7 +32,7 @@ Page { VisualItemModel { id: visualModel MyList{ - id: tlHome; + id: tlHome title: qsTr("Home") type: "timelines/home" mdl: Logic.modelTLhome @@ -42,35 +42,35 @@ Page { } 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 { diff --git a/qml/pages/ProfilePage.qml b/qml/pages/ProfilePage.qml index b6e9d78..e2318af 100644 --- a/qml/pages/ProfilePage.qml +++ b/qml/pages/ProfilePage.qml @@ -15,7 +15,7 @@ Page { property string profileBackground: "" property string note: "" property string url: "" - property int user_id + property string user_id: "" property int statuses_count property int following_count property int followers_count @@ -175,7 +175,6 @@ Page { id: txtContainer width: parent.width height: Math.min( txtNote.height, parent.height * 0.55 ) - //color: "transparent" visible: { if ((note.text === "") || ( note.text === "

" )) { false diff --git a/qml/pages/SettingsPage.qml b/qml/pages/SettingsPage.qml index 70a6dd6..876929c 100644 --- a/qml/pages/SettingsPage.qml +++ b/qml/pages/SettingsPage.qml @@ -46,7 +46,7 @@ Page { height: txtRemoveAccount.height + btnRemoveAccount.height + Theme.paddingLarge anchors { left: parent.left - leftMargin: Theme.paddingLarge + leftMargin: Theme.horizontalPageMargin right: parent.right rightMargin: Theme.paddingLarge } @@ -99,9 +99,8 @@ Page { color: Theme.highlightColor anchors { left: parent.left - leftMargin: Theme.paddingLarge * 1.9 right: parent.right - rightMargin: Theme.paddingLarge * 1.2 + rightMargin: Theme.paddingLarge + icnRemoveAccount } } } diff --git a/qml/pages/components/MyList.qml b/qml/pages/components/MyList.qml index adad1ea..e3b1d14 100644 --- a/qml/pages/components/MyList.qml +++ b/qml/pages/components/MyList.qml @@ -22,6 +22,7 @@ SilicaListView { property variant vars property variant conf property bool notifier: false + model: mdl signal notify (string what, int num) diff --git a/qml/pages/components/VisualContainer.qml b/qml/pages/components/VisualContainer.qml index 5382131..b86e715 100644 --- a/qml/pages/components/VisualContainer.qml +++ b/qml/pages/components/VisualContainer.qml @@ -13,6 +13,7 @@ BackgroundItem { 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) Rectangle { + id: bgDirect x: 0 y: 0 visible: status_visibility == 'direct' @@ -22,6 +23,20 @@ BackgroundItem { color: Theme.highlightBackgroundColor } + /* Rectangle { + id: bgDelegate + x: 0 + y: 0 + visible: status_visibility !== 'direct' + width: parent.width + height: parent.height + opacity: 0.15 + gradient: Gradient { + GradientStop { position: 0.7; color: "transparent" } + GradientStop { position: 1.0; color: Theme.highlightDimmerColor } + } + } */ + MiniStatus { id: miniStatus anchors { @@ -117,13 +132,16 @@ BackgroundItem { Text { id: lblContent + visible: model.type !== "follow" text: content.replace(new RegExp("
paintedHeight ? contentWarningLabel.paintedHeight : paintedHeight) : 0 + height: if (model.type === "follow") { + Theme.paddingLarge + } else content.length ? (contentWarningLabel.paintedHeight > paintedHeight ? contentWarningLabel.paintedHeight : paintedHeight) : 0 anchors { left: miniHeader.left leftMargin: Theme.paddingMedium @@ -210,7 +228,7 @@ BackgroundItem { id: mnu MenuItem { - enabled: model.type !== "follow" + visible: model.type !== "follow" text: typeof model.reblogged !== "undefined" && model.reblogged ? qsTr("Unboost") : qsTr("Boost") onClicked: { var status = typeof model.reblogged !== "undefined" && model.reblogged @@ -250,7 +268,7 @@ BackgroundItem { } MenuItem { - enabled: model.type !== "follow" + visible: model.type !== "follow" text: typeof model.favourited !== "undefined" && model.favourited ? qsTr("Unfavorite") : qsTr("Favorite") onClicked: { var status = typeof model.favourited !== "undefined" && model.favourited @@ -288,6 +306,30 @@ BackgroundItem { } } } + + MenuItem { + 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: { From 5f4dae2a2ddd42aca31cd4ae05d8096e8a08f1ca Mon Sep 17 00:00:00 2001 From: molan-git Date: Fri, 5 Jun 2020 18:38:15 +0200 Subject: [PATCH 08/22] added icon-s-following - added custom follower icon for miniHeader - theme coloring for miniHeader icons - removed unused icons - changed icon name emojis --- harbour-tooter.pro | 6 +-- qml/images/boosted.svg | 16 -------- .../{emojiselect.svg => icon-m-emoji.svg} | 0 qml/images/icon-s-following.svg | 12 ++++++ qml/images/notification.svg | 39 ------------------- qml/images/verified.svg | 26 ------------- qml/lib/Worker.js | 2 +- qml/pages/ConversationPage.qml | 2 +- qml/pages/MainPage.qml | 2 +- qml/pages/components/MiniHeader.qml | 4 +- qml/pages/components/MiniStatus.qml | 3 +- qml/pages/components/MyList.qml | 29 +++++++------- 12 files changed, 37 insertions(+), 104 deletions(-) delete mode 100644 qml/images/boosted.svg rename qml/images/{emojiselect.svg => icon-m-emoji.svg} (100%) create mode 100644 qml/images/icon-s-following.svg delete mode 100644 qml/images/notification.svg delete mode 100644 qml/images/verified.svg diff --git a/harbour-tooter.pro b/harbour-tooter.pro index a7c61ae..fc04db3 100644 --- a/harbour-tooter.pro +++ b/harbour-tooter.pro @@ -74,11 +74,9 @@ DISTFILES += qml/harbour-tooter.qml \ qml/pages/components/Toot.qml \ qml/pages/Browser.qml \ qml/lib/API.js \ - qml/images/notification.svg \ - qml/images/verified.svg \ - qml/images/boosted.svg \ + qml/images/icon-s-following \ qml/images/tooter.svg \ - qml/images/emojiselect.svg \ + qml/images/icon-m-emoji.svg \ qml/images/icon-m-profile.svg \ qml/images/icon-l-profile.svg \ qml/lib/Mastodon.js \ 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 @@ + + Artboard 1 + + + + + + + + + + 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/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/Worker.js b/qml/lib/Worker.js index 19469c6..0317523 100644 --- a/qml/lib/Worker.js +++ b/qml/lib/Worker.js @@ -190,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; diff --git a/qml/pages/ConversationPage.qml b/qml/pages/ConversationPage.qml index db97654..fb57082 100644 --- a/qml/pages/ConversationPage.qml +++ b/qml/pages/ConversationPage.qml @@ -262,7 +262,7 @@ Page { color: Theme.secondaryColor width: Theme.iconSizeSmallPlus fillMode: Image.PreserveAspectFit - source: "../../qml/images/emojiselect.svg" + source: "../../qml/images/icon-m-emoji.svg" } anchors { top: warningContent.bottom diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml index acd1a89..c809e19 100644 --- a/qml/pages/MainPage.qml +++ b/qml/pages/MainPage.qml @@ -208,7 +208,7 @@ Page { } IconButton { - id: newTweet + id: newToot width: Theme.iconSizeLarge height: width visible: !isPortrait ? true : !infoPanel.open diff --git a/qml/pages/components/MiniHeader.qml b/qml/pages/components/MiniHeader.qml index af5c608..0b52e44 100644 --- a/qml/pages/components/MiniHeader.qml +++ b/qml/pages/components/MiniHeader.qml @@ -26,7 +26,7 @@ Item { } Image { - id: iconVerified + id: iconLocked y: Theme.paddingLarge anchors { left: lblName.right @@ -47,7 +47,7 @@ Item { font.pixelSize: Theme.fontSizeExtraSmall color: (pressed ? Theme.secondaryHighlightColor : Theme.secondaryColor) anchors { - left: iconVerified.right + left: iconLocked.right right: lblDate.left leftMargin: Theme.paddingMedium baseline: lblName.baseline diff --git a/qml/pages/components/MiniStatus.qml b/qml/pages/components/MiniStatus.qml index a38dfca..d9dc96c 100644 --- a/qml/pages/components/MiniStatus.qml +++ b/qml/pages/components/MiniStatus.qml @@ -7,9 +7,10 @@ Item { 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 : "" diff --git a/qml/pages/components/MyList.qml b/qml/pages/components/MyList.qml index e3b1d14..ce8f5e6 100644 --- a/qml/pages/components/MyList.qml +++ b/qml/pages/components/MyList.qml @@ -39,17 +39,18 @@ SilicaListView { console.log("LIST send signal emitted with notice: " + notice) } - 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 enabled: model.count === 0 @@ -65,6 +66,16 @@ SilicaListView { } } + MenuItem { + text: qsTr("New Toot") + onClicked: { + pageStack.push(Qt.resolvedUrl("../ConversationPage.qml"), { + //headerTitle: "New Toot", + type: "new" + }) + } + } + MenuItem { text: qsTr("Load more") onClicked: { @@ -72,14 +83,6 @@ SilicaListView { } } } - clip: true - section { - property: 'section' - delegate: SectionHeader { - height: Theme.itemSizeExtraSmall - text: Format.formatDate(section, Formatter.DateMedium) - } - } delegate: VisualContainer { } //Toot {} From 9fb1efc189830af7db028091d97c956e887fe4ca Mon Sep 17 00:00:00 2001 From: molan-git Date: Sat, 6 Jun 2020 23:17:27 +0200 Subject: [PATCH 09/22] improved notifications UI notifications (mentions, favs, reblogs) are distinguished by different looks (initial commits) --- qml/pages/ConversationPage.qml | 6 ++-- qml/pages/components/VisualContainer.qml | 43 +++++++++++++++++++++--- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/qml/pages/ConversationPage.qml b/qml/pages/ConversationPage.qml index fb57082..221ae56 100644 --- a/qml/pages/ConversationPage.qml +++ b/qml/pages/ConversationPage.qml @@ -17,7 +17,7 @@ Page { property ListModel suggestedModel property string toot_id: "" property string toot_url: "" - property int tootMaxChar: 500; + property int tootMaxChar: 500 property ListModel mdl allowedOrientations: Orientation.All @@ -65,8 +65,8 @@ Page { visible: false } - SilicaListView { - id: conversationList + SilicaListView { + id: myList header: PageHeader { title: headerTitle // pageTitle pushed from MainPage.qml or VisualContainer.qml } diff --git a/qml/pages/components/VisualContainer.qml b/qml/pages/components/VisualContainer.qml index b86e715..b82044e 100644 --- a/qml/pages/components/VisualContainer.qml +++ b/qml/pages/components/VisualContainer.qml @@ -10,8 +10,9 @@ BackgroundItem { 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) Rectangle { id: bgDirect x: 0 @@ -37,6 +38,20 @@ BackgroundItem { } } */ + Rectangle { + id: bgDelegate + 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 anchors { @@ -83,6 +98,13 @@ BackgroundItem { } } + 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 @@ -109,6 +131,7 @@ BackgroundItem { } Image { + id: reblogAvatar asynchronous: true smooth: true opacity: status === Image.Ready ? 1.0 : 0.0 @@ -118,6 +141,13 @@ BackgroundItem { width: Theme.iconSizeSmall height: width } + + Rectangle { + visible: myList.type === "notifications" && ( model.type === "favourite" || model.type === "reblog" ) + opacity: 0.5 + color: Theme.highlightDimmerColor + anchors.fill: reblogAvatar + } } } @@ -136,9 +166,13 @@ BackgroundItem { text: content.replace(new RegExp(" paintedHeight ? contentWarningLabel.paintedHeight : paintedHeight) : 0 @@ -213,6 +247,7 @@ BackgroundItem { 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 { From d0125d86acc486d43198132480730e47142d4a63 Mon Sep 17 00:00:00 2001 From: molan-git Date: Mon, 8 Jun 2020 17:34:32 +0200 Subject: [PATCH 10/22] improved notifications UI - small changes / additions --- harbour-tooter.pro | 2 +- qml/cover/CoverPage.qml | 20 +++++---- qml/images/{tooter.svg => tooter-cover.svg} | 0 qml/pages/components/MediaFullScreen.qml | 23 +++++----- qml/pages/components/VisualContainer.qml | 50 ++++++++++++++++++--- 5 files changed, 68 insertions(+), 27 deletions(-) rename qml/images/{tooter.svg => tooter-cover.svg} (100%) diff --git a/harbour-tooter.pro b/harbour-tooter.pro index fc04db3..bd4e9d9 100644 --- a/harbour-tooter.pro +++ b/harbour-tooter.pro @@ -53,6 +53,7 @@ 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 \ @@ -75,7 +76,6 @@ DISTFILES += qml/harbour-tooter.qml \ qml/pages/Browser.qml \ qml/lib/API.js \ qml/images/icon-s-following \ - qml/images/tooter.svg \ qml/images/icon-m-emoji.svg \ qml/images/icon-m-profile.svg \ qml/images/icon-l-profile.svg \ diff --git a/qml/cover/CoverPage.qml b/qml/cover/CoverPage.qml index 63b9d01..70879fc 100644 --- a/qml/cover/CoverPage.qml +++ b/qml/cover/CoverPage.qml @@ -46,19 +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 @@ -69,34 +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) 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/pages/components/MediaFullScreen.qml b/qml/pages/components/MediaFullScreen.qml index fda8df1..cd182f1 100644 --- a/qml/pages/components/MediaFullScreen.qml +++ b/qml/pages/components/MediaFullScreen.qml @@ -5,12 +5,12 @@ import QtMultimedia 5.0 FullscreenContentPage { id: mediaPage - allowedOrientations: Orientation.All property string type: "" property string previewURL: "" property string mediaURL: "" + allowedOrientations: Orientation.All Component.onCompleted: function(){ console.log(type) console.log(previewURL) @@ -27,12 +27,12 @@ FullscreenContentPage { } Flickable { - id: videoFlickable + id: videoFlickable visible: false - anchors.fill: parent + clip: true contentWidth: imageContainer.width contentHeight: imageContainer.height - clip: true + anchors.fill: parent Image { id: videoPreview @@ -45,7 +45,7 @@ FullscreenContentPage { id: video anchors.fill: parent onErrorStringChanged: function(){ - videoError.visible = true; + videoError.visible = true } onStatusChanged: { console.log(status) @@ -83,19 +83,22 @@ FullscreenContentPage { playerProgress.value = position } } - onStopped: function(){ - stop() + onStopped: function() { + if (video.duration < 30000) + video.play() + else + video.stop() } IconButton { id: playerIcon + icon.source: "image://theme/icon-m-play" anchors { left: parent.left bottom: parent.bottom leftMargin: Theme.horizontalPageMargin bottomMargin: Theme.horizontalPageMargin } - icon.source: "image://theme/icon-m-play" onClicked: function() { if (video.playbackState === MediaPlayer.PlayingState) video.pause() @@ -161,7 +164,7 @@ FullscreenContentPage { clip: true anchors.fill: parent onHeightChanged: if (imagePreview.status === Image.Ready) { - imagePreview.fitToScreen(); + imagePreview.fitToScreen() } Item { @@ -218,11 +221,11 @@ FullscreenContentPage { 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 diff --git a/qml/pages/components/VisualContainer.qml b/qml/pages/components/VisualContainer.qml index b82044e..d023566 100644 --- a/qml/pages/components/VisualContainer.qml +++ b/qml/pages/components/VisualContainer.qml @@ -12,7 +12,7 @@ BackgroundItem { width: parent.width 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) + } 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 { id: bgDirect x: 0 @@ -39,7 +39,7 @@ BackgroundItem { } */ Rectangle { - id: bgDelegate + id: bgNotifications x: 0 y: 0 visible: myList.type === "notifications" && ( model.type === "favourite" || model.type === "reblog" ) @@ -118,7 +118,22 @@ BackgroundItem { } } + 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 { + id: bgReblogAvatar color: Theme.highlightDimmerColor width: Theme.iconSizeSmall height: width @@ -141,14 +156,35 @@ BackgroundItem { width: Theme.iconSizeSmall height: width } + } - Rectangle { - visible: myList.type === "notifications" && ( model.type === "favourite" || model.type === "reblog" ) - opacity: 0.5 - color: Theme.highlightDimmerColor - anchors.fill: reblogAvatar + Rectangle { + id: bgBotIcon + color: Theme.highlightDimmerColor + radius: Theme.paddingSmall + width: Theme.iconSizeSmall + height: width + visible: true //typeof status_reblog !== "undefined" && status_reblog + anchors { + top: parent.top + topMargin: -width/3 + left: parent.left + leftMargin: -width/3 + } + + Image { + id: botIcon + asynchronous: true + smooth: true + opacity: status === Image.Ready ? 1.0 : 0.0 + Behavior on opacity { FadeAnimator {} } + source: "image://theme/icon-s-alarm?" //typeof reblog_account_avatar !== "undefined" ? reblog_account_avatar : '' + visible: typeof bot === true //typeof status_reblog !== "undefined" && status_reblog + width: Theme.iconSizeSmall + height: width } } + } MiniHeader { From 092c7d880f1963b2b60a165eba51f6f123fd017a Mon Sep 17 00:00:00 2001 From: molan-git Date: Tue, 9 Jun 2020 08:52:22 +0200 Subject: [PATCH 11/22] revert bgBotIcon --- qml/pages/components/VisualContainer.qml | 30 +----------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/qml/pages/components/VisualContainer.qml b/qml/pages/components/VisualContainer.qml index d023566..afe3ce9 100644 --- a/qml/pages/components/VisualContainer.qml +++ b/qml/pages/components/VisualContainer.qml @@ -134,7 +134,7 @@ BackgroundItem { Rectangle { id: bgReblogAvatar - color: Theme.highlightDimmerColor + color: Theme.secondaryColor width: Theme.iconSizeSmall height: width visible: typeof status_reblog !== "undefined" && status_reblog @@ -157,34 +157,6 @@ BackgroundItem { height: width } } - - Rectangle { - id: bgBotIcon - color: Theme.highlightDimmerColor - radius: Theme.paddingSmall - width: Theme.iconSizeSmall - height: width - visible: true //typeof status_reblog !== "undefined" && status_reblog - anchors { - top: parent.top - topMargin: -width/3 - left: parent.left - leftMargin: -width/3 - } - - Image { - id: botIcon - asynchronous: true - smooth: true - opacity: status === Image.Ready ? 1.0 : 0.0 - Behavior on opacity { FadeAnimator {} } - source: "image://theme/icon-s-alarm?" //typeof reblog_account_avatar !== "undefined" ? reblog_account_avatar : '' - visible: typeof bot === true //typeof status_reblog !== "undefined" && status_reblog - width: Theme.iconSizeSmall - height: width - } - } - } MiniHeader { From c22254364e6bc8dc7909b891533d0b8d595bc77d Mon Sep 17 00:00:00 2001 From: molan-git Date: Tue, 9 Jun 2020 12:05:25 +0200 Subject: [PATCH 12/22] avoid empty search-results show # results also uf term is entered by user without # --- qml/pages/MainPage.qml | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml index c809e19..408c939 100644 --- a/qml/pages/MainPage.qml +++ b/qml/pages/MainPage.qml @@ -84,7 +84,11 @@ Page { 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.sourceComponen = tagListComponent + } else { loader.sourceComponent = worldListComponent} } Loader { @@ -183,6 +187,31 @@ 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") + } + } + } } } From 6c4e5466c019319edfa96461d376bbf3b7bf8d5c Mon Sep 17 00:00:00 2001 From: molan-git Date: Tue, 9 Jun 2020 18:46:36 +0200 Subject: [PATCH 13/22] fix copy toot-URL if the toot url isn't provided (for example in retoots), the toot uri will be used --- qml/pages/ConversationPage.qml | 30 +++++++++++++++++------- qml/pages/components/VisualContainer.qml | 1 + 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/qml/pages/ConversationPage.qml b/qml/pages/ConversationPage.qml index fb57082..841d49d 100644 --- a/qml/pages/ConversationPage.qml +++ b/qml/pages/ConversationPage.qml @@ -17,8 +17,9 @@ Page { 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: { @@ -100,13 +101,26 @@ Page { } PullDownMenu { - visible: type === "reply" && toot_url !== "" - MenuItem { - text: qsTr("Copy Link to Clipboard") - onClicked: Clipboard.text = toot_url - } - } - } + 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 diff --git a/qml/pages/components/VisualContainer.qml b/qml/pages/components/VisualContainer.qml index b86e715..279635d 100644 --- a/qml/pages/components/VisualContainer.qml +++ b/qml/pages/components/VisualContainer.qml @@ -340,6 +340,7 @@ BackgroundItem { headerTitle: "Conversation", toot_id: status_id, toot_url: status_url, + toot_uri: status_uri, title: account_display_name, description: '@'+account_acct, avatar: account_avatar, From d157c08c34393a72c18e9fb1c55e65cb845ba985 Mon Sep 17 00:00:00 2001 From: molan-git Date: Tue, 9 Jun 2020 19:14:40 +0200 Subject: [PATCH 14/22] component id fix --- qml/pages/MainPage.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml index 408c939..1429b5b 100644 --- a/qml/pages/MainPage.qml +++ b/qml/pages/MainPage.qml @@ -88,7 +88,7 @@ Page { loader.sourceComponent = userListComponent } else if (search.charAt(0) === "#") { loader.sourceComponen = tagListComponent - } else { loader.sourceComponent = worldListComponent} + } else { loader.sourceComponent = wordListComponent} } Loader { From 7eaad1b867227ac64436e9237ad6dd0994928544 Mon Sep 17 00:00:00 2001 From: molan-git Date: Wed, 10 Jun 2020 10:17:51 +0200 Subject: [PATCH 15/22] small fixes for notification page --- qml/pages/ConversationPage.qml | 6 ++-- qml/pages/MainPage.qml | 2 +- qml/pages/components/MiniHeader.qml | 40 +++++++++++++----------- qml/pages/components/Toot.qml | 4 +-- qml/pages/components/VisualContainer.qml | 25 +++++---------- 5 files changed, 35 insertions(+), 42 deletions(-) diff --git a/qml/pages/ConversationPage.qml b/qml/pages/ConversationPage.qml index bd5378f..4218bea 100644 --- a/qml/pages/ConversationPage.qml +++ b/qml/pages/ConversationPage.qml @@ -270,7 +270,9 @@ Page { IconButton { id: btnSmileys + property string selection + opacity: 0.7 icon { color: Theme.secondaryColor @@ -284,9 +286,7 @@ Page { right: parent.right rightMargin: Theme.paddingSmall } - onSelectionChanged: { - console.log(selection) - } + onSelectionChanged: { console.log(selection) } onClicked: pageStack.push(emojiSelect) } diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml index 1429b5b..2ff089f 100644 --- a/qml/pages/MainPage.qml +++ b/qml/pages/MainPage.qml @@ -87,7 +87,7 @@ Page { if (search.charAt(0) === "@") { loader.sourceComponent = userListComponent } else if (search.charAt(0) === "#") { - loader.sourceComponen = tagListComponent + loader.sourceComponent = tagListComponent } else { loader.sourceComponent = wordListComponent} } diff --git a/qml/pages/components/MiniHeader.qml b/qml/pages/components/MiniHeader.qml index 0b52e44..e227fd0 100644 --- a/qml/pages/components/MiniHeader.qml +++ b/qml/pages/components/MiniHeader.qml @@ -9,45 +9,47 @@ Item { 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: iconLocked + 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 - truncationMode: TruncationMode.Fade text: '@'+account_username font.pixelSize: Theme.fontSizeExtraSmall color: (pressed ? Theme.secondaryHighlightColor : Theme.secondaryColor) + truncationMode: TruncationMode.Fade anchors { - left: iconLocked.right + left: icnLocked.right right: lblDate.left leftMargin: Theme.paddingMedium baseline: lblName.baseline @@ -56,9 +58,9 @@ Item { 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 diff --git a/qml/pages/components/Toot.qml b/qml/pages/components/Toot.qml index 5a705e1..6361ab5 100644 --- a/qml/pages/components/Toot.qml +++ b/qml/pages/components/Toot.qml @@ -85,7 +85,7 @@ BackgroundItem { } Image { - id: iconVerified + id: iconLocked visible: account_locked y: Theme.paddingLarge opacity: 0.8 @@ -108,7 +108,7 @@ BackgroundItem { font.pixelSize: Theme.fontSizeExtraSmall color: (pressed ? Theme.secondaryHighlightColor : Theme.secondaryColor) anchors { - left: iconVerified.right + left: iconLocked.right right: lblDate.left leftMargin: Theme.paddingMedium baseline: lblName.baseline diff --git a/qml/pages/components/VisualContainer.qml b/qml/pages/components/VisualContainer.qml index 304f299..708c56e 100644 --- a/qml/pages/components/VisualContainer.qml +++ b/qml/pages/components/VisualContainer.qml @@ -13,31 +13,18 @@ BackgroundItem { 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 { id: bgDirect x: 0 y: 0 - visible: status_visibility == 'direct' + visible: status_visibility === "direct" width: parent.width height: parent.height opacity: 0.3 color: Theme.highlightBackgroundColor } - /* Rectangle { - id: bgDelegate - x: 0 - y: 0 - visible: status_visibility !== 'direct' - width: parent.width - height: parent.height - opacity: 0.15 - gradient: Gradient { - GradientStop { position: 0.7; color: "transparent" } - GradientStop { position: 1.0; color: Theme.highlightDimmerColor } - } - } */ - Rectangle { id: bgNotifications x: 0 @@ -120,7 +107,7 @@ BackgroundItem { Image { id: iconDirectMsg - visible: status_visibility == 'direct' + visible: status_visibility === "direct" width: Theme.iconSizeMedium height: width source: "image://theme/icon-m-mail" @@ -271,7 +258,9 @@ BackgroundItem { id: mnu MenuItem { + 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 @@ -311,7 +300,8 @@ BackgroundItem { } MenuItem { - visible: 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 @@ -351,6 +341,7 @@ BackgroundItem { } MenuItem { + id: mnuMention visible: model.type === "follow" text: qsTr("Mention") onClicked: { From 5dad14eafbf063dcca2894db57c119c0039f7bb0 Mon Sep 17 00:00:00 2001 From: molan-git Date: Wed, 10 Jun 2020 11:44:58 +0200 Subject: [PATCH 16/22] ui-improvements --- qml/pages/components/EmojiSelect.qml | 2 +- qml/pages/components/MediaFullScreen.qml | 1 + qml/pages/components/ProfileHeader.qml | 8 ++++---- qml/pages/components/ProfileImage.qml | 5 +++-- qml/pages/components/Toot.qml | 4 ++-- qml/pages/components/VisualContainer.qml | 5 ++++- 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/qml/pages/components/EmojiSelect.qml b/qml/pages/components/EmojiSelect.qml index 3e4f8fa..45a6f10 100644 --- a/qml/pages/components/EmojiSelect.qml +++ b/qml/pages/components/EmojiSelect.qml @@ -162,5 +162,5 @@ Component { } } -} +} diff --git a/qml/pages/components/MediaFullScreen.qml b/qml/pages/components/MediaFullScreen.qml index cd182f1..324fa76 100644 --- a/qml/pages/components/MediaFullScreen.qml +++ b/qml/pages/components/MediaFullScreen.qml @@ -319,6 +319,7 @@ FullscreenContentPage { FileDownloader.downloadFile(mediaURL, filename[filename.length-1]); } } + VerticalScrollDecorator { flickable: imageFlickable } } diff --git a/qml/pages/components/ProfileHeader.qml b/qml/pages/components/ProfileHeader.qml index af2126d..e79402a 100644 --- a/qml/pages/components/ProfileHeader.qml +++ b/qml/pages/components/ProfileHeader.qml @@ -12,7 +12,7 @@ Item { property string bg: "" width: parent.width - height: icon.height + Theme.paddingLarge*2 + height: avatarImage.height + Theme.paddingLarge*2 Rectangle { id: bgImage @@ -33,10 +33,10 @@ Item { } Image { - id: icon + id: avatarImage asynchronous: true source: - if (icon.status === Image.Error) + if (avatarImage.status === Image.Error) source = "../../images/icon-l-profile.svg?" + (pressed ? Theme.highlightColor : Theme.primaryColor) @@ -69,7 +69,7 @@ Item { Column { anchors { - left: icon.right + left: avatarImage.right leftMargin: Theme.paddingLarge right: parent.right rightMargin: Theme.paddingLarge diff --git a/qml/pages/components/ProfileImage.qml b/qml/pages/components/ProfileImage.qml index 38fdde0..1e000b0 100644 --- a/qml/pages/components/ProfileImage.qml +++ b/qml/pages/components/ProfileImage.qml @@ -3,9 +3,10 @@ import Sailfish.Silica 1.0 FullscreenContentPage { id: profileImage - allowedOrientations: Orientation.All - property string image: "" + property string image: "" + + allowedOrientations: Orientation.All Image { source: image diff --git a/qml/pages/components/Toot.qml b/qml/pages/components/Toot.qml index 6361ab5..190cd82 100644 --- a/qml/pages/components/Toot.qml +++ b/qml/pages/components/Toot.qml @@ -4,11 +4,11 @@ import QtGraphicalEffects 1.0 BackgroundItem { + id: delegate + signal send (string notice) signal navigateTo(string link) - id: delegate - //property string text: "0" width: parent.width height: lblText.paintedHeight + (lblText.text.length > 0 ? Theme.paddingLarge : 0 )+ lblName.paintedHeight + (type.length ? Theme.paddingLarge + iconRT.height : 0) + Theme.paddingLarge diff --git a/qml/pages/components/VisualContainer.qml b/qml/pages/components/VisualContainer.qml index 708c56e..2bb06a0 100644 --- a/qml/pages/components/VisualContainer.qml +++ b/qml/pages/components/VisualContainer.qml @@ -22,7 +22,10 @@ BackgroundItem { 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 { From 52c8f549c0b6ab5331a1122066e3e6b4c024345c Mon Sep 17 00:00:00 2001 From: molan-git Date: Wed, 10 Jun 2020 13:26:16 +0200 Subject: [PATCH 17/22] info labels for profile header adds info labels to profile header ('Following you' / 'Bot') --- qml/pages/ProfilePage.qml | 4 ++ qml/pages/components/ProfileHeader.qml | 69 +++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/qml/pages/ProfilePage.qml b/qml/pages/ProfilePage.qml index e2318af..4478e4c 100644 --- a/qml/pages/ProfilePage.qml +++ b/qml/pages/ProfilePage.qml @@ -23,6 +23,7 @@ Page { 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 @@ -77,6 +78,9 @@ Page { case 'locked': locked = messageObject.data break; + case 'bot': + bot = messageObject.data + break; case 'created_at': created_at = messageObject.data break; diff --git a/qml/pages/components/ProfileHeader.qml b/qml/pages/components/ProfileHeader.qml index e79402a..a19c5b8 100644 --- a/qml/pages/components/ProfileHeader.qml +++ b/qml/pages/components/ProfileHeader.qml @@ -12,7 +12,9 @@ Item { property string bg: "" width: parent.width - height: avatarImage.height + Theme.paddingLarge*2 + height: if (following === true || bot === true) { + avatarImage.height + Theme.paddingLarge*2 + infoLbl.height + Theme.paddingLarge + } else avatarImage.height + Theme.paddingLarge*2 Rectangle { id: bgImage @@ -69,6 +71,8 @@ Item { Column { anchors { + top: parent.top + topMargin: Theme.paddingLarge left: avatarImage.right leftMargin: Theme.paddingLarge right: parent.right @@ -77,12 +81,11 @@ Item { } Label { - id: ttl - text: - if (title === "") { - description.split('@')[0] - } - else title + id: profileTitle + text: if (title === "") { + description.split('@')[0] + } + else title font.pixelSize: Theme.fontSizeLarge font.family: Theme.fontFamilyHeading color: Theme.highlightColor @@ -93,6 +96,7 @@ Item { } Label { + id: profileDescription text: "@"+description font.pixelSize: Theme.fontSizeSmall font.family: Theme.fontFamilyHeading @@ -104,4 +108,55 @@ Item { } } + Row { + id: infoLbl + spacing: Theme.paddingLarge + layoutDirection: Qt.RightToLeft + height: Theme.iconSizeSmall + Theme.paddingSmall + anchors { + top: avatarImage.bottom + topMargin: Theme.paddingLarge + left: parent.left + leftMargin: Theme.paddingLarge + right: parent.right + rightMargin: Theme.paddingLarge + } + + Rectangle { + id: followingBg + visible: (following ? true : false) + radius: Theme.paddingSmall + color: Theme.secondaryHighlightColor + width: Theme.buttonWidthExtraSmall + height: parent.height + + Label { + id: followingLbl + text: qsTr("Follows you") + font.pixelSize: Theme.fontSizeExtraSmall + color: Theme.primaryColor + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + } + } + + Rectangle { + id: botBg + visible: (bot ? true : false) + radius: Theme.paddingSmall + color: Theme.secondaryHighlightColor + width: botLabel.width + 2*Theme.paddingLarge + height: parent.height + + Label { + id: botLbl + text: qsTr("Bot") + font.pixelSize: Theme.fontSizeExtraSmall + color: Theme.primaryColor + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + } + } + } + } From 9b5e8e5516cd09ea559467dc74127ffaa2baa248 Mon Sep 17 00:00:00 2001 From: molan-git Date: Wed, 10 Jun 2020 14:33:23 +0200 Subject: [PATCH 18/22] fix anchors profile labels --- qml/pages/components/ProfileHeader.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qml/pages/components/ProfileHeader.qml b/qml/pages/components/ProfileHeader.qml index a19c5b8..b302072 100644 --- a/qml/pages/components/ProfileHeader.qml +++ b/qml/pages/components/ProfileHeader.qml @@ -127,7 +127,7 @@ Item { visible: (following ? true : false) radius: Theme.paddingSmall color: Theme.secondaryHighlightColor - width: Theme.buttonWidthExtraSmall + width: followingLbl.width + 2*Theme.paddingLarge height: parent.height Label { @@ -145,7 +145,7 @@ Item { visible: (bot ? true : false) radius: Theme.paddingSmall color: Theme.secondaryHighlightColor - width: botLabel.width + 2*Theme.paddingLarge + width: botLbl.width + 2*Theme.paddingLarge height: parent.height Label { From 6f9ed5a8467f3588aea6dce9851b92d3d6d87b87 Mon Sep 17 00:00:00 2001 From: molan-git Date: Wed, 10 Jun 2020 16:20:54 +0200 Subject: [PATCH 19/22] remove WIP feature --- qml/pages/components/ProfileHeader.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qml/pages/components/ProfileHeader.qml b/qml/pages/components/ProfileHeader.qml index b302072..20c93d9 100644 --- a/qml/pages/components/ProfileHeader.qml +++ b/qml/pages/components/ProfileHeader.qml @@ -12,7 +12,7 @@ Item { property string bg: "" width: parent.width - height: if (following === true || bot === true) { + height: if (bot === true) { avatarImage.height + Theme.paddingLarge*2 + infoLbl.height + Theme.paddingLarge } else avatarImage.height + Theme.paddingLarge*2 @@ -122,7 +122,7 @@ Item { rightMargin: Theme.paddingLarge } - Rectangle { + /* Rectangle { id: followingBg visible: (following ? true : false) radius: Theme.paddingSmall @@ -138,7 +138,7 @@ Item { anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter } - } + } */ Rectangle { id: botBg From d53d5c7af3febe5fce3b6f531eed41c2d14c8c0e Mon Sep 17 00:00:00 2001 From: molan-git Date: Wed, 10 Jun 2020 17:50:00 +0200 Subject: [PATCH 20/22] small fixes --- qml/pages/ConversationPage.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qml/pages/ConversationPage.qml b/qml/pages/ConversationPage.qml index 4218bea..a85b305 100644 --- a/qml/pages/ConversationPage.qml +++ b/qml/pages/ConversationPage.qml @@ -19,6 +19,7 @@ Page { property string toot_url: "" property string toot_uri: "" property int tootMaxChar: 500; + property bool bot: false property ListModel mdl allowedOrientations: Orientation.All @@ -102,7 +103,7 @@ Page { PullDownMenu { id: pulleyConversation - visible: type === "reply" //&& toot_url !== "" + visible: type === "reply" MenuItem { text: qsTr("Copy Link to Clipboard") onClicked: if (toot_url === "") { From e9c1c3814185c11a4e2e73db3df90284874624da Mon Sep 17 00:00:00 2001 From: molan-git Date: Thu, 11 Jun 2020 14:11:39 +0200 Subject: [PATCH 21/22] fix contextMnu --- qml/harbour-tooter.qml | 31 ++++----- qml/pages/ConversationPage.qml | 42 ++++++------ qml/pages/LoginPage.qml | 82 ++++++++++++------------ qml/pages/components/InfoBanner.qml | 4 +- qml/pages/components/MediaFullScreen.qml | 2 +- qml/pages/components/ProfileHeader.qml | 2 +- qml/pages/components/ProfileImage.qml | 2 +- qml/pages/components/VisualContainer.qml | 18 +++--- 8 files changed, 92 insertions(+), 91 deletions(-) diff --git a/qml/harbour-tooter.qml b/qml/harbour-tooter.qml index b0f9abd..b50b096 100644 --- a/qml/harbour-tooter.qml +++ b/qml/harbour-tooter.qml @@ -35,8 +35,8 @@ import "./lib/API.js" as Logic ApplicationWindow { id: appWindow - cover: Qt.resolvedUrl("cover/CoverPage.qml") allowedOrientations: defaultAllowedOrientations + cover: Qt.resolvedUrl("cover/CoverPage.qml") Component.onCompleted: { var obj = {} Logic.mediator.installTo(obj) @@ -44,26 +44,26 @@ ApplicationWindow { 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 = 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() @@ -73,6 +73,7 @@ ApplicationWindow { //Logic.conf.notificationLastID = 0; Logic.saveData() } + Connections { target: Dbus onViewtoot: { diff --git a/qml/pages/ConversationPage.qml b/qml/pages/ConversationPage.qml index a85b305..9ce3a3c 100644 --- a/qml/pages/ConversationPage.qml +++ b/qml/pages/ConversationPage.qml @@ -47,6 +47,27 @@ Page { } } + PullDownMenu { + id: pulleyConversation + visible: type === "reply" + 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 + } + } + ListModel { id: mediaModel onCountChanged: { @@ -100,27 +121,6 @@ Page { } } } - - PullDownMenu { - id: pulleyConversation - visible: type === "reply" - 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 { diff --git a/qml/pages/LoginPage.qml b/qml/pages/LoginPage.qml index b35ad7a..3a2cb10 100644 --- a/qml/pages/LoginPage.qml +++ b/qml/pages/LoginPage.qml @@ -39,37 +39,37 @@ Page { EnterKey.onClicked: { 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 - "http://grave-design.com/harbour-tooter", //website on the login screen - function(data) { + 'http://localhost/harbour-tooter', // redirect uri, we will need this later on + ["read", "write", "follow"], //scopes + "http://grave-design.com/harbour-tooter", //website on the login screen + function(data) { - console.log(data) - var conf = JSON.parse(data) - conf.instance = instance.text; - conf.login = false; + console.log(data) + var conf = JSON.parse(data) + conf.instance = instance.text; + conf.login = false; - /*conf['login'] = false; + /*conf['login'] = false; conf['mastodon_client_id'] = data['mastodon_client_id']; conf['mastodon_client_secret'] = data['mastodon_client_secret']; conf['mastodon_client_redirect_uri'] = data['mastodon_client_redirect_uri']; delete Logic.conf;*/ - Logic.conf = conf; - console.log(JSON.stringify(conf)) - console.log(JSON.stringify(Logic.conf)) - // we got our application + Logic.conf = conf; + console.log(JSON.stringify(conf)) + console.log(JSON.stringify(Logic.conf)) + // we got our application - // our user to it! - var url = Logic.api.generateAuthLink(Logic.conf["client_id"], - Logic.conf["redirect_uri"], - "code", // oauth method - ["read", "write", "follow"] //scopes - ); - console.log(url) - webView.url = url - webView.visible = true - } - ); + // our user to it! + var url = Logic.api.generateAuthLink(Logic.conf["client_id"], + Logic.conf["redirect_uri"], + "code", // oauth method + ["read", "write", "follow"] //scopes + ); + console.log(url) + webView.url = url + webView.visible = true + } + ); } } Label { @@ -109,7 +109,7 @@ Page { if ( (url+"").substr(0, 37) === 'http://localhost/harbour-tooter?code=' || (url+"").substr(0, 38) === 'https://localhost/harbour-tooter?code=' - ) { + ) { visible = false; var vars = {}; @@ -120,22 +120,22 @@ Page { console.log(authCode) Logic.api.getAccessTokenFromAuthCode( - Logic.conf["client_id"], - Logic.conf["client_secret"], - Logic.conf["redirect_uri"], - authCode, - function(data) { - // AAAND DATA CONTAINS OUR TOKEN! - console.log(data) - data = JSON.parse(data) - console.log(JSON.stringify(data)) - console.log(JSON.stringify(data.access_token)) - Logic.conf["api_user_token"] = data.access_token - Logic.conf["login"] = true; - Logic.api.setConfig("api_user_token", Logic.conf["api_user_token"]) - pageStack.replace(Qt.resolvedUrl("MainPage.qml"), {}) - } - ) + Logic.conf["client_id"], + Logic.conf["client_secret"], + Logic.conf["redirect_uri"], + authCode, + function(data) { + // AAAND DATA CONTAINS OUR TOKEN! + console.log(data) + data = JSON.parse(data) + console.log(JSON.stringify(data)) + console.log(JSON.stringify(data.access_token)) + Logic.conf["api_user_token"] = data.access_token + Logic.conf["login"] = true; + Logic.api.setConfig("api_user_token", Logic.conf["api_user_token"]) + pageStack.replace(Qt.resolvedUrl("MainPage.qml"), {}) + } + ) } diff --git a/qml/pages/components/InfoBanner.qml b/qml/pages/components/InfoBanner.qml index 8d33b9a..06601aa 100644 --- a/qml/pages/components/InfoBanner.qml +++ b/qml/pages/components/InfoBanner.qml @@ -3,7 +3,7 @@ import Sailfish.Silica 1.0 DockedPanel { - id: root + id: root dock: Dock.Top width: parent.width height: content.height @@ -28,7 +28,7 @@ DockedPanel { right: parent.right rightMargin: Theme.horizontalPageMargin verticalCenter: parent.verticalCenter - } + } } MouseArea { diff --git a/qml/pages/components/MediaFullScreen.qml b/qml/pages/components/MediaFullScreen.qml index 324fa76..38ec83a 100644 --- a/qml/pages/components/MediaFullScreen.qml +++ b/qml/pages/components/MediaFullScreen.qml @@ -27,7 +27,7 @@ FullscreenContentPage { } Flickable { - id: videoFlickable + id: videoFlickable visible: false clip: true contentWidth: imageContainer.width diff --git a/qml/pages/components/ProfileHeader.qml b/qml/pages/components/ProfileHeader.qml index 20c93d9..de9c0af 100644 --- a/qml/pages/components/ProfileHeader.qml +++ b/qml/pages/components/ProfileHeader.qml @@ -122,7 +122,7 @@ Item { rightMargin: Theme.paddingLarge } - /* Rectangle { + /* Rectangle { id: followingBg visible: (following ? true : false) radius: Theme.paddingSmall diff --git a/qml/pages/components/ProfileImage.qml b/qml/pages/components/ProfileImage.qml index 1e000b0..5c49285 100644 --- a/qml/pages/components/ProfileImage.qml +++ b/qml/pages/components/ProfileImage.qml @@ -4,7 +4,7 @@ import Sailfish.Silica 1.0 FullscreenContentPage { id: profileImage - property string image: "" + property string image: "" allowedOrientations: Orientation.All diff --git a/qml/pages/components/VisualContainer.qml b/qml/pages/components/VisualContainer.qml index 2bb06a0..7635dc9 100644 --- a/qml/pages/components/VisualContainer.qml +++ b/qml/pages/components/VisualContainer.qml @@ -23,8 +23,8 @@ BackgroundItem { height: parent.height opacity: 0.3 gradient: Gradient { - GradientStop { position: -1.5; color: "transparent" } - GradientStop { position: 0.6; color: Theme.highlightBackgroundColor } + GradientStop { position: -1.5; color: "transparent" } + GradientStop { position: 0.6; color: Theme.highlightBackgroundColor } } } @@ -37,8 +37,8 @@ BackgroundItem { height: parent.height opacity: 0.5 gradient: Gradient { - GradientStop { position: -0.5; color: "transparent" } - GradientStop { position: 0.4; color: Theme.highlightDimmerColor } + GradientStop { position: -0.5; color: "transparent" } + GradientStop { position: 0.4; color: Theme.highlightDimmerColor } } } @@ -71,8 +71,8 @@ BackgroundItem { onStatusChanged: { if (avatar.status === Image.Error) source = "../../images/icon-m-profile.svg?" + (pressed - ? Theme.highlightColor - : Theme.primaryColor) + ? Theme.highlightColor + : Theme.primaryColor) } MouseArea { @@ -165,8 +165,8 @@ BackgroundItem { textFormat: Text.RichText font.pixelSize: Theme.fontSizeSmall linkColor: if (myList.type === "notifications" && ( model.type === "favourite" || model.type === "reblog" )) { - Theme.secondaryHighlightColor - } else Theme.highlightColor + Theme.secondaryHighlightColor + } else Theme.highlightColor wrapMode: Text.Wrap color: if (myList.type === "notifications" && ( model.type === "favourite" || model.type === "reblog" )) { (pressed ? Theme.secondaryHighlightColor : (!highlight ? Theme.secondaryColor : Theme.secondaryHighlightColor)) @@ -304,7 +304,7 @@ BackgroundItem { MenuItem { id: mnuFavourite - visible: model.type !== "follow" || model.status_visibility !== "direct" + visible: model.type !== "follow" text: typeof model.favourited !== "undefined" && model.favourited ? qsTr("Unfavorite") : qsTr("Favorite") onClicked: { var status = typeof model.favourited !== "undefined" && model.favourited From 9febf8409237478ce3382b0af3bb3bd3e150fc1c Mon Sep 17 00:00:00 2001 From: molan-git Date: Thu, 11 Jun 2020 14:22:09 +0200 Subject: [PATCH 22/22] pulleyMnu fix --- qml/pages/ConversationPage.qml | 42 +++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/qml/pages/ConversationPage.qml b/qml/pages/ConversationPage.qml index 9ce3a3c..a85b305 100644 --- a/qml/pages/ConversationPage.qml +++ b/qml/pages/ConversationPage.qml @@ -47,27 +47,6 @@ Page { } } - PullDownMenu { - id: pulleyConversation - visible: type === "reply" - 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 - } - } - ListModel { id: mediaModel onCountChanged: { @@ -121,6 +100,27 @@ Page { } } } + + PullDownMenu { + id: pulleyConversation + visible: type === "reply" + 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 {