Version 0.004

This commit is contained in:
LubuWest 2017-05-11 22:15:34 +02:00
parent 10dccdcdbb
commit 438f8a4e4d
64 changed files with 2736 additions and 636 deletions

30
CHANGELOG.md Normal file
View File

@ -0,0 +1,30 @@
## v0.004#
# News #
* Conversation opens as child of news item
* Pull-to-refresh news
* Delete Icon
* Animated Gif attachments shown below news item
* Improved image selector for new message
* Gif attachments for new message
* Timeline reloaded after new message
# Contacts #
* Contact details window mechanism completely reworked
* New calendar icon for Friendica contacts
* "Connect" opens connect request page for Friendica contacs
# Calendar #
* new calendar tab
* shows own public events and public events of Friendica contacts
* list view of events of selected date
* click on event to show details
# Config #
* the icon of the server is shown if url is correct
* Click on icon for server details
# Translations #
* German

View File

@ -1,16 +1,16 @@
## Friendiqa# ## Friendiqa#
QML based client for the Friendica Social Network. QML based client for the Friendica Social Network.
Tabs for news (incl. Direct Messages), friends and photos. Tabs for news (incl. Direct Messages), friends, photos and events.
Delete old version first when upgrading (due to database changes) OS: currently Linux and Android(4.3).
OS: currently Linux and Android(4.3). Source code is a QtCreator project.
Source code is a QtCreator project.
## Screenshots ## ## Screenshots ##
![Newstab](Screenshots/NewsTab.jpg) ![Newstab](Screenshots/NewsTab.jpg)
![Friendstab](Screenshots/FriendsTab.jpg) ![Friendstab](Screenshots/FriendsTab.jpg)
![Photostab](Screenshots/PhotoTab.jpg) ![Photostab](Screenshots/PhotoTab.jpg)
![Eventstab](Screenshots/EventTab.jpg)
![Configtab](Screenshots/ConfigTab.jpg) ![Configtab](Screenshots/ConfigTab.jpg)
@ -18,34 +18,36 @@ Source code is a QtCreator project.
# News # # News #
Currently supported: Currently supported:
* Shows Posts from friends, favorited messages, Direct Messages and Notifications * Shows Posts from friends, favorited messages, Direct Messages and Notifications
* Show news as timeline or tree (conversation opens in same window) * Open links in external browser
* Open links in external browser * Click on contact photo for contact details
* Click on contact phot for additional information
* Deletion, Reposting, Answering of Posts
* Liking, disliking, favoriting
* Click on like text for additional contact info * Click on like text for additional contact info
* Attending events * Deletion, Reposting, Answering of Posts
* Update fetches new posts since last in local DB * Liking, disliking, favoriting
* Attending for event posts
* Update fetches new posts (up to last 50) since last in local DB
* More shows older posts from local DB * More shows older posts from local DB
* Create new Message with images or direct messages, Contact/Group access rights(can be stored), smileys * Create new Message with images or direct messages, Contact/Group access rights(can be stored), smileys
* New image dialog * New image dialog
ToDo: ToDo:
* Videos and other binary data as attachment (sending and receiving)
* Rich text editing in Send Dialog * Videos and other binary data as attachment (sending and receiving)
* More than one attachment
* Rich text editing in Send Dialog
* Attachments for Direct messages (currently not supported in API) * Attachments for Direct messages (currently not supported in API)
# Friends # # Friends #
Currently supported: Currently supported:
* Tabs for friends, other contacts and groups * Tabs for friends, other contacts and groups
* Grid of all known contacts with locally downloaded pictures * Grid of all known contacts with locally downloaded pictures
* Large friend item for addional information and functionality * Large friend item for addional information and functionality
* Show news of contact from local database * Show news of contact from local database
* Send direct message, if contact is following * Send direct message, if contact is following
* Show public pictures of contact (screenscraping of contact's website, works only with certain theme) * Show public pictures of contact (screenscraping of contact's website, works only with certain theme)
* Open website of contact or connect page (for other contacts) * Open website of contact or connect page (for other contacts)
ToDo: ToDo:
* More information for contact from description page, possibly private information for friends * More information for contact from description page, possibly private information for friends
@ -58,12 +60,21 @@ Currently supported:
* Show albums in grid, show images in album in grid and fullscreen * Show albums in grid, show images in album in grid and fullscreen
* Show albums and images of contacts * Show albums and images of contacts
* Pinch to zoom, swipe to scroll * Pinch to zoom, swipe to scroll
ToDo: ToDo:
* Private images of friends * Private images of friends
* Support for all themes of friends * Support for all themes of friends
* Delete downloaded own images * Delete downloaded own images
# Events #
* download own public events and public events of Friendica contacts
* list view of events of selected date
* click on event to show details
ToDo
* private events
# Config # # Config #
Currently supported: Currently supported:
@ -73,27 +84,20 @@ Currently supported:
ToDo ToDo
* OAuth? * OAuth?
# Other # # Other #
ToDo ToDo
* Calendar tab, video tab * Video tab
* Photo upload to album (needs API change) * Photo upload to album (needs API change)
* Translation * Translation
* Blingbling * Blingbling
# Translations #
* German
# New in version 0.003
* improved BackButton behaviour
* click on contact everywhere to get to contact details
* Image dialog automatically opens in Android camera directory
* Smiley Dialog in Message Dialog
* Extensive use of FontAwesome for icons
* Bugfixes
## License ## ## License ##
* v0.001 for Friendica < 3.5 Pubished under the [GPL v3](http://gplv3.fsf.org).
* v0.002 for Friendica >= 3.5
* Published under the [GPL v3](http://gplv3.fsf.org).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

BIN
Screenshots/EventsTab.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,6 +1,6 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<manifest package="org.qtproject.friendiqa" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.3" android:versionCode="3" android:installLocation="auto"> <manifest package="org.qtproject.friendiqa" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.4" android:versionCode="4" android:installLocation="auto">
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Friendiqa" android:icon="@drawable/icon" android:logo="@drawable/icon"> <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Friendiqa" android:icon="@drawable/friendiqa" android:logo="@drawable/friendiqa">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="Friendiqa" android:screenOrientation="unspecified" android:launchMode="singleTop"> <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="Friendiqa" android:screenOrientation="unspecified" android:launchMode="singleTop">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -196,5 +196,17 @@
<file>images/smileys/adult/finger.gif</file> <file>images/smileys/adult/finger.gif</file>
<file>images/smileys/adult/sperm.gif</file> <file>images/smileys/adult/sperm.gif</file>
<file>images/smileys/adult/tits.gif</file> <file>images/smileys/adult/tits.gif</file>
<file>common/filesystem.cpp</file>
<file>common/filesystem.h</file>
<file>common/friendiqa.cpp</file>
<file>common/uploadableimage.cpp</file>
<file>common/uploadableimage.h</file>
<file>common/xhr.cpp</file>
<file>common/xhr.h</file>
<file>qml/calendarqml/CalendarTab.qml</file>
<file>qml/calendarqml/CalendarDay.qml</file>
<file>qml/calendarqml/EventList.qml</file>
<file>translations/friendiqa-de.qm</file>
<file>translations/friendiqa-de.ts</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -7,7 +7,9 @@
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
QApplication app(argc, argv); QApplication app(argc, argv);
QQuickView view; QQuickView view;
QTranslator qtTranslator;
qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations");
app.installTranslator(&qtTranslator);
XHR* xhr = XHR::instance(); XHR* xhr = XHR::instance();
view.rootContext()->setContextProperty("xhr", xhr); view.rootContext()->setContextProperty("xhr", xhr);

View File

@ -9,12 +9,12 @@ function friendicaRequest(login,api,rootwindow,callback) {
try{ if (xhrequest.status=200){ //if (xhrequest.responseText!=""){ try{ if (xhrequest.status=200){ //if (xhrequest.responseText!=""){
callback(xhrequest.responseText) callback(xhrequest.responseText)
}else{ }else{
showMessage("Error","API:" +api+"\n NO RESPONSE"+xhrequest.statusText,rootwindow); showMessage("Error","API:" +login.server+api+"\n NO RESPONSE"+xhrequest.statusText,rootwindow);
callback(xhrequest.responseText) //callback(xhrequest.responseText)
} }
} }
catch (e){ catch (e){print(e);
showMessage("Error", api+" "+e+" "+xhrequest.statusText,rootwindow) showMessage("Error", xhrequest.responseText,rootwindow)
} }
} }
} }
@ -60,7 +60,7 @@ function friendicaWebRequest(url,rootwindow,callback) {
} else if(xhrequest.readyState === XMLHttpRequest.DONE) { } else if(xhrequest.readyState === XMLHttpRequest.DONE) {
try{ callback(xhrequest.responseText); try{ callback(xhrequest.responseText);
} }
catch (e){ catch (e){print(e);
showMessage("Error",url+" "+e, rootwindow) showMessage("Error",url+" "+e, rootwindow)
} }
} }
@ -130,3 +130,8 @@ var arraystring=JSON.stringify(array);
arraystring=arraystring.replace(/[\[\]]/g , ''); arraystring=arraystring.replace(/[\[\]]/g , '');
return arraystring; return arraystring;
} }
function cleanDate(date){
var cleanedDate= date.slice(0,3)+", "+date.slice(8,11)+date.slice(4,7)+date.slice(25,30)+date.slice(10,25);
return cleanedDate
}

View File

@ -32,13 +32,12 @@ function requestGroups(login,database,rootwindow,callback){
function getFriendsTimeline(login,database,contacts,onlynew,rootwindow,callback){ function getFriendsTimeline(login,database,contacts,onlynew,rootwindow,callback){
// retrieve and return timeline since last news, return contacts which are not friends and older than 2 days for update (friends can be updated in Contactstab) // retrieve and return timeline since last news, return contacts which are not friends and older than 2 days for update (friends can be updated in Contactstab)
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
var parameter = ""; var parameter = "?count=50";
if(onlynew){db.transaction( function(tx) { if(onlynew){db.transaction( function(tx) {
var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1'); // check for last news id var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1'); // check for last news id
try{parameter="&since_id="+result.rows.item(0).status_id;}catch(e){};})} try{parameter=parameter+"&since_id="+result.rows.item(0).status_id;}catch(e){};})}
var newContacts=[]; var newContacts=[];
//print("/api/statuses/friends_timeline"+parameter); Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){print(obj);
Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){
var news=JSON.parse(obj); var news=JSON.parse(obj);
var newContacts=findNewContacts(news,contacts); var newContacts=findNewContacts(news,contacts);
callback(news,newContacts) callback(news,newContacts)
@ -53,7 +52,7 @@ function getCurrentContacts(login,database,callback){
contactlist.push(result.rows.item(i).url ) contactlist.push(result.rows.item(i).url )
//print(result.rows.item(i).url) //print(result.rows.item(i).url)
} }
var lastDate=Date.now()-172800000;// 2 days old var lastDate=Date.now()-604800000;// 7 days old
//print('SELECT url from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge>'+lastDate); //print('SELECT url from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge>'+lastDate);
var result2 = tx.executeSql('SELECT url from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge > '+lastDate); var result2 = tx.executeSql('SELECT url from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge > '+lastDate);
for (var j=0;j<result2.rows.length;j++){ for (var j=0;j<result2.rows.length;j++){
@ -63,18 +62,18 @@ function getCurrentContacts(login,database,callback){
callback(contactlist) callback(contactlist)
} }
function findNewContacts(news,contacts){//print("contacts: "+JSON.stringify(contacts)) function findNewContacts(news,contacts){//print("contacts: "+JSON.stringify(news))
var newContacts=[]; var newContacts=[];
for (var i=0;i<news.length;i++){ for (var i=0;i<news.length;i++){
var url=news[i].user.url; var url=news[i].user.url;
if(contacts.indexOf(url)==-1 && !(inArray(newContacts,"url",url))){print("new contact "+JSON.stringify(news[i].user)); if(contacts.indexOf(url)==-1 && !(inArray(newContacts,"url",url))){
news[i].user.isFriend=0; news[i].user.isFriend=0;
newContacts.push(news[i].user); newContacts.push(news[i].user);
} }
if (news[i].friendica_activities.like.length>0){ if (news[i].friendica_activities.like.length>0){
for (var j=0;j<news[i].friendica_activities.like.length;j++){ for (var j=0;j<news[i].friendica_activities.like.length;j++){
var like_url=news[i].friendica_activities.like[j].url; var like_url=news[i].friendica_activities.like[j].url;
if(contacts.indexOf(like_url)==-1 && !(inArray(newContacts,"url",like_url))){print("new like contact "+JSON.stringify(news[i].friendica_activities.like[j])); if(contacts.indexOf(like_url)==-1 && !(inArray(newContacts,"url",like_url))){
news[i].friendica_activities.like[j].isFriend=0; news[i].friendica_activities.like[j].isFriend=0;
newContacts.push(news[i].friendica_activities.like[j]); newContacts.push(news[i].friendica_activities.like[j]);
} }
@ -83,7 +82,7 @@ function findNewContacts(news,contacts){//print("contacts: "+JSON.stringify(cont
if (news[i].friendica_activities.dislike.length>0){ if (news[i].friendica_activities.dislike.length>0){
for (var k=0;j<news[k].friendica_activities.dislike.length;k++){ for (var k=0;j<news[k].friendica_activities.dislike.length;k++){
var dislike_url=news[i].friendica_activities.dislike[k].url; var dislike_url=news[i].friendica_activities.dislike[k].url;
if(contacts.indexOf(dislike_url)==-1 && !(inArray(newContacts,"url",dislike_url))){print("new dislike contact "+JSON.stringify(news[i].friendica_activities.dislike[k])); if(contacts.indexOf(dislike_url)==-1 && !(inArray(newContacts,"url",dislike_url))){
news[i].friendica_activities.dislike[k].isFriend=0; news[i].friendica_activities.dislike[k].isFriend=0;
newContacts.push(news[i].friendica_activities.dislike[k]); newContacts.push(news[i].friendica_activities.dislike[k]);
} }
@ -110,7 +109,7 @@ function storeNews(login,database,news,rootwindow,callback){
var attendnoarray=[]; for (var user in news[i].friendica_activities.attendno){attendnoarray.push(news[i].friendica_activities.attendno[user].url)} var attendnoarray=[]; for (var user in news[i].friendica_activities.attendno){attendnoarray.push(news[i].friendica_activities.attendno[user].url)}
var attendmaybearray=[]; for (var user in news[i].friendica_activities.attendmaybe){attendmaybearray.push(news[i].friendica_activities.attendmaybe[user].url)} var attendmaybearray=[]; for (var user in news[i].friendica_activities.attendmaybe){attendmaybearray.push(news[i].friendica_activities.attendmaybe[user].url)}
var friendica_activities=[likearray,dislikearray,attendyesarray,attendnoarray,attendmaybearray] var friendica_activities=[likearray,dislikearray,attendyesarray,attendnoarray,attendmaybearray]
var attachments="";if (news[i].attachments){attachments=Qt.btoa(JSON.stringify(news[i].attachments))}print(attachments) var attachments="";if (news[i].attachments){attachments=Qt.btoa(JSON.stringify(news[i].attachments))}
db.transaction( function(tx) { db.transaction( function(tx) {
var result = tx.executeSql('SELECT * from news where username="'+login.username+'" AND status_id = "'+news[i].id+'" AND messagetype=0'); // check for news id var result = tx.executeSql('SELECT * from news where username="'+login.username+'" AND status_id = "'+news[i].id+'" AND messagetype=0'); // check for news id
if(result.rows.length === 1) {// use update if(result.rows.length === 1) {// use update
@ -265,7 +264,7 @@ function likerequest(login,database,verb,newsid,rootwindow){
db.transaction( function(tx) { db.transaction( function(tx) {
var currentActivities_rs=tx.executeSql('select friendica_activities_self from news WHERE username="'+login.username+'" AND status_id='+newsid) ; var currentActivities_rs=tx.executeSql('select friendica_activities_self from news WHERE username="'+login.username+'" AND status_id='+newsid) ;
var currentActivities=JSON.parse(currentActivities_rs.rows.item(0).friendica_activities_self); var currentActivities=JSON.parse(currentActivities_rs.rows.item(0).friendica_activities_self);
print(verb+"currentActivities "+JSON.stringify(currentActivities)); //print(verb+"currentActivities "+JSON.stringify(currentActivities));
if ((verb=="like")&&(currentActivities.indexOf(1)==-1)){ currentActivities.push(1); if ((verb=="like")&&(currentActivities.indexOf(1)==-1)){ currentActivities.push(1);
if (currentActivities.indexOf(2)!=-1){currentActivities.splice(currentActivities.indexOf(2),1)} if (currentActivities.indexOf(2)!=-1){currentActivities.splice(currentActivities.indexOf(2),1)}
} }
@ -349,7 +348,7 @@ function requestFavorites(login,database,contacts,rootwindow,callback){
function favoritesfromdb(database,user,callback){ function favoritesfromdb(database,user,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) { db.transaction( function(tx) {
print('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC'); //print('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC');
var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC'); var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC');
var newsArray=[]; var newsArray=[];
for(var i = 0; i < newsrs.rows.length; i++) { for(var i = 0; i < newsrs.rows.length; i++) {

View File

@ -19,7 +19,7 @@ WorkerScript.onMessage = function(msg) {
else {likeText= newsitemobject.like.length+" "+ qsTr("like this.")} else {likeText= newsitemobject.like.length+" "+ qsTr("like this.")}
} }
if (newsitemobject.dislike.length>0){ if (newsitemobject.dislike.length>0){
if (newsitemobject.dislike.length==1){dislikeText= QT.atob(newsitemobject.dislike[0].name)+" "+ qsTr("doesn't like this.")} if (newsitemobject.dislike.length==1){dislikeText= Qt.atob(newsitemobject.dislike[0].name)+" "+ qsTr("doesn't like this.")}
else {dislikeText= newsitemobject.dislike.length+" "+ qsTr("don't like this.")} else {dislikeText= newsitemobject.dislike.length+" "+ qsTr("don't like this.")}
} }
if (newsitemobject.attendyes.length>0){ if (newsitemobject.attendyes.length>0){
@ -42,7 +42,15 @@ WorkerScript.onMessage = function(msg) {
if (newsitemobject.friendica_activities_self.indexOf(2)!=-1){self.disliked=1} if (newsitemobject.friendica_activities_self.indexOf(2)!=-1){self.disliked=1}
} }
var friendica_activities={likeText:likeText,dislikeText:dislikeText,attendyesText:attendyesText,attendnoText:attendnoText,attendmaybeText:attendmaybeText,self:self} var friendica_activities={likeText:likeText,dislikeText:dislikeText,attendyesText:attendyesText,attendnoText:attendnoText,attendmaybeText:attendmaybeText,self:self}
//print(JSON.stringify(friendica_activities) ) ;
var attachmentList=[];if(newsitemobject.attachments){
var attachArray=JSON.parse(Qt.atob(newsitemobject.attachments));
for (var image in attachArray){if(attachArray[image].mimetype=="image/gif"){
attachmentList.push(attachArray[image])
}
}
}
newsitemobject.attachmentList=attachmentList;
var seconds=(msg.currentTime-newsitemobject.created_at)/1000; var seconds=(msg.currentTime-newsitemobject.created_at)/1000;
var timestring=""; var timestring="";
if (seconds<60) {timestring=seconds+" "+qsTr("seconds") +" "+qsTr("ago");} if (seconds<60) {timestring=seconds+" "+qsTr("seconds") +" "+qsTr("ago");}
@ -54,7 +62,7 @@ WorkerScript.onMessage = function(msg) {
else if (seconds<3888000){timestring=Math.round(seconds/86400)+" "+qsTr("days") +" "+qsTr("ago");} else if (seconds<3888000){timestring=Math.round(seconds/86400)+" "+qsTr("days") +" "+qsTr("ago");}
else if (seconds<5832000){timestring=Math.round(seconds/3888000)+" "+qsTr("month") +" "+qsTr("ago");} else if (seconds<5832000){timestring=Math.round(seconds/3888000)+" "+qsTr("month") +" "+qsTr("ago");}
else if (seconds<69984000){timestring=Math.round(seconds/3888000)+" "+qsTr("months") +" "+qsTr("ago");} else if (seconds<69984000){timestring=Math.round(seconds/3888000)+" "+qsTr("months") +" "+qsTr("ago");}
else {timestring=Math.round(seconds/69984000)+" "+qsTr("years") +" "+qsTr("ago");} else {timestring=Math.round(seconds/46656000)+" "+qsTr("years") +" "+qsTr("ago");}
var data=({"newsitemobject": newsitemobject,"dateDiff":timestring,"friendica_activities":friendica_activities})} var data=({"newsitemobject": newsitemobject,"dateDiff":timestring,"friendica_activities":friendica_activities})}
//print("News:"+j+msg.news.length+JSON.stringify(data)); //print("News:"+j+msg.news.length+JSON.stringify(data));
msg.model.append(data);} msg.model.append(data);}

View File

@ -121,8 +121,93 @@ function initDatabase(database) { // initialize the database object
tx.executeSql('CREATE TABLE IF NOT EXISTS news(username TEXT, messagetype INT, text TEXT, created_at INT, in_reply_to_status_id INT, source TEXT, status_id INT, in_reply_to_user_id INT, geo TEXT,favorited TEXT, uid INT, statusnet_html TEXT, statusnet_conversation_id TEXT,friendica_activities TEXT, friendica_activities_self TEXT, attachments TEXT, friendica_owner INT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS news(username TEXT, messagetype INT, text TEXT, created_at INT, in_reply_to_status_id INT, source TEXT, status_id INT, in_reply_to_user_id INT, geo TEXT,favorited TEXT, uid INT, statusnet_html TEXT, statusnet_conversation_id TEXT,friendica_activities TEXT, friendica_activities_self TEXT, attachments TEXT, friendica_owner INT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS contacts(username TEXT, id INT, name TEXT, screen_name TEXT, location TEXT,imageAge INT, profile_image_url TEXT, description TEXT, profile_image BLOB, url TEXT, protected TEXT, followers_count INT, friends_count INT, created_at INT, favourites_count TEXT, utc_offset TEXT, time_zone TEXT, statuses_count INT, following TEXT, verified TEXT, statusnet_blocking TEXT, notifications TEXT, statusnet_profile_url TEXT, cid INT, network TEXT, isFriend INT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS contacts(username TEXT, id INT, name TEXT, screen_name TEXT, location TEXT,imageAge INT, profile_image_url TEXT, description TEXT, profile_image BLOB, url TEXT, protected TEXT, followers_count INT, friends_count INT, created_at INT, favourites_count TEXT, utc_offset TEXT, time_zone TEXT, statuses_count INT, following TEXT, verified TEXT, statusnet_blocking TEXT, notifications TEXT, statusnet_profile_url TEXT, cid INT, network TEXT, isFriend INT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS groups(username TEXT, groupname TEXT, gid INT, members TEXT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS groups(username TEXT, groupname TEXT, gid INT, members TEXT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS events(username TEXT, id INT, start INT, end INT, allday INT, title TEXT, j INT, d TEXT, isFirst INT, uid INT, cid INT, uri TEXT, created INT, edited INT, desc TEXT, location TEXT, type TEXT, nofinish TEXT, adjust INT, ignore INT, permissions TEXT, guid INT, itemid INT, plink TEXT, authorName TEXT, authorAvatar TEXT, authorLink TEXT, html TEXT)');
})} })}
function cleanPermissions(oldperms){
var newperms=oldperms.replace("<","");newperms=newperms.replace(">","");newperms="["+newperms+"]";
var newpermArray=JSON.parse(newperms);
return (newpermArray)
}
function getEvents(database,login,rootwindow,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
Helperjs.friendicaWebRequest(login.server+"/cal/"+login.username+"/json",rootwindow,function(obj){
var events = JSON.parse(obj);
db.transaction( function(tx) {
for (var i=0;i<events.length;i++){
var permissions=[];
permissions.push(cleanPermissions(events[i].item.allow_cid));
permissions.push(cleanPermissions(events[i].item.allow_gid));
permissions.push(cleanPermissions(events[i].item.deny_cid));
permissions.push(cleanPermissions(events[i].item.deny_gid));
var result = tx.executeSql('SELECT * from events where username="'+login.username+'" AND id = '+events[i].id); // check for news id
if(result.rows.length === 1) {// use update
result = tx.executeSql('UPDATE events SET username="'+login.username+'", start="'+Date.parse(events[i].start)+'", end="'+Date.parse(events[i].end)+'", allday="'+Number(events[i].allday)+'", title="'+events[i].title+'", j="'+events[i].j+'", d="'+events[i].d+ '", isFirst="'+Number(events[i].isFirst)+'", uid="'+events[i].item.uid+'", cid="'+events[i].item.cid+'", uri="'+events[i].item.uri+'", created="'+ Date.parse(events[i].item.created)+'", edited="'+ Date.parse(events[i].item.edited)+'", desc="'+events[i].item.desc+'", location="'+events[i].item.location+'", type="'+events[i].item.type+'", nofinish="'+events[i].item.nofinish+'", adjust ="'+events[i].item.adjust+'", ignore="'+events[i].item.ignore+'", permissions="'+ JSON.stringify(permissions)+'", guid="'+events[i].item.guid+'", itemid="'+events[i].item.itemid+ '", plink="'+events[i].item.plink+ '", authorName="'+events[i].item["author-name"]+ '", authorAvatar="'+events[i].item["author-avatar"]+ '", authorLink="'+events[i].item["author-link"]+ '", html="'+Qt.btoa(events[i].html)+'" where username="'+login.username+'" AND id='+events[i].id);
} else {// use insert
result = tx.executeSql('INSERT INTO events (username,id,start,end,allday,title,j,d,isFirst,uid,cid,uri,created,edited,desc,location,type,nofinish,adjust,ignore,permissions,guid,itemid,plink,authorName,authorAvatar,authorLink,html) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username, events[i].id, Date.parse(events[i].start), Date.parse(events[i].end), events[i].allday, events[i].title, events[i].j, events[i].d, events[i].isFirst, events[i].item.uid, events[i].item.cid, events[i].item.uri, Date.parse(events[i].item.created), Date.parse(events[i].item.edited), events[i].item.desc, events[i].item.location, events[i].item.type, events[i].item.nofinish, events[i].item.adjust, events[i].item.ignore, JSON.stringify(permissions), events[i].item.guid, events[i].item.itemid, events[i].item.plink, events[i].item["author-name"], events[i].item["author-avatar"], events[i].item["author-link"], Qt.btoa(events[i].html)])}
callback()
}
})})}
function newscount(database, callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) {
var newscountrs = tx.executeSql('SELECT COUNT(*) from news');
var newscount = newscountrs.rows.item(0)["COUNT(*)"];
callback(newscount)
})
}
function eventsfromdb(database, username,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) {
var eventrs=tx.executeSql('select * from events WHERE username="'+username+'" ORDER BY start ASC');
var eventArray=[];
var dayArray=[];
for(var i = 0; i < eventrs.rows.length; i++) {
eventArray.push(eventrs.rows.item(i));
// eventArray[i]=fetchUsersForNews(database,username,newsArray[i])
dayArray.push(Math.floor(eventrs.rows.item(i).start/86400000));
}
callback(eventArray,dayArray)});
}
function requestFriendsEvents(login,friend,rootwindow,callback){
// get calendar JSON object of contact without user and password
Helperjs.friendicaWebRequest(friend.replace("profile","cal")+"/json",rootwindow,function(calhtml){
//print(calhtml);
var eventarray=[];var eventdays=[];
var events=JSON.parse(calhtml);
for (var i=0;i<events.length;i++){
var permissions=[];
permissions.push(cleanPermissions(events[i].item.allow_cid));
permissions.push(cleanPermissions(events[i].item.allow_gid));
permissions.push(cleanPermissions(events[i].item.deny_cid));
permissions.push(cleanPermissions(events[i].item.deny_gid));
var event ={}
event.start=Date.parse(events[i].start);event.end=Date.parse(events[i].end);
event.allday=events[i].allday; event.title=events[i].title; event.j=events[i].j;
event.d=events[i].d; event.isFirst=events[i].isFirst; event.uid=events[i].item.uid;
event.cid=events[i].item.cid; event.uri=events[i].item.uri;
event.created=Date.parse(events[i].item.created); event.edited=Date.parse(events[i].item.edited);
event.desc=events[i].item.desc; event.location=events[i].item.location; event.type=events[i].item.type;
event.nofinish=events[i].item.nofinish; event.adjust =events[i].item.adjust; event.ignore=events[i].item.ignore;
event.permissions=JSON.stringify(permissions); event.guid=events[i].item.guid;
event.itemid=events[i].item.itemid; event.plink=events[i].plink; event.authorName=events[i].item["author-name"];
event.authorAvatar=events[i].item["author-avatar"]; event. authorLink=events[i].item["author-link"];
event.html=Qt.btoa(events[i].html);
eventarray.push(event);
// var offsetTime = new Date().getTimezoneOffset() * 60 * 1000;print(new Date(event.start).toLocaleString()+"Zeitverschiebung:"+offsetTime)
// var time = event.start - offsetTime;
eventdays.push(Math.floor(event.start/(24*60*60*1000)))
}
//print(JSON.stringify(eventarray));
callback(eventarray,eventdays)
})
}
function savePermissions(database,obj) { // stores config to DB function savePermissions(database,obj) { // stores config to DB
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
var permissions=JSON.stringify(obj) var permissions=JSON.stringify(obj)
@ -147,6 +232,18 @@ function storeConfig(database,obj) { // stores config to DB
} }
})} })}
function showServerConfig(url,rootwindow,callback){//print(url);
Helperjs.friendicaWebRequest(url+"/api/statusnet/config",rootwindow, function (obj){
var serverconfig = JSON.parse(obj);
var serverConfigString="import QtQuick 2.0; import QtQuick.Dialogs 1.2; MessageDialog{ visible: true; title:'Server';standardButtons: StandardButton.Ok;text: 'Name: "+serverconfig.site.name+"\nLanguage: "+serverconfig.site.language+
"\nEmail: "+serverconfig.site.email+"\nTimezone: "+serverconfig.site.timezone+"\nClosed: "+serverconfig.site.closed+
"\nText limit: "+serverconfig.site.textlimit+"\nShort Url length: "+serverconfig.site.shorturllength+
"\nFriendica version: "+serverconfig.site.friendica.FRIENDICA_VERSION+"\nDFRN version: "+serverconfig.site.friendica.DFRN_PROTOCOL_VERSION +
"\nDB Update version: "+serverconfig.site.friendica.DB_UPDATE_VERSION+"'}";
callback(serverConfigString)
})}
function getServerConfig(database,login,rootwindow,callback){ function getServerConfig(database,login,rootwindow,callback){
// check server with given credentials // check server with given credentials
try {Helperjs.friendicaRequest(login,"/api/statusnet/config",rootwindow, function (obj){ try {Helperjs.friendicaRequest(login,"/api/statusnet/config",rootwindow, function (obj){
@ -212,8 +309,9 @@ function cleanNews(database,callback){
var maxnews=maxnewsrs.rows.item(0).maxnews; var maxnews=maxnewsrs.rows.item(0).maxnews;
var newscountrs = tx.executeSql('SELECT COUNT(*) from news'); var newscountrs = tx.executeSql('SELECT COUNT(*) from news');
var newscount = newscountrs.rows.item(0)["COUNT(*)"]; var newscount = newscountrs.rows.item(0)["COUNT(*)"];
if (newscount>maxnews){var lastvalidtimers= tx.executeSql('select created_at from news ORDER BY created_at DESC LIMIT ' +(newscount-maxnews)); if (newscount>maxnews){
var lastvalidtime=lastvalidtimers.rows.item(maxnews).created_at; var lastvalidtimers= tx.executeSql('SELECT DISTINCT created_at FROM news ORDER BY created_at ASC LIMIT ' +(newscount-maxnews));
var lastvalidtime=lastvalidtimers.rows.item(newscount-maxnews-1).created_at;
var deleters = tx.executeSql('DELETE from news WHERE created_at<='+lastvalidtime)} var deleters = tx.executeSql('DELETE from news WHERE created_at<='+lastvalidtime)}
callback() callback()
}) })
@ -260,13 +358,17 @@ function processNews(callback){
function updateContactInDB(login,database,isFriend,contact){// for newstab and friendstab function updateContactInDB(login,database,isFriend,contact){// for newstab and friendstab
// var suffix=contact.profile_image_url.substring(contact.profile_image_url.lastIndexOf("."), contact.profile_image_url.length); // var suffix=contact.profile_image_url.substring(contact.profile_image_url.lastIndexOf("."), contact.profile_image_url.length);
// var imagename=login.imagestore+"contacts/"+contact.screen_name.trim()+suffix; // var imagename=login.imagestore+"contacts/"+contact.screen_name.trim()+suffix;
var imagename=login.imagestore+"contacts/"+contact.screen_name+"-"+contact.profile_image_url.substring(contact.profile_image_url.lastIndexOf("/")+1, contact.profile_image_url.length);
contacttimer.restart(); var imagename="";
contacttimer.restart();
var currentTime=Date.now(); var currentTime=Date.now();
if(contact.profile_image_url==""){root.currentContact=root.currentContact+1 } else{//print(JSON.stringify(contact))
imagename=login.imagestore+"contacts/"+contact.screen_name+"-"+contact.profile_image_url.substring(contact.profile_image_url.lastIndexOf("/")+1, contact.profile_image_url.length);
xhr.setUrl(Qt.resolvedUrl(contact.profile_image_url)); xhr.setUrl(Qt.resolvedUrl(contact.profile_image_url));
xhr.setFilename(imagename); xhr.setFilename(imagename);
xhr.setDownloadtype("contact"); xhr.setDownloadtype("contact");
xhr.download(); xhr.download();}
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
var result; var result;
db.transaction( function(tx) { db.transaction( function(tx) {

View File

@ -0,0 +1,47 @@
import QtQuick 2.0
import QtQuick.Controls 1.4
Item {
id: calendarDay
width:7*mm
height: 7*mm
property int dateInt:Math.floor((Date.parse(model.date)-(new Date().getTimezoneOffset() * 60 * 1000))/86400000)
Rectangle {
id: placeHolder
color: 'lightblue'; antialiasing: true
anchors.fill:parent
}
Text {
id:daytext
anchors.right: parent.right
anchors.margins: 0.5*mm
color:(model.month==monthgrid.month)?"black":"grey"
wrapMode: Text.WrapAnywhere
text: model.day
font.bold: model.today
font.pixelSize: 4*mm
}
Rectangle {
id:eventRect
color:"black"
anchors.margins: 0.5*mm
anchors.bottom: calendarDay.bottom
width: parent.width-mm
height: mm
visible: eventdays.indexOf(dateInt)>-1
}
MouseArea {
anchors.fill: calendarDay
onClicked: {
var eventDate=[];
var idx = eventdays.indexOf(dateInt);
while (idx != -1) {
eventDate.push(idx);
idx = eventdays.indexOf(dateInt,idx + 1)
}
var component = Qt.createComponent("qrc:/qml/calendarqml/EventList.qml");
if (component.status== Component.Ready){
var eventlist = component.createObject(calendartab,{"daylist": eventDate})}
}
}
}

View File

@ -0,0 +1,134 @@
import QtQuick 2.0
import QtQuick.Controls 2.1
import QtQml 2.2
import Qt.labs.calendar 1.0
import QtQuick.Layouts 1.3
import "qrc:/js/service.js" as Service
import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/calendarqml"
import "qrc:/qml/genericqml"
Rectangle {
id:calendarrectangle
y:1
width:root.width-mm
height:root.height-5*mm
color: '#fff'
property date currentTime: new Date()
property int offsetTime: currentTime.getTimezoneOffset() * 60 * 1000
property var events:[]
property var eventdays:[]
onEventdaysChanged: print(JSON.stringify(eventdays))
function showEvents(friend){
if(friend=="backButton"){Service.eventsfromdb(db,login.username,function(eventArray,dayArray){
events=eventArray;
eventdays=dayArray})
}
else if (friend!=""){
calendartab.calendartabstatus=friend.substring(friend.lastIndexOf("/")+1,friend.length)
Service.requestFriendsEvents(login,friend,calendartab,function(eventArray,dayArray){
events=eventArray;
eventdays=dayArray})
}
else {calendartab.calendartabstatus="Events";
Service.eventsfromdb(db,login.username,function(eventArray,dayArray){
events=eventArray;
eventdays=dayArray;
calBusy.running=false
})
}
}
BusyIndicator{
id: calBusy
anchors.horizontalCenter: calendarView.horizontalCenter
anchors.top:calendarView.top
anchors.topMargin: 2*mm
width:10*mm
height: 10*mm
running: false
}
BlueButton{
id: updateEvents
anchors.top: parent.top
anchors.topMargin: 0.5*mm
anchors.right:calendartabstatusButton.left
anchors.rightMargin:mm
text:"\uf021"
onClicked: {
Service.getEvents(db,login, calendartab,function(){
showEvents("")
})}}
BlueButton{
id: calendartabstatusButton
anchors.top: parent.top
anchors.topMargin: 0.5*mm
anchors.right: parent.right
anchors.rightMargin:2*mm
text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus
onClicked: {calendartabmenu.popup()}
}
Menu {
id:calendartabmenu
MenuItem {
text: qsTr("Own Calendar")
onTriggered: {
calendartab.calendartabstatus="Events";
// calendartabstatusButton.text=qsTr("own Calendar");
showEvents("")}
}
}
ListView{
id: calendarView
x: mm;y:8*mm
width: parent.width-2*mm; height: parent.height-9*mm
clip: true
snapMode: ListView.SnapOneItem
orientation: ListView.Horizontal
highlightRangeMode: ListView.StrictlyEnforceRange
model: CalendarModel {id:calendarModel
from: new Date()
to: new Date(new Date().valueOf()+93312000000)
}
delegate:
ColumnLayout{
width:calendarView.width
Text{
font.bold: true
Layout.fillWidth: true
horizontalAlignment:Text.AlignHCenter
text: model.year
}
Text{
text: Qt.locale().standaloneMonthName(model.month)
Layout.fillWidth: true
horizontalAlignment:Text.AlignHCenter
}
DayOfWeekRow{
locale: monthgrid.locale
Layout.fillWidth: true
}
MonthGrid {
id: monthgrid
Layout.fillWidth: true
month: model.month
year: model.year
locale: Qt.locale()
delegate: CalendarDay{}
}
}
ScrollIndicator.horizontal: ScrollIndicator { }
}
Component.onCompleted: {
root.eventSignal.connect(showEvents);
if (calendartab.calendartabstatus=="Events"){showEvents("")}
}
}

View File

@ -0,0 +1,85 @@
import QtQuick 2.0
import QtQuick.Controls 1.2
import "qrc:/js/service.js" as Service
import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/genericqml"
Rectangle{
id:eventList
z:2
border.color: "grey"
width: parent.width-4*mm
height:parent.height-12*mm
x:mm
y:mm
property var daylist:[]
BlueButton{
id:closeButton
anchors.top: parent.top
anchors.topMargin: 1*mm
anchors.right: parent.right
anchors.rightMargin: 1*mm
text: "\uf057"
onClicked:{eventList.destroy()}
}
ListView {
id: eventlistView
x: mm
y:closeButton.height+2*mm
width: eventList.width-2*mm
height: eventList.height-closeButton.height-4*mm
clip: true
model: eventModel
delegate: eventItem
}
ListModel{
id: eventModel
}
Component.onCompleted:{
//print(JSON.stringify(daylist))
for (var i=0; i<daylist.length;i++){//print(JSON.stringify(events[daylist[i]]));
var liststate="";if(daylist.length<2){liststate="large"}
eventModel.append({"event":events[daylist[i]],"eventstatus":liststate});
}
}
Component{
id:eventItem
Rectangle{
property string status: eventstatus
width:eventlistView.width
height:eventNameText.height+eventDetailsText.height+mm
border.color: "light grey"
border.width: 1
Text {
id:eventNameText
x:mm
width:parent.width
height:contentHeight
text: new Date(event.start+calendarrectangle.offsetTime).toLocaleTimeString()+": "+event.title
font.pixelSize: 3*mm
wrapMode:Text.Wrap
}
Text {
id:eventDetailsText
x:mm
z:4
width: parent.width
height: contentHeight
text: status==""?"":Qt.atob(event.html)
anchors.top: eventNameText.bottom
font.pixelSize: 3*mm
wrapMode:Text.Wrap
}
MouseArea{
anchors.fill: parent
onClicked:{if (status==""){status="large"} else {status=""}
}
}
}
}
}

View File

@ -1,4 +1,4 @@
import QtQuick 2.0 import QtQuick 2.7
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import "qrc:/js/service.js" as Service import "qrc:/js/service.js" as Service
@ -15,13 +15,18 @@ StackView{
height:root.height-12*mm height:root.height-12*mm
contentHeight: configBackground.height contentHeight: configBackground.height
boundsBehavior: Flickable.StopAtBounds boundsBehavior: Flickable.StopAtBounds
Rectangle{ Rectangle{
id:configBackground id:configBackground
color: "white" color: "white"
width:parent.width width:parent.width
height:Math.max(90*mm,root.height-12*mm) height:Math.max(90*mm,root.height-12*mm)
property var users:[] property var users:[]
function setServericon(server){
try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",configBackground, function (obj){
var serverdata = JSON.parse(obj);
servericon.source=serverdata.site.logo})} catch(e){print(e)}
}
BlueButton{ BlueButton{
id:userButton id:userButton
text:qsTr("User") text:qsTr("User")
@ -35,6 +40,7 @@ StackView{
"'; onTriggered: {Service.readConfig(db,function(obj){ "'; onTriggered: {Service.readConfig(db,function(obj){
userButton.text=obj.username; userButton.text=obj.username;
servername.text=obj.server; servername.text=obj.server;
configBackground.setServericon(obj.server);
username.text= obj.username; username.text= obj.username;
password.text=Qt.atob(obj.password); password.text=Qt.atob(obj.password);
imagestore.text=obj.imagestore; imagestore.text=obj.imagestore;
@ -49,37 +55,51 @@ StackView{
} }
Text { Text {
text: "Server" text: qsTr("Server")
x: 4*mm; y: 10*mm x: 4*mm; y: 10*mm
} }
Text { Text {
text: "User" text: qsTr("User")
x: 4*mm; y: 20*mm x: 4*mm; y: 20*mm
} }
Text { Text {
text: "Password" text: qsTr("Password")
x: 4*mm; y: 30*mm x: 4*mm; y: 30*mm
} }
Text { Text {
text: "Image dir." text: qsTr("Image dir.")
x: 4*mm; y: 40*mm x: 4*mm; y: 40*mm
} }
Text { Text {
text: "Max. News" text: qsTr("Max. News")
x: 4*mm; y: 50*mm x: 4*mm; y: 50*mm
} }
Text { Text {
text: "News as" text: qsTr("News as")
x: 4*mm; y: 60*mm x: 4*mm; y: 60*mm
} }
Text { Text {
text: "Interval (0=None)" text: qsTr("Interval (0=None)")
visible: false visible: false
x: 4*mm; y: 70*mm; width:20*mm;wrapMode: Text.Wrap x: 4*mm; y: 70*mm; width:20*mm;wrapMode: Text.Wrap
} }
Image{
id:servericon
x:19*mm;y:10*mm
width:5*mm; height: 5*mm
source:""
MouseArea{
anchors.fill:parent
onClicked:{
Service.showServerConfig(servername.text, configBackground, function(configString){
var serverconfigObject=Qt.createQmlObject(configString,configBackground,"serverconfigOutput");})
}
}
}
Rectangle{color: "light grey"; x: 25*mm; y: 10*mm; width: root.width/2; height: 5*mm;} Rectangle{color: "light grey"; x: 25*mm; y: 10*mm; width: root.width/2; height: 5*mm;}
Flickable { Flickable {
id: servernameFlickable id: servernameFlickable
@ -93,9 +113,13 @@ StackView{
height: servernameFlickable.height height: servernameFlickable.height
focus: true focus: true
text:"https://..." text:"https://..."
//wrapMode: TextEdit.NoWrap onEditingFinished:{
//validator: RegExpValidator { regExp: /^(((http|https|ftp):\/\/)?([[a-zA-Z0-9]\-\.])+(\.)([[a-zA-Z0-9]]){2,4}([[a-zA-Z0-9]\/+=%&_\.~?\-]*))*$/} if((servername.text).substring(0,14) =="https://...http"){
// onEditingFinished:{} serverstring.text= (serverstring.text).substring(11)
}
configBackground.setServericon(servername.text)
}
onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,servernameFlickable) onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,servernameFlickable)
} }
} }
@ -134,9 +158,11 @@ StackView{
} }
} }
Slider{ id: maxNews Slider{ id: maxNews
x:37*mm; y: 50*mm;width: root.width/3;height:5*mm x:34*mm; y: 50*mm;width: root.width/3;height:5*mm
minimumValue: 0;maximumValue:100000; stepSize: 1000 minimumValue: 0;maximumValue:2000; stepSize: 100
} }
Rectangle{color: "light grey"; x: 25*mm; y: 50*mm; width: 9*mm; height: 5*mm; Rectangle{color: "light grey"; x: 25*mm; y: 50*mm; width: 9*mm; height: 5*mm;
TextEdit{id:maxNewsText; TextEdit{id:maxNewsText;
anchors.fill: parent anchors.fill: parent
@ -199,13 +225,12 @@ StackView{
BlueButton { BlueButton {
x: 25*mm; y: 80*mm x: 25*mm; y: 78*mm
text: "Confirm" text: qsTr("Confirm")
onClicked:{ onClicked:{
var userconfig={server: servername.text, username: username.text, password:Qt.btoa(password.text), imagestore:imagestore.text,maxnews:maxNewsText.text,interval: messageIntervalField.text, newsViewType:newsTypeField.text}; var userconfig={server: servername.text, username: username.text, password:Qt.btoa(password.text), imagestore:imagestore.text,maxnews:maxNewsText.text,interval: messageIntervalField.text, newsViewType:newsTypeField.text};
var errormessage=""; var errormessage="";
if (servername.text==""){errormessage=qsTr("No server given! ")} if (servername.text==""){errormessage=qsTr("No server given! ")}
//if (!servername.acceptableInput){errormessage+=qsTr("Server name not valid! ")}
else if (username.text==""){errormessage+=qsTr("No username given! ")} else if (username.text==""){errormessage+=qsTr("No username given! ")}
else if (password.text=="") {errormessage+=qsTr("No password given! ")} else if (password.text=="") {errormessage+=qsTr("No password given! ")}
else if (imagestore.text=="") {errormessage+=qsTr("No image directory given!")} else if (imagestore.text=="") {errormessage+=qsTr("No image directory given!")}
@ -228,11 +253,6 @@ StackView{
userButton.color="black" userButton.color="black"
//reset values //reset values
root.login=userconfig; root.login=userconfig;
// root.contactlist=[];
// root.news=[];
// root.newContacts=[];
// root.currentContact= 0;
// root.contactLoadType= "";
newstab.newstabstatus=userconfig.newsViewType; newstab.newstabstatus=userconfig.newsViewType;
root.currentIndex=0; root.currentIndex=0;
newstab.active=true; newstab.active=true;
@ -252,6 +272,7 @@ StackView{
filesystem.Directory=imagestore.text+"albums"; filesystem.Directory=imagestore.text+"albums";
filesystem.rmDir(); filesystem.rmDir();
servername.text="https://..."; servername.text="https://...";
servericon.source="";
username.text=""; username.text="";
password.text=""; password.text="";
imagestore.text=""; imagestore.text="";
@ -272,6 +293,7 @@ StackView{
text: "+" text: "+"
onClicked:{ onClicked:{
servername.text="https://..." servername.text="https://..."
servericon.source="";
username.text="" username.text=""
password.text="" password.text=""
imagestore.text="" imagestore.text=""
@ -297,8 +319,8 @@ StackView{
onTriggered: {newsTypeField.text="Timeline"} onTriggered: {newsTypeField.text="Timeline"}
} }
MenuItem { MenuItem {
text: qsTr("Tree") text: qsTr("Conversations")
onTriggered: {newsTypeField.text="Tree"} onTriggered: {newsTypeField.text="Conversations"}
} }
} }
@ -311,6 +333,7 @@ StackView{
Service.readConfig(db,function(obj){ Service.readConfig(db,function(obj){
userButton.text=obj.username; userButton.text=obj.username;
servername.text=obj.server; servername.text=obj.server;
configBackground.setServericon(obj.server);
username.text= obj.username; username.text= obj.username;
password.text=Qt.atob(obj.password); password.text=Qt.atob(obj.password);
imagestore.text=obj.imagestore; imagestore.text=obj.imagestore;

View File

@ -47,38 +47,11 @@ Rectangle {
anchors.topMargin: mm anchors.topMargin: mm
anchors.top: parent.top anchors.top: parent.top
onClicked:{ onClicked:{
contactComponent.state="large";
var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml"); var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml");
if (component.status== Component.Ready){ if (component.status== Component.Ready){
var contactDetails = component.createObject(wrapper,{"contact": contact})} var contactDetails = component.createObject(friendstab,{"contact": contact})}
} }
} }
} }
Timer{id:selectiontimer; //weird behaviour when state set to "large" onCompleted
interval: 200; running: false; repeat: false
onTriggered: {
contactComponent.state="large";
var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml");
if (component.status== Component.Ready){
var contactDetails = component.createObject(wrapper,{"contact": contact})}
}
}
Component.onCompleted: {
if(status=="large"){selectiontimer.start()}
else{contactComponent.state=""}
}
states: [
State {
name: "large"
PropertyChanges { target: namelabel; font.pixelSize: 4*mm; x:mm; width:friendsTabView.width-4*mm; text:Qt.atob(contact.name)+" (@"+contact.screen_name+")"}
ParentChange{target:contactComponent;parent:root; x:mm;y:2*mm}
//PropertyChanges { target: contactComponent; z: 2; x:0;y:0}
PropertyChanges { target: wrapper; width:friendsTabView.width;height:friendsTabView.height-15*mm}
PropertyChanges { target: photoImage; width:15*mm;height:15*mm;x:mm;y:mm }
PropertyChanges { target: contactComponent.GridView.view; interactive:false}
}
]
} }

View File

@ -2,6 +2,44 @@ import QtQuick 2.0
import QtQuick.Controls 1.3 import QtQuick.Controls 1.3
import "qrc:/qml/genericqml" import "qrc:/qml/genericqml"
Item {
id: contactLargeComponent
x:mm
y:mm
property var contact:{}
property var createdAtDate: new Date(contact.created_at)
property string connectUrl: (contact.network!=="dfrn")||(contact.isFriend==1)?"":( "<a href='"+contact.url.replace("profile","dfrn_request") +"'>"+qsTr("Connect")+"</a><br>")
Rectangle {
id: wrapper
width:friendsTabView.width;
height:friendsTabView.height-15*mm
border.color: "grey"
color:"white"
Image {
id: photoImage
x:mm
y:mm
width: 15*mm
height:15*mm
source:(contact.profile_image!="")? "file://"+contact.profile_image : contact.profile_image_url
onStatusChanged: if (photoImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"}
}
Label {
id: namelabel
x: mm
width:friendsTabView.width-4*mm
height: 3*mm
text:Qt.atob(contact.name)+" (@"+contact.screen_name+")"
elide:Text.ElideRight
anchors.topMargin: 0
anchors.left: photoImage.left
color: "#303030"
font.pixelSize: 4*mm
anchors.top: photoImage.bottom
}
Rectangle{ Rectangle{
id: detailsrectangle id: detailsrectangle
anchors.top: namelabel.bottom anchors.top: namelabel.bottom
@ -69,10 +107,27 @@ Rectangle{
} }
} }
BlueButton{
id:eventbutton
visible:(contact.network=="dfrn")
text:"\uf073"
onClicked:{
root.currentIndex=3;
calendartab.active=true;
calendartab.calendartabstatus="Friend"
root.eventSignal(contact.url);
}
}
BlueButton{ BlueButton{
id: closeButton id: closeButton
text: "\uf057" //"close" text: "\uf057" //"close"
onClicked:{detailsrectangle.destroy();contactComponent.state="";friendsTabView.contactSignal} onClicked:{contactLargeComponent.destroy();
//contactComponent.state="";
friendsTabView.contactSignal}
} }
} }
} }
}
}

View File

@ -0,0 +1,91 @@
import QtQuick 2.0
import QtQuick.Controls 1.3
import "qrc:/qml/genericqml"
Rectangle{
id: detailsrectangle
anchors.top: namelabel.bottom
anchors.topMargin: 2*mm
ScrollView{
horizontalScrollBarPolicy:Qt.ScrollBarAlwaysOff
frameVisible: true
id:namelabelflickable
width: root.width-10*mm
height:friendsTabView.height-45*mm
x: mm
clip:true
Text{
id:namelabeltext
width: namelabelflickable.width
height: implicitHeight
font.pixelSize: 3*mm
textFormat:Text.RichText
wrapMode: Text.Wrap
text:"<b>"+qsTr("Description")+": </b> "+Qt.atob(contact.description)+"<br> <b>"+qsTr("Location")+":</b> "+contact.location+"<br> <b>"+qsTr("Posts")+":</b> "+contact.statuses_count+
"<br> <b>"+qsTr("URL")+":</b> <a href='"+ contact.url+"'>"+contact.url+"</a><br>"+
connectUrl+ "<b>"+qsTr("Created at")+":</b> "+createdAtDate.toLocaleString(Qt.locale())
onLinkActivated: {
Qt.openUrlExternally(link)}
}
}
Row{
anchors.top: namelabelflickable.bottom
anchors.topMargin: 2*mm
x: mm
spacing:4
BlueButton{
id:photobutton
text: "\uf03e" // "Photos"
visible:(contact.network=="dfrn")
onClicked:{
fotostab.phototabstatus="Contact";
root.currentIndex=2;
fotostab.active=true;
root.fotoSignal(contact) ;
}
}
BlueButton{
id:messagebutton
text: "\uf0e6" //"Messages"
onClicked:{
root.currentIndex=0;
newstab.active=true;
root.messageSignal(contact.id) ;
}
}
BlueButton{
id:dmbutton
visible: (contact.following=="true")
text: "\uf040" //"DM"
onClicked:{
root.currentIndex=0;
newstab.active=true;
root.directmessageSignal(contact.screen_name);
}
}
BlueButton{
id:eventbutton
visible:(contact.network=="dfrn")
text:"\uf073"
onClicked:{
root.currentIndex=3;
calendartab.active=true;
calendartab.calendartabstatus="Friend"
root.eventSignal(contact.url);
}
}
BlueButton{
id: closeButton
text: "\uf057" //"close"
onClicked:{detailsrectangle.destroy();contactComponent.state="";friendsTabView.contactSignal}
}
}
}

View File

@ -11,12 +11,13 @@ Rectangle {
color: "white" color: "white"
function showContactdetails(contact){ function showContactdetails(contact){
var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml");
if(contact.isFriend){ if(contact.isFriend){
friendsTabView.currentIndex=0; friendsTabView.currentIndex=0;
friendsTabView.contactsSignal(contact) var contactDetails = component.createObject(friendstab,{"contact": contact})
} }
else{friendsTabView.currentIndex=1; else{friendsTabView.currentIndex=1;
friendsTabView.contactsSignal(contact) var contactDetails = component.createObject(friendstab,{"contact": contact})
} }
} }
TabView{ TabView{
@ -30,7 +31,7 @@ Rectangle {
signal contactsSignal(var contact) signal contactsSignal(var contact)
signal groupsSignal(var username) signal groupsSignal(var username)
onCurrentIndexChanged:{ onCurrentIndexChanged:{
if (currentIndex==0){//print("currentindex 0"); if (currentIndex==0){
contactsSignal("") contactsSignal("")
} }
else if (currentIndex==1){ else if (currentIndex==1){
@ -60,18 +61,14 @@ Rectangle {
title: qsTr("Friends") title: qsTr("Friends")
Rectangle{ Rectangle{
id: friendsGridTab id: friendsGridTab
function makebig(friendindex){print("friendindex"+friendindex);if (friendindex){friendsModel.set(friendindex,{"status":"large"})}} function showFriends(contact){
function showFriends(contact,callback){//print("contact"+JSON.stringify(contact));
try {friendsModel.clear()} catch(e){print(e)}; try {friendsModel.clear()} catch(e){print(e)};
var friendindex;
Helperjs.readData(db,"contacts",root.login.username,function(friendsobject){ Helperjs.readData(db,"contacts",root.login.username,function(friendsobject){
for (var i=0;i<friendsobject.length;i++){ for (var i=0;i<friendsobject.length;i++){
var status=""; if(Helperjs.getCount(db,login,"contacts","screen_name",friendsobject[i].screen_name)>1){
if(Helperjs.getCount(db,login,"contacts","screen_name",friendsobject[i].screen_name)>1){
friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid
} }
if(contact){if (contact.cid==friendsobject[i].cid){status="large"}} friendsModel.append({"contact":friendsobject[i]});
friendsModel.append({"contact":friendsobject[i],"status":status});
} }
@ -113,12 +110,11 @@ Rectangle {
clip: true clip: true
cellHeight: 16*mm cellHeight: 16*mm
cellWidth: 17*mm cellWidth: 17*mm
add: Transition { //add: Transition {
NumberAnimation { properties: "x,y"; from: 300; duration: 1000 } // NumberAnimation { properties: "x,y"; from: 300; duration: 1000 }
} // }
model: friendsModel model: friendsModel
delegate: ContactComponent { } delegate: ContactComponent { }
Component.onCompleted: positionViewAtBeginning()
} }
ListModel{id:friendsModel} ListModel{id:friendsModel}
@ -132,7 +128,7 @@ Rectangle {
} }
Tab{ Tab{
title: qsTr("Other Contacts") title: qsTr("Contacts")
Rectangle{ Rectangle{
id: contactsGridTab id: contactsGridTab
@ -140,9 +136,7 @@ Rectangle {
try {contactsModel.clear()} catch(e){print(e)}; try {contactsModel.clear()} catch(e){print(e)};
Helperjs.readData(db, "contacts",root.login.username,function(contactsobject){ Helperjs.readData(db, "contacts",root.login.username,function(contactsobject){
for (var j=0;j<contactsobject.length;j++){ for (var j=0;j<contactsobject.length;j++){
var status=""; contactsModel.append({"contact":contactsobject[j]});
if(contact){if (contact.id==contactsobject[j].id){status="large"}}
contactsModel.append({"contact":contactsobject[j],"status":status});
} }
},"isFriend",0,"screen_name ASC"); },"isFriend",0,"screen_name ASC");
} }
@ -156,12 +150,11 @@ Rectangle {
clip: true clip: true
cellHeight: 16*mm cellHeight: 16*mm
cellWidth: 17*mm cellWidth: 17*mm
add: Transition { //add: Transition {
NumberAnimation { properties: "x,y"; from: 300; duration: 1000 } // NumberAnimation { properties: "x,y"; from: 300; duration: 1000 }
} // }
model: contactsModel model: contactsModel
delegate: ContactComponent { } delegate: ContactComponent { }
Component.onCompleted: positionViewAtBeginning()
} }
ListModel{id: contactsModel} ListModel{id: contactsModel}

View File

@ -24,6 +24,7 @@ TabView{
signal newsSignal(var news) signal newsSignal(var news)
signal friendsSignal(var username) signal friendsSignal(var username)
signal contactdetailsSignal(var contact) signal contactdetailsSignal(var contact)
signal eventSignal(var contact)
//currentIndex: (login=="")? 3:0 //currentIndex: (login=="")? 3:0
property var news:[] property var news:[]
@ -32,13 +33,13 @@ TabView{
property string contactLoadType: "" property string contactLoadType: ""
onLoginChanged:{ onLoginChanged:{
if(login==""){root.currentIndex=3} if(login==""){root.currentIndex=4}
else{ else{
newstab.newstabstatus=login.newsViewType; newstab.newstabstatus=login.newsViewType;
Newsjs.getCurrentContacts(login,db,function(contacts){ Newsjs.getCurrentContacts(login,db,function(contacts){
contactlist=contacts})} contactlist=contacts})}
} }
onNewContactsChanged:{ onNewContactsChanged:{//print(JSON.stringify(newContacts));
if(newContacts.length>0){// download first contact image and update db if(newContacts.length>0){// download first contact image and update db
Service.updateContactInDB(login,db,newContacts[currentContact].isFriend,newContacts[currentContact])} Service.updateContactInDB(login,db,newContacts[currentContact].isFriend,newContacts[currentContact])}
else if (contactLoadType!=""){ else if (contactLoadType!=""){
@ -49,6 +50,7 @@ TabView{
} }
onCurrentContactChanged:{// download next contact image after photoplaceholder is finished saving and update db onCurrentContactChanged:{// download next contact image after photoplaceholder is finished saving and update db
if(currentContact<newContacts.length){ if(currentContact<newContacts.length){
Service.updateContactInDB(login,db,newContacts[currentContact].isFriend,newContacts[currentContact])} Service.updateContactInDB(login,db,newContacts[currentContact].isFriend,newContacts[currentContact])}
else if (contactLoadType!=""){ else if (contactLoadType!=""){
@ -96,10 +98,12 @@ TabView{
if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,function(dbnews){ if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,function(dbnews){
newsSignal(dbnews) newsSignal(dbnews)
})} })}
else{Newsjs.chatsfromdb(db,login.username,function(dbnews){ else{
Newsjs.chatsfromdb(db,login.username,function(dbnews){
newsSignal(dbnews) newsSignal(dbnews)
})} })}
} }
else if (newstab.conversation.length>0){newstab.conversation=[]}
else{Service.cleanNews(root.db,function(){Qt.quit()})} else{Service.cleanNews(root.db,function(){Qt.quit()})}
} }
else if (currentIndex==2){fotoSignal("backButton")} else if (currentIndex==2){fotoSignal("backButton")}
@ -113,8 +117,8 @@ TabView{
tab: Rectangle { tab: Rectangle {
color: styleData.selected?"sky blue":"light blue" color: styleData.selected?"sky blue":"light blue"
border.color: "light grey" border.color: "light grey"
implicitWidth: root.width/4-2*mm implicitWidth: root.width/5-2*mm
implicitHeight: 4*mm implicitHeight: 5*mm
Text { id: text Text { id: text
anchors.centerIn: parent anchors.centerIn: parent
text: styleData.title text: styleData.title
@ -145,9 +149,17 @@ TabView{
property string phototabstatus:"Images" property string phototabstatus:"Images"
source: (root.currentIndex==2)?"qrc:/qml/photoqml/PhotoTab.qml":"" source: (root.currentIndex==2)?"qrc:/qml/photoqml/PhotoTab.qml":""
} }
Tab{
title: "\uf073"
id: calendartab
property string calendartabstatus:"Events"
source: (root.currentIndex==3)?"qrc:/qml/calendarqml/CalendarTab.qml":""
}
Tab{ Tab{
title:"\uf085" title:"\uf085"
id: configtab id: configtab
source: (root.currentIndex==3)?"qrc:/qml/configqml/ConfigTab.qml":"" source: (root.currentIndex==4)?"qrc:/qml/configqml/ConfigTab.qml":""
} }
} }

View File

@ -1,34 +1,106 @@
// ConversationStack with buttons // ConversationView with button
import QtQuick 2.0 import QtQuick 2.0
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/genericqml" import "qrc:/qml/genericqml"
Rectangle { Rectangle {
id:conversationStack id:conversationList
property var news property var news
y:1 y:1
color: "white" z:2
width:root.width-2*mm color: "white"
height:root.height-8*mm border.color: "grey"
width:root.width-5*mm
height: conversationView.height+10*mm
Connections{
target:newstab
onConversationChanged:{
if(newstab.conversation.length==0){
newsView.positionViewAtIndex(newsStack.conversationIndex,ListView.Beginning);
conversationList.destroy(); conversationsymbol.color="grey"
}
}
}
ListView { ListView {
id: conversationView id: conversationView
x:3*mm x:3*mm
y:8*mm y:8*mm
width: conversationStack.width-4*mm width: conversationList.width-4*mm
height: conversationStack.height-10*mm height: contentHeight
clip: true clip: true
spacing: 0 spacing: 0
footer: footerReply
model: conversationModel model: conversationModel
delegate: Newsitem{} delegate: Newsitem{}
} }
ListModel{id: conversationModel} Component { id:footerReply
Rectangle{
border.color: "#EEEEEE"
border.width: 1
color:"lightgrey"
width:conversationView.width
height:Math.max(replyText.contentHeight+2*mm,6*mm)
Rectangle{
color: "white"
radius:0.5*mm
anchors.left: parent.left
anchors.leftMargin:mm
anchors.top:parent.top
anchors.topMargin: 0.5*mm
width:parent.width-12*mm
height:Math.max( replyText.contentHeight,5*mm)
WorkerScript { TextInput {
id: conversationWorker id: replyText
source: "qrc:/js/newsworker.js" font.pixelSize: 3*mm
} wrapMode: Text.Wrap
anchors.fill: parent
selectByMouse: true
}
}
BlueButton {
id: sendButton
text: "\uf1d9"
anchors.right: parent.right
anchors.rightMargin:mm
anchors.top:parent.top
anchors.topMargin: 0.5*mm
color:"white"
onClicked: { try{
var body=replyText.getText(0,replyText.length);
newsBusy.running=true;
replyText.text=""
xhr.clearParams();
xhr.setLogin(login.username+":"+Qt.atob(login.password));
if (conversationModel.get(0).newsitemobject.messagetype==0){
xhr.setParam("source", "Friendiqa");
xhr.url= login.server + "/api/statuses/update.json";
xhr.setParam("status", body);
xhr.setParam("in_reply_to_status_id", conversationModel.get(conversationModel.count-1).newsitemobject.status_id)}
else {xhr.url= login.server + "/api/direct_messages/new.json";
xhr.setParam("text", body);
xhr.setParam("screen_name",conversationModel.get(conversationModel.count-1).newsitemobject.screen_name);
xhr.setParam("replyto", conversationModel.get(conversationModel.count-1).newsitemobject.status_id)
}
xhr.post();
//replyText.text=""
} catch(e){Helperjs.showMessage("Error",e.toString(),root)}
}
}
}
}
ListModel{id: conversationModel}
WorkerScript {
id: conversationWorker
source: "qrc:/js/newsworker.js"
}
BlueButton { BlueButton {
id: closeButton id: closeButton
@ -37,10 +109,11 @@ Rectangle {
anchors.topMargin: 1*mm anchors.topMargin: 1*mm
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 1*mm anchors.rightMargin: 1*mm
text: "\uf057"// qsTr("Close") text: "\uf057"
onClicked: { onClicked: {
newstab.newstabstatus=login.newsViewType; newsView.positionViewAtIndex(newsStack.conversationIndex,ListView.Beginning);
newsStack.pop() conversationList.destroy();
conversationsymbol.color="grey"
} }
} }

View File

@ -42,12 +42,11 @@ Rectangle{
clip: true clip: true
model: imageModel model: imageModel
delegate: imageItem delegate: imageItem
} }
FolderListModel{ FolderListModel{
id: imageModel id: imageModel
nameFilters: ["*.png", "*.jpg",".jpeg","*.JPG"] nameFilters: ["*.png", "*.jpg",".jpeg","*.JPG","*.gif"]
sortField: FolderListModel.Time sortField: FolderListModel.Time
sortReversed:false sortReversed:false
showDotAndDotDot: true showDotAndDotDot: true
@ -111,8 +110,9 @@ Rectangle{
directory=fileURL directory=fileURL
} }
else{ else{
attachImageURL=fileURL; attachImageURLs.push(fileURL);
imageDialog.destroy() attachImage(fileURL);
imageDialog.destroy()
} }
} }
} }

View File

@ -16,7 +16,7 @@ Flickable{
id:messageSend id:messageSend
property string parentId: "" property string parentId: ""
property string reply_to_user:"" property string reply_to_user:""
property string attachImageURL: ""; property var attachImageURLs: [];
property int directmessage: 0; property int directmessage: 0;
property var contacts: [] property var contacts: []
property var groups: [] property var groups: []
@ -25,11 +25,13 @@ Flickable{
property var group_allow:login.permissions[2] property var group_allow:login.permissions[2]
property var group_deny:login.permissions[3] property var group_deny:login.permissions[3]
onAttachImageURLChanged: {if(attachImageURL!=""){ function attachImage(url){
var imageAttachmentObject=Qt.createQmlObject('import QtQuick 2.0; Image {id:imageAttachment; source:"'+ //onAttachImageURLsChanged: {if(attachImageURL!=""){
attachImageURL.toString()+'"; width: 15*mm; height: 15*mm;fillMode: Image.PreserveAspectFit;MouseArea{anchors.fill:parent;onClicked:{attachImageURL="";imageAttachment.destroy()}}}',messageColumn,"attachedImage"); var imageAttachmentObject=Qt.createQmlObject('import QtQuick 2.0; Image {id:imageAttachment'+attachImageURLs.length+'; source:"'+
console.log("You chose: " + attachImageURL) url.toString()+'"; width: 15*mm; height: 15*mm;fillMode: Image.PreserveAspectFit;MouseArea{anchors.fill:parent;onClicked:{attachImageURLs.splice(attachImageURLs.indexOf("'+url+'",1)); imageAttachment'+attachImageURLs.length+'.destroy()}}}',messageColumn,"attachedImage");
}} console.log("You chose: " + url)
}
function statusUpdate(title,status,in_reply_to_status_id,attachImageURL) { function statusUpdate(title,status,in_reply_to_status_id,attachImageURL) {
xhr.url= login.server + "/api/statuses/update.json"; xhr.url= login.server + "/api/statuses/update.json";
xhr.setLogin(login.username+":"+Qt.atob(login.password)); xhr.setLogin(login.username+":"+Qt.atob(login.password));
@ -42,7 +44,7 @@ Flickable{
if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))}; if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))};
if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))}; if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))};
if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))}; if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))};
if (attachImageURL!=="") {xhr.setImageFileParam("media", attachImageURL )}; if (attachImageURL.length>0) {for (var image in attachImageURL){xhr.setImageFileParam("media", attachImageURL[image] )}};
xhr.post(); xhr.post();
} }
@ -122,12 +124,11 @@ Flickable{
} }
} }
Row{ Row{
spacing:2 spacing:2
BlueButton{id:permButton BlueButton{id:permButton
visible: (directmessage==1)?false:true visible: (directmessage==1)?false:true
text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023"//qsTr("Permissions") text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023"
onClicked: { onClicked: {
var component = Qt.createComponent("qrc:/qml/newsqml/PermissionDialog.qml"); var component = Qt.createComponent("qrc:/qml/newsqml/PermissionDialog.qml");
var permissions = component.createObject(messageColumn); var permissions = component.createObject(messageColumn);
@ -137,14 +138,14 @@ Flickable{
text: "\uf0c6" text: "\uf0c6"
visible:(directmessage==0) visible:(directmessage==0)
onClicked: { onClicked: {
if (attachImageURL!=""){ if (attachImageURLs.length>0){//Server currently accepts only one attachment
Helperjs.showMessage( qsTr("Error"),qsTr("Only one attachment. Remove other attachment first!"), messageColumn)} Helperjs.showMessage( qsTr("Error"),qsTr("Only one attachment supported at the moment.\n Remove other attachment first!"), messageColumn)
else{print(filesystem.homePath); }
var defaultDirectory="file://"+osSettings.attachImageDir;//"file:///storage/emif.open() else{
print(defaultDirectory); var defaultDirectory="file://"+osSettings.attachImageDir;
var component = Qt.createComponent("qrc:/qml/newsqml/ImageDialog.qml"); var component = Qt.createComponent("qrc:/qml/newsqml/ImageDialog.qml");
var imagedialog = component.createObject(messageSend,{"directory": defaultDirectory}); var imagedialog = component.createObject(messageSend,{"directory": defaultDirectory});
} }
} }
} }
BlueButton{ BlueButton{
@ -188,7 +189,7 @@ Flickable{
var title=titleField.text.replace("\"","\'"); var title=titleField.text.replace("\"","\'");
var body=bodyField.getText(0,bodyField.length); var body=bodyField.getText(0,bodyField.length);
if (directmessage==0){ if (directmessage==0){
statusUpdate(title,body,messageSend.parentId,attachImageURL.toString())} statusUpdate(title,body,messageSend.parentId,attachImageURLs)}
else {dmUpdate(title,body,"",messageSend.reply_to_user) } else {dmUpdate(title,body,"",messageSend.reply_to_user) }
newstab.newstabstatus=login.newsViewType; newsStack.pop() newstab.newstabstatus=login.newsViewType; newsStack.pop()
} }

View File

@ -13,23 +13,13 @@ Item {
} }
} }
Connections{
target:newstab
onConversationChanged:{
newsBusy.running=false;
newstab.newstabstatus="Conversation";
//newsStack.push({item:"qrc:/qml/newsqml/Conversation.qml",properties:{"news": conversation}})
showNews(conversation);
}
}
Connections{ Connections{
target:root target:root
onCurrentContactChanged:{ onCurrentContactChanged:{
if (root.newContacts.length>0){ if (root.newContacts.length>0){
if(root.currentContact<root.newContacts.length){ if(root.currentContact<root.newContacts.length){
downloadNotice.text= qsTr("Download profile image for ")+ root.newContacts[root.currentContact].name; downloadNotice.text= qsTr("Download profile image for ")+ root.newContacts[root.currentContact].name;
print(root.newContacts[root.currentContact].name) //print(root.newContacts[root.currentContact].name)
} }
}else{downloadNotice.text=""} }else{downloadNotice.text=""}
} }
@ -62,23 +52,19 @@ Item {
newsWorker.sendMessage(msg); newsWorker.sendMessage(msg);
} }
function showConversation(timelineIndex,newsitemobject){ function showConversation(conversationIndex,newsitemobject){
newsBusy.running=true; newsBusy.running=true;
root.contactLoadType="conversation"; root.contactLoadType="conversation";
newsStack.timelineIndex= timelineIndex; newsStack.conversationIndex= conversationIndex;
if(newsitemobject.messagetype==0){ if(newsitemobject.messagetype==0){
Newsjs.requestConversation(root.login,db,newsitemobject.status_id,root.contactlist,root,function(ns,nc){ Newsjs.requestConversation(root.login,db,newsitemobject.status_id,root.contactlist,root,function(ns,nc){
root.news=ns;root.newContacts=nc;root.currentContact=0; root.news=ns;root.newContacts=nc;root.currentContact=0;
})} })}
else{Newsjs.conversationfromdb(root.db,root.login.username,newsitemobject.statusnet_conversation_id, function(newsarray){ else{Newsjs.conversationfromdb(root.db,root.login.username,newsitemobject.statusnet_conversation_id, function(newsarray){
root.news=newsarray;root.newContacts=[];root.currentContact=1; root.news=newsarray;root.newContacts=[];root.currentContact=1;
})} })}
} }
function onFriendsMessages(friend){ function onFriendsMessages(friend){
newstab.newstabstatus="Contact" newstab.newstabstatus="Contact"
Newsjs.newsfromdb(db,root.login.username, function(dbnews){showNews(dbnews)},friend) Newsjs.newsfromdb(db,root.login.username, function(dbnews){showNews(dbnews)},friend)
@ -92,14 +78,11 @@ Item {
StackView{ StackView{
id: newsStack id: newsStack
anchors.fill:parent anchors.fill:parent
property int timelineIndex: 0 property int conversationIndex: 0
onTimelineIndexChanged:print("timelineindex:"+ timelineIndex)
initialItem:Rectangle { initialItem:Rectangle {
y:1 y:1
color: "white" color: "white"
width:root.width-2*mm
height:root.height-8*mm
BlueButton{ BlueButton{
id:newstabstatusButton id:newstabstatusButton
@ -116,26 +99,27 @@ Item {
anchors.right: parent.right anchors.right: parent.right
BlueButton { BlueButton {
id: newMessageButton id: newMessageButton
width:10*mm width:10*mm
text: "\uf040" text: "\uf040"
onClicked: { onClicked: {
var groups=[]; var groups=[];
Helperjs.readData(root.db,"groups",root.login.username,function(groupobject){ Helperjs.readData(root.db,"groups",root.login.username,function(groupobject){
groups=groupobject}); groups=groupobject
newstab.newstabstatus="SendMessage"; });
Helperjs.readData(root.db,"contacts",root.login.username,function(friends){ newstab.newstabstatus="SendMessage";
newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"contacts": friends,"login":root.login}}) Helperjs.readData(root.db,"contacts",root.login.username,function(friends){
},"isFriend",1); newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"contacts": friends,"login":root.login}})
} },"isFriend",1);
} }
BlueButton { }
id: quitButton BlueButton {
width:10*mm id: quitButton
text: "\uf08b" width:10*mm
onClicked: {Service.cleanNews(root.db,function(){Qt.quit() })} text: "\uf08b"
} onClicked: {Service.cleanNews(root.db,function(){Qt.quit() })}
BlueButton { }
BlueButton {
id: update id: update
text: "\uf021" text: "\uf021"
onClicked: { onClicked: {
@ -176,7 +160,7 @@ Item {
var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true};
newsWorker.sendMessage(msg); newsWorker.sendMessage(msg);
},false,lastnews_id)} },false,lastnews_id)}
if(newstab.newstabstatus=="Tree"){ if(newstab.newstabstatus=="Conversations"){
var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at; var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at;
Newsjs.chatsfromdb(root.db,root.login.username, function(news){ Newsjs.chatsfromdb(root.db,root.login.username, function(news){
var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true};
@ -191,83 +175,35 @@ Item {
} }
} }
Component { id:footerReply
Rectangle{
border.color: "#EEEEEE"
border.width: 1
color:"lightgrey"
width:newsView.width
height:Math.max(replyText.contentHeight+2*mm,6*mm)
Rectangle{
color: "white"
radius:0.5*mm
anchors.left: parent.left
anchors.leftMargin:mm
anchors.top:parent.top
anchors.topMargin: 0.5*mm
width:parent.width-12*mm
height:Math.max( replyText.contentHeight,5*mm)
TextInput {
id: replyText
font.pixelSize: 3*mm
wrapMode: Text.Wrap
//width: parent.width
anchors.fill: parent
selectByMouse: true
}
}
BlueButton {
id: sendButton
text: "\uf1d9"
anchors.right: parent.right
anchors.rightMargin:mm
anchors.top:parent.top
anchors.topMargin: 0.5*mm
color:"white"
onClicked: { try{
var body=replyText.getText(0,replyText.length);
newsBusy.running=true;
replyText.text=""
xhr.clearParams();
xhr.setLogin(login.username+":"+Qt.atob(login.password));
if (newsModel.get(0).newsitemobject.messagetype==0){
xhr.setParam("source", "Friendiqa");
xhr.url= login.server + "/api/statuses/update.json";
xhr.setParam("status", body);
xhr.setParam("in_reply_to_status_id", newsModel.get(newsModel.count-1).newsitemobject.status_id)}
else {xhr.url= login.server + "/api/direct_messages/new.json";
xhr.setParam("text", body);
xhr.setParam("screen_name",newsModel.get(newsModel.count-1).newsitemobject.screen_name);
xhr.setParam("replyto", newsModel.get(newsModel.count-1).newsitemobject.status_id)
}
xhr.post();
//replyText.text=""
} catch(e){Helperjs.showMessage("Error",e.toString(),root)}
}
}
}
}
ListView { ListView {
id: newsView id: newsView
anchors.fill: parent anchors.fill: parent
anchors.topMargin: 8*root.mm anchors.topMargin: 7*root.mm
anchors.leftMargin: 3*root.mm; anchors.rightMargin: root.mm anchors.leftMargin: 3*root.mm; anchors.rightMargin: root.mm
anchors.bottomMargin: 1*root.mm anchors.bottomMargin: 1*root.mm
clip: true clip: true
spacing: 0 spacing: 0
footer: (newstab.newstabstatus=="Conversation")?footerReply:footerComponent footer: footerComponent
model: newsModel model: newsModel
delegate: Newsitem{} delegate: Newsitem{}
Component.onCompleted: {//print(newstab.newstabstatus); //onContentYChanged:{if(contentY<-15*mm&&contentY>(-15*mm-1)){print("refreshing");
if(newstab.newstabstatus!="Conversation"){ onDragEnded:{if(contentY<-8*mm){//print("refreshing");
positionViewAtIndex(newsStack.timelineIndex-1, ListView.Beginning)} newsBusy.running=true;
else {positionViewAtBeginning(); newstab.newstabstatus=login.newsViewType;
newsStack.timelineIndex=0 root.contactLoadType="news";
}} var onlynew=true;
} Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(ns,nc){
root.news=ns;root.newContacts=nc;root.currentContact=0;
if (ns.length==0){// update last 20 existing news for changes and likes
onlynew=false;
Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(rns,rnc){
root.contactLoadType="news";
root.news=rns;root.newContacts=rnc;root.currentContact=0})
}
})
}}
}
ListModel{id: newsModel} ListModel{id: newsModel}
@ -331,10 +267,10 @@ Item {
} }
MenuItem { MenuItem {
text: qsTr("Tree") text: qsTr("Conversations")
onTriggered:{ onTriggered:{
newsModel.clear(); newsModel.clear();
newstab.newstabstatus="Tree"; newstab.newstabstatus="Conversations";
Newsjs.chatsfromdb(db,root.login.username,function(news){showNews(news)}) Newsjs.chatsfromdb(db,root.login.username,function(news){showNews(news)})
} }
} }

View File

@ -7,9 +7,23 @@ import "qrc:/js/helper.js" as Helperjs
Item { Item {
id: newsitem id: newsitem
width: newsView.width width: parent.width
height:Math.max((itemMessage.height+topFlow.height+friendicaActivities.height+4*mm),profileImage.height+user_name.height+mm) height:toprow.height+friendicaActivities.height+controlrow.height+1//Math.max((itemMessage.height+topFlow.height+friendicaActivities.height+4*mm),profileImage.height+user_name.height+mm)
Connections{
target:newstab
onConversationChanged:{
newsBusy.running=false;
if(index==newsStack.conversationIndex){
if(newstab.conversation.length>0){
var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml");
var conversation = component.createObject(friendicaActivities,{"news":newstab.conversation});
}
else{conversationsymbol.color="grey"}
}
}
}
property string attending: "" property string attending: ""
onAttendingChanged: {attendLabel.visible=true; onAttendingChanged: {attendLabel.visible=true;
attendLabel.text= qsTr("attending: ")+ qsTr(attending)} attendLabel.text= qsTr("attending: ")+ qsTr(attending)}
@ -19,9 +33,7 @@ Item {
function showActivityContacts(contacts){ function showActivityContacts(contacts){
var component = Qt.createComponent("qrc:/qml/newsqml/FriendicaActivities.qml"); var component = Qt.createComponent("qrc:/qml/newsqml/FriendicaActivities.qml");
var imagedialog = component.createObject(friendicaActivities,{"activitymembers": contacts}); var imagedialog = component.createObject(friendicaActivities,{"activitymembers": contacts});
} }
Rectangle{width:newsitem.width; height: 1; anchors.bottom: newsitem.bottom; color:"light grey"} Rectangle{width:newsitem.width; height: 1; anchors.bottom: newsitem.bottom; color:"light grey"}
Rectangle{ Rectangle{
@ -29,7 +41,8 @@ Item {
height:newsitem.height-1 height:newsitem.height-1
color: (newsitemobject.messagetype==1)?"#ffe6e6" : "white" color: (newsitemobject.messagetype==1)?"#ffe6e6" : "white"
Column { Row{id:toprow
Column {
id: authorcolumn id: authorcolumn
width: 8*mm width: 8*mm
@ -41,7 +54,7 @@ Item {
height: 7*mm height: 7*mm
MouseArea{ MouseArea{
anchors.fill: parent anchors.fill: parent
onClicked:{print(root.currentIndex); onClicked:{
try{root.currentIndex=1; try{root.currentIndex=1;
friendstab.active=true; friendstab.active=true;
root.contactdetailsSignal(newsitemobject.user)} catch (e){Helperjs.showMessage("Error",e,root)} root.contactdetailsSignal(newsitemobject.user)} catch (e){Helperjs.showMessage("Error",e,root)}
@ -61,7 +74,7 @@ Item {
Column { Column {
id:newscolumn id:newscolumn
width: newsitem.width-8*mm width: newsitem.width-8*mm
anchors.left: authorcolumn.right //anchors.left: authorcolumn.right
Flow{ Flow{
id:topFlow id:topFlow
@ -92,7 +105,7 @@ Item {
Label { Label {
id:newscountLabel id:newscountLabel
visible:((newstabstatus=="Tree")&&(newsitemobject.newscount>1))?true:false visible:((newstabstatus=="Conversations")&&(newsitemobject.newscount>1))?true:false
color: "grey" color: "grey"
height:3.5*mm height:3.5*mm
font.pixelSize: 1.5*mm font.pixelSize: 1.5*mm
@ -117,12 +130,25 @@ Item {
wrapMode: Text.Wrap wrapMode: Text.Wrap
onLinkActivated:{ onLinkActivated:{
Qt.openUrlExternally(link)} Qt.openUrlExternally(link)}
Component.onCompleted:{
if (newsitemobject.attachmentList.length>0){
for(var attachments in newsitemobject.attachmentList){// (newsitemobject.attachmentList[attachments].url);
var attachcomponent = Qt.createQmlObject('import QtQuick 2.0; '+
'AnimatedImage {id:gif;source: "'+newsitemobject.attachmentList[attachments].url+
'";onStatusChanged: playing = (status == AnimatedImage.Ready)}',
friendicaActivities,"Attachment"+attachments);
}
}
}
} }
}
Flow{ }
Flow{
id:friendicaActivities id:friendicaActivities
anchors.top:toprow.bottom
width:parent.width width:parent.width
spacing:mm spacing:mm
Label{color: "grey" Label{color: "grey"
font.pixelSize: 1.5*mm font.pixelSize: 1.5*mm
text: friendica_activities.likeText text: friendica_activities.likeText
@ -162,11 +188,22 @@ Item {
onClicked: { showActivityContacts(newsitemobject.attendmaybe)} onClicked: { showActivityContacts(newsitemobject.attendmaybe)}
} }
} }
Label{
id:attendLabel
//visible: false
color: "grey"
height:3.5*mm
font.pixelSize: 1.5*mm
horizontalAlignment: Label.AlignRight
text: (friendica_activities.self.attending)?(qsTr("Attending: ")+ qsTr(friendica_activities.self.attending)):""
}
} }
Row{ Row{id:controlrow
anchors.top:friendicaActivities.bottom
CheckBox{ CheckBox{
id:likeCheckbox id:likeCheckbox
height:3*mm //height:3*mm
width:8*mm width:8*mm
visible: (newsitemobject.messagetype==0)? true:false visible: (newsitemobject.messagetype==0)? true:false
checked:(friendica_activities.self.liked==1)?true:false checked:(friendica_activities.self.liked==1)?true:false
@ -195,7 +232,7 @@ Item {
} }
CheckBox{ CheckBox{
id: dislikeCheckbox id: dislikeCheckbox
height:3*mm //height:3*mm
width:8*mm width:8*mm
visible: (newsitemobject.messagetype==0)? true:false visible: (newsitemobject.messagetype==0)? true:false
checked: (friendica_activities.self.disliked==1)?true:false checked: (friendica_activities.self.disliked==1)?true:false
@ -222,10 +259,30 @@ Item {
if (dislikeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"dislike",newsitemobject.status_id,root);likeCheckbox.checked=false; model.friendica_activities.self.disliked=0} if (dislikeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"dislike",newsitemobject.status_id,root);likeCheckbox.checked=false; model.friendica_activities.self.disliked=0}
else {Newsjs.like(root.login,root.db,0,"dislike",newsitemobject.status_id,root); model.friendica_activities.self.disliked=1}} else {Newsjs.like(root.login,root.db,0,"dislike",newsitemobject.status_id,root); model.friendica_activities.self.disliked=1}}
} }
// Rectangle{
// width: 8*mm
// height: 3*mm
// color:"transparent"
// Text{
// id:trashsymbol
// color: "grey"
// anchors.centerIn: parent
// font.pixelSize: 2*mm
// font.bold: true
// text: "\uf1f8"
// }
// MouseArea{
// anchors.fill:parent
// onClicked: {
// Newsjs.deleteNews(root.login,root.db,newsitemobject.status_id,newsitemobject.messagetype,root,function(reply){
// newsModel.remove(index)})
// }}
// }
CheckBox { CheckBox {
id:favoritedCheckbox id:favoritedCheckbox
visible:(newsitemobject.messagetype==0) visible:(newsitemobject.messagetype==0)
width: 7*mm width: 8*mm
style: CheckBoxStyle { style: CheckBoxStyle {
background: Rectangle { background: Rectangle {
implicitWidth: 6*mm implicitWidth: 6*mm
@ -251,7 +308,7 @@ Item {
} }
} }
Rectangle{ Rectangle{
width: 7*mm width: 8*mm
height: 3*mm height: 3*mm
color:"transparent" color:"transparent"
Text{ Text{
@ -267,7 +324,7 @@ Item {
onClicked: {newsmenu.popup()}} onClicked: {newsmenu.popup()}}
} }
Rectangle{ Rectangle{
width: 7*mm width: 8*mm
height: 3*mm height: 3*mm
visible:newstab.newstabstatus!="Conversation" visible:newstab.newstabstatus!="Conversation"
color:"transparent" color:"transparent"
@ -281,20 +338,15 @@ Item {
} }
MouseArea{ MouseArea{
anchors.fill:parent anchors.fill:parent
onClicked: { conversationsymbol.color="black";showConversation(index,newsitemobject)} onClicked:{
conversationsymbol.color="black";
showConversation(index,newsitemobject)
}
} }
} }
Label{
id:attendLabel
//visible: false
color: "grey"
height:3.5*mm
font.pixelSize: 1.5*mm
horizontalAlignment: Label.AlignRight
text: (friendica_activities.self.attending)?(qsTr("Attending: ")+ qsTr(friendica_activities.self.attending)):""
}
} }
}
Menu { Menu {
id:newsmenu id:newsmenu
MenuItem { MenuItem {
@ -350,6 +402,4 @@ Item {
} }
} }
} }
} }}
}

View File

@ -32,7 +32,7 @@ Rectangle{
Text{ Text{
x:0.5*mm x:0.5*mm
y:0.5*mm y:0.5*mm
text: "Contacts" text: qsTr("Friends")
} }
ListView { ListView {
id: contactView id: contactView
@ -93,7 +93,7 @@ Rectangle{
Text{ Text{
x:contactView.width+2*mm x:contactView.width+2*mm
y:0.5*mm y:0.5*mm
text: "Groups" text: qsTr("Groups")
} }
ListView { ListView {
id: groupView id: groupView

View File

@ -105,7 +105,7 @@ Rectangle {
anchors.topMargin: 0.5*mm anchors.topMargin: 0.5*mm
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin:2*mm anchors.rightMargin:2*mm
text: qsTr(phototabstatus) text: fotostab.phototabstatus=="Images"?qsTr("Own Images"):fotostab.phototabstatus
onClicked: {phototabmenu.popup()} onClicked: {phototabmenu.popup()}
} }
Menu { Menu {
@ -114,7 +114,7 @@ Rectangle {
text: qsTr("Own Images") text: qsTr("Own Images")
onTriggered: { onTriggered: {
fotostab.phototabstatus="Images"; fotostab.phototabstatus="Images";
phototabstatusButton.text=qsTr("own images"); // phototabstatusButton.text=qsTr("Own images");
showFotos("")} showFotos("")}
} }
} }

Binary file not shown.

View File

@ -0,0 +1,470 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="de">
<context>
<name>CalendarTab</name>
<message>
<location filename="../qml/calendarqml/CalendarTab.qml" line="73"/>
<source>Events</source>
<translation>Termine</translation>
</message>
<message>
<location filename="../qml/calendarqml/CalendarTab.qml" line="79"/>
<source>Own Calendar</source>
<translation>Eigener Kalender</translation>
</message>
</context>
<context>
<name>ConfigTab</name>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="32"/>
<location filename="../qml/configqml/ConfigTab.qml" line="62"/>
<location filename="../qml/configqml/ConfigTab.qml" line="288"/>
<location filename="../qml/configqml/ConfigTab.qml" line="309"/>
<source>User</source>
<translation>Name</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="58"/>
<source>Server</source>
<translation>Server</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="67"/>
<source>Password</source>
<translation>Passwort</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="71"/>
<source>Image dir.</source>
<translation>Bildverz.</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="76"/>
<source>Max. News</source>
<translation>Max. Nachr.</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="80"/>
<source>News as</source>
<translation>Anzeige</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="84"/>
<source>Interval (0=None)</source>
<translation>Intervall (0=keins)</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="235"/>
<source>Confirm</source>
<translation>Bestätigen</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="239"/>
<source>No server given! </source>
<translation>Kein Server angegeben!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="240"/>
<source>No username given! </source>
<translation>Kein Nutzername angegeben!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="241"/>
<source>No password given! </source>
<translation>Kein Passwort angegeben!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="242"/>
<source>No image directory given!</source>
<translation>Kein Verzeichnis für Bilder angegeben!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="243"/>
<source>No maximum news number given!</source>
<translation>Maximale News-Anzahl nicht angegeben!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="324"/>
<source>Timeline</source>
<translation>Chronologisch</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="328"/>
<source>Conversations</source>
<translation>Unterhaltungen</translation>
</message>
</context>
<context>
<name>ContactComponent</name>
<message>
<location filename="../qml/contactqml/ContactComponent.qml" line="8"/>
<source>Connect</source>
<translation>Kontaktanfrage</translation>
</message>
</context>
<context>
<name>ContactDetailsComponent</name>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="11"/>
<source>Connect</source>
<translation>Kontaktanfrage</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/>
<source>Description</source>
<translation>Beschreibung</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/>
<source>Location</source>
<translation>Ort</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/>
<source>Posts</source>
<translation>Beiträge</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="64"/>
<source>URL</source>
<translation>Profilseite</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="65"/>
<source>Created at</source>
<translation>Erstellt</translation>
</message>
</context>
<context>
<name>FriendsTab</name>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="61"/>
<source>Friends</source>
<translation>Freunde</translation>
</message>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="131"/>
<source>Contacts</source>
<translation>Kontakte</translation>
</message>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="167"/>
<source>Groups</source>
<translation>Gruppen</translation>
</message>
</context>
<context>
<name>MessageSend</name>
<message>
<location filename="../qml/newsqml/MessageSend.qml" line="69"/>
<source>Title (optional)</source>
<translation>Überschrift (optional)</translation>
</message>
<message>
<location filename="../qml/newsqml/MessageSend.qml" line="142"/>
<source>Error</source>
<translation>Fehler</translation>
</message>
<message>
<location filename="../qml/newsqml/MessageSend.qml" line="142"/>
<source>Only one attachment supported at the moment.
Remove other attachment first!</source>
<translation>Nur ein Anhang derzeit unterstützt.
Lösche zuerst den anderen Anhang!</translation>
</message>
</context>
<context>
<name>NewsTab</name>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="21"/>
<source>Download profile image for </source>
<translation>Lade Profilbild für </translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="152"/>
<source>More</source>
<translation>Mehr</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="249"/>
<source>Timeline</source>
<translation>Chronologisch</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="258"/>
<source>Favorites</source>
<translation>Markierte News</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="270"/>
<source>Conversations</source>
<translation>Unterhaltungen</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="278"/>
<source>Notifications</source>
<translation>Meldungen</translation>
</message>
</context>
<context>
<name>Newsitem</name>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="29"/>
<source>attending: </source>
<translation>Teilnahme</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="86"/>
<source>Source: </source>
<translation>Quelle: </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="87"/>
<source>Direct Message</source>
<translation>Direktnachricht</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="102"/>
<source>In reply to </source>
<translation>Antwort an </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="114"/>
<source> comments</source>
<translation> Kommentare</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="198"/>
<source>Attending: </source>
<translation>Teilnahme: </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="353"/>
<source>Reply</source>
<translation>Antworten</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="361"/>
<source>DM</source>
<translation>Direktnachricht</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="367"/>
<source>Repost</source>
<translation>Teilen</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="374"/>
<source>Conversation</source>
<translation>Unterhaltung</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="379"/>
<source>Attending</source>
<translation>Teilnahme</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="381"/>
<source>yes</source>
<translation>ja</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="386"/>
<source>maybe</source>
<translation>vielleicht</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="391"/>
<source>no</source>
<translation>nein</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="398"/>
<source>Delete</source>
<translation>Löschen</translation>
</message>
</context>
<context>
<name>PermissionDialog</name>
<message>
<location filename="../qml/newsqml/PermissionDialog.qml" line="35"/>
<source>Friends</source>
<translation>Freunde</translation>
</message>
<message>
<location filename="../qml/newsqml/PermissionDialog.qml" line="96"/>
<source>Groups</source>
<translation>Gruppen</translation>
</message>
</context>
<context>
<name>PhotoTab</name>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="66"/>
<source>&apos;s images</source>
<translation>s Bilder</translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="108"/>
<location filename="../qml/photoqml/PhotoTab.qml" line="114"/>
<source>Own Images</source>
<translation>Eigene Bilder</translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="148"/>
<source>More</source>
<translation>Mehr</translation>
</message>
</context>
<context>
<name>SmileyDialog</name>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="51"/>
<source>Standard</source>
<translation>Standard</translation>
</message>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="77"/>
<source>Addon</source>
<translation>Addon</translation>
</message>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="101"/>
<source>Adult</source>
<translation>XXX</translation>
</message>
</context>
<context>
<name>newsworker</name>
<message>
<location filename="../js/newsworker.js" line="18"/>
<source>likes this.</source>
<translation>mag das.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="19"/>
<source>like this.</source>
<translation>mögen das.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="22"/>
<source>doesn&apos;t like this.</source>
<translation>mag das nicht.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="23"/>
<source>don&apos;t like this.</source>
<translation>mögen das nicht.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="26"/>
<source>will attend.</source>
<translation>nehmen teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="27"/>
<source>persons will attend.</source>
<translation>Personen nehmen teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="30"/>
<source>will not attend.</source>
<translation>nimmt nicht teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="31"/>
<source>persons will not attend.</source>
<translation>Personen nehmen nicht teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="34"/>
<source>may attend.</source>
<translation>nimmt vielleicht teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="35"/>
<source>persons may attend.</source>
<translation>Personen nehmen vielleicht teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="38"/>
<source>yes</source>
<translation>ja</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="39"/>
<source>no</source>
<translation>nein</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="40"/>
<source>maybe</source>
<translation>vielleicht</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="56"/>
<source>seconds</source>
<translation>Sekunden</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="56"/>
<location filename="../js/newsworker.js" line="57"/>
<location filename="../js/newsworker.js" line="58"/>
<location filename="../js/newsworker.js" line="59"/>
<location filename="../js/newsworker.js" line="60"/>
<location filename="../js/newsworker.js" line="61"/>
<location filename="../js/newsworker.js" line="62"/>
<location filename="../js/newsworker.js" line="63"/>
<location filename="../js/newsworker.js" line="64"/>
<location filename="../js/newsworker.js" line="65"/>
<source>ago</source>
<translation>her</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="57"/>
<source>minute</source>
<translation>Minute</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="58"/>
<source>minutes</source>
<translation>Minuten</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="59"/>
<source>hour</source>
<translation>Stunde</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="60"/>
<source>hours</source>
<translation>Stunden</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="61"/>
<source>day</source>
<translation>Tag</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="62"/>
<source>days</source>
<translation>Tage</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="63"/>
<source>month</source>
<translation>Monat</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="64"/>
<source>months</source>
<translation>Monate</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="65"/>
<source>years</source>
<translation></translation>
</message>
</context>
</TS>

View File

@ -196,5 +196,17 @@
<file>images/smileys/adult/finger.gif</file> <file>images/smileys/adult/finger.gif</file>
<file>images/smileys/adult/sperm.gif</file> <file>images/smileys/adult/sperm.gif</file>
<file>images/smileys/adult/tits.gif</file> <file>images/smileys/adult/tits.gif</file>
<file>common/filesystem.cpp</file>
<file>common/filesystem.h</file>
<file>common/friendiqa.cpp</file>
<file>common/uploadableimage.cpp</file>
<file>common/uploadableimage.h</file>
<file>common/xhr.cpp</file>
<file>common/xhr.h</file>
<file>qml/calendarqml/CalendarTab.qml</file>
<file>qml/calendarqml/CalendarDay.qml</file>
<file>qml/calendarqml/EventList.qml</file>
<file>translations/friendiqa-de.qm</file>
<file>translations/friendiqa-de.ts</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -8,7 +8,9 @@ int main(int argc, char *argv[]) {
QApplication app(argc, argv); QApplication app(argc, argv);
QQuickView view; QQuickView view;
QTranslator qtTranslator;
qtTranslator.load("friendiqa-" + QLocale::system().name(),":/translations");
app.installTranslator(&qtTranslator);
XHR* xhr = XHR::instance(); XHR* xhr = XHR::instance();
view.rootContext()->setContextProperty("xhr", xhr); view.rootContext()->setContextProperty("xhr", xhr);
FILESYSTEM* filesystem = FILESYSTEM::instance(); FILESYSTEM* filesystem = FILESYSTEM::instance();

View File

@ -3,7 +3,10 @@
#include <QHttpPart> #include <QHttpPart>
#include <QTextCodec> #include <QTextCodec>
#include <QUrlQuery> #include <QUrlQuery>
#include <QNetworkCookieJar>
#include <QNetworkCookie>
#include <QList>
#include <QDataStream>
#include "uploadableimage.h" #include "uploadableimage.h"
XHR *XHR::instance() XHR *XHR::instance()
@ -114,7 +117,8 @@ void XHR::get()
QByteArray loginData = m_login.toLocal8Bit().toBase64(); QByteArray loginData = m_login.toLocal8Bit().toBase64();
QString headerData = "Basic " + loginData; QString headerData = "Basic " + loginData;
request.setRawHeader("Authorization", headerData.toLocal8Bit()); request.setRawHeader("Authorization", headerData.toLocal8Bit());
QNetworkCookieJar* cJar = new QNetworkCookieJar;
manager.setCookieJar(cJar);
request.setUrl(requrl); request.setUrl(requrl);
reply = manager.get(request); reply = manager.get(request);
@ -206,6 +210,15 @@ void XHR::onReadyRead()
{ {
qDebug() << "."; qDebug() << ".";
buffer += reply->readAll(); buffer += reply->readAll();
QList<QNetworkCookie> list = manager.cookieJar()->cookiesForUrl(m_url);
QFile f("/home/pankraz/cookie.txt");
f.open(QIODevice::ReadWrite);
for(int i = 0; i < list.size(); ++i){
QDataStream s(&f);
s << list.at(i).toRawForm();
}
f.close();
} }
//void XHR::updateDownloadProgress(qint64 bytesRead, qint64 totalBytes) //void XHR::updateDownloadProgress(qint64 bytesRead, qint64 totalBytes)
@ -227,5 +240,3 @@ QString XHR::bufferToString()
{ {
return QTextCodec::codecForName("utf-8")->toUnicode(buffer); return QTextCodec::codecForName("utf-8")->toUnicode(buffer);
} }

View File

@ -34,6 +34,7 @@ OTHER_FILES += qml/friendiqa.qml \
# planning to localize your app, remember to comment out the # planning to localize your app, remember to comment out the
# following TRANSLATIONS line. And also do not forget to # following TRANSLATIONS line. And also do not forget to
# modify the localized app name in the the .desktop file. # modify the localized app name in the the .desktop file.
TRANSLATIONS += translations/friendiqa-de.ts TRANSLATIONS += translations/friendiqa-de.ts
HEADERS += \ HEADERS += \
@ -41,4 +42,7 @@ HEADERS += \
common/xhr.h \ common/xhr.h \
common/filesystem.h common/filesystem.h
DISTFILES += \
qml/calendarqml/CalendarTab.qml

View File

@ -9,12 +9,12 @@ function friendicaRequest(login,api,rootwindow,callback) {
try{ if (xhrequest.status=200){ //if (xhrequest.responseText!=""){ try{ if (xhrequest.status=200){ //if (xhrequest.responseText!=""){
callback(xhrequest.responseText) callback(xhrequest.responseText)
}else{ }else{
showMessage("Error","API:" +api+"\n NO RESPONSE"+xhrequest.statusText,rootwindow); showMessage("Error","API:" +login.server+api+"\n NO RESPONSE"+xhrequest.statusText,rootwindow);
callback(xhrequest.responseText) //callback(xhrequest.responseText)
} }
} }
catch (e){ catch (e){print(e);
showMessage("Error", api+" "+e+" "+xhrequest.statusText,rootwindow) showMessage("Error", xhrequest.responseText,rootwindow)
} }
} }
} }
@ -60,7 +60,7 @@ function friendicaWebRequest(url,rootwindow,callback) {
} else if(xhrequest.readyState === XMLHttpRequest.DONE) { } else if(xhrequest.readyState === XMLHttpRequest.DONE) {
try{ callback(xhrequest.responseText); try{ callback(xhrequest.responseText);
} }
catch (e){ catch (e){print(e);
showMessage("Error",url+" "+e, rootwindow) showMessage("Error",url+" "+e, rootwindow)
} }
} }
@ -130,3 +130,8 @@ var arraystring=JSON.stringify(array);
arraystring=arraystring.replace(/[\[\]]/g , ''); arraystring=arraystring.replace(/[\[\]]/g , '');
return arraystring; return arraystring;
} }
function cleanDate(date){
var cleanedDate= date.slice(0,3)+", "+date.slice(8,11)+date.slice(4,7)+date.slice(25,30)+date.slice(10,25);
return cleanedDate
}

View File

@ -32,13 +32,12 @@ function requestGroups(login,database,rootwindow,callback){
function getFriendsTimeline(login,database,contacts,onlynew,rootwindow,callback){ function getFriendsTimeline(login,database,contacts,onlynew,rootwindow,callback){
// retrieve and return timeline since last news, return contacts which are not friends and older than 2 days for update (friends can be updated in Contactstab) // retrieve and return timeline since last news, return contacts which are not friends and older than 2 days for update (friends can be updated in Contactstab)
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
var parameter = ""; var parameter = "?count=50";
if(onlynew){db.transaction( function(tx) { if(onlynew){db.transaction( function(tx) {
var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1'); // check for last news id var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" AND messagetype=0 ORDER BY status_id DESC LIMIT 1'); // check for last news id
try{parameter="&since_id="+result.rows.item(0).status_id;}catch(e){};})} try{parameter=parameter+"&since_id="+result.rows.item(0).status_id;}catch(e){};})}
var newContacts=[]; var newContacts=[];
//print("/api/statuses/friends_timeline"+parameter); Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){print(obj);
Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){
var news=JSON.parse(obj); var news=JSON.parse(obj);
var newContacts=findNewContacts(news,contacts); var newContacts=findNewContacts(news,contacts);
callback(news,newContacts) callback(news,newContacts)
@ -53,7 +52,7 @@ function getCurrentContacts(login,database,callback){
contactlist.push(result.rows.item(i).url ) contactlist.push(result.rows.item(i).url )
//print(result.rows.item(i).url) //print(result.rows.item(i).url)
} }
var lastDate=Date.now()-172800000;// 2 days old var lastDate=Date.now()-604800000;// 7 days old
//print('SELECT url from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge>'+lastDate); //print('SELECT url from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge>'+lastDate);
var result2 = tx.executeSql('SELECT url from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge > '+lastDate); var result2 = tx.executeSql('SELECT url from contacts WHERE username="'+login.username+'" AND isFriend=0 AND imageAge > '+lastDate);
for (var j=0;j<result2.rows.length;j++){ for (var j=0;j<result2.rows.length;j++){
@ -63,18 +62,18 @@ function getCurrentContacts(login,database,callback){
callback(contactlist) callback(contactlist)
} }
function findNewContacts(news,contacts){//print("contacts: "+JSON.stringify(contacts)) function findNewContacts(news,contacts){//print("contacts: "+JSON.stringify(news))
var newContacts=[]; var newContacts=[];
for (var i=0;i<news.length;i++){ for (var i=0;i<news.length;i++){
var url=news[i].user.url; var url=news[i].user.url;
if(contacts.indexOf(url)==-1 && !(inArray(newContacts,"url",url))){print("new contact "+JSON.stringify(news[i].user)); if(contacts.indexOf(url)==-1 && !(inArray(newContacts,"url",url))){
news[i].user.isFriend=0; news[i].user.isFriend=0;
newContacts.push(news[i].user); newContacts.push(news[i].user);
} }
if (news[i].friendica_activities.like.length>0){ if (news[i].friendica_activities.like.length>0){
for (var j=0;j<news[i].friendica_activities.like.length;j++){ for (var j=0;j<news[i].friendica_activities.like.length;j++){
var like_url=news[i].friendica_activities.like[j].url; var like_url=news[i].friendica_activities.like[j].url;
if(contacts.indexOf(like_url)==-1 && !(inArray(newContacts,"url",like_url))){print("new like contact "+JSON.stringify(news[i].friendica_activities.like[j])); if(contacts.indexOf(like_url)==-1 && !(inArray(newContacts,"url",like_url))){
news[i].friendica_activities.like[j].isFriend=0; news[i].friendica_activities.like[j].isFriend=0;
newContacts.push(news[i].friendica_activities.like[j]); newContacts.push(news[i].friendica_activities.like[j]);
} }
@ -83,7 +82,7 @@ function findNewContacts(news,contacts){//print("contacts: "+JSON.stringify(cont
if (news[i].friendica_activities.dislike.length>0){ if (news[i].friendica_activities.dislike.length>0){
for (var k=0;j<news[k].friendica_activities.dislike.length;k++){ for (var k=0;j<news[k].friendica_activities.dislike.length;k++){
var dislike_url=news[i].friendica_activities.dislike[k].url; var dislike_url=news[i].friendica_activities.dislike[k].url;
if(contacts.indexOf(dislike_url)==-1 && !(inArray(newContacts,"url",dislike_url))){print("new dislike contact "+JSON.stringify(news[i].friendica_activities.dislike[k])); if(contacts.indexOf(dislike_url)==-1 && !(inArray(newContacts,"url",dislike_url))){
news[i].friendica_activities.dislike[k].isFriend=0; news[i].friendica_activities.dislike[k].isFriend=0;
newContacts.push(news[i].friendica_activities.dislike[k]); newContacts.push(news[i].friendica_activities.dislike[k]);
} }
@ -110,7 +109,7 @@ function storeNews(login,database,news,rootwindow,callback){
var attendnoarray=[]; for (var user in news[i].friendica_activities.attendno){attendnoarray.push(news[i].friendica_activities.attendno[user].url)} var attendnoarray=[]; for (var user in news[i].friendica_activities.attendno){attendnoarray.push(news[i].friendica_activities.attendno[user].url)}
var attendmaybearray=[]; for (var user in news[i].friendica_activities.attendmaybe){attendmaybearray.push(news[i].friendica_activities.attendmaybe[user].url)} var attendmaybearray=[]; for (var user in news[i].friendica_activities.attendmaybe){attendmaybearray.push(news[i].friendica_activities.attendmaybe[user].url)}
var friendica_activities=[likearray,dislikearray,attendyesarray,attendnoarray,attendmaybearray] var friendica_activities=[likearray,dislikearray,attendyesarray,attendnoarray,attendmaybearray]
var attachments="";if (news[i].attachments){attachments=Qt.btoa(JSON.stringify(news[i].attachments))}print(attachments) var attachments="";if (news[i].attachments){attachments=Qt.btoa(JSON.stringify(news[i].attachments))}
db.transaction( function(tx) { db.transaction( function(tx) {
var result = tx.executeSql('SELECT * from news where username="'+login.username+'" AND status_id = "'+news[i].id+'" AND messagetype=0'); // check for news id var result = tx.executeSql('SELECT * from news where username="'+login.username+'" AND status_id = "'+news[i].id+'" AND messagetype=0'); // check for news id
if(result.rows.length === 1) {// use update if(result.rows.length === 1) {// use update
@ -265,7 +264,7 @@ function likerequest(login,database,verb,newsid,rootwindow){
db.transaction( function(tx) { db.transaction( function(tx) {
var currentActivities_rs=tx.executeSql('select friendica_activities_self from news WHERE username="'+login.username+'" AND status_id='+newsid) ; var currentActivities_rs=tx.executeSql('select friendica_activities_self from news WHERE username="'+login.username+'" AND status_id='+newsid) ;
var currentActivities=JSON.parse(currentActivities_rs.rows.item(0).friendica_activities_self); var currentActivities=JSON.parse(currentActivities_rs.rows.item(0).friendica_activities_self);
print(verb+"currentActivities "+JSON.stringify(currentActivities)); //print(verb+"currentActivities "+JSON.stringify(currentActivities));
if ((verb=="like")&&(currentActivities.indexOf(1)==-1)){ currentActivities.push(1); if ((verb=="like")&&(currentActivities.indexOf(1)==-1)){ currentActivities.push(1);
if (currentActivities.indexOf(2)!=-1){currentActivities.splice(currentActivities.indexOf(2),1)} if (currentActivities.indexOf(2)!=-1){currentActivities.splice(currentActivities.indexOf(2),1)}
} }
@ -349,7 +348,7 @@ function requestFavorites(login,database,contacts,rootwindow,callback){
function favoritesfromdb(database,user,callback){ function favoritesfromdb(database,user,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) { db.transaction( function(tx) {
print('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC'); //print('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC');
var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC'); var newsrs=tx.executeSql('select * from news WHERE username="'+user+'" AND favorited=1 ORDER BY status_id DESC');
var newsArray=[]; var newsArray=[];
for(var i = 0; i < newsrs.rows.length; i++) { for(var i = 0; i < newsrs.rows.length; i++) {

View File

@ -19,7 +19,7 @@ WorkerScript.onMessage = function(msg) {
else {likeText= newsitemobject.like.length+" "+ qsTr("like this.")} else {likeText= newsitemobject.like.length+" "+ qsTr("like this.")}
} }
if (newsitemobject.dislike.length>0){ if (newsitemobject.dislike.length>0){
if (newsitemobject.dislike.length==1){dislikeText= QT.atob(newsitemobject.dislike[0].name)+" "+ qsTr("doesn't like this.")} if (newsitemobject.dislike.length==1){dislikeText= Qt.atob(newsitemobject.dislike[0].name)+" "+ qsTr("doesn't like this.")}
else {dislikeText= newsitemobject.dislike.length+" "+ qsTr("don't like this.")} else {dislikeText= newsitemobject.dislike.length+" "+ qsTr("don't like this.")}
} }
if (newsitemobject.attendyes.length>0){ if (newsitemobject.attendyes.length>0){
@ -42,7 +42,15 @@ WorkerScript.onMessage = function(msg) {
if (newsitemobject.friendica_activities_self.indexOf(2)!=-1){self.disliked=1} if (newsitemobject.friendica_activities_self.indexOf(2)!=-1){self.disliked=1}
} }
var friendica_activities={likeText:likeText,dislikeText:dislikeText,attendyesText:attendyesText,attendnoText:attendnoText,attendmaybeText:attendmaybeText,self:self} var friendica_activities={likeText:likeText,dislikeText:dislikeText,attendyesText:attendyesText,attendnoText:attendnoText,attendmaybeText:attendmaybeText,self:self}
//print(JSON.stringify(friendica_activities) ) ;
var attachmentList=[];if(newsitemobject.attachments){
var attachArray=JSON.parse(Qt.atob(newsitemobject.attachments));
for (var image in attachArray){if(attachArray[image].mimetype=="image/gif"){
attachmentList.push(attachArray[image])
}
}
}
newsitemobject.attachmentList=attachmentList;
var seconds=(msg.currentTime-newsitemobject.created_at)/1000; var seconds=(msg.currentTime-newsitemobject.created_at)/1000;
var timestring=""; var timestring="";
if (seconds<60) {timestring=seconds+" "+qsTr("seconds") +" "+qsTr("ago");} if (seconds<60) {timestring=seconds+" "+qsTr("seconds") +" "+qsTr("ago");}
@ -54,7 +62,7 @@ WorkerScript.onMessage = function(msg) {
else if (seconds<3888000){timestring=Math.round(seconds/86400)+" "+qsTr("days") +" "+qsTr("ago");} else if (seconds<3888000){timestring=Math.round(seconds/86400)+" "+qsTr("days") +" "+qsTr("ago");}
else if (seconds<5832000){timestring=Math.round(seconds/3888000)+" "+qsTr("month") +" "+qsTr("ago");} else if (seconds<5832000){timestring=Math.round(seconds/3888000)+" "+qsTr("month") +" "+qsTr("ago");}
else if (seconds<69984000){timestring=Math.round(seconds/3888000)+" "+qsTr("months") +" "+qsTr("ago");} else if (seconds<69984000){timestring=Math.round(seconds/3888000)+" "+qsTr("months") +" "+qsTr("ago");}
else {timestring=Math.round(seconds/69984000)+" "+qsTr("years") +" "+qsTr("ago");} else {timestring=Math.round(seconds/46656000)+" "+qsTr("years") +" "+qsTr("ago");}
var data=({"newsitemobject": newsitemobject,"dateDiff":timestring,"friendica_activities":friendica_activities})} var data=({"newsitemobject": newsitemobject,"dateDiff":timestring,"friendica_activities":friendica_activities})}
//print("News:"+j+msg.news.length+JSON.stringify(data)); //print("News:"+j+msg.news.length+JSON.stringify(data));
msg.model.append(data);} msg.model.append(data);}

View File

@ -121,8 +121,93 @@ function initDatabase(database) { // initialize the database object
tx.executeSql('CREATE TABLE IF NOT EXISTS news(username TEXT, messagetype INT, text TEXT, created_at INT, in_reply_to_status_id INT, source TEXT, status_id INT, in_reply_to_user_id INT, geo TEXT,favorited TEXT, uid INT, statusnet_html TEXT, statusnet_conversation_id TEXT,friendica_activities TEXT, friendica_activities_self TEXT, attachments TEXT, friendica_owner INT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS news(username TEXT, messagetype INT, text TEXT, created_at INT, in_reply_to_status_id INT, source TEXT, status_id INT, in_reply_to_user_id INT, geo TEXT,favorited TEXT, uid INT, statusnet_html TEXT, statusnet_conversation_id TEXT,friendica_activities TEXT, friendica_activities_self TEXT, attachments TEXT, friendica_owner INT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS contacts(username TEXT, id INT, name TEXT, screen_name TEXT, location TEXT,imageAge INT, profile_image_url TEXT, description TEXT, profile_image BLOB, url TEXT, protected TEXT, followers_count INT, friends_count INT, created_at INT, favourites_count TEXT, utc_offset TEXT, time_zone TEXT, statuses_count INT, following TEXT, verified TEXT, statusnet_blocking TEXT, notifications TEXT, statusnet_profile_url TEXT, cid INT, network TEXT, isFriend INT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS contacts(username TEXT, id INT, name TEXT, screen_name TEXT, location TEXT,imageAge INT, profile_image_url TEXT, description TEXT, profile_image BLOB, url TEXT, protected TEXT, followers_count INT, friends_count INT, created_at INT, favourites_count TEXT, utc_offset TEXT, time_zone TEXT, statuses_count INT, following TEXT, verified TEXT, statusnet_blocking TEXT, notifications TEXT, statusnet_profile_url TEXT, cid INT, network TEXT, isFriend INT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS groups(username TEXT, groupname TEXT, gid INT, members TEXT)'); tx.executeSql('CREATE TABLE IF NOT EXISTS groups(username TEXT, groupname TEXT, gid INT, members TEXT)');
tx.executeSql('CREATE TABLE IF NOT EXISTS events(username TEXT, id INT, start INT, end INT, allday INT, title TEXT, j INT, d TEXT, isFirst INT, uid INT, cid INT, uri TEXT, created INT, edited INT, desc TEXT, location TEXT, type TEXT, nofinish TEXT, adjust INT, ignore INT, permissions TEXT, guid INT, itemid INT, plink TEXT, authorName TEXT, authorAvatar TEXT, authorLink TEXT, html TEXT)');
})} })}
function cleanPermissions(oldperms){
var newperms=oldperms.replace("<","");newperms=newperms.replace(">","");newperms="["+newperms+"]";
var newpermArray=JSON.parse(newperms);
return (newpermArray)
}
function getEvents(database,login,rootwindow,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
Helperjs.friendicaWebRequest(login.server+"/cal/"+login.username+"/json",rootwindow,function(obj){
var events = JSON.parse(obj);
db.transaction( function(tx) {
for (var i=0;i<events.length;i++){
var permissions=[];
permissions.push(cleanPermissions(events[i].item.allow_cid));
permissions.push(cleanPermissions(events[i].item.allow_gid));
permissions.push(cleanPermissions(events[i].item.deny_cid));
permissions.push(cleanPermissions(events[i].item.deny_gid));
var result = tx.executeSql('SELECT * from events where username="'+login.username+'" AND id = '+events[i].id); // check for news id
if(result.rows.length === 1) {// use update
result = tx.executeSql('UPDATE events SET username="'+login.username+'", start="'+Date.parse(events[i].start)+'", end="'+Date.parse(events[i].end)+'", allday="'+Number(events[i].allday)+'", title="'+events[i].title+'", j="'+events[i].j+'", d="'+events[i].d+ '", isFirst="'+Number(events[i].isFirst)+'", uid="'+events[i].item.uid+'", cid="'+events[i].item.cid+'", uri="'+events[i].item.uri+'", created="'+ Date.parse(events[i].item.created)+'", edited="'+ Date.parse(events[i].item.edited)+'", desc="'+events[i].item.desc+'", location="'+events[i].item.location+'", type="'+events[i].item.type+'", nofinish="'+events[i].item.nofinish+'", adjust ="'+events[i].item.adjust+'", ignore="'+events[i].item.ignore+'", permissions="'+ JSON.stringify(permissions)+'", guid="'+events[i].item.guid+'", itemid="'+events[i].item.itemid+ '", plink="'+events[i].item.plink+ '", authorName="'+events[i].item["author-name"]+ '", authorAvatar="'+events[i].item["author-avatar"]+ '", authorLink="'+events[i].item["author-link"]+ '", html="'+Qt.btoa(events[i].html)+'" where username="'+login.username+'" AND id='+events[i].id);
} else {// use insert
result = tx.executeSql('INSERT INTO events (username,id,start,end,allday,title,j,d,isFirst,uid,cid,uri,created,edited,desc,location,type,nofinish,adjust,ignore,permissions,guid,itemid,plink,authorName,authorAvatar,authorLink,html) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username, events[i].id, Date.parse(events[i].start), Date.parse(events[i].end), events[i].allday, events[i].title, events[i].j, events[i].d, events[i].isFirst, events[i].item.uid, events[i].item.cid, events[i].item.uri, Date.parse(events[i].item.created), Date.parse(events[i].item.edited), events[i].item.desc, events[i].item.location, events[i].item.type, events[i].item.nofinish, events[i].item.adjust, events[i].item.ignore, JSON.stringify(permissions), events[i].item.guid, events[i].item.itemid, events[i].item.plink, events[i].item["author-name"], events[i].item["author-avatar"], events[i].item["author-link"], Qt.btoa(events[i].html)])}
callback()
}
})})}
function newscount(database, callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) {
var newscountrs = tx.executeSql('SELECT COUNT(*) from news');
var newscount = newscountrs.rows.item(0)["COUNT(*)"];
callback(newscount)
})
}
function eventsfromdb(database, username,callback){
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
db.transaction( function(tx) {
var eventrs=tx.executeSql('select * from events WHERE username="'+username+'" ORDER BY start ASC');
var eventArray=[];
var dayArray=[];
for(var i = 0; i < eventrs.rows.length; i++) {
eventArray.push(eventrs.rows.item(i));
// eventArray[i]=fetchUsersForNews(database,username,newsArray[i])
dayArray.push(Math.floor(eventrs.rows.item(i).start/86400000));
}
callback(eventArray,dayArray)});
}
function requestFriendsEvents(login,friend,rootwindow,callback){
// get calendar JSON object of contact without user and password
Helperjs.friendicaWebRequest(friend.replace("profile","cal")+"/json",rootwindow,function(calhtml){
//print(calhtml);
var eventarray=[];var eventdays=[];
var events=JSON.parse(calhtml);
for (var i=0;i<events.length;i++){
var permissions=[];
permissions.push(cleanPermissions(events[i].item.allow_cid));
permissions.push(cleanPermissions(events[i].item.allow_gid));
permissions.push(cleanPermissions(events[i].item.deny_cid));
permissions.push(cleanPermissions(events[i].item.deny_gid));
var event ={}
event.start=Date.parse(events[i].start);event.end=Date.parse(events[i].end);
event.allday=events[i].allday; event.title=events[i].title; event.j=events[i].j;
event.d=events[i].d; event.isFirst=events[i].isFirst; event.uid=events[i].item.uid;
event.cid=events[i].item.cid; event.uri=events[i].item.uri;
event.created=Date.parse(events[i].item.created); event.edited=Date.parse(events[i].item.edited);
event.desc=events[i].item.desc; event.location=events[i].item.location; event.type=events[i].item.type;
event.nofinish=events[i].item.nofinish; event.adjust =events[i].item.adjust; event.ignore=events[i].item.ignore;
event.permissions=JSON.stringify(permissions); event.guid=events[i].item.guid;
event.itemid=events[i].item.itemid; event.plink=events[i].plink; event.authorName=events[i].item["author-name"];
event.authorAvatar=events[i].item["author-avatar"]; event. authorLink=events[i].item["author-link"];
event.html=Qt.btoa(events[i].html);
eventarray.push(event);
// var offsetTime = new Date().getTimezoneOffset() * 60 * 1000;print(new Date(event.start).toLocaleString()+"Zeitverschiebung:"+offsetTime)
// var time = event.start - offsetTime;
eventdays.push(Math.floor(event.start/(24*60*60*1000)))
}
//print(JSON.stringify(eventarray));
callback(eventarray,eventdays)
})
}
function savePermissions(database,obj) { // stores config to DB function savePermissions(database,obj) { // stores config to DB
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
var permissions=JSON.stringify(obj) var permissions=JSON.stringify(obj)
@ -147,6 +232,18 @@ function storeConfig(database,obj) { // stores config to DB
} }
})} })}
function showServerConfig(url,rootwindow,callback){//print(url);
Helperjs.friendicaWebRequest(url+"/api/statusnet/config",rootwindow, function (obj){
var serverconfig = JSON.parse(obj);
var serverConfigString="import QtQuick 2.0; import QtQuick.Dialogs 1.2; MessageDialog{ visible: true; title:'Server';standardButtons: StandardButton.Ok;text: 'Name: "+serverconfig.site.name+"\nLanguage: "+serverconfig.site.language+
"\nEmail: "+serverconfig.site.email+"\nTimezone: "+serverconfig.site.timezone+"\nClosed: "+serverconfig.site.closed+
"\nText limit: "+serverconfig.site.textlimit+"\nShort Url length: "+serverconfig.site.shorturllength+
"\nFriendica version: "+serverconfig.site.friendica.FRIENDICA_VERSION+"\nDFRN version: "+serverconfig.site.friendica.DFRN_PROTOCOL_VERSION +
"\nDB Update version: "+serverconfig.site.friendica.DB_UPDATE_VERSION+"'}";
callback(serverConfigString)
})}
function getServerConfig(database,login,rootwindow,callback){ function getServerConfig(database,login,rootwindow,callback){
// check server with given credentials // check server with given credentials
try {Helperjs.friendicaRequest(login,"/api/statusnet/config",rootwindow, function (obj){ try {Helperjs.friendicaRequest(login,"/api/statusnet/config",rootwindow, function (obj){
@ -212,8 +309,9 @@ function cleanNews(database,callback){
var maxnews=maxnewsrs.rows.item(0).maxnews; var maxnews=maxnewsrs.rows.item(0).maxnews;
var newscountrs = tx.executeSql('SELECT COUNT(*) from news'); var newscountrs = tx.executeSql('SELECT COUNT(*) from news');
var newscount = newscountrs.rows.item(0)["COUNT(*)"]; var newscount = newscountrs.rows.item(0)["COUNT(*)"];
if (newscount>maxnews){var lastvalidtimers= tx.executeSql('select created_at from news ORDER BY created_at DESC LIMIT ' +(newscount-maxnews)); if (newscount>maxnews){
var lastvalidtime=lastvalidtimers.rows.item(maxnews).created_at; var lastvalidtimers= tx.executeSql('SELECT DISTINCT created_at FROM news ORDER BY created_at ASC LIMIT ' +(newscount-maxnews));
var lastvalidtime=lastvalidtimers.rows.item(newscount-maxnews-1).created_at;
var deleters = tx.executeSql('DELETE from news WHERE created_at<='+lastvalidtime)} var deleters = tx.executeSql('DELETE from news WHERE created_at<='+lastvalidtime)}
callback() callback()
}) })
@ -260,13 +358,17 @@ function processNews(callback){
function updateContactInDB(login,database,isFriend,contact){// for newstab and friendstab function updateContactInDB(login,database,isFriend,contact){// for newstab and friendstab
// var suffix=contact.profile_image_url.substring(contact.profile_image_url.lastIndexOf("."), contact.profile_image_url.length); // var suffix=contact.profile_image_url.substring(contact.profile_image_url.lastIndexOf("."), contact.profile_image_url.length);
// var imagename=login.imagestore+"contacts/"+contact.screen_name.trim()+suffix; // var imagename=login.imagestore+"contacts/"+contact.screen_name.trim()+suffix;
var imagename=login.imagestore+"contacts/"+contact.screen_name+"-"+contact.profile_image_url.substring(contact.profile_image_url.lastIndexOf("/")+1, contact.profile_image_url.length);
contacttimer.restart(); var imagename="";
contacttimer.restart();
var currentTime=Date.now(); var currentTime=Date.now();
if(contact.profile_image_url==""){root.currentContact=root.currentContact+1 } else{//print(JSON.stringify(contact))
imagename=login.imagestore+"contacts/"+contact.screen_name+"-"+contact.profile_image_url.substring(contact.profile_image_url.lastIndexOf("/")+1, contact.profile_image_url.length);
xhr.setUrl(Qt.resolvedUrl(contact.profile_image_url)); xhr.setUrl(Qt.resolvedUrl(contact.profile_image_url));
xhr.setFilename(imagename); xhr.setFilename(imagename);
xhr.setDownloadtype("contact"); xhr.setDownloadtype("contact");
xhr.download(); xhr.download();}
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]); var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
var result; var result;
db.transaction( function(tx) { db.transaction( function(tx) {

View File

@ -0,0 +1,47 @@
import QtQuick 2.0
import QtQuick.Controls 1.4
Item {
id: calendarDay
width:7*mm
height: 7*mm
property int dateInt:Math.floor((Date.parse(model.date)-(new Date().getTimezoneOffset() * 60 * 1000))/86400000)
Rectangle {
id: placeHolder
color: 'lightblue'; antialiasing: true
anchors.fill:parent
}
Text {
id:daytext
anchors.right: parent.right
anchors.margins: 0.5*mm
color:(model.month==monthgrid.month)?"black":"grey"
wrapMode: Text.WrapAnywhere
text: model.day
font.bold: model.today
font.pixelSize: 4*mm
}
Rectangle {
id:eventRect
color:"black"
anchors.margins: 0.5*mm
anchors.bottom: calendarDay.bottom
width: parent.width-mm
height: mm
visible: eventdays.indexOf(dateInt)>-1
}
MouseArea {
anchors.fill: calendarDay
onClicked: {
var eventDate=[];
var idx = eventdays.indexOf(dateInt);
while (idx != -1) {
eventDate.push(idx);
idx = eventdays.indexOf(dateInt,idx + 1)
}
var component = Qt.createComponent("qrc:/qml/calendarqml/EventList.qml");
if (component.status== Component.Ready){
var eventlist = component.createObject(calendartab,{"daylist": eventDate})}
}
}
}

View File

@ -0,0 +1,134 @@
import QtQuick 2.0
import QtQuick.Controls 2.1
import QtQml 2.2
import Qt.labs.calendar 1.0
import QtQuick.Layouts 1.3
import "qrc:/js/service.js" as Service
import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/calendarqml"
import "qrc:/qml/genericqml"
Rectangle {
id:calendarrectangle
y:1
width:root.width-mm
height:root.height-5*mm
color: '#fff'
property date currentTime: new Date()
property int offsetTime: currentTime.getTimezoneOffset() * 60 * 1000
property var events:[]
property var eventdays:[]
onEventdaysChanged: print(JSON.stringify(eventdays))
function showEvents(friend){
if(friend=="backButton"){Service.eventsfromdb(db,login.username,function(eventArray,dayArray){
events=eventArray;
eventdays=dayArray})
}
else if (friend!=""){
calendartab.calendartabstatus=friend.substring(friend.lastIndexOf("/")+1,friend.length)
Service.requestFriendsEvents(login,friend,calendartab,function(eventArray,dayArray){
events=eventArray;
eventdays=dayArray})
}
else {calendartab.calendartabstatus="Events";
Service.eventsfromdb(db,login.username,function(eventArray,dayArray){
events=eventArray;
eventdays=dayArray;
calBusy.running=false
})
}
}
BusyIndicator{
id: calBusy
anchors.horizontalCenter: calendarView.horizontalCenter
anchors.top:calendarView.top
anchors.topMargin: 2*mm
width:10*mm
height: 10*mm
running: false
}
BlueButton{
id: updateEvents
anchors.top: parent.top
anchors.topMargin: 0.5*mm
anchors.right:calendartabstatusButton.left
anchors.rightMargin:mm
text:"\uf021"
onClicked: {
Service.getEvents(db,login, calendartab,function(){
showEvents("")
})}}
BlueButton{
id: calendartabstatusButton
anchors.top: parent.top
anchors.topMargin: 0.5*mm
anchors.right: parent.right
anchors.rightMargin:2*mm
text: calendartab.calendartabstatus=="Events"?qsTr("Events"):calendartabstatus
onClicked: {calendartabmenu.popup()}
}
Menu {
id:calendartabmenu
MenuItem {
text: qsTr("Own Calendar")
onTriggered: {
calendartab.calendartabstatus="Events";
// calendartabstatusButton.text=qsTr("own Calendar");
showEvents("")}
}
}
ListView{
id: calendarView
x: mm;y:8*mm
width: parent.width-2*mm; height: parent.height-9*mm
clip: true
snapMode: ListView.SnapOneItem
orientation: ListView.Horizontal
highlightRangeMode: ListView.StrictlyEnforceRange
model: CalendarModel {id:calendarModel
from: new Date()
to: new Date(new Date().valueOf()+93312000000)
}
delegate:
ColumnLayout{
width:calendarView.width
Text{
font.bold: true
Layout.fillWidth: true
horizontalAlignment:Text.AlignHCenter
text: model.year
}
Text{
text: Qt.locale().standaloneMonthName(model.month)
Layout.fillWidth: true
horizontalAlignment:Text.AlignHCenter
}
DayOfWeekRow{
locale: monthgrid.locale
Layout.fillWidth: true
}
MonthGrid {
id: monthgrid
Layout.fillWidth: true
month: model.month
year: model.year
locale: Qt.locale()
delegate: CalendarDay{}
}
}
ScrollIndicator.horizontal: ScrollIndicator { }
}
Component.onCompleted: {
root.eventSignal.connect(showEvents);
if (calendartab.calendartabstatus=="Events"){showEvents("")}
}
}

View File

@ -0,0 +1,85 @@
import QtQuick 2.0
import QtQuick.Controls 1.2
import "qrc:/js/service.js" as Service
import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/genericqml"
Rectangle{
id:eventList
z:2
border.color: "grey"
width: parent.width-4*mm
height:parent.height-12*mm
x:mm
y:mm
property var daylist:[]
BlueButton{
id:closeButton
anchors.top: parent.top
anchors.topMargin: 1*mm
anchors.right: parent.right
anchors.rightMargin: 1*mm
text: "\uf057"
onClicked:{eventList.destroy()}
}
ListView {
id: eventlistView
x: mm
y:closeButton.height+2*mm
width: eventList.width-2*mm
height: eventList.height-closeButton.height-4*mm
clip: true
model: eventModel
delegate: eventItem
}
ListModel{
id: eventModel
}
Component.onCompleted:{
//print(JSON.stringify(daylist))
for (var i=0; i<daylist.length;i++){//print(JSON.stringify(events[daylist[i]]));
var liststate="";if(daylist.length<2){liststate="large"}
eventModel.append({"event":events[daylist[i]],"eventstatus":liststate});
}
}
Component{
id:eventItem
Rectangle{
property string status: eventstatus
width:eventlistView.width
height:eventNameText.height+eventDetailsText.height+mm
border.color: "light grey"
border.width: 1
Text {
id:eventNameText
x:mm
width:parent.width
height:contentHeight
text: new Date(event.start+calendarrectangle.offsetTime).toLocaleTimeString()+": "+event.title
font.pixelSize: 3*mm
wrapMode:Text.Wrap
}
Text {
id:eventDetailsText
x:mm
z:4
width: parent.width
height: contentHeight
text: status==""?"":Qt.atob(event.html)
anchors.top: eventNameText.bottom
font.pixelSize: 3*mm
wrapMode:Text.Wrap
}
MouseArea{
anchors.fill: parent
onClicked:{if (status==""){status="large"} else {status=""}
}
}
}
}
}

View File

@ -1,4 +1,4 @@
import QtQuick 2.0 import QtQuick 2.7
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import "qrc:/js/service.js" as Service import "qrc:/js/service.js" as Service
@ -15,13 +15,18 @@ StackView{
height:root.height-12*mm height:root.height-12*mm
contentHeight: configBackground.height contentHeight: configBackground.height
boundsBehavior: Flickable.StopAtBounds boundsBehavior: Flickable.StopAtBounds
Rectangle{ Rectangle{
id:configBackground id:configBackground
color: "white" color: "white"
width:parent.width width:parent.width
height:Math.max(90*mm,root.height-12*mm) height:Math.max(90*mm,root.height-12*mm)
property var users:[] property var users:[]
function setServericon(server){
try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",configBackground, function (obj){
var serverdata = JSON.parse(obj);
servericon.source=serverdata.site.logo})} catch(e){print(e)}
}
BlueButton{ BlueButton{
id:userButton id:userButton
text:qsTr("User") text:qsTr("User")
@ -35,6 +40,7 @@ StackView{
"'; onTriggered: {Service.readConfig(db,function(obj){ "'; onTriggered: {Service.readConfig(db,function(obj){
userButton.text=obj.username; userButton.text=obj.username;
servername.text=obj.server; servername.text=obj.server;
configBackground.setServericon(obj.server);
username.text= obj.username; username.text= obj.username;
password.text=Qt.atob(obj.password); password.text=Qt.atob(obj.password);
imagestore.text=obj.imagestore; imagestore.text=obj.imagestore;
@ -49,37 +55,51 @@ StackView{
} }
Text { Text {
text: "Server" text: qsTr("Server")
x: 4*mm; y: 10*mm x: 4*mm; y: 10*mm
} }
Text { Text {
text: "User" text: qsTr("User")
x: 4*mm; y: 20*mm x: 4*mm; y: 20*mm
} }
Text { Text {
text: "Password" text: qsTr("Password")
x: 4*mm; y: 30*mm x: 4*mm; y: 30*mm
} }
Text { Text {
text: "Image dir." text: qsTr("Image dir.")
x: 4*mm; y: 40*mm x: 4*mm; y: 40*mm
} }
Text { Text {
text: "Max. News" text: qsTr("Max. News")
x: 4*mm; y: 50*mm x: 4*mm; y: 50*mm
} }
Text { Text {
text: "News as" text: qsTr("News as")
x: 4*mm; y: 60*mm x: 4*mm; y: 60*mm
} }
Text { Text {
text: "Interval (0=None)" text: qsTr("Interval (0=None)")
visible: false visible: false
x: 4*mm; y: 70*mm; width:20*mm;wrapMode: Text.Wrap x: 4*mm; y: 70*mm; width:20*mm;wrapMode: Text.Wrap
} }
Image{
id:servericon
x:19*mm;y:10*mm
width:5*mm; height: 5*mm
source:""
MouseArea{
anchors.fill:parent
onClicked:{
Service.showServerConfig(servername.text, configBackground, function(configString){
var serverconfigObject=Qt.createQmlObject(configString,configBackground,"serverconfigOutput");})
}
}
}
Rectangle{color: "light grey"; x: 25*mm; y: 10*mm; width: root.width/2; height: 5*mm;} Rectangle{color: "light grey"; x: 25*mm; y: 10*mm; width: root.width/2; height: 5*mm;}
Flickable { Flickable {
id: servernameFlickable id: servernameFlickable
@ -93,9 +113,13 @@ StackView{
height: servernameFlickable.height height: servernameFlickable.height
focus: true focus: true
text:"https://..." text:"https://..."
//wrapMode: TextEdit.NoWrap onEditingFinished:{
//validator: RegExpValidator { regExp: /^(((http|https|ftp):\/\/)?([[a-zA-Z0-9]\-\.])+(\.)([[a-zA-Z0-9]]){2,4}([[a-zA-Z0-9]\/+=%&_\.~?\-]*))*$/} if((servername.text).substring(0,14) =="https://...http"){
// onEditingFinished:{} serverstring.text= (serverstring.text).substring(11)
}
configBackground.setServericon(servername.text)
}
onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,servernameFlickable) onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,servernameFlickable)
} }
} }
@ -134,9 +158,11 @@ StackView{
} }
} }
Slider{ id: maxNews Slider{ id: maxNews
x:37*mm; y: 50*mm;width: root.width/3;height:5*mm x:34*mm; y: 50*mm;width: root.width/3;height:5*mm
minimumValue: 0;maximumValue:100000; stepSize: 1000 minimumValue: 0;maximumValue:2000; stepSize: 100
} }
Rectangle{color: "light grey"; x: 25*mm; y: 50*mm; width: 9*mm; height: 5*mm; Rectangle{color: "light grey"; x: 25*mm; y: 50*mm; width: 9*mm; height: 5*mm;
TextEdit{id:maxNewsText; TextEdit{id:maxNewsText;
anchors.fill: parent anchors.fill: parent
@ -199,13 +225,12 @@ StackView{
BlueButton { BlueButton {
x: 25*mm; y: 80*mm x: 25*mm; y: 78*mm
text: "Confirm" text: qsTr("Confirm")
onClicked:{ onClicked:{
var userconfig={server: servername.text, username: username.text, password:Qt.btoa(password.text), imagestore:imagestore.text,maxnews:maxNewsText.text,interval: messageIntervalField.text, newsViewType:newsTypeField.text}; var userconfig={server: servername.text, username: username.text, password:Qt.btoa(password.text), imagestore:imagestore.text,maxnews:maxNewsText.text,interval: messageIntervalField.text, newsViewType:newsTypeField.text};
var errormessage=""; var errormessage="";
if (servername.text==""){errormessage=qsTr("No server given! ")} if (servername.text==""){errormessage=qsTr("No server given! ")}
//if (!servername.acceptableInput){errormessage+=qsTr("Server name not valid! ")}
else if (username.text==""){errormessage+=qsTr("No username given! ")} else if (username.text==""){errormessage+=qsTr("No username given! ")}
else if (password.text=="") {errormessage+=qsTr("No password given! ")} else if (password.text=="") {errormessage+=qsTr("No password given! ")}
else if (imagestore.text=="") {errormessage+=qsTr("No image directory given!")} else if (imagestore.text=="") {errormessage+=qsTr("No image directory given!")}
@ -228,11 +253,6 @@ StackView{
userButton.color="black" userButton.color="black"
//reset values //reset values
root.login=userconfig; root.login=userconfig;
// root.contactlist=[];
// root.news=[];
// root.newContacts=[];
// root.currentContact= 0;
// root.contactLoadType= "";
newstab.newstabstatus=userconfig.newsViewType; newstab.newstabstatus=userconfig.newsViewType;
root.currentIndex=0; root.currentIndex=0;
newstab.active=true; newstab.active=true;
@ -252,6 +272,7 @@ StackView{
filesystem.Directory=imagestore.text+"albums"; filesystem.Directory=imagestore.text+"albums";
filesystem.rmDir(); filesystem.rmDir();
servername.text="https://..."; servername.text="https://...";
servericon.source="";
username.text=""; username.text="";
password.text=""; password.text="";
imagestore.text=""; imagestore.text="";
@ -272,6 +293,7 @@ StackView{
text: "+" text: "+"
onClicked:{ onClicked:{
servername.text="https://..." servername.text="https://..."
servericon.source="";
username.text="" username.text=""
password.text="" password.text=""
imagestore.text="" imagestore.text=""
@ -297,8 +319,8 @@ StackView{
onTriggered: {newsTypeField.text="Timeline"} onTriggered: {newsTypeField.text="Timeline"}
} }
MenuItem { MenuItem {
text: qsTr("Tree") text: qsTr("Conversations")
onTriggered: {newsTypeField.text="Tree"} onTriggered: {newsTypeField.text="Conversations"}
} }
} }
@ -311,6 +333,7 @@ StackView{
Service.readConfig(db,function(obj){ Service.readConfig(db,function(obj){
userButton.text=obj.username; userButton.text=obj.username;
servername.text=obj.server; servername.text=obj.server;
configBackground.setServericon(obj.server);
username.text= obj.username; username.text= obj.username;
password.text=Qt.atob(obj.password); password.text=Qt.atob(obj.password);
imagestore.text=obj.imagestore; imagestore.text=obj.imagestore;

View File

@ -47,38 +47,11 @@ Rectangle {
anchors.topMargin: mm anchors.topMargin: mm
anchors.top: parent.top anchors.top: parent.top
onClicked:{ onClicked:{
contactComponent.state="large";
var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml"); var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml");
if (component.status== Component.Ready){ if (component.status== Component.Ready){
var contactDetails = component.createObject(wrapper,{"contact": contact})} var contactDetails = component.createObject(friendstab,{"contact": contact})}
} }
} }
} }
Timer{id:selectiontimer; //weird behaviour when state set to "large" onCompleted
interval: 200; running: false; repeat: false
onTriggered: {
contactComponent.state="large";
var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml");
if (component.status== Component.Ready){
var contactDetails = component.createObject(wrapper,{"contact": contact})}
}
}
Component.onCompleted: {
if(status=="large"){selectiontimer.start()}
else{contactComponent.state=""}
}
states: [
State {
name: "large"
PropertyChanges { target: namelabel; font.pixelSize: 4*mm; x:mm; width:friendsTabView.width-4*mm; text:Qt.atob(contact.name)+" (@"+contact.screen_name+")"}
ParentChange{target:contactComponent;parent:root; x:mm;y:2*mm}
//PropertyChanges { target: contactComponent; z: 2; x:0;y:0}
PropertyChanges { target: wrapper; width:friendsTabView.width;height:friendsTabView.height-15*mm}
PropertyChanges { target: photoImage; width:15*mm;height:15*mm;x:mm;y:mm }
PropertyChanges { target: contactComponent.GridView.view; interactive:false}
}
]
} }

View File

@ -2,6 +2,44 @@ import QtQuick 2.0
import QtQuick.Controls 1.3 import QtQuick.Controls 1.3
import "qrc:/qml/genericqml" import "qrc:/qml/genericqml"
Item {
id: contactLargeComponent
x:mm
y:mm
property var contact:{}
property var createdAtDate: new Date(contact.created_at)
property string connectUrl: (contact.network!=="dfrn")||(contact.isFriend==1)?"":( "<a href='"+contact.url.replace("profile","dfrn_request") +"'>"+qsTr("Connect")+"</a><br>")
Rectangle {
id: wrapper
width:friendsTabView.width;
height:friendsTabView.height-15*mm
border.color: "grey"
color:"white"
Image {
id: photoImage
x:mm
y:mm
width: 15*mm
height:15*mm
source:(contact.profile_image!="")? "file://"+contact.profile_image : contact.profile_image_url
onStatusChanged: if (photoImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"}
}
Label {
id: namelabel
x: mm
width:friendsTabView.width-4*mm
height: 3*mm
text:Qt.atob(contact.name)+" (@"+contact.screen_name+")"
elide:Text.ElideRight
anchors.topMargin: 0
anchors.left: photoImage.left
color: "#303030"
font.pixelSize: 4*mm
anchors.top: photoImage.bottom
}
Rectangle{ Rectangle{
id: detailsrectangle id: detailsrectangle
anchors.top: namelabel.bottom anchors.top: namelabel.bottom
@ -69,10 +107,27 @@ Rectangle{
} }
} }
BlueButton{
id:eventbutton
visible:(contact.network=="dfrn")
text:"\uf073"
onClicked:{
root.currentIndex=3;
calendartab.active=true;
calendartab.calendartabstatus="Friend"
root.eventSignal(contact.url);
}
}
BlueButton{ BlueButton{
id: closeButton id: closeButton
text: "\uf057" //"close" text: "\uf057" //"close"
onClicked:{detailsrectangle.destroy();contactComponent.state="";friendsTabView.contactSignal} onClicked:{contactLargeComponent.destroy();
//contactComponent.state="";
friendsTabView.contactSignal}
} }
} }
} }
}
}

View File

@ -11,12 +11,13 @@ Rectangle {
color: "white" color: "white"
function showContactdetails(contact){ function showContactdetails(contact){
var component = Qt.createComponent("qrc:/qml/contactqml/ContactDetailsComponent.qml");
if(contact.isFriend){ if(contact.isFriend){
friendsTabView.currentIndex=0; friendsTabView.currentIndex=0;
friendsTabView.contactsSignal(contact) var contactDetails = component.createObject(friendstab,{"contact": contact})
} }
else{friendsTabView.currentIndex=1; else{friendsTabView.currentIndex=1;
friendsTabView.contactsSignal(contact) var contactDetails = component.createObject(friendstab,{"contact": contact})
} }
} }
TabView{ TabView{
@ -30,7 +31,7 @@ Rectangle {
signal contactsSignal(var contact) signal contactsSignal(var contact)
signal groupsSignal(var username) signal groupsSignal(var username)
onCurrentIndexChanged:{ onCurrentIndexChanged:{
if (currentIndex==0){//print("currentindex 0"); if (currentIndex==0){
contactsSignal("") contactsSignal("")
} }
else if (currentIndex==1){ else if (currentIndex==1){
@ -60,18 +61,14 @@ Rectangle {
title: qsTr("Friends") title: qsTr("Friends")
Rectangle{ Rectangle{
id: friendsGridTab id: friendsGridTab
function makebig(friendindex){print("friendindex"+friendindex);if (friendindex){friendsModel.set(friendindex,{"status":"large"})}} function showFriends(contact){
function showFriends(contact,callback){//print("contact"+JSON.stringify(contact));
try {friendsModel.clear()} catch(e){print(e)}; try {friendsModel.clear()} catch(e){print(e)};
var friendindex;
Helperjs.readData(db,"contacts",root.login.username,function(friendsobject){ Helperjs.readData(db,"contacts",root.login.username,function(friendsobject){
for (var i=0;i<friendsobject.length;i++){ for (var i=0;i<friendsobject.length;i++){
var status=""; if(Helperjs.getCount(db,login,"contacts","screen_name",friendsobject[i].screen_name)>1){
if(Helperjs.getCount(db,login,"contacts","screen_name",friendsobject[i].screen_name)>1){
friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid
} }
if(contact){if (contact.cid==friendsobject[i].cid){status="large"}} friendsModel.append({"contact":friendsobject[i]});
friendsModel.append({"contact":friendsobject[i],"status":status});
} }
@ -113,12 +110,11 @@ Rectangle {
clip: true clip: true
cellHeight: 16*mm cellHeight: 16*mm
cellWidth: 17*mm cellWidth: 17*mm
add: Transition { //add: Transition {
NumberAnimation { properties: "x,y"; from: 300; duration: 1000 } // NumberAnimation { properties: "x,y"; from: 300; duration: 1000 }
} // }
model: friendsModel model: friendsModel
delegate: ContactComponent { } delegate: ContactComponent { }
Component.onCompleted: positionViewAtBeginning()
} }
ListModel{id:friendsModel} ListModel{id:friendsModel}
@ -132,7 +128,7 @@ Rectangle {
} }
Tab{ Tab{
title: qsTr("Other Contacts") title: qsTr("Contacts")
Rectangle{ Rectangle{
id: contactsGridTab id: contactsGridTab
@ -140,9 +136,7 @@ Rectangle {
try {contactsModel.clear()} catch(e){print(e)}; try {contactsModel.clear()} catch(e){print(e)};
Helperjs.readData(db, "contacts",root.login.username,function(contactsobject){ Helperjs.readData(db, "contacts",root.login.username,function(contactsobject){
for (var j=0;j<contactsobject.length;j++){ for (var j=0;j<contactsobject.length;j++){
var status=""; contactsModel.append({"contact":contactsobject[j]});
if(contact){if (contact.id==contactsobject[j].id){status="large"}}
contactsModel.append({"contact":contactsobject[j],"status":status});
} }
},"isFriend",0,"screen_name ASC"); },"isFriend",0,"screen_name ASC");
} }
@ -156,12 +150,11 @@ Rectangle {
clip: true clip: true
cellHeight: 16*mm cellHeight: 16*mm
cellWidth: 17*mm cellWidth: 17*mm
add: Transition { //add: Transition {
NumberAnimation { properties: "x,y"; from: 300; duration: 1000 } // NumberAnimation { properties: "x,y"; from: 300; duration: 1000 }
} // }
model: contactsModel model: contactsModel
delegate: ContactComponent { } delegate: ContactComponent { }
Component.onCompleted: positionViewAtBeginning()
} }
ListModel{id: contactsModel} ListModel{id: contactsModel}

View File

@ -24,6 +24,7 @@ TabView{
signal newsSignal(var news) signal newsSignal(var news)
signal friendsSignal(var username) signal friendsSignal(var username)
signal contactdetailsSignal(var contact) signal contactdetailsSignal(var contact)
signal eventSignal(var contact)
//currentIndex: (login=="")? 3:0 //currentIndex: (login=="")? 3:0
property var news:[] property var news:[]
@ -32,13 +33,13 @@ TabView{
property string contactLoadType: "" property string contactLoadType: ""
onLoginChanged:{ onLoginChanged:{
if(login==""){root.currentIndex=3} if(login==""){root.currentIndex=4}
else{ else{
newstab.newstabstatus=login.newsViewType; newstab.newstabstatus=login.newsViewType;
Newsjs.getCurrentContacts(login,db,function(contacts){ Newsjs.getCurrentContacts(login,db,function(contacts){
contactlist=contacts})} contactlist=contacts})}
} }
onNewContactsChanged:{ onNewContactsChanged:{//print(JSON.stringify(newContacts));
if(newContacts.length>0){// download first contact image and update db if(newContacts.length>0){// download first contact image and update db
Service.updateContactInDB(login,db,newContacts[currentContact].isFriend,newContacts[currentContact])} Service.updateContactInDB(login,db,newContacts[currentContact].isFriend,newContacts[currentContact])}
else if (contactLoadType!=""){ else if (contactLoadType!=""){
@ -49,6 +50,7 @@ TabView{
} }
onCurrentContactChanged:{// download next contact image after photoplaceholder is finished saving and update db onCurrentContactChanged:{// download next contact image after photoplaceholder is finished saving and update db
if(currentContact<newContacts.length){ if(currentContact<newContacts.length){
Service.updateContactInDB(login,db,newContacts[currentContact].isFriend,newContacts[currentContact])} Service.updateContactInDB(login,db,newContacts[currentContact].isFriend,newContacts[currentContact])}
else if (contactLoadType!=""){ else if (contactLoadType!=""){
@ -96,10 +98,12 @@ TabView{
if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,function(dbnews){ if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,function(dbnews){
newsSignal(dbnews) newsSignal(dbnews)
})} })}
else{Newsjs.chatsfromdb(db,login.username,function(dbnews){ else{
Newsjs.chatsfromdb(db,login.username,function(dbnews){
newsSignal(dbnews) newsSignal(dbnews)
})} })}
} }
else if (newstab.conversation.length>0){newstab.conversation=[]}
else{Service.cleanNews(root.db,function(){Qt.quit()})} else{Service.cleanNews(root.db,function(){Qt.quit()})}
} }
else if (currentIndex==2){fotoSignal("backButton")} else if (currentIndex==2){fotoSignal("backButton")}
@ -113,8 +117,8 @@ TabView{
tab: Rectangle { tab: Rectangle {
color: styleData.selected?"sky blue":"light blue" color: styleData.selected?"sky blue":"light blue"
border.color: "light grey" border.color: "light grey"
implicitWidth: root.width/4-2*mm implicitWidth: root.width/5-2*mm
implicitHeight: 4*mm implicitHeight: 5*mm
Text { id: text Text { id: text
anchors.centerIn: parent anchors.centerIn: parent
text: styleData.title text: styleData.title
@ -145,9 +149,17 @@ TabView{
property string phototabstatus:"Images" property string phototabstatus:"Images"
source: (root.currentIndex==2)?"qrc:/qml/photoqml/PhotoTab.qml":"" source: (root.currentIndex==2)?"qrc:/qml/photoqml/PhotoTab.qml":""
} }
Tab{
title: "\uf073"
id: calendartab
property string calendartabstatus:"Events"
source: (root.currentIndex==3)?"qrc:/qml/calendarqml/CalendarTab.qml":""
}
Tab{ Tab{
title:"\uf085" title:"\uf085"
id: configtab id: configtab
source: (root.currentIndex==3)?"qrc:/qml/configqml/ConfigTab.qml":"" source: (root.currentIndex==4)?"qrc:/qml/configqml/ConfigTab.qml":""
} }
} }

View File

@ -1,34 +1,106 @@
// ConversationStack with buttons // ConversationView with button
import QtQuick 2.0 import QtQuick 2.0
import "qrc:/js/helper.js" as Helperjs import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/genericqml" import "qrc:/qml/genericqml"
Rectangle { Rectangle {
id:conversationStack id:conversationList
property var news property var news
y:1 y:1
color: "white" z:2
width:root.width-2*mm color: "white"
height:root.height-8*mm border.color: "grey"
width:root.width-5*mm
height: conversationView.height+10*mm
Connections{
target:newstab
onConversationChanged:{
if(newstab.conversation.length==0){
newsView.positionViewAtIndex(newsStack.conversationIndex,ListView.Beginning);
conversationList.destroy(); conversationsymbol.color="grey"
}
}
}
ListView { ListView {
id: conversationView id: conversationView
x:3*mm x:3*mm
y:8*mm y:8*mm
width: conversationStack.width-4*mm width: conversationList.width-4*mm
height: conversationStack.height-10*mm height: contentHeight
clip: true clip: true
spacing: 0 spacing: 0
footer: footerReply
model: conversationModel model: conversationModel
delegate: Newsitem{} delegate: Newsitem{}
} }
ListModel{id: conversationModel} Component { id:footerReply
Rectangle{
border.color: "#EEEEEE"
border.width: 1
color:"lightgrey"
width:conversationView.width
height:Math.max(replyText.contentHeight+2*mm,6*mm)
Rectangle{
color: "white"
radius:0.5*mm
anchors.left: parent.left
anchors.leftMargin:mm
anchors.top:parent.top
anchors.topMargin: 0.5*mm
width:parent.width-12*mm
height:Math.max( replyText.contentHeight,5*mm)
WorkerScript { TextInput {
id: conversationWorker id: replyText
source: "qrc:/js/newsworker.js" font.pixelSize: 3*mm
} wrapMode: Text.Wrap
anchors.fill: parent
selectByMouse: true
}
}
BlueButton {
id: sendButton
text: "\uf1d9"
anchors.right: parent.right
anchors.rightMargin:mm
anchors.top:parent.top
anchors.topMargin: 0.5*mm
color:"white"
onClicked: { try{
var body=replyText.getText(0,replyText.length);
newsBusy.running=true;
replyText.text=""
xhr.clearParams();
xhr.setLogin(login.username+":"+Qt.atob(login.password));
if (conversationModel.get(0).newsitemobject.messagetype==0){
xhr.setParam("source", "Friendiqa");
xhr.url= login.server + "/api/statuses/update.json";
xhr.setParam("status", body);
xhr.setParam("in_reply_to_status_id", conversationModel.get(conversationModel.count-1).newsitemobject.status_id)}
else {xhr.url= login.server + "/api/direct_messages/new.json";
xhr.setParam("text", body);
xhr.setParam("screen_name",conversationModel.get(conversationModel.count-1).newsitemobject.screen_name);
xhr.setParam("replyto", conversationModel.get(conversationModel.count-1).newsitemobject.status_id)
}
xhr.post();
//replyText.text=""
} catch(e){Helperjs.showMessage("Error",e.toString(),root)}
}
}
}
}
ListModel{id: conversationModel}
WorkerScript {
id: conversationWorker
source: "qrc:/js/newsworker.js"
}
BlueButton { BlueButton {
id: closeButton id: closeButton
@ -37,10 +109,11 @@ Rectangle {
anchors.topMargin: 1*mm anchors.topMargin: 1*mm
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 1*mm anchors.rightMargin: 1*mm
text: "\uf057"// qsTr("Close") text: "\uf057"
onClicked: { onClicked: {
newstab.newstabstatus=login.newsViewType; newsView.positionViewAtIndex(newsStack.conversationIndex,ListView.Beginning);
newsStack.pop() conversationList.destroy();
conversationsymbol.color="grey"
} }
} }

View File

@ -42,12 +42,11 @@ Rectangle{
clip: true clip: true
model: imageModel model: imageModel
delegate: imageItem delegate: imageItem
} }
FolderListModel{ FolderListModel{
id: imageModel id: imageModel
nameFilters: ["*.png", "*.jpg",".jpeg","*.JPG"] nameFilters: ["*.png", "*.jpg",".jpeg","*.JPG","*.gif"]
sortField: FolderListModel.Time sortField: FolderListModel.Time
sortReversed:false sortReversed:false
showDotAndDotDot: true showDotAndDotDot: true
@ -111,8 +110,9 @@ Rectangle{
directory=fileURL directory=fileURL
} }
else{ else{
attachImageURL=fileURL; attachImageURLs.push(fileURL);
imageDialog.destroy() attachImage(fileURL);
imageDialog.destroy()
} }
} }
} }

View File

@ -16,7 +16,7 @@ Flickable{
id:messageSend id:messageSend
property string parentId: "" property string parentId: ""
property string reply_to_user:"" property string reply_to_user:""
property string attachImageURL: ""; property var attachImageURLs: [];
property int directmessage: 0; property int directmessage: 0;
property var contacts: [] property var contacts: []
property var groups: [] property var groups: []
@ -25,11 +25,13 @@ Flickable{
property var group_allow:login.permissions[2] property var group_allow:login.permissions[2]
property var group_deny:login.permissions[3] property var group_deny:login.permissions[3]
onAttachImageURLChanged: {if(attachImageURL!=""){ function attachImage(url){
var imageAttachmentObject=Qt.createQmlObject('import QtQuick 2.0; Image {id:imageAttachment; source:"'+ //onAttachImageURLsChanged: {if(attachImageURL!=""){
attachImageURL.toString()+'"; width: 15*mm; height: 15*mm;fillMode: Image.PreserveAspectFit;MouseArea{anchors.fill:parent;onClicked:{attachImageURL="";imageAttachment.destroy()}}}',messageColumn,"attachedImage"); var imageAttachmentObject=Qt.createQmlObject('import QtQuick 2.0; Image {id:imageAttachment'+attachImageURLs.length+'; source:"'+
console.log("You chose: " + attachImageURL) url.toString()+'"; width: 15*mm; height: 15*mm;fillMode: Image.PreserveAspectFit;MouseArea{anchors.fill:parent;onClicked:{attachImageURLs.splice(attachImageURLs.indexOf("'+url+'",1)); imageAttachment'+attachImageURLs.length+'.destroy()}}}',messageColumn,"attachedImage");
}} console.log("You chose: " + url)
}
function statusUpdate(title,status,in_reply_to_status_id,attachImageURL) { function statusUpdate(title,status,in_reply_to_status_id,attachImageURL) {
xhr.url= login.server + "/api/statuses/update.json"; xhr.url= login.server + "/api/statuses/update.json";
xhr.setLogin(login.username+":"+Qt.atob(login.password)); xhr.setLogin(login.username+":"+Qt.atob(login.password));
@ -42,7 +44,7 @@ Flickable{
if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))}; if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))};
if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))}; if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))};
if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))}; if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))};
if (attachImageURL!=="") {xhr.setImageFileParam("media", attachImageURL )}; if (attachImageURL.length>0) {for (var image in attachImageURL){xhr.setImageFileParam("media", attachImageURL[image] )}};
xhr.post(); xhr.post();
} }
@ -122,12 +124,11 @@ Flickable{
} }
} }
Row{ Row{
spacing:2 spacing:2
BlueButton{id:permButton BlueButton{id:permButton
visible: (directmessage==1)?false:true visible: (directmessage==1)?false:true
text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023"//qsTr("Permissions") text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023"
onClicked: { onClicked: {
var component = Qt.createComponent("qrc:/qml/newsqml/PermissionDialog.qml"); var component = Qt.createComponent("qrc:/qml/newsqml/PermissionDialog.qml");
var permissions = component.createObject(messageColumn); var permissions = component.createObject(messageColumn);
@ -137,14 +138,14 @@ Flickable{
text: "\uf0c6" text: "\uf0c6"
visible:(directmessage==0) visible:(directmessage==0)
onClicked: { onClicked: {
if (attachImageURL!=""){ if (attachImageURLs.length>0){//Server currently accepts only one attachment
Helperjs.showMessage( qsTr("Error"),qsTr("Only one attachment. Remove other attachment first!"), messageColumn)} Helperjs.showMessage( qsTr("Error"),qsTr("Only one attachment supported at the moment.\n Remove other attachment first!"), messageColumn)
else{print(filesystem.homePath); }
var defaultDirectory="file://"+osSettings.attachImageDir;//"file:///storage/emif.open() else{
print(defaultDirectory); var defaultDirectory="file://"+osSettings.attachImageDir;
var component = Qt.createComponent("qrc:/qml/newsqml/ImageDialog.qml"); var component = Qt.createComponent("qrc:/qml/newsqml/ImageDialog.qml");
var imagedialog = component.createObject(messageSend,{"directory": defaultDirectory}); var imagedialog = component.createObject(messageSend,{"directory": defaultDirectory});
} }
} }
} }
BlueButton{ BlueButton{
@ -188,7 +189,7 @@ Flickable{
var title=titleField.text.replace("\"","\'"); var title=titleField.text.replace("\"","\'");
var body=bodyField.getText(0,bodyField.length); var body=bodyField.getText(0,bodyField.length);
if (directmessage==0){ if (directmessage==0){
statusUpdate(title,body,messageSend.parentId,attachImageURL.toString())} statusUpdate(title,body,messageSend.parentId,attachImageURLs)}
else {dmUpdate(title,body,"",messageSend.reply_to_user) } else {dmUpdate(title,body,"",messageSend.reply_to_user) }
newstab.newstabstatus=login.newsViewType; newsStack.pop() newstab.newstabstatus=login.newsViewType; newsStack.pop()
} }

View File

@ -13,23 +13,13 @@ Item {
} }
} }
Connections{
target:newstab
onConversationChanged:{
newsBusy.running=false;
newstab.newstabstatus="Conversation";
//newsStack.push({item:"qrc:/qml/newsqml/Conversation.qml",properties:{"news": conversation}})
showNews(conversation);
}
}
Connections{ Connections{
target:root target:root
onCurrentContactChanged:{ onCurrentContactChanged:{
if (root.newContacts.length>0){ if (root.newContacts.length>0){
if(root.currentContact<root.newContacts.length){ if(root.currentContact<root.newContacts.length){
downloadNotice.text= qsTr("Download profile image for ")+ root.newContacts[root.currentContact].name; downloadNotice.text= qsTr("Download profile image for ")+ root.newContacts[root.currentContact].name;
print(root.newContacts[root.currentContact].name) //print(root.newContacts[root.currentContact].name)
} }
}else{downloadNotice.text=""} }else{downloadNotice.text=""}
} }
@ -62,23 +52,19 @@ Item {
newsWorker.sendMessage(msg); newsWorker.sendMessage(msg);
} }
function showConversation(timelineIndex,newsitemobject){ function showConversation(conversationIndex,newsitemobject){
newsBusy.running=true; newsBusy.running=true;
root.contactLoadType="conversation"; root.contactLoadType="conversation";
newsStack.timelineIndex= timelineIndex; newsStack.conversationIndex= conversationIndex;
if(newsitemobject.messagetype==0){ if(newsitemobject.messagetype==0){
Newsjs.requestConversation(root.login,db,newsitemobject.status_id,root.contactlist,root,function(ns,nc){ Newsjs.requestConversation(root.login,db,newsitemobject.status_id,root.contactlist,root,function(ns,nc){
root.news=ns;root.newContacts=nc;root.currentContact=0; root.news=ns;root.newContacts=nc;root.currentContact=0;
})} })}
else{Newsjs.conversationfromdb(root.db,root.login.username,newsitemobject.statusnet_conversation_id, function(newsarray){ else{Newsjs.conversationfromdb(root.db,root.login.username,newsitemobject.statusnet_conversation_id, function(newsarray){
root.news=newsarray;root.newContacts=[];root.currentContact=1; root.news=newsarray;root.newContacts=[];root.currentContact=1;
})} })}
} }
function onFriendsMessages(friend){ function onFriendsMessages(friend){
newstab.newstabstatus="Contact" newstab.newstabstatus="Contact"
Newsjs.newsfromdb(db,root.login.username, function(dbnews){showNews(dbnews)},friend) Newsjs.newsfromdb(db,root.login.username, function(dbnews){showNews(dbnews)},friend)
@ -92,14 +78,11 @@ Item {
StackView{ StackView{
id: newsStack id: newsStack
anchors.fill:parent anchors.fill:parent
property int timelineIndex: 0 property int conversationIndex: 0
onTimelineIndexChanged:print("timelineindex:"+ timelineIndex)
initialItem:Rectangle { initialItem:Rectangle {
y:1 y:1
color: "white" color: "white"
width:root.width-2*mm
height:root.height-8*mm
BlueButton{ BlueButton{
id:newstabstatusButton id:newstabstatusButton
@ -116,26 +99,27 @@ Item {
anchors.right: parent.right anchors.right: parent.right
BlueButton { BlueButton {
id: newMessageButton id: newMessageButton
width:10*mm width:10*mm
text: "\uf040" text: "\uf040"
onClicked: { onClicked: {
var groups=[]; var groups=[];
Helperjs.readData(root.db,"groups",root.login.username,function(groupobject){ Helperjs.readData(root.db,"groups",root.login.username,function(groupobject){
groups=groupobject}); groups=groupobject
newstab.newstabstatus="SendMessage"; });
Helperjs.readData(root.db,"contacts",root.login.username,function(friends){ newstab.newstabstatus="SendMessage";
newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"contacts": friends,"login":root.login}}) Helperjs.readData(root.db,"contacts",root.login.username,function(friends){
},"isFriend",1); newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"contacts": friends,"login":root.login}})
} },"isFriend",1);
} }
BlueButton { }
id: quitButton BlueButton {
width:10*mm id: quitButton
text: "\uf08b" width:10*mm
onClicked: {Service.cleanNews(root.db,function(){Qt.quit() })} text: "\uf08b"
} onClicked: {Service.cleanNews(root.db,function(){Qt.quit() })}
BlueButton { }
BlueButton {
id: update id: update
text: "\uf021" text: "\uf021"
onClicked: { onClicked: {
@ -176,7 +160,7 @@ Item {
var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true};
newsWorker.sendMessage(msg); newsWorker.sendMessage(msg);
},false,lastnews_id)} },false,lastnews_id)}
if(newstab.newstabstatus=="Tree"){ if(newstab.newstabstatus=="Conversations"){
var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at; var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at;
Newsjs.chatsfromdb(root.db,root.login.username, function(news){ Newsjs.chatsfromdb(root.db,root.login.username, function(news){
var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true}; var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true};
@ -191,83 +175,35 @@ Item {
} }
} }
Component { id:footerReply
Rectangle{
border.color: "#EEEEEE"
border.width: 1
color:"lightgrey"
width:newsView.width
height:Math.max(replyText.contentHeight+2*mm,6*mm)
Rectangle{
color: "white"
radius:0.5*mm
anchors.left: parent.left
anchors.leftMargin:mm
anchors.top:parent.top
anchors.topMargin: 0.5*mm
width:parent.width-12*mm
height:Math.max( replyText.contentHeight,5*mm)
TextInput {
id: replyText
font.pixelSize: 3*mm
wrapMode: Text.Wrap
//width: parent.width
anchors.fill: parent
selectByMouse: true
}
}
BlueButton {
id: sendButton
text: "\uf1d9"
anchors.right: parent.right
anchors.rightMargin:mm
anchors.top:parent.top
anchors.topMargin: 0.5*mm
color:"white"
onClicked: { try{
var body=replyText.getText(0,replyText.length);
newsBusy.running=true;
replyText.text=""
xhr.clearParams();
xhr.setLogin(login.username+":"+Qt.atob(login.password));
if (newsModel.get(0).newsitemobject.messagetype==0){
xhr.setParam("source", "Friendiqa");
xhr.url= login.server + "/api/statuses/update.json";
xhr.setParam("status", body);
xhr.setParam("in_reply_to_status_id", newsModel.get(newsModel.count-1).newsitemobject.status_id)}
else {xhr.url= login.server + "/api/direct_messages/new.json";
xhr.setParam("text", body);
xhr.setParam("screen_name",newsModel.get(newsModel.count-1).newsitemobject.screen_name);
xhr.setParam("replyto", newsModel.get(newsModel.count-1).newsitemobject.status_id)
}
xhr.post();
//replyText.text=""
} catch(e){Helperjs.showMessage("Error",e.toString(),root)}
}
}
}
}
ListView { ListView {
id: newsView id: newsView
anchors.fill: parent anchors.fill: parent
anchors.topMargin: 8*root.mm anchors.topMargin: 7*root.mm
anchors.leftMargin: 3*root.mm; anchors.rightMargin: root.mm anchors.leftMargin: 3*root.mm; anchors.rightMargin: root.mm
anchors.bottomMargin: 1*root.mm anchors.bottomMargin: 1*root.mm
clip: true clip: true
spacing: 0 spacing: 0
footer: (newstab.newstabstatus=="Conversation")?footerReply:footerComponent footer: footerComponent
model: newsModel model: newsModel
delegate: Newsitem{} delegate: Newsitem{}
Component.onCompleted: {//print(newstab.newstabstatus); //onContentYChanged:{if(contentY<-15*mm&&contentY>(-15*mm-1)){print("refreshing");
if(newstab.newstabstatus!="Conversation"){ onDragEnded:{if(contentY<-8*mm){//print("refreshing");
positionViewAtIndex(newsStack.timelineIndex-1, ListView.Beginning)} newsBusy.running=true;
else {positionViewAtBeginning(); newstab.newstabstatus=login.newsViewType;
newsStack.timelineIndex=0 root.contactLoadType="news";
}} var onlynew=true;
} Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(ns,nc){
root.news=ns;root.newContacts=nc;root.currentContact=0;
if (ns.length==0){// update last 20 existing news for changes and likes
onlynew=false;
Newsjs.getFriendsTimeline(login,db,contactlist,onlynew,newstab,function(rns,rnc){
root.contactLoadType="news";
root.news=rns;root.newContacts=rnc;root.currentContact=0})
}
})
}}
}
ListModel{id: newsModel} ListModel{id: newsModel}
@ -331,10 +267,10 @@ Item {
} }
MenuItem { MenuItem {
text: qsTr("Tree") text: qsTr("Conversations")
onTriggered:{ onTriggered:{
newsModel.clear(); newsModel.clear();
newstab.newstabstatus="Tree"; newstab.newstabstatus="Conversations";
Newsjs.chatsfromdb(db,root.login.username,function(news){showNews(news)}) Newsjs.chatsfromdb(db,root.login.username,function(news){showNews(news)})
} }
} }

View File

@ -7,9 +7,23 @@ import "qrc:/js/helper.js" as Helperjs
Item { Item {
id: newsitem id: newsitem
width: newsView.width width: parent.width
height:Math.max((itemMessage.height+topFlow.height+friendicaActivities.height+4*mm),profileImage.height+user_name.height+mm) height:toprow.height+friendicaActivities.height+controlrow.height+1//Math.max((itemMessage.height+topFlow.height+friendicaActivities.height+4*mm),profileImage.height+user_name.height+mm)
Connections{
target:newstab
onConversationChanged:{
newsBusy.running=false;
if(index==newsStack.conversationIndex){
if(newstab.conversation.length>0){
var component = Qt.createComponent("qrc:/qml/newsqml/Conversation.qml");
var conversation = component.createObject(friendicaActivities,{"news":newstab.conversation});
}
else{conversationsymbol.color="grey"}
}
}
}
property string attending: "" property string attending: ""
onAttendingChanged: {attendLabel.visible=true; onAttendingChanged: {attendLabel.visible=true;
attendLabel.text= qsTr("attending: ")+ qsTr(attending)} attendLabel.text= qsTr("attending: ")+ qsTr(attending)}
@ -19,9 +33,7 @@ Item {
function showActivityContacts(contacts){ function showActivityContacts(contacts){
var component = Qt.createComponent("qrc:/qml/newsqml/FriendicaActivities.qml"); var component = Qt.createComponent("qrc:/qml/newsqml/FriendicaActivities.qml");
var imagedialog = component.createObject(friendicaActivities,{"activitymembers": contacts}); var imagedialog = component.createObject(friendicaActivities,{"activitymembers": contacts});
} }
Rectangle{width:newsitem.width; height: 1; anchors.bottom: newsitem.bottom; color:"light grey"} Rectangle{width:newsitem.width; height: 1; anchors.bottom: newsitem.bottom; color:"light grey"}
Rectangle{ Rectangle{
@ -29,7 +41,8 @@ Item {
height:newsitem.height-1 height:newsitem.height-1
color: (newsitemobject.messagetype==1)?"#ffe6e6" : "white" color: (newsitemobject.messagetype==1)?"#ffe6e6" : "white"
Column { Row{id:toprow
Column {
id: authorcolumn id: authorcolumn
width: 8*mm width: 8*mm
@ -41,7 +54,7 @@ Item {
height: 7*mm height: 7*mm
MouseArea{ MouseArea{
anchors.fill: parent anchors.fill: parent
onClicked:{print(root.currentIndex); onClicked:{
try{root.currentIndex=1; try{root.currentIndex=1;
friendstab.active=true; friendstab.active=true;
root.contactdetailsSignal(newsitemobject.user)} catch (e){Helperjs.showMessage("Error",e,root)} root.contactdetailsSignal(newsitemobject.user)} catch (e){Helperjs.showMessage("Error",e,root)}
@ -61,7 +74,7 @@ Item {
Column { Column {
id:newscolumn id:newscolumn
width: newsitem.width-8*mm width: newsitem.width-8*mm
anchors.left: authorcolumn.right //anchors.left: authorcolumn.right
Flow{ Flow{
id:topFlow id:topFlow
@ -92,7 +105,7 @@ Item {
Label { Label {
id:newscountLabel id:newscountLabel
visible:((newstabstatus=="Tree")&&(newsitemobject.newscount>1))?true:false visible:((newstabstatus=="Conversations")&&(newsitemobject.newscount>1))?true:false
color: "grey" color: "grey"
height:3.5*mm height:3.5*mm
font.pixelSize: 1.5*mm font.pixelSize: 1.5*mm
@ -117,12 +130,25 @@ Item {
wrapMode: Text.Wrap wrapMode: Text.Wrap
onLinkActivated:{ onLinkActivated:{
Qt.openUrlExternally(link)} Qt.openUrlExternally(link)}
Component.onCompleted:{
if (newsitemobject.attachmentList.length>0){
for(var attachments in newsitemobject.attachmentList){// (newsitemobject.attachmentList[attachments].url);
var attachcomponent = Qt.createQmlObject('import QtQuick 2.0; '+
'AnimatedImage {id:gif;source: "'+newsitemobject.attachmentList[attachments].url+
'";onStatusChanged: playing = (status == AnimatedImage.Ready)}',
friendicaActivities,"Attachment"+attachments);
}
}
}
} }
}
Flow{ }
Flow{
id:friendicaActivities id:friendicaActivities
anchors.top:toprow.bottom
width:parent.width width:parent.width
spacing:mm spacing:mm
Label{color: "grey" Label{color: "grey"
font.pixelSize: 1.5*mm font.pixelSize: 1.5*mm
text: friendica_activities.likeText text: friendica_activities.likeText
@ -162,11 +188,22 @@ Item {
onClicked: { showActivityContacts(newsitemobject.attendmaybe)} onClicked: { showActivityContacts(newsitemobject.attendmaybe)}
} }
} }
Label{
id:attendLabel
//visible: false
color: "grey"
height:3.5*mm
font.pixelSize: 1.5*mm
horizontalAlignment: Label.AlignRight
text: (friendica_activities.self.attending)?(qsTr("Attending: ")+ qsTr(friendica_activities.self.attending)):""
}
} }
Row{ Row{id:controlrow
anchors.top:friendicaActivities.bottom
CheckBox{ CheckBox{
id:likeCheckbox id:likeCheckbox
height:3*mm //height:3*mm
width:8*mm width:8*mm
visible: (newsitemobject.messagetype==0)? true:false visible: (newsitemobject.messagetype==0)? true:false
checked:(friendica_activities.self.liked==1)?true:false checked:(friendica_activities.self.liked==1)?true:false
@ -195,7 +232,7 @@ Item {
} }
CheckBox{ CheckBox{
id: dislikeCheckbox id: dislikeCheckbox
height:3*mm //height:3*mm
width:8*mm width:8*mm
visible: (newsitemobject.messagetype==0)? true:false visible: (newsitemobject.messagetype==0)? true:false
checked: (friendica_activities.self.disliked==1)?true:false checked: (friendica_activities.self.disliked==1)?true:false
@ -222,10 +259,30 @@ Item {
if (dislikeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"dislike",newsitemobject.status_id,root);likeCheckbox.checked=false; model.friendica_activities.self.disliked=0} if (dislikeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"dislike",newsitemobject.status_id,root);likeCheckbox.checked=false; model.friendica_activities.self.disliked=0}
else {Newsjs.like(root.login,root.db,0,"dislike",newsitemobject.status_id,root); model.friendica_activities.self.disliked=1}} else {Newsjs.like(root.login,root.db,0,"dislike",newsitemobject.status_id,root); model.friendica_activities.self.disliked=1}}
} }
// Rectangle{
// width: 8*mm
// height: 3*mm
// color:"transparent"
// Text{
// id:trashsymbol
// color: "grey"
// anchors.centerIn: parent
// font.pixelSize: 2*mm
// font.bold: true
// text: "\uf1f8"
// }
// MouseArea{
// anchors.fill:parent
// onClicked: {
// Newsjs.deleteNews(root.login,root.db,newsitemobject.status_id,newsitemobject.messagetype,root,function(reply){
// newsModel.remove(index)})
// }}
// }
CheckBox { CheckBox {
id:favoritedCheckbox id:favoritedCheckbox
visible:(newsitemobject.messagetype==0) visible:(newsitemobject.messagetype==0)
width: 7*mm width: 8*mm
style: CheckBoxStyle { style: CheckBoxStyle {
background: Rectangle { background: Rectangle {
implicitWidth: 6*mm implicitWidth: 6*mm
@ -251,7 +308,7 @@ Item {
} }
} }
Rectangle{ Rectangle{
width: 7*mm width: 8*mm
height: 3*mm height: 3*mm
color:"transparent" color:"transparent"
Text{ Text{
@ -267,7 +324,7 @@ Item {
onClicked: {newsmenu.popup()}} onClicked: {newsmenu.popup()}}
} }
Rectangle{ Rectangle{
width: 7*mm width: 8*mm
height: 3*mm height: 3*mm
visible:newstab.newstabstatus!="Conversation" visible:newstab.newstabstatus!="Conversation"
color:"transparent" color:"transparent"
@ -281,20 +338,15 @@ Item {
} }
MouseArea{ MouseArea{
anchors.fill:parent anchors.fill:parent
onClicked: { conversationsymbol.color="black";showConversation(index,newsitemobject)} onClicked:{
conversationsymbol.color="black";
showConversation(index,newsitemobject)
}
} }
} }
Label{
id:attendLabel
//visible: false
color: "grey"
height:3.5*mm
font.pixelSize: 1.5*mm
horizontalAlignment: Label.AlignRight
text: (friendica_activities.self.attending)?(qsTr("Attending: ")+ qsTr(friendica_activities.self.attending)):""
}
} }
}
Menu { Menu {
id:newsmenu id:newsmenu
MenuItem { MenuItem {
@ -350,6 +402,4 @@ Item {
} }
} }
} }
} }}
}

View File

@ -32,7 +32,7 @@ Rectangle{
Text{ Text{
x:0.5*mm x:0.5*mm
y:0.5*mm y:0.5*mm
text: "Contacts" text: qsTr("Friends")
} }
ListView { ListView {
id: contactView id: contactView
@ -93,7 +93,7 @@ Rectangle{
Text{ Text{
x:contactView.width+2*mm x:contactView.width+2*mm
y:0.5*mm y:0.5*mm
text: "Groups" text: qsTr("Groups")
} }
ListView { ListView {
id: groupView id: groupView

View File

@ -105,7 +105,7 @@ Rectangle {
anchors.topMargin: 0.5*mm anchors.topMargin: 0.5*mm
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin:2*mm anchors.rightMargin:2*mm
text: qsTr(phototabstatus) text: fotostab.phototabstatus=="Images"?qsTr("Own Images"):fotostab.phototabstatus
onClicked: {phototabmenu.popup()} onClicked: {phototabmenu.popup()}
} }
Menu { Menu {
@ -114,7 +114,7 @@ Rectangle {
text: qsTr("Own Images") text: qsTr("Own Images")
onTriggered: { onTriggered: {
fotostab.phototabstatus="Images"; fotostab.phototabstatus="Images";
phototabstatusButton.text=qsTr("own images"); // phototabstatusButton.text=qsTr("Own images");
showFotos("")} showFotos("")}
} }
} }

Binary file not shown.

View File

@ -0,0 +1,470 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="de">
<context>
<name>CalendarTab</name>
<message>
<location filename="../qml/calendarqml/CalendarTab.qml" line="73"/>
<source>Events</source>
<translation>Termine</translation>
</message>
<message>
<location filename="../qml/calendarqml/CalendarTab.qml" line="79"/>
<source>Own Calendar</source>
<translation>Eigener Kalender</translation>
</message>
</context>
<context>
<name>ConfigTab</name>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="32"/>
<location filename="../qml/configqml/ConfigTab.qml" line="62"/>
<location filename="../qml/configqml/ConfigTab.qml" line="288"/>
<location filename="../qml/configqml/ConfigTab.qml" line="309"/>
<source>User</source>
<translation>Name</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="58"/>
<source>Server</source>
<translation>Server</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="67"/>
<source>Password</source>
<translation>Passwort</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="71"/>
<source>Image dir.</source>
<translation>Bildverz.</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="76"/>
<source>Max. News</source>
<translation>Max. Nachr.</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="80"/>
<source>News as</source>
<translation>Anzeige</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="84"/>
<source>Interval (0=None)</source>
<translation>Intervall (0=keins)</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="235"/>
<source>Confirm</source>
<translation>Bestätigen</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="239"/>
<source>No server given! </source>
<translation>Kein Server angegeben!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="240"/>
<source>No username given! </source>
<translation>Kein Nutzername angegeben!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="241"/>
<source>No password given! </source>
<translation>Kein Passwort angegeben!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="242"/>
<source>No image directory given!</source>
<translation>Kein Verzeichnis für Bilder angegeben!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="243"/>
<source>No maximum news number given!</source>
<translation>Maximale News-Anzahl nicht angegeben!</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="324"/>
<source>Timeline</source>
<translation>Chronologisch</translation>
</message>
<message>
<location filename="../qml/configqml/ConfigTab.qml" line="328"/>
<source>Conversations</source>
<translation>Unterhaltungen</translation>
</message>
</context>
<context>
<name>ContactComponent</name>
<message>
<location filename="../qml/contactqml/ContactComponent.qml" line="8"/>
<source>Connect</source>
<translation>Kontaktanfrage</translation>
</message>
</context>
<context>
<name>ContactDetailsComponent</name>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="11"/>
<source>Connect</source>
<translation>Kontaktanfrage</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/>
<source>Description</source>
<translation>Beschreibung</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/>
<source>Location</source>
<translation>Ort</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="63"/>
<source>Posts</source>
<translation>Beiträge</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="64"/>
<source>URL</source>
<translation>Profilseite</translation>
</message>
<message>
<location filename="../qml/contactqml/ContactDetailsComponent.qml" line="65"/>
<source>Created at</source>
<translation>Erstellt</translation>
</message>
</context>
<context>
<name>FriendsTab</name>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="61"/>
<source>Friends</source>
<translation>Freunde</translation>
</message>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="131"/>
<source>Contacts</source>
<translation>Kontakte</translation>
</message>
<message>
<location filename="../qml/contactqml/FriendsTab.qml" line="167"/>
<source>Groups</source>
<translation>Gruppen</translation>
</message>
</context>
<context>
<name>MessageSend</name>
<message>
<location filename="../qml/newsqml/MessageSend.qml" line="69"/>
<source>Title (optional)</source>
<translation>Überschrift (optional)</translation>
</message>
<message>
<location filename="../qml/newsqml/MessageSend.qml" line="142"/>
<source>Error</source>
<translation>Fehler</translation>
</message>
<message>
<location filename="../qml/newsqml/MessageSend.qml" line="142"/>
<source>Only one attachment supported at the moment.
Remove other attachment first!</source>
<translation>Nur ein Anhang derzeit unterstützt.
Lösche zuerst den anderen Anhang!</translation>
</message>
</context>
<context>
<name>NewsTab</name>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="21"/>
<source>Download profile image for </source>
<translation>Lade Profilbild für </translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="152"/>
<source>More</source>
<translation>Mehr</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="249"/>
<source>Timeline</source>
<translation>Chronologisch</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="258"/>
<source>Favorites</source>
<translation>Markierte News</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="270"/>
<source>Conversations</source>
<translation>Unterhaltungen</translation>
</message>
<message>
<location filename="../qml/newsqml/NewsTab.qml" line="278"/>
<source>Notifications</source>
<translation>Meldungen</translation>
</message>
</context>
<context>
<name>Newsitem</name>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="29"/>
<source>attending: </source>
<translation>Teilnahme</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="86"/>
<source>Source: </source>
<translation>Quelle: </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="87"/>
<source>Direct Message</source>
<translation>Direktnachricht</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="102"/>
<source>In reply to </source>
<translation>Antwort an </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="114"/>
<source> comments</source>
<translation> Kommentare</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="198"/>
<source>Attending: </source>
<translation>Teilnahme: </translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="353"/>
<source>Reply</source>
<translation>Antworten</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="361"/>
<source>DM</source>
<translation>Direktnachricht</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="367"/>
<source>Repost</source>
<translation>Teilen</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="374"/>
<source>Conversation</source>
<translation>Unterhaltung</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="379"/>
<source>Attending</source>
<translation>Teilnahme</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="381"/>
<source>yes</source>
<translation>ja</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="386"/>
<source>maybe</source>
<translation>vielleicht</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="391"/>
<source>no</source>
<translation>nein</translation>
</message>
<message>
<location filename="../qml/newsqml/Newsitem.qml" line="398"/>
<source>Delete</source>
<translation>Löschen</translation>
</message>
</context>
<context>
<name>PermissionDialog</name>
<message>
<location filename="../qml/newsqml/PermissionDialog.qml" line="35"/>
<source>Friends</source>
<translation>Freunde</translation>
</message>
<message>
<location filename="../qml/newsqml/PermissionDialog.qml" line="96"/>
<source>Groups</source>
<translation>Gruppen</translation>
</message>
</context>
<context>
<name>PhotoTab</name>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="66"/>
<source>&apos;s images</source>
<translation>s Bilder</translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="108"/>
<location filename="../qml/photoqml/PhotoTab.qml" line="114"/>
<source>Own Images</source>
<translation>Eigene Bilder</translation>
</message>
<message>
<location filename="../qml/photoqml/PhotoTab.qml" line="148"/>
<source>More</source>
<translation>Mehr</translation>
</message>
</context>
<context>
<name>SmileyDialog</name>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="51"/>
<source>Standard</source>
<translation>Standard</translation>
</message>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="77"/>
<source>Addon</source>
<translation>Addon</translation>
</message>
<message>
<location filename="../qml/newsqml/SmileyDialog.qml" line="101"/>
<source>Adult</source>
<translation>XXX</translation>
</message>
</context>
<context>
<name>newsworker</name>
<message>
<location filename="../js/newsworker.js" line="18"/>
<source>likes this.</source>
<translation>mag das.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="19"/>
<source>like this.</source>
<translation>mögen das.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="22"/>
<source>doesn&apos;t like this.</source>
<translation>mag das nicht.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="23"/>
<source>don&apos;t like this.</source>
<translation>mögen das nicht.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="26"/>
<source>will attend.</source>
<translation>nehmen teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="27"/>
<source>persons will attend.</source>
<translation>Personen nehmen teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="30"/>
<source>will not attend.</source>
<translation>nimmt nicht teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="31"/>
<source>persons will not attend.</source>
<translation>Personen nehmen nicht teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="34"/>
<source>may attend.</source>
<translation>nimmt vielleicht teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="35"/>
<source>persons may attend.</source>
<translation>Personen nehmen vielleicht teil.</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="38"/>
<source>yes</source>
<translation>ja</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="39"/>
<source>no</source>
<translation>nein</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="40"/>
<source>maybe</source>
<translation>vielleicht</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="56"/>
<source>seconds</source>
<translation>Sekunden</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="56"/>
<location filename="../js/newsworker.js" line="57"/>
<location filename="../js/newsworker.js" line="58"/>
<location filename="../js/newsworker.js" line="59"/>
<location filename="../js/newsworker.js" line="60"/>
<location filename="../js/newsworker.js" line="61"/>
<location filename="../js/newsworker.js" line="62"/>
<location filename="../js/newsworker.js" line="63"/>
<location filename="../js/newsworker.js" line="64"/>
<location filename="../js/newsworker.js" line="65"/>
<source>ago</source>
<translation>her</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="57"/>
<source>minute</source>
<translation>Minute</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="58"/>
<source>minutes</source>
<translation>Minuten</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="59"/>
<source>hour</source>
<translation>Stunde</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="60"/>
<source>hours</source>
<translation>Stunden</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="61"/>
<source>day</source>
<translation>Tag</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="62"/>
<source>days</source>
<translation>Tage</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="63"/>
<source>month</source>
<translation>Monat</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="64"/>
<source>months</source>
<translation>Monate</translation>
</message>
<message>
<location filename="../js/newsworker.js" line="65"/>
<source>years</source>
<translation></translation>
</message>
</context>
</TS>