Merge branch 'development'

This commit is contained in:
Morgan McMillian 2016-11-12 17:14:04 -08:00
commit 480ffeb725
12 changed files with 356 additions and 54 deletions

View file

@ -1,5 +1,5 @@
1 1
43 45
AboutPage.qml AboutPage.qml
AppCover.qml AppCover.qml
icons/at.png icons/at.png
@ -43,3 +43,5 @@ RefreshItem.qml
SettingsPage.qml SettingsPage.qml
StreamTab.qml StreamTab.qml
ThreadPage.qml ThreadPage.qml
UserItem.qml
UserPage.qml

View file

@ -64,13 +64,14 @@ Container {
Container { Container {
Label { Label {
id: username id: username
text: "<a href=\"#profile\">" + ListItemData.user.username + "</a>" text: ListItemData.user.username
activeTextHandler: ActiveTextHandler { // text: "<a href=\"#profile\">" + ListItemData.user.username + "</a>"
onTriggered: { // activeTextHandler: ActiveTextHandler {
postitem.ListItem.view.viewProfile(ListItemData.user) // onTriggered: {
} // postitem.ListItem.view.viewProfile(ListItemData.user)
} // }
textFormat: TextFormat.Html // }
// textFormat: TextFormat.Html
} }
} }
} }

View file

@ -23,7 +23,7 @@ import org.labsquare 1.0
Page { Page {
property variant user 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. " 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 follow(string uid)
@ -32,11 +32,13 @@ Page {
signal unblock(string uid) signal unblock(string uid)
signal mute(string uid) signal mute(string uid)
signal unmute(string uid) signal unmute(string uid)
signal getPosts(string uid)
ScrollView { ScrollView {
Container { Container {
Container { Container {
layout: DockLayout {} layout: DockLayout {
}
horizontalAlignment: HorizontalAlignment.Fill horizontalAlignment: HorizontalAlignment.Fill
preferredHeight: cover.height preferredHeight: cover.height
Container { Container {
@ -100,7 +102,8 @@ Page {
topPadding: ui.sdu(3) topPadding: ui.sdu(3)
leftPadding: ui.sdu(3) leftPadding: ui.sdu(3)
rightPadding: ui.sdu(3) rightPadding: ui.sdu(3)
layout: DockLayout {} layout: DockLayout {
}
horizontalAlignment: HorizontalAlignment.Fill horizontalAlignment: HorizontalAlignment.Fill
Container { Container {
preferredWidth: ui.du(45) preferredWidth: ui.du(45)
@ -170,8 +173,58 @@ Page {
} }
} }
Divider {
} }
Container {
layout: StackLayout {
orientation: LayoutOrientation.LeftToRight
}
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)
nav.push(page)
}
}
}
Container {
leftPadding: ui.sdu(.5)
rightPadding: ui.sdu(.5)
Button {
text: qsTr("Following")
onClicked: {
var page = userListPage.createObject()
pnut.followSuccess.connect(page.updateUser)
pnut.unfollowSuccess.connect(page.updateUser)
pnut.userListReceived.connect(page.loadThread)
pnut.getFollowing(user.id)
nav.push(page)
}
}
}
Container {
leftPadding: ui.sdu(.5)
rightPadding: ui.sdu(1)
Button {
text: qsTr("Followers")
onClicked: {
var page = userListPage.createObject()
pnut.followSuccess.connect(page.updateUser)
pnut.unfollowSuccess.connect(page.updateUser)
pnut.userListReceived.connect(page.loadThread)
pnut.getFollowers(user.id)
nav.push(page)
}
}
}
}
}
} }
actions: [ actions: [
@ -215,4 +268,15 @@ Page {
enabled: (_app.setting("username") === user.username) ? false : true enabled: (_app.setting("username") === user.username) ? false : true
} }
] ]
attachedObjects: [
ComponentDefinition {
id: postPage
source: "ThreadPage.qml"
},
ComponentDefinition {
id: userListPage
source: "UserPage.qml"
}
]
} }

View file

@ -110,6 +110,29 @@ Page {
} }
} }
Divider {} 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 { // Container {
// layout: DockLayout {} // layout: DockLayout {}
// horizontalAlignment: HorizontalAlignment.Fill // horizontalAlignment: HorizontalAlignment.Fill

View file

@ -74,12 +74,15 @@ NavigationPane {
function viewProfile(userobj) { function viewProfile(userobj) {
var page = profilePage.createObject(); var page = profilePage.createObject();
page.user = userobj page.user = userobj
//pnut.userStreamReceived.connect(page.loadThread)
//pnut.getUserStream(userobj.id)
page.follow.connect(pnut.followUser) page.follow.connect(pnut.followUser)
page.unfollow.connect(pnut.unfollowUser) page.unfollow.connect(pnut.unfollowUser)
page.block.connect(pnut.blockUser) page.block.connect(pnut.blockUser)
page.unblock.connect(pnut.unblockUser) page.unblock.connect(pnut.unblockUser)
page.mute.connect(pnut.muteUser) page.mute.connect(pnut.muteUser)
page.unmute.connect(pnut.unmuteUser) page.unmute.connect(pnut.unmuteUser)
//page.getPosts.connect(pnut.getUserStream)
nav.push(page); nav.push(page);
} }
function sendReply(text, pid) { function sendReply(text, pid) {

69
assets/UserItem.qml Normal file
View file

@ -0,0 +1,69 @@
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)
} else {
useritem.ListItem.view.follow(ListItemData)
}
}
}
}
}
}
Divider {
}
}

59
assets/UserPage.qml Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright (C) 2016 Morgan McMillian <gilag@monkeystew.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
import bb.cascades 1.4
Page {
property variant updateUserObj
Container {
ListView {
id: userListView
dataModel: ArrayDataModel {
id: listModel
}
listItemComponents: [
ListItemComponent {
id: root
UserItem {}
}
]
function follow(usero) {
console.log("---> follow")
updateUserObj = usero
pnut.followUser(usero.id)
}
function unfollow(usero) {
console.log("---> unfollow")
updateUserObj = usero
pnut.unfollowUser(usero.id)
}
}
}
function loadThread(data) {
listModel.append(data);
}
function updateUser(userobj) {
console.log("---> updating entry " + listModel.indexOf(updateUserObj))
listModel.replace(listModel.indexOf(updateUserObj), userobj)
}
}

View file

@ -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)
}
}
} }

View file

@ -76,6 +76,8 @@ config_pri_assets {
$$quote($$BASEDIR/assets/SettingsPage.qml) \ $$quote($$BASEDIR/assets/SettingsPage.qml) \
$$quote($$BASEDIR/assets/StreamTab.qml) \ $$quote($$BASEDIR/assets/StreamTab.qml) \
$$quote($$BASEDIR/assets/ThreadPage.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/at.png) \
$$quote($$BASEDIR/assets/icons/bell-slash.png) \ $$quote($$BASEDIR/assets/icons/bell-slash.png) \
$$quote($$BASEDIR/assets/icons/bell.png) \ $$quote($$BASEDIR/assets/icons/bell.png) \

View file

@ -192,7 +192,7 @@ void Pnut::onAuthorizedRequestReady(QByteArray data, int id)
qDebug() << "- onAuthorizedRequestReady"; qDebug() << "- onAuthorizedRequestReady";
qDebug() << "- id: " << id; qDebug() << "- id: " << id;
qDebug() << "- endpoint: " << endpoint; qDebug() << "- endpoint: " << endpoint;
// qDebug() << data; qDebug() << data;
QVariant variant; QVariant variant;
bb::data::JsonDataAccess jda; bb::data::JsonDataAccess jda;
@ -223,6 +223,16 @@ void Pnut::onAuthorizedRequestReady(QByteArray data, int id)
emit threadReceived(variant.toMap()["data"].toList()); emit threadReceived(variant.toMap()["data"].toList());
req_map.remove(id); req_map.remove(id);
} }
else if (endpoint == ":userstream")
{
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") else if (endpoint == ":logout")
{ {
qDebug() << "Logout successful!"; qDebug() << "Logout successful!";
@ -485,3 +495,27 @@ void Pnut::getPost(QString pid)
req_map[++req_id] = ":getpost:" + pid; req_map[++req_id] = ":getpost:" + pid;
getRequest(url, parameters, req_id); 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);
}
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);
}

View file

@ -85,6 +85,9 @@ public:
Q_INVOKABLE void logout(); Q_INVOKABLE void logout();
Q_INVOKABLE void deletePost(QString pid); Q_INVOKABLE void deletePost(QString pid);
Q_INVOKABLE void getPost(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: public slots:
void onRequestReady(QByteArray data); void onRequestReady(QByteArray data);
@ -103,6 +106,8 @@ Q_SIGNALS:
void muteSuccess(QVariantMap user); void muteSuccess(QVariantMap user);
void unmuteSuccess(QVariantMap user); void unmuteSuccess(QVariantMap user);
void postReceived(QVariantMap post); void postReceived(QVariantMap post);
void userStreamReceived(QVariantList stream);
void userListReceived(QVariantList users);
private: private:
static const QString PNUT_API_ROOT; static const QString PNUT_API_ROOT;

View file

@ -30,52 +30,52 @@
<context> <context>
<name>PostItem</name> <name>PostItem</name>
<message> <message>
<location filename="../assets/PostItem.qml" line="138"/> <location filename="../assets/PostItem.qml" line="139"/>
<source>&lt;i&gt;{{POST DELETED}}&lt;/i&gt;</source> <source>&lt;i&gt;{{POST DELETED}}&lt;/i&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/PostItem.qml" line="168"/> <location filename="../assets/PostItem.qml" line="169"/>
<source>Reply</source> <source>Reply</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/PostItem.qml" line="177"/> <location filename="../assets/PostItem.qml" line="178"/>
<source>Reply All</source> <source>Reply All</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/PostItem.qml" line="187"/> <location filename="../assets/PostItem.qml" line="188"/>
<source>Add Bookmark</source> <source>Add Bookmark</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/PostItem.qml" line="187"/> <location filename="../assets/PostItem.qml" line="188"/>
<source>Delete Bookmark</source> <source>Delete Bookmark</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/PostItem.qml" line="198"/> <location filename="../assets/PostItem.qml" line="199"/>
<source>Repost</source> <source>Repost</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/PostItem.qml" line="198"/> <location filename="../assets/PostItem.qml" line="199"/>
<source>Delete Repost</source> <source>Delete Repost</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/PostItem.qml" line="209"/> <location filename="../assets/PostItem.qml" line="210"/>
<source>Quote</source> <source>Quote</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/PostItem.qml" line="218"/> <location filename="../assets/PostItem.qml" line="219"/>
<source>View Profile</source> <source>View Profile</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/PostItem.qml" line="236"/> <location filename="../assets/PostItem.qml" line="237"/>
<source>Delete</source> <source>Delete</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -83,52 +83,55 @@
<context> <context>
<name>ProfilePage</name> <name>ProfilePage</name>
<message> <message>
<location filename="../assets/ProfilePage.qml" line="124"/> <location filename="../assets/ProfilePage.qml" line="127"/>
<location filename="../assets/ProfilePage.qml" line="200"/>
<source>Following</source> <source>Following</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/ProfilePage.qml" line="137"/> <location filename="../assets/ProfilePage.qml" line="140"/>
<location filename="../assets/ProfilePage.qml" line="215"/>
<source>Followers</source> <source>Followers</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/ProfilePage.qml" line="150"/> <location filename="../assets/ProfilePage.qml" line="153"/>
<location filename="../assets/ProfilePage.qml" line="187"/>
<source>Posts</source> <source>Posts</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/ProfilePage.qml" line="163"/> <location filename="../assets/ProfilePage.qml" line="166"/>
<source>Bookmarks</source> <source>Bookmarks</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/ProfilePage.qml" line="179"/> <location filename="../assets/ProfilePage.qml" line="232"/>
<source>Unfollow</source> <source>Unfollow</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/ProfilePage.qml" line="179"/> <location filename="../assets/ProfilePage.qml" line="232"/>
<source>Follow</source> <source>Follow</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/ProfilePage.qml" line="192"/> <location filename="../assets/ProfilePage.qml" line="245"/>
<source>Unmute</source> <source>Unmute</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/ProfilePage.qml" line="192"/> <location filename="../assets/ProfilePage.qml" line="245"/>
<source>Mute</source> <source>Mute</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/ProfilePage.qml" line="205"/> <location filename="../assets/ProfilePage.qml" line="258"/>
<source>Unblock</source> <source>Unblock</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/ProfilePage.qml" line="205"/> <location filename="../assets/ProfilePage.qml" line="258"/>
<source>Block</source> <source>Block</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -168,30 +171,58 @@
<source>Additional mentions follow /</source> <source>Additional mentions follow /</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../assets/SettingsPage.qml" line="117"/>
<source>Theme</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../assets/SettingsPage.qml" line="119"/>
<source>Bright</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../assets/SettingsPage.qml" line="124"/>
<source>Dark</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>StreamTab</name> <name>StreamTab</name>
<message> <message>
<location filename="../assets/StreamTab.qml" line="137"/> <location filename="../assets/StreamTab.qml" line="140"/>
<source>New Post</source> <source>New Post</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/StreamTab.qml" line="151"/> <location filename="../assets/StreamTab.qml" line="154"/>
<source>To Top</source> <source>To Top</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/StreamTab.qml" line="179"/> <location filename="../assets/StreamTab.qml" line="182"/>
<source>To Bottom</source> <source>To Bottom</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../assets/StreamTab.qml" line="166"/> <location filename="../assets/StreamTab.qml" line="169"/>
<source>Reload</source> <source>Reload</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>UserItem</name>
<message>
<location filename="../assets/UserItem.qml" line="54"/>
<source>Unfollow</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../assets/UserItem.qml" line="54"/>
<source>Follow</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>main</name> <name>main</name>
<message> <message>