From fd2f317f254ecb1e16f9ecbef0fddc45c389b240 Mon Sep 17 00:00:00 2001 From: molan-git Date: Fri, 29 May 2020 20:05:05 +0200 Subject: [PATCH] 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