Refactoring timelines and notification lists

This commit is contained in:
Dusko Angirevic 2017-06-13 16:45:52 +02:00
parent 98d6eaa3d8
commit 86f12f75c1
12 changed files with 399 additions and 54 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*.user

View file

@ -54,4 +54,7 @@ DISTFILES += \
qml/images/verified.svg \ qml/images/verified.svg \
qml/lib/Mastodon.js \ qml/lib/Mastodon.js \
qml/lib/Worker.js \ qml/lib/Worker.js \
qml/images/boosted.svg qml/images/boosted.svg \
qml/pages/components/VisualContainer.qml \
qml/pages/components/MiniStatus.qml \
qml/pages/components/MiniHeader.qml

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.0.1, 2017-06-09T09:25:36. --> <!-- Written by QtCreator 4.0.1, 2017-06-13T09:21:48. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>
@ -8,7 +8,7 @@
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.ActiveTarget</variable> <variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">1</value> <value type="int">0</value>
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.EditorSettings</variable> <variable>ProjectExplorer.Project.EditorSettings</variable>

View file

@ -36,6 +36,7 @@ WorkerScript.onMessage = function(msg) {
} else if (data[i].hasOwnProperty("content")){ } else if (data[i].hasOwnProperty("content")){
console.log("Is toot... parsing...") console.log("Is toot... parsing...")
var item = parseToot(data[i]); var item = parseToot(data[i]);
item['id'] = item['status_id']
items.push(item) items.push(item)
} else { } else {
WorkerScript.sendMessage({ 'action': msg.action, 'success': true, key: i, "data": data[i]}) WorkerScript.sendMessage({ 'action': msg.action, 'success': true, key: i, "data": data[i]})
@ -62,22 +63,27 @@ function addDataToModel (model, mode, items){
model.sync() model.sync()
} }
function parseAccounts(data){ function parseAccounts(collection, prefix, data){
return (data); var res = collection;
res[prefix + 'account_id'] = data["id"]
res[prefix + 'account_username'] = data["username"]
res[prefix + 'account_acct'] = data["acct"]
res[prefix + 'account_display_name'] = data["display_name"]
res[prefix + 'account_locked'] = data["locked"]
res[prefix + 'account_created_at'] = data["created_at"]
res[prefix + 'account_avatar'] = data["avatar"]
// /console.log(JSON.stringify(res))
return (res);
} }
function parseNotification(data){ function parseNotification(data){
console.log(JSON.stringify(data)) //console.log(JSON.stringify(data))
var item = { var item = {
id: data.id, id: data.id,
type: data.type, type: data.type,
created_at: data.created_at, created_at: new Date(data.created_at)
account_id: data.account.id,
account_acct: data.account.acct,
account_username: data.account.username,
account_display_name: data.account.display_name,
account_avatar: data.account.avatar,
account_locked: data.account.locked
}; };
switch (item['type']){ switch (item['type']){
case "mention": case "mention":
@ -87,57 +93,117 @@ function parseNotification(data){
break; break;
case "reblog": case "reblog":
item = parseToot(data.status) item = parseToot(data.status)
item['isReblog'] = true; item = parseAccounts(item, "reblog_", data["account"])
item = parseAccounts(item, "", data["status"]["account"])
item['status_reblog'] = true;
item['type'] = "reblog"; item['type'] = "reblog";
item['retweetScreenName'] = data['account']['username'];
item['typeIcon'] = "image://theme/icon-s-retweet" item['typeIcon'] = "image://theme/icon-s-retweet"
break; break;
case "favourite": case "favourite":
item = parseToot(data.status) item = parseToot(data.status)
item = parseAccounts(item, "reblog_", data["account"])
item = parseAccounts(item, "", data["status"]["account"])
item['status_reblog'] = true;
item['typeIcon'] = "image://theme/icon-s-favorite" item['typeIcon'] = "image://theme/icon-s-favorite"
item['type'] = "favourite"; item['type'] = "favourite";
item['retweetScreenName'] = data['account']['username']; //item['retweetScreenName'] = item['reblog_account_username'];
break; break;
case "follow": case "follow":
item['type'] = "follow"; item['type'] = "follow";
item['retweetScreenName'] = data['account']['username']; item = parseAccounts(item, "", data["account"])
item = parseAccounts(item, "reblog_", data["account"])
item['content'] = data['account']['note']
item['typeIcon'] = "image://theme/icon-s-installed" item['typeIcon'] = "image://theme/icon-s-installed"
break; break;
default: default:
item['typeIcon'] = "image://theme/icon-s-sailfish" item['typeIcon'] = "image://theme/icon-s-sailfish"
} }
item['id'] = data.id
return item; return item;
} }
function collect() {
var ret = {};
var len = arguments.length;
for (var i=0; i<len; i++) {
for (p in arguments[i]) {
if (arguments[i].hasOwnProperty(p)) {
ret[p] = arguments[i][p];
}
}
}
return ret;
}
function parseToot (data){ function parseToot (data){
//console.log(JSON.stringify(data)) //console.log(JSON.stringify(data))
var item = {}; var item = {};
item['account_username'] = "Mjau" item['status_id'] = data["id"]
item['type'] = ""; item['status_uri'] = data["uri"]
item['status_in_reply_to_id'] = data["in_reply_to_id"]
item['status_in_reply_to_account_id'] = data["in_reply_to_account_id"]
item['status_reblog'] = data["reblog"] ? true : false
item['status_content'] = data["content"]
item['status_created_at'] = item['created_at'] = new Date(data["created_at"]);
item['status_reblogs_count'] = data["reblogs_count"]
item['status_favourites_count'] = data["favourites_count"]
item['status_reblogged'] = data["reblogged"]
item['status_favourited'] = data["favourited"]
item['status_sensitive'] = data["sensitive"]
item['status_spoiler_text'] = data["spoiler_text"]
item['status_visibility'] = data["visibility"]
//item.concat(parseAccounts("", data["account"]));
//item = collect(item, );
if(item['status_reblog']){
item['type'] = "reblog";
item['typeIcon'] = "image://theme/icon-s-retweet"
item = parseAccounts(item, "", data['reblog']["account"])
item = parseAccounts(item, "reblog_", data["account"])
} else {
item = parseAccounts(item, "", data["account"])
}
//item['application_name'] = data["application"]["name"]
//item['application_website'] = data["application"]["website"]
// account
/*
*/
/*item['type'] = "";
item['retweetScreenName'] = ''; item['retweetScreenName'] = '';
item['isVerified'] = false; item['isVerified'] = false;
item['isReblog'] = false; item['isReblog'] = false;
item['favourited'] = data['favourited']; item['favourited'] = data['favourited'];
item['reblogged'] = data['reblogged']; item['reblogged'] = data['reblogged'];
item['muted'] = data['muted']; item['muted'] = data['muted'];
item['reblogs_count'] = data['reblogs_count']; item['status_reblogs_count'] = data['reblogs_count'];
item['favourites_count'] = data['favourites_count']; item['status_favourites_count'] = data['favourites_count'];
if(data['id']){ if(data['id']){
item['id'] = data['id']; item['status_id'] = data['id'];
} }
if(data['created_at']){ if(data['created_at']){
item['created_at'] = data['created_at']; item['status_created_at'] = data['created_at'];
} }
if(data['account']){ if(data['account']){
item['account_id'] = data['account']['id']; item['status_account_id'] = data['account']['id'];
item['account_username'] = data['account']['acct']; item['status_account_username'] = data['account']['acct'];
item['account_display_name'] = data['account']['display_name']; item['status_account_display_name'] = data['account']['display_name'];
item['account_locked'] = data['account']['locked']; item['status_account_locked'] = data['account']['locked'];
item['account_avatar'] = data['account']['avatar']; item['status_account_avatar'] = data['account']['avatar'];
} }
if(data['reblog']){ if(data['reblog']){
item['retweetScreenName'] = data['account']['username']; item['retweetScreenName'] = data['account']['username'];
@ -149,14 +215,20 @@ function parseToot (data){
item['account_locked'] = data['reblog']['account']['locked']; item['account_locked'] = data['reblog']['account']['locked'];
item['account_avatar'] = data['reblog']['account']['avatar']; item['account_avatar'] = data['reblog']['account']['avatar'];
item['reblogs_count'] = data['reblog']['reblogs_count']; item['status_reblogs_count'] = data['reblog']['reblogs_count'];
item['favourites_count'] = data['reblog']['favourites_count']; item['status_favourites_count'] = data['reblog']['favourites_count'];
item['favourited'] = data['reblog']['favourited']; item['status_favourited'] = data['reblog']['favourited'];
item['reblogged'] = data['reblog']['reblogged']; item['status_reblogged'] = data['reblog']['reblogged'];
item['muted'] = data['reblog']['muted']; item['status_muted'] = data['reblog']['muted'];
} }
*/
item['content'] = data['content'].replace(/(<([^>]+)>)/ig,""); item['content'] = data['content'].replace(/(<([^>]+)>)/ig,"");
/*for(var i = 0; i < data['tags'].length ; i++){
var tag = data['tags'][i]['name'];
console.log(tag)
item['content'] = item['content'].replaceAll('#'+tag, '<a href="#'+tag+'">'+tag+'</a>')
}*/
item['content'] = item['content'].split(" ") item['content'] = item['content'].split(" ")
for(var i = 0; i < item['content'].length ; i++){ for(var i = 0; i < item['content'].length ; i++){
if(item['content'][i][0] === "#"){ if(item['content'][i][0] === "#"){
@ -168,7 +240,7 @@ function parseToot (data){
} }
item['content'] = item['content'].join(" ").autoLink() item['content'] = item['content'].join(" ").autoLink()
console.log(JSON.stringify(item))
return item; return item;
} }

View file

@ -27,7 +27,7 @@ Page {
id: panel id: panel
open: true open: true
width: parent.width width: parent.width
height: toot.height + btnAddImages.height + Theme.paddingMedium + (warningContent.visible ? warningContent.height : 0) height: toot.height + btnContentWarning.height + Theme.paddingMedium + (warningContent.visible ? warningContent.height : 0)
dock: Dock.Bottom dock: Dock.Bottom
TextField { TextField {
id: warningContent id: warningContent
@ -65,24 +65,12 @@ Page {
//tweet() //tweet()
} }
} }
IconButton {
id: btnAddImages
enabled: false
anchors {
verticalCenter: btnSend.verticalCenter
left: parent.left
leftMargin: Theme.paddingMedium
}
icon.source: "image://theme/icon-s-attach?" + (pressed
? Theme.highlightColor
: Theme.primaryColor)
onClicked: console.log("Delete!")
}
IconButton { IconButton {
id: btnContentWarning id: btnContentWarning
anchors { anchors {
verticalCenter: btnSend.verticalCenter verticalCenter: privacy.verticalCenter
left: btnAddImages.right left: parent.left
leftMargin: Theme.paddingMedium
} }
icon.source: "image://theme/icon-s-high-importance?" + (pressed icon.source: "image://theme/icon-s-high-importance?" + (pressed
? Theme.highlightColor ? Theme.highlightColor
@ -93,6 +81,7 @@ Page {
id: privacy id: privacy
anchors { anchors {
top: toot.bottom top: toot.bottom
topMargin: -Theme.paddingSmall*2
left: btnContentWarning.right left: btnContentWarning.right
right: btnSend.left right: btnSend.left
} }

View file

@ -84,7 +84,6 @@ Page {
width: parent.width width: parent.width
height: parent.height height: parent.height
onOpenDrawer: infoPanel.open = setDrawer onOpenDrawer: infoPanel.open = setDrawer
//delegate: Notification {}
} }
MyList{ MyList{
property string search; property string search;

View file

@ -0,0 +1,67 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
Item {
id: miniheader
height: lblName.height
width: parent.width
Label {
id: lblName
anchors {
left: parent.left
leftMargin: Theme.paddingMedium
}
text: account_display_name
width: contentWidth > parent.width /2 ? parent.width /2 : contentWidth
truncationMode: TruncationMode.Fade
font.weight: Font.Bold
font.pixelSize: Theme.fontSizeSmall
color: (pressed ? Theme.highlightColor : Theme.primaryColor)
}
Image {
id: iconVerified
y: Theme.paddingLarge
anchors {
left: lblName.right
leftMargin: Theme.paddingSmall
verticalCenter: lblName.verticalCenter
}
visible: account_locked
width: account_locked ? Theme.iconSizeExtraSmall*0.8 : 0
opacity: 0.8
height: width
source: "image://theme/icon-s-secure?" + (pressed
? Theme.highlightColor
: Theme.primaryColor)
}
Label {
id: lblScreenName
anchors {
left: iconVerified.right
right: lblDate.left
leftMargin: Theme.paddingMedium
baseline: lblName.baseline
}
truncationMode: TruncationMode.Fade
text: '@'+account_username
font.pixelSize: Theme.fontSizeExtraSmall
color: (pressed ? Theme.secondaryHighlightColor : Theme.secondaryColor)
}
Label {
id: lblDate
color: (pressed ? Theme.highlightColor : Theme.primaryColor)
text: Format.formatDate(created_at, new Date() - created_at < 60*60*1000 ? Formatter.DurationElapsedShort : Formatter.TimeValueTwentyFourHours)
font.pixelSize: Theme.fontSizeExtraSmall
horizontalAlignment: Text.AlignRight
anchors {
right: parent.right
baseline: lblName.baseline
rightMargin: Theme.paddingLarge
}
}
}

View file

@ -0,0 +1,54 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
Item {
id: ministatus
visible: true
height: icon.height+Theme.paddingMedium
width: parent.width
Image {
id: icon
anchors {
top: parent.top
topMargin: Theme.paddingMedium
bottomMargin: Theme.paddingMedium
left: parent.left
leftMargin: Theme.horizontalPageMargin + Theme.iconSizeMedium - width
}
visible: type.length
width: Theme.iconSizeExtraSmall
height: width
source: typeIcon
}
Label {
id: lblRtByName
visible: type.length
anchors {
left: icon.right
leftMargin: Theme.paddingMedium
verticalCenter: icon.verticalCenter
}
text: {
var action = "";
switch(type){
case "reblog":
action = qsTr('boosted');
break;
case "favourite":
action = qsTr('favourited');
break;
case "follow":
action = qsTr('followed you');
break;
default:
ministatus.visible = false
action = type;
}
return '@' + reblog_account_username + ' ' + action
}
font.pixelSize: Theme.fontSizeExtraSmall
color: Theme.highlightColor
}
}

View file

@ -107,7 +107,7 @@ SilicaListView {
} }
} }
delegate: Toot {} delegate: VisualContainer {} //Toot {}
add: Transition { add: Transition {
NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 800 } NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 800 }

View file

@ -0,0 +1,129 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
BackgroundItem {
id: delegate
signal send (string notice)
signal navigateTo(string link)
width: parent.width
height: miniHeader.height + lblContent.height + Theme.paddingLarge + (ministatus.visible ? ministatus.height : 0) +Theme.paddingLarge
MiniStatus {
id: ministatus
anchors {
leftMargin: Theme.horizontalPageMargin
rightMargin: Theme.horizontalPageMargin
top: parent.top
topMargin: Theme.paddingMedium
}
}
Image {
id: avatar
anchors {
top: ministatus.visible ? ministatus.bottom : parent.top
topMargin: ministatus.visible ? Theme.paddingMedium : Theme.paddingLarge
left: parent.left
leftMargin: Theme.horizontalPageMargin
}
asynchronous: true
width: Theme.iconSizeMedium
height: width
smooth: true
source: account_avatar
visible: true
MouseArea {
anchors.fill: parent
onClicked: {
pageStack.push(Qt.resolvedUrl("../Profile.qml"), {
"displayname": model.status_account_display_name,
"username": model.status_account_acct,
"profileImage": model.status_account_avatar
})
}
}
Rectangle {
color: Theme.highlightDimmerColor
width: Theme.iconSizeSmall
height: width
visible: typeof status_reblog !== "undefined" && status_reblog
anchors {
bottom: parent.bottom
bottomMargin: -width/3
left: parent.left
leftMargin: -width/3
}
Image {
asynchronous: true
width: Theme.iconSizeSmall
height: width
smooth: true
source: reblog_account_avatar
visible: typeof status_reblog !== "undefined" && status_reblog
}
}
}
MiniHeader {
id: miniHeader
anchors {
top: avatar.top
left: avatar.right
right: parent.right
}
}
Label {
id: lblContent
anchors {
left: miniHeader.left
leftMargin: Theme.paddingMedium
right: miniHeader.right
rightMargin: Theme.horizontalPageMargin
top: miniHeader.bottom
topMargin: Theme.paddingSmall
bottomMargin: Theme.paddingLarge
}
height: content.length ? paintedHeight : 0
onLinkActivated: {
console.log(link)
if (link[0] === "@") {
pageStack.push(Qt.resolvedUrl("../Profile.qml"), {
"name": "",
"username": link.substring(1),
"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 {
pageStack.push(Qt.resolvedUrl("../Browser.qml"), {"href" : link})
}
}
text: content
textFormat: Text.StyledText
linkColor : Theme.highlightColor
wrapMode: Text.Wrap
font.pixelSize: Theme.fontSizeSmall
color: (pressed ? Theme.highlightColor : Theme.primaryColor)
}
onClicked: {
pageStack.push(Qt.resolvedUrl("../Conversation.qml"), {
toot_id: id,
title: account_display_name,
description: '@'+account_username,
avatar: account_avatar,
type: "reply"
})
}
}

View file

@ -80,6 +80,21 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>MiniStatus</name>
<message>
<source>boosted</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>favourited</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>followed you</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>MyList</name> <name>MyList</name>
<message> <message>

View file

@ -80,6 +80,21 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>MiniStatus</name>
<message>
<source>boosted</source>
<translation type="unfinished">boosted</translation>
</message>
<message>
<source>favourited</source>
<translation type="unfinished">favourited</translation>
</message>
<message>
<source>followed you</source>
<translation type="unfinished">followed you</translation>
</message>
</context>
<context> <context>
<name>MyList</name> <name>MyList</name>
<message> <message>