From 77f0f1e7d98646554e0a7f2a38b6a5618a825885 Mon Sep 17 00:00:00 2001 From: Morgan McMillian Date: Thu, 10 Nov 2016 17:57:31 -0800 Subject: [PATCH 1/9] fix reply-all from thread view, closes issue #5 --- assets/ThreadPage.qml | 7 +++++++ bar-descriptor.xml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/assets/ThreadPage.qml b/assets/ThreadPage.qml index c2e36ce..30b8ef4 100644 --- a/assets/ThreadPage.qml +++ b/assets/ThreadPage.qml @@ -57,6 +57,13 @@ Page { page.unmute.connect(unmute) nav.push(page); } + function ccOnReply() { + if (_app.setting("cc") === "true") { + return true + } else { + return false + } + } } } diff --git a/bar-descriptor.xml b/bar-descriptor.xml index 8ae55de..6a210ca 100644 --- a/bar-descriptor.xml +++ b/bar-descriptor.xml @@ -55,7 +55,7 @@ - 0.5.0 + 0.5.1 From 40878e1059fa947c91fe2ef7a58d6e99ea56496b Mon Sep 17 00:00:00 2001 From: Morgan McMillian Date: Fri, 11 Nov 2016 09:51:17 -0800 Subject: [PATCH 2/9] initial post stream added to profile view (issue #8) --- assets/ProfilePage.qml | 42 +++++++++++++++++++++++++++++++++++++++++- assets/StreamTab.qml | 2 ++ src/Pnut.cpp | 15 ++++++++++++++- src/Pnut.h | 2 ++ translations/Goober.ts | 20 ++++++++++---------- 5 files changed, 69 insertions(+), 12 deletions(-) diff --git a/assets/ProfilePage.qml b/assets/ProfilePage.qml index 4894f57..1513122 100644 --- a/assets/ProfilePage.qml +++ b/assets/ProfilePage.qml @@ -170,8 +170,48 @@ Page { } } - + Divider {} + ListView { + id: threadView + dataModel: ArrayDataModel { + id: threadModel + } + listItemComponents: [ + ListItemComponent { + id: root + PostItem {} + } + ] + function sendReply(text, pid) { + pnut.sendReply(text, pid); + } + function getUserName() { + return _app.setting("username") + } + function viewProfile(userobj) { + var page = profilePage.createObject(); + page.user = userobj + page.follow.connect(follow) + page.unfollow.connect(unfollow) + page.block.connect(block) + page.unblock.connect(unblock) + page.mute.connect(mute) + page.unmute.connect(unmute) + nav.push(page); + } + function ccOnReply() { + if (_app.setting("cc") === "true") { + return true + } else { + return false + } + } } + } + } + + function loadThread(data) { + threadModel.append(data); } actions: [ diff --git a/assets/StreamTab.qml b/assets/StreamTab.qml index 82a8d29..16c2798 100644 --- a/assets/StreamTab.qml +++ b/assets/StreamTab.qml @@ -74,6 +74,8 @@ NavigationPane { function viewProfile(userobj) { var page = profilePage.createObject(); page.user = userobj + pnut.userStreamReceived.connect(page.loadThread) + pnut.getUserStream(userobj.id) page.follow.connect(pnut.followUser) page.unfollow.connect(pnut.unfollowUser) page.block.connect(pnut.blockUser) diff --git a/src/Pnut.cpp b/src/Pnut.cpp index 7e8b4a0..047d4f9 100644 --- a/src/Pnut.cpp +++ b/src/Pnut.cpp @@ -192,7 +192,7 @@ void Pnut::onAuthorizedRequestReady(QByteArray data, int id) qDebug() << "- onAuthorizedRequestReady"; qDebug() << "- id: " << id; qDebug() << "- endpoint: " << endpoint; -// qDebug() << data; + qDebug() << data; QVariant variant; bb::data::JsonDataAccess jda; @@ -223,6 +223,11 @@ void Pnut::onAuthorizedRequestReady(QByteArray data, int id) emit threadReceived(variant.toMap()["data"].toList()); req_map.remove(id); } + else if (endpoint == ":userstream") + { + emit userStreamReceived(variant.toMap()["data"].toList()); + req_map.remove(id); + } else if (endpoint == ":logout") { qDebug() << "Logout successful!"; @@ -485,3 +490,11 @@ void Pnut::getPost(QString pid) req_map[++req_id] = ":getpost:" + pid; getRequest(url, parameters, req_id); } + +void Pnut::getUserStream(QString uid) +{ + QUrl url(PNUT_API_ROOT + "/users/" + uid + "/posts"); + KQOAuthParameters parameters; + req_map[++req_id] = ":userstream"; + getRequest(url, parameters, req_id); +} diff --git a/src/Pnut.h b/src/Pnut.h index 3176981..12cbe1e 100644 --- a/src/Pnut.h +++ b/src/Pnut.h @@ -85,6 +85,7 @@ public: Q_INVOKABLE void logout(); Q_INVOKABLE void deletePost(QString pid); Q_INVOKABLE void getPost(QString pid); + Q_INVOKABLE void getUserStream(QString uid); public slots: void onRequestReady(QByteArray data); @@ -103,6 +104,7 @@ Q_SIGNALS: void muteSuccess(QVariantMap user); void unmuteSuccess(QVariantMap user); void postReceived(QVariantMap post); + void userStreamReceived(QVariantList stream); private: static const QString PNUT_API_ROOT; diff --git a/translations/Goober.ts b/translations/Goober.ts index aca0054..cf1ff4e 100644 --- a/translations/Goober.ts +++ b/translations/Goober.ts @@ -103,32 +103,32 @@ - + Unfollow - + Follow - + Unmute - + Mute - + Unblock - + Block @@ -172,22 +172,22 @@ StreamTab - + New Post - + To Top - + To Bottom - + Reload From eee1fe6eda29f72a19911f880909f01d163c9572 Mon Sep 17 00:00:00 2001 From: Morgan McMillian Date: Fri, 11 Nov 2016 09:52:45 -0800 Subject: [PATCH 3/9] fix code formatting --- assets/ProfilePage.qml | 112 +++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 54 deletions(-) diff --git a/assets/ProfilePage.qml b/assets/ProfilePage.qml index 1513122..29b6383 100644 --- a/assets/ProfilePage.qml +++ b/assets/ProfilePage.qml @@ -1,18 +1,18 @@ /* * Copyright (C) 2016 Morgan McMillian - * + * * This file is apart of the Goober application, a client for pnut.io - * + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -21,22 +21,23 @@ import bb.cascades 1.4 import org.labsquare 1.0 Page { - + property variant user - property variant theme : Application.themeSupport.theme.colorTheme.style + property variant theme: Application.themeSupport.theme.colorTheme.style property string lorem: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non enim tellus. Donec vestibulum enim urna, eget faucibus diam commodo a. Donec eget hendrerit metus. Pellentesque vehicula nisi nec vehicula ullamcorper. Aliquam a elit eget mi fringilla porta fermentum eget eros. Phasellus vestibulum nulla sed elit congue adipiscing. Cras imperdiet urna ac ipsum volutpat lobortis. Maecenas vehicula tortor at viverra convallis. Curabitur nibh massa, tristique id felis ut, venenatis faucibus dui. Donec fringilla, mi nec tincidunt dignissim, neque nunc semper mi, quis rutrum diam turpis sit amet erat. Cras a sodales nisi. Nunc sit amet diam sed lectus molestie cursus convallis et erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis vitae varius leo. Mauris eu leo a nunc bibendum rutrum euismod et ipsum. " - + signal follow(string uid) signal unfollow(string uid) signal block(string uid) signal unblock(string uid) signal mute(string uid) signal unmute(string uid) - + ScrollView { Container { Container { - layout: DockLayout {} + layout: DockLayout { + } horizontalAlignment: HorizontalAlignment.Fill preferredHeight: cover.height Container { @@ -79,7 +80,7 @@ Page { text: user.name textStyle.fontWeight: FontWeight.Bold textStyle.fontSize: FontSize.Large - + } } Container { @@ -87,20 +88,21 @@ Page { //text: "thrrgilag" text: user.username textStyle.fontSize: FontSize.Medium - + } - + } } - + } - + } Container { topPadding: ui.sdu(3) leftPadding: ui.sdu(3) rightPadding: ui.sdu(3) - layout: DockLayout {} + layout: DockLayout { + } horizontalAlignment: HorizontalAlignment.Fill Container { preferredWidth: ui.du(45) @@ -122,7 +124,7 @@ Page { horizontalAlignment: HorizontalAlignment.Right Label { text: qsTr("Following") - + } Label { text: user.counts.following @@ -135,7 +137,7 @@ Page { horizontalAlignment: HorizontalAlignment.Right Label { text: qsTr("Followers") - + } Label { text: user.counts.followers @@ -148,7 +150,7 @@ Page { horizontalAlignment: HorizontalAlignment.Right Label { text: qsTr("Posts") - + } Label { text: user.counts.posts @@ -161,55 +163,57 @@ Page { horizontalAlignment: HorizontalAlignment.Right Label { text: qsTr("Bookmarks") - + } Label { text: user.counts.bookmarks } } } - + } - Divider {} - ListView { - id: threadView - dataModel: ArrayDataModel { - id: threadModel + Divider { } - listItemComponents: [ - ListItemComponent { - id: root - PostItem {} + ListView { + id: threadView + dataModel: ArrayDataModel { + id: threadModel } - ] - function sendReply(text, pid) { - pnut.sendReply(text, pid); - } - function getUserName() { - return _app.setting("username") - } - function viewProfile(userobj) { - var page = profilePage.createObject(); - page.user = userobj - page.follow.connect(follow) - page.unfollow.connect(unfollow) - page.block.connect(block) - page.unblock.connect(unblock) - page.mute.connect(mute) - page.unmute.connect(unmute) - nav.push(page); - } - function ccOnReply() { - if (_app.setting("cc") === "true") { - return true - } else { - return false + listItemComponents: [ + ListItemComponent { + id: root + PostItem { + } + } + ] + function sendReply(text, pid) { + pnut.sendReply(text, pid); + } + function getUserName() { + return _app.setting("username") + } + function viewProfile(userobj) { + var page = profilePage.createObject(); + page.user = userobj + page.follow.connect(follow) + page.unfollow.connect(unfollow) + page.block.connect(block) + page.unblock.connect(unblock) + page.mute.connect(mute) + page.unmute.connect(unmute) + nav.push(page); + } + function ccOnReply() { + if (_app.setting("cc") === "true") { + return true + } else { + return false + } } } } - } } - + function loadThread(data) { threadModel.append(data); } From 7fcfaac2bce470cf331ebe89d760d0e22964e063 Mon Sep 17 00:00:00 2001 From: Morgan McMillian Date: Fri, 11 Nov 2016 16:10:08 -0800 Subject: [PATCH 4/9] add segmented control --- assets/PostItem.qml | 18 +++++++++------ assets/ProfilePage.qml | 30 ++++++++++++++++++++++++- assets/StreamTab.qml | 1 + translations/Goober.ts | 51 ++++++++++++++++++++++-------------------- 4 files changed, 68 insertions(+), 32 deletions(-) diff --git a/assets/PostItem.qml b/assets/PostItem.qml index 1440892..a2fb289 100644 --- a/assets/PostItem.qml +++ b/assets/PostItem.qml @@ -64,13 +64,14 @@ Container { Container { Label { id: username - text: "" + ListItemData.user.username + "" - activeTextHandler: ActiveTextHandler { - onTriggered: { - postitem.ListItem.view.viewProfile(ListItemData.user) - } - } - textFormat: TextFormat.Html + text: ListItemData.user.username +// text: "" + ListItemData.user.username + "" +// activeTextHandler: ActiveTextHandler { +// onTriggered: { +// postitem.ListItem.view.viewProfile(ListItemData.user) +// } +// } +// textFormat: TextFormat.Html } } } @@ -266,4 +267,7 @@ Container { return "" } } + onCreationCompleted: { + console.log(" My Height is " + postitem.preferredHeight) + } } diff --git a/assets/ProfilePage.qml b/assets/ProfilePage.qml index 29b6383..5bdf87c 100644 --- a/assets/ProfilePage.qml +++ b/assets/ProfilePage.qml @@ -32,6 +32,7 @@ Page { signal unblock(string uid) signal mute(string uid) signal unmute(string uid) + signal getPosts(string uid) ScrollView { Container { @@ -172,10 +173,36 @@ Page { } } - Divider { + SegmentedControl { + Option { + id: opt_posts + text: qsTr("Posts") + } + Option { + id: opt_following + text: qsTr("Following") + } + Option { + id: opt_followers + text: qsTr("Followers") + } + onSelectedOptionChanged: { + if (selectedOption == opt_posts) { + threadModel.clear() + getPosts(user.id) + } else if (selectedOption == opt_following) { + threadModel.clear() + // do something + } else if (selectedOption == opt_followers) { + threadModel.clear() + // do something + } + } } ListView { id: threadView + //preferredHeight: threadModel.size() + //preferredHeight: ( height of content row + content padding ) * count of entires in ListView dataModel: ArrayDataModel { id: threadModel } @@ -183,6 +210,7 @@ Page { ListItemComponent { id: root PostItem { + id: postitem } } ] diff --git a/assets/StreamTab.qml b/assets/StreamTab.qml index 16c2798..fc5cae1 100644 --- a/assets/StreamTab.qml +++ b/assets/StreamTab.qml @@ -82,6 +82,7 @@ NavigationPane { page.unblock.connect(pnut.unblockUser) page.mute.connect(pnut.muteUser) page.unmute.connect(pnut.unmuteUser) + page.getPosts.connect(pnut.getUserStream) nav.push(page); } function sendReply(text, pid) { diff --git a/translations/Goober.ts b/translations/Goober.ts index cf1ff4e..96866af 100644 --- a/translations/Goober.ts +++ b/translations/Goober.ts @@ -30,52 +30,52 @@ PostItem - + <i>{{POST DELETED}}</i> - + Reply - + Reply All - + Add Bookmark - + Delete Bookmark - + Repost - + Delete Repost - + Quote - + View Profile - + Delete @@ -83,52 +83,55 @@ ProfilePage - + + Following - + + Followers - + + Posts - + Bookmarks - + Unfollow - + Follow - + Unmute - + Mute - + Unblock - + Block @@ -172,22 +175,22 @@ StreamTab - + New Post - + To Top - + To Bottom - + Reload From af24b6ae69e2f475114d53fb0a1f4bb2f9504ee6 Mon Sep 17 00:00:00 2001 From: Morgan McMillian Date: Sat, 12 Nov 2016 06:22:29 -0800 Subject: [PATCH 5/9] replaced segmented control with buttons to launch seperate page views --- assets/PostItem.qml | 3 - assets/ProfilePage.qml | 170 ++++++++++++++++++++++++++--------------- assets/StreamTab.qml | 6 +- translations/Goober.ts | 18 ++--- 4 files changed, 121 insertions(+), 76 deletions(-) diff --git a/assets/PostItem.qml b/assets/PostItem.qml index a2fb289..0cc6deb 100644 --- a/assets/PostItem.qml +++ b/assets/PostItem.qml @@ -267,7 +267,4 @@ Container { return "" } } - onCreationCompleted: { - console.log(" My Height is " + postitem.preferredHeight) - } } diff --git a/assets/ProfilePage.qml b/assets/ProfilePage.qml index 5bdf87c..b44e8e6 100644 --- a/assets/ProfilePage.qml +++ b/assets/ProfilePage.qml @@ -173,78 +173,119 @@ Page { } } - SegmentedControl { - Option { - id: opt_posts - text: qsTr("Posts") - } - Option { - id: opt_following - text: qsTr("Following") - } - Option { - id: opt_followers - text: qsTr("Followers") - } - onSelectedOptionChanged: { - if (selectedOption == opt_posts) { - threadModel.clear() - getPosts(user.id) - } else if (selectedOption == opt_following) { - threadModel.clear() - // do something - } else if (selectedOption == opt_followers) { - threadModel.clear() - // do something - } - } + Divider { + } - ListView { - id: threadView - //preferredHeight: threadModel.size() - //preferredHeight: ( height of content row + content padding ) * count of entires in ListView - dataModel: ArrayDataModel { - id: threadModel + Container { + layout: StackLayout { + orientation: LayoutOrientation.LeftToRight } - listItemComponents: [ - ListItemComponent { - id: root - PostItem { - id: postitem + Container { + leftPadding: ui.sdu(1) + rightPadding: ui.sdu(.5) + Button { + text: qsTr("Posts") + onClicked: { + var page = postPage.createObject() + pnut.userStreamReceived.connect(page.loadThread); + pnut.getUserStream(user.id) + //page.follow.connect(pnut.followUser) + //page.unfollow.connect(pnut.unfollowUser) + //page.block.connect(pnut.blockUser) + //page.unblock.connect(pnut.unblockUser) + //page.mute.connect(pnut.muteUser) + //page.unmute.connect(pnut.unmuteUser) + nav.push(page); } } - ] - function sendReply(text, pid) { - pnut.sendReply(text, pid); } - function getUserName() { - return _app.setting("username") - } - function viewProfile(userobj) { - var page = profilePage.createObject(); - page.user = userobj - page.follow.connect(follow) - page.unfollow.connect(unfollow) - page.block.connect(block) - page.unblock.connect(unblock) - page.mute.connect(mute) - page.unmute.connect(unmute) - nav.push(page); - } - function ccOnReply() { - if (_app.setting("cc") === "true") { - return true - } else { - return false + Container { + leftPadding: ui.sdu(.5) + rightPadding: ui.sdu(.5) + Button { + text: qsTr("Following") } } + Container { + leftPadding: ui.sdu(.5) + rightPadding: ui.sdu(1) + Button { + text: qsTr("Followers") + } + } } +// SegmentedControl { +// Option { +// id: opt_posts +// text: qsTr("Posts") +// } +// Option { +// id: opt_following +// text: qsTr("Following") +// } +// Option { +// id: opt_followers +// text: qsTr("Followers") +// } +// onSelectedOptionChanged: { +// if (selectedOption == opt_posts) { +// threadModel.clear() +// getPosts(user.id) +// } else if (selectedOption == opt_following) { +// threadModel.clear() +// // do something +// } else if (selectedOption == opt_followers) { +// threadModel.clear() +// // do something +// } +// } +// } +// ListView { +// id: threadView +// //preferredHeight: threadModel.size() +// //preferredHeight: ( height of content row + content padding ) * count of entires in ListView +// dataModel: ArrayDataModel { +// id: threadModel +// } +// listItemComponents: [ +// ListItemComponent { +// id: root +// PostItem { +// id: postitem +// } +// } +// ] +// function sendReply(text, pid) { +// pnut.sendReply(text, pid); +// } +// function getUserName() { +// return _app.setting("username") +// } +// function viewProfile(userobj) { +// var page = profilePage.createObject(); +// page.user = userobj +// page.follow.connect(follow) +// page.unfollow.connect(unfollow) +// page.block.connect(block) +// page.unblock.connect(unblock) +// page.mute.connect(mute) +// page.unmute.connect(unmute) +// nav.push(page); +// } +// function ccOnReply() { +// if (_app.setting("cc") === "true") { +// return true +// } else { +// return false +// } +// } +// } } } - function loadThread(data) { - threadModel.append(data); - } +// function loadThread(data) { +// threadModel.append(data); +// } actions: [ ActionItem { @@ -287,4 +328,11 @@ Page { enabled: (_app.setting("username") === user.username) ? false : true } ] + + attachedObjects: [ + ComponentDefinition { + id: postPage + source: "ThreadPage.qml" + } + ] } diff --git a/assets/StreamTab.qml b/assets/StreamTab.qml index fc5cae1..50a9fdc 100644 --- a/assets/StreamTab.qml +++ b/assets/StreamTab.qml @@ -74,15 +74,15 @@ NavigationPane { function viewProfile(userobj) { var page = profilePage.createObject(); page.user = userobj - pnut.userStreamReceived.connect(page.loadThread) - pnut.getUserStream(userobj.id) + //pnut.userStreamReceived.connect(page.loadThread) + //pnut.getUserStream(userobj.id) page.follow.connect(pnut.followUser) page.unfollow.connect(pnut.unfollowUser) page.block.connect(pnut.blockUser) page.unblock.connect(pnut.unblockUser) page.mute.connect(pnut.muteUser) page.unmute.connect(pnut.unmuteUser) - page.getPosts.connect(pnut.getUserStream) + //page.getPosts.connect(pnut.getUserStream) nav.push(page); } function sendReply(text, pid) { diff --git a/translations/Goober.ts b/translations/Goober.ts index 96866af..0842944 100644 --- a/translations/Goober.ts +++ b/translations/Goober.ts @@ -84,19 +84,19 @@ ProfilePage - + Following - + Followers - + Posts @@ -106,32 +106,32 @@ - + Unfollow - + Follow - + Unmute - + Mute - + Unblock - + Block From c581ff985f98c0575a1dde2326fb383a3163c397 Mon Sep 17 00:00:00 2001 From: Morgan McMillian Date: Sat, 12 Nov 2016 07:57:24 -0800 Subject: [PATCH 6/9] added following and followers lists, addresses issue #8 --- assets/.assets.index | 4 ++- assets/ProfilePage.qml | 32 ++++++++++++----- assets/UserItem.qml | 66 +++++++++++++++++++++++++++++++++++ assets/UserPage.qml | 79 ++++++++++++++++++++++++++++++++++++++++++ config.pri | 2 ++ src/Pnut.cpp | 21 +++++++++++ src/Pnut.h | 3 ++ translations/Goober.ts | 29 +++++++++++----- 8 files changed, 218 insertions(+), 18 deletions(-) create mode 100644 assets/UserItem.qml create mode 100644 assets/UserPage.qml diff --git a/assets/.assets.index b/assets/.assets.index index 3495f3d..4a5571a 100644 --- a/assets/.assets.index +++ b/assets/.assets.index @@ -1,5 +1,5 @@ 1 -43 +45 AboutPage.qml AppCover.qml icons/at.png @@ -43,3 +43,5 @@ RefreshItem.qml SettingsPage.qml StreamTab.qml ThreadPage.qml +UserItem.qml +UserPage.qml diff --git a/assets/ProfilePage.qml b/assets/ProfilePage.qml index b44e8e6..6a631a3 100644 --- a/assets/ProfilePage.qml +++ b/assets/ProfilePage.qml @@ -187,15 +187,9 @@ Page { text: qsTr("Posts") onClicked: { var page = postPage.createObject() - pnut.userStreamReceived.connect(page.loadThread); + pnut.userStreamReceived.connect(page.loadThread) pnut.getUserStream(user.id) - //page.follow.connect(pnut.followUser) - //page.unfollow.connect(pnut.unfollowUser) - //page.block.connect(pnut.blockUser) - //page.unblock.connect(pnut.unblockUser) - //page.mute.connect(pnut.muteUser) - //page.unmute.connect(pnut.unmuteUser) - nav.push(page); + nav.push(page) } } } @@ -204,6 +198,14 @@ Page { rightPadding: ui.sdu(.5) Button { text: qsTr("Following") + onClicked: { + var page = userListPage.createObject() +// page.follow.connect(pnut.followUser) +// page.unfollow.connect(pnut.unfollowUser) + pnut.userListReceived.connect(page.loadThread) + pnut.getFollowing(user.id) + nav.push(page) + } } } Container { @@ -211,7 +213,15 @@ Page { rightPadding: ui.sdu(1) Button { text: qsTr("Followers") - } + onClicked: { + var page = userListPage.createObject() +// page.follow.connect(pnut.followUser) +// page.unfollow.connect(pnut.unfollowUser) + pnut.userListReceived.connect(page.loadThread) + pnut.getFollowers(user.id) + nav.push(page) + } + } } } // SegmentedControl { @@ -333,6 +343,10 @@ Page { ComponentDefinition { id: postPage source: "ThreadPage.qml" + }, + ComponentDefinition { + id: userListPage + source: "UserPage.qml" } ] } diff --git a/assets/UserItem.qml b/assets/UserItem.qml new file mode 100644 index 0000000..92386dd --- /dev/null +++ b/assets/UserItem.qml @@ -0,0 +1,66 @@ +import bb.cascades 1.4 +import org.labsquare 1.0 + +Container { + id: useritem + + property variant theme : Application.themeSupport.theme.colorTheme.style + property string lorem: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non enim tellus. Donec vestibulum enim urna, eget faucibus diam commodo a. Donec eget hendrerit metus. Pellentesque vehicula nisi nec vehicula ullamcorper. Aliquam a elit eget mi fringilla porta fermentum eget eros. Phasellus vestibulum nulla sed elit congue adipiscing. Cras imperdiet urna ac ipsum volutpat lobortis. Maecenas vehicula tortor at viverra convallis. Curabitur nibh massa, tristique id felis ut, venenatis faucibus dui. Donec fringilla, mi nec tincidunt dignissim, neque nunc semper mi, quis rutrum diam turpis sit amet erat. Cras a sodales nisi. Nunc sit amet diam sed lectus molestie cursus convallis et erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis vitae varius leo. Mauris eu leo a nunc bibendum rutrum euismod et ipsum. " + + leftPadding: ui.sdu(3.0) + rightPadding: ui.sdu(3.0) + topPadding: ui.sdu(2.0) + Container { + layout: DockLayout { + } + Container { + layout: StackLayout { + orientation: LayoutOrientation.LeftToRight + } + Container { + minWidth: ui.du(12) + background: (theme === VisualStyle.Bright) ? Color.create("#e9e9e9") : Color.create("#282828") + WebImageView { + id: avatar + url: ListItemData.content.avatar_image.link + maxWidth: ui.du(12) + maxHeight: ui.du(12) + //imageSource: "asset:///icons/laughing_man.png" + } + } + Container { + preferredWidth: 1440 + leftMargin: ui.sdu(3.0) + Container { + Label { + id: username + text: ListItemData.username + textStyle.fontWeight: FontWeight.Bold + } + } + Container { + Label { + id: description + text: ListItemData.content.html + multiline: true + textFormat: TextFormat.Html + } + } + } + Container { + minWidth: ui.du(24) + verticalAlignment: VerticalAlignment.Center + Button { + text: (ListItemData.you_follow) ? qsTr("Unfollow") : qsTr("Follow") + onClicked: { + if (ListItemData.you_follow) { + useritem.ListItem.view.unfollow(ListItemData.id) + } else { + useritem.ListItem.view.follow(ListItemData.id) + } + } + } + } + } + } +} diff --git a/assets/UserPage.qml b/assets/UserPage.qml new file mode 100644 index 0000000..709ee4f --- /dev/null +++ b/assets/UserPage.qml @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2016 Morgan McMillian + * + * This file is apart of the Goober application, a client for pnut.io + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import bb.cascades 1.4 + +Page { + + signal follow(string uid) + signal unfollow(string uid) + signal block(string uid) + signal unblock(string uid) + signal mute(string uid) + signal unmute(string uid) + + Container { + ListView { + id: userListView + dataModel: ArrayDataModel { + id: listModel + } + listItemComponents: [ + ListItemComponent { + id: root + UserItem {} + } + ] + function follow(uid) { + pnut.followUser(uid) + } + function unfollow(uid) { + pnut.unfollowUser(uid) + } +// function sendReply(text, pid) { +// pnut.sendReply(text, pid); +// } +// function getUserName() { +// return _app.setting("username") +// } +// function viewProfile(userobj) { +// var page = profilePage.createObject(); +// page.user = userobj +// page.follow.connect(follow) +// page.unfollow.connect(unfollow) +// page.block.connect(block) +// page.unblock.connect(unblock) +// page.mute.connect(mute) +// page.unmute.connect(unmute) +// nav.push(page); +// } +// function ccOnReply() { +// if (_app.setting("cc") === "true") { +// return true +// } else { +// return false +// } +// } + } + } + + function loadThread(data) { + listModel.append(data); + } +} diff --git a/config.pri b/config.pri index 5f84b1b..f94503d 100644 --- a/config.pri +++ b/config.pri @@ -76,6 +76,8 @@ config_pri_assets { $$quote($$BASEDIR/assets/SettingsPage.qml) \ $$quote($$BASEDIR/assets/StreamTab.qml) \ $$quote($$BASEDIR/assets/ThreadPage.qml) \ + $$quote($$BASEDIR/assets/UserItem.qml) \ + $$quote($$BASEDIR/assets/UserPage.qml) \ $$quote($$BASEDIR/assets/icons/at.png) \ $$quote($$BASEDIR/assets/icons/bell-slash.png) \ $$quote($$BASEDIR/assets/icons/bell.png) \ diff --git a/src/Pnut.cpp b/src/Pnut.cpp index 047d4f9..7ad1cfc 100644 --- a/src/Pnut.cpp +++ b/src/Pnut.cpp @@ -228,6 +228,11 @@ void Pnut::onAuthorizedRequestReady(QByteArray data, int id) emit userStreamReceived(variant.toMap()["data"].toList()); req_map.remove(id); } + else if (endpoint == ":followers" || endpoint == ":following") + { + emit userListReceived(variant.toMap()["data"].toList()); + req_map.remove(id); + } else if (endpoint == ":logout") { qDebug() << "Logout successful!"; @@ -498,3 +503,19 @@ void Pnut::getUserStream(QString uid) req_map[++req_id] = ":userstream"; getRequest(url, parameters, req_id); } + +void Pnut::getFollowers(QString uid) +{ + QUrl url(PNUT_API_ROOT + "/users/" + uid + "/followers"); + KQOAuthParameters parameters; + req_map[++req_id] = ":followers"; + getRequest(url, parameters, req_id); +} + +void Pnut::getFollowing(QString uid) +{ + QUrl url(PNUT_API_ROOT + "/users/" + uid + "/following"); + KQOAuthParameters parameters; + req_map[++req_id] = ":following"; + getRequest(url, parameters, req_id); +} diff --git a/src/Pnut.h b/src/Pnut.h index 12cbe1e..4c1db5f 100644 --- a/src/Pnut.h +++ b/src/Pnut.h @@ -86,6 +86,8 @@ public: Q_INVOKABLE void deletePost(QString pid); Q_INVOKABLE void getPost(QString pid); Q_INVOKABLE void getUserStream(QString uid); + Q_INVOKABLE void getFollowers(QString uid); + Q_INVOKABLE void getFollowing(QString uid); public slots: void onRequestReady(QByteArray data); @@ -105,6 +107,7 @@ Q_SIGNALS: void unmuteSuccess(QVariantMap user); void postReceived(QVariantMap post); void userStreamReceived(QVariantList stream); + void userListReceived(QVariantList users); private: static const QString PNUT_API_ROOT; diff --git a/translations/Goober.ts b/translations/Goober.ts index 0842944..dca5d81 100644 --- a/translations/Goober.ts +++ b/translations/Goober.ts @@ -84,13 +84,13 @@ ProfilePage - + Following - + Followers @@ -106,32 +106,32 @@ - + Unfollow - + Follow - + Unmute - + Mute - + Unblock - + Block @@ -195,6 +195,19 @@ + + UserItem + + + Unfollow + + + + + Follow + + + main From 358f0adddc4553c95d02e5cbd50e5a430134a41e Mon Sep 17 00:00:00 2001 From: Morgan McMillian Date: Sat, 12 Nov 2016 08:55:16 -0800 Subject: [PATCH 7/9] attached follow/unfollow signals and cleaned up commented out code --- assets/ProfilePage.qml | 78 +++--------------------------------------- assets/UserItem.qml | 4 +-- assets/UserPage.qml | 48 ++++++++------------------ translations/Goober.ts | 12 +++---- 4 files changed, 26 insertions(+), 116 deletions(-) diff --git a/assets/ProfilePage.qml b/assets/ProfilePage.qml index 6a631a3..55466d2 100644 --- a/assets/ProfilePage.qml +++ b/assets/ProfilePage.qml @@ -200,8 +200,8 @@ Page { text: qsTr("Following") onClicked: { var page = userListPage.createObject() -// page.follow.connect(pnut.followUser) -// page.unfollow.connect(pnut.unfollowUser) + pnut.followSuccess.connect(page.updateUser) + pnut.unfollowSuccess.connect(page.updateUser) pnut.userListReceived.connect(page.loadThread) pnut.getFollowing(user.id) nav.push(page) @@ -215,8 +215,8 @@ Page { text: qsTr("Followers") onClicked: { var page = userListPage.createObject() -// page.follow.connect(pnut.followUser) -// page.unfollow.connect(pnut.unfollowUser) + pnut.followSuccess.connect(page.updateUser) + pnut.unfollowSuccess.connect(page.updateUser) pnut.userListReceived.connect(page.loadThread) pnut.getFollowers(user.id) nav.push(page) @@ -224,79 +224,9 @@ Page { } } } -// SegmentedControl { -// Option { -// id: opt_posts -// text: qsTr("Posts") -// } -// Option { -// id: opt_following -// text: qsTr("Following") -// } -// Option { -// id: opt_followers -// text: qsTr("Followers") -// } -// onSelectedOptionChanged: { -// if (selectedOption == opt_posts) { -// threadModel.clear() -// getPosts(user.id) -// } else if (selectedOption == opt_following) { -// threadModel.clear() -// // do something -// } else if (selectedOption == opt_followers) { -// threadModel.clear() -// // do something -// } -// } -// } -// ListView { -// id: threadView -// //preferredHeight: threadModel.size() -// //preferredHeight: ( height of content row + content padding ) * count of entires in ListView -// dataModel: ArrayDataModel { -// id: threadModel -// } -// listItemComponents: [ -// ListItemComponent { -// id: root -// PostItem { -// id: postitem -// } -// } -// ] -// function sendReply(text, pid) { -// pnut.sendReply(text, pid); -// } -// function getUserName() { -// return _app.setting("username") -// } -// function viewProfile(userobj) { -// var page = profilePage.createObject(); -// page.user = userobj -// page.follow.connect(follow) -// page.unfollow.connect(unfollow) -// page.block.connect(block) -// page.unblock.connect(unblock) -// page.mute.connect(mute) -// page.unmute.connect(unmute) -// nav.push(page); -// } -// function ccOnReply() { -// if (_app.setting("cc") === "true") { -// return true -// } else { -// return false -// } -// } -// } } } -// function loadThread(data) { -// threadModel.append(data); -// } - actions: [ ActionItem { title: (user.you_follow) ? qsTr("Unfollow") : qsTr("Follow") diff --git a/assets/UserItem.qml b/assets/UserItem.qml index 92386dd..f6a8150 100644 --- a/assets/UserItem.qml +++ b/assets/UserItem.qml @@ -54,9 +54,9 @@ Container { text: (ListItemData.you_follow) ? qsTr("Unfollow") : qsTr("Follow") onClicked: { if (ListItemData.you_follow) { - useritem.ListItem.view.unfollow(ListItemData.id) + useritem.ListItem.view.unfollow(ListItemData) } else { - useritem.ListItem.view.follow(ListItemData.id) + useritem.ListItem.view.follow(ListItemData) } } } diff --git a/assets/UserPage.qml b/assets/UserPage.qml index 709ee4f..b7687f7 100644 --- a/assets/UserPage.qml +++ b/assets/UserPage.qml @@ -21,12 +21,7 @@ import bb.cascades 1.4 Page { - signal follow(string uid) - signal unfollow(string uid) - signal block(string uid) - signal unblock(string uid) - signal mute(string uid) - signal unmute(string uid) + property variant updateUserObj Container { ListView { @@ -40,40 +35,25 @@ Page { UserItem {} } ] - function follow(uid) { - pnut.followUser(uid) + function follow(usero) { + console.log("---> follow") + updateUserObj = usero + pnut.followUser(usero.id) } - function unfollow(uid) { - pnut.unfollowUser(uid) + function unfollow(usero) { + console.log("---> unfollow") + updateUserObj = usero + pnut.unfollowUser(usero.id) } -// function sendReply(text, pid) { -// pnut.sendReply(text, pid); -// } -// function getUserName() { -// return _app.setting("username") -// } -// function viewProfile(userobj) { -// var page = profilePage.createObject(); -// page.user = userobj -// page.follow.connect(follow) -// page.unfollow.connect(unfollow) -// page.block.connect(block) -// page.unblock.connect(unblock) -// page.mute.connect(mute) -// page.unmute.connect(unmute) -// nav.push(page); -// } -// function ccOnReply() { -// if (_app.setting("cc") === "true") { -// return true -// } else { -// return false -// } -// } } } function loadThread(data) { listModel.append(data); } + + function updateUser(userobj) { + console.log("---> updating entry " + listModel.indexOf(updateUserObj)) + listModel.replace(listModel.indexOf(updateUserObj), userobj) + } } diff --git a/translations/Goober.ts b/translations/Goober.ts index dca5d81..6baa771 100644 --- a/translations/Goober.ts +++ b/translations/Goober.ts @@ -106,32 +106,32 @@ - + Unfollow - + Follow - + Unmute - + Mute - + Unblock - + Block From b47acf21382b0d04c5dd72adcf2d894b973ac389 Mon Sep 17 00:00:00 2001 From: Morgan McMillian Date: Sat, 12 Nov 2016 15:49:32 -0800 Subject: [PATCH 8/9] add theme support (dark mode) issue #6 --- assets/SettingsPage.qml | 23 +++++++++++++++++++++++ assets/main.qml | 9 +++++++++ translations/Goober.ts | 15 +++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/assets/SettingsPage.qml b/assets/SettingsPage.qml index 4d677ed..67b85c1 100644 --- a/assets/SettingsPage.qml +++ b/assets/SettingsPage.qml @@ -110,6 +110,29 @@ Page { } } Divider {} + Container { + leftPadding: ui.sdu(3) + rightPadding: ui.sdu(3) + DropDown { + title: qsTr("Theme") + Option { + text: qsTr("Bright") + value: VisualStyle.Bright + selected: Application.themeSupport.theme.colorTheme.style == VisualStyle.Bright + } + Option { + text: qsTr("Dark") + value: VisualStyle.Dark + selected: Application.themeSupport.theme.colorTheme.style == VisualStyle.Dark + } + onSelectedOptionChanged: { + _app.setSetting("theme", selectedValue) + Application.themeSupport.setVisualStyle(selectedValue) + } + } + + } + Divider {} // Container { // layout: DockLayout {} // horizontalAlignment: HorizontalAlignment.Fill diff --git a/assets/main.qml b/assets/main.qml index 77d37d3..1138ac3 100644 --- a/assets/main.qml +++ b/assets/main.qml @@ -172,4 +172,13 @@ TabbedPane { } ] + onCreationCompleted: { + var style = _app.setting("theme").toString() + if (style === "1") { + Application.themeSupport.setVisualStyle(VisualStyle.Bright) + } else if (style === "2") { + Application.themeSupport.setVisualStyle(VisualStyle.Dark) + } + } + } diff --git a/translations/Goober.ts b/translations/Goober.ts index 6baa771..db39926 100644 --- a/translations/Goober.ts +++ b/translations/Goober.ts @@ -171,6 +171,21 @@ Additional mentions follow / + + + Theme + + + + + Bright + + + + + Dark + + StreamTab From 42f015c72ca4abb7b71a1e14c5585cc766d70bdb Mon Sep 17 00:00:00 2001 From: Morgan McMillian Date: Sat, 12 Nov 2016 16:52:41 -0800 Subject: [PATCH 9/9] added a divider to the user item --- assets/UserItem.qml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/UserItem.qml b/assets/UserItem.qml index f6a8150..380bdeb 100644 --- a/assets/UserItem.qml +++ b/assets/UserItem.qml @@ -63,4 +63,7 @@ Container { } } } + Divider { + + } }