2018-10-01 21:17:54 +02:00
// This file is part of Friendiqa
2018-11-09 22:06:13 +01:00
// https://git.friendi.ca/lubuwest/Friendiqa
2020-05-24 21:14:23 +02:00
// Copyright (C) 2020 Marco R. <thomasschmidt45@gmx.net>
2018-10-01 21:17:54 +02:00
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0
2020-05-24 21:14:23 +02:00
import QtQuick . Controls 2.12
2018-10-01 21:17:54 +02:00
import "qrc:/js/helper.js" as Helperjs
2021-05-12 21:41:34 +02:00
import "qrc:/js/news.js" as Newsjs
import "qrc:/js/service.js" as Service
2018-10-01 21:17:54 +02:00
import "qrc:/qml/genericqml"
2021-05-12 21:41:34 +02:00
Page {
2018-10-01 21:17:54 +02:00
id:contactList
property var contact: ( { } )
property string profileimagesource: contact . profile_image
2021-05-12 21:41:34 +02:00
//function backRequested(){pageStack.pop()}
function getDateDiffString ( seconds ) {
var timestring = "" ;
if ( seconds < 60 ) { timestring = Math . round ( seconds ) + " " + qsTr ( "seconds" ) ; }
else if ( seconds < 90 ) { timestring = Math . round ( seconds / 60 ) + " " + qsTr ( "minute" ) ; }
else if ( seconds < 3600 ) { timestring = Math . round ( seconds / 60 ) + " " + qsTr ( "minutes" ) ; }
else if ( seconds < 5400 ) { timestring = Math . round ( seconds / 3600 ) + " " + qsTr ( "hour" ) ; }
else if ( seconds < 86400 ) { timestring = Math . round ( seconds / 3600 ) + " " + qsTr ( "hours" ) ; }
else if ( seconds < 129600 ) { timestring = Math . round ( seconds / 86400 ) + " " + qsTr ( "day" ) ; }
else if ( seconds < 3888000 ) { timestring = Math . round ( seconds / 86400 ) + " " + qsTr ( "days" ) ; }
else if ( seconds < 5832000 ) { timestring = Math . round ( seconds / 3888000 ) + " " + qsTr ( "month" ) ; }
else if ( seconds < 69984000 ) { timestring = Math . round ( seconds / 3888000 ) + " " + qsTr ( "months" ) ; }
else { timestring = Math . round ( seconds / 46656000 ) + " " + qsTr ( "years" ) ; }
return timestring ;
}
function getActivitiesView ( newsitemobject ) {
var likeText = "" ; var dislikeText = "" ; var attendyesText = "" ; var attendnoText = "" ; var attendmaybeText = "" ; var self = { } ;
try { if ( newsitemobject . messagetype == 0 && newsitemobject . hasOwnProperty ( 'friendica_activities' ) ) {
if ( newsitemobject . friendica_activities . like . length > 0 ) {
if ( newsitemobject . friendica_activities . like . length == 1 ) { likeText = newsitemobject . friendica_activities . like [ 0 ] . name + " " + qsTr ( "likes this." ) }
else { likeText = newsitemobject . friendica_activities . like . length + " " + qsTr ( "like this." ) }
}
if ( newsitemobject . friendica_activities . dislike . length > 0 ) {
if ( newsitemobject . friendica_activities . dislike . length == 1 ) { dislikeText = newsitemobject . friendica_activities . dislike [ 0 ] . name + " " + qsTr ( "doesn't like this." ) }
else { dislikeText = newsitemobject . friendica_activities . dislike . length + " " + qsTr ( "don't like this." ) }
}
if ( newsitemobject . friendica_activities . attendyes . length > 0 ) {
if ( newsitemobject . friendica_activities . attendyes . length == 1 ) { attendyesText = newsitemobject . friendica_activities . attendyes [ 0 ] . name + " " + qsTr ( "will attend." ) }
else { attendyesText = newsitemobject . friendica_activities . attendyes . length + " " + qsTr ( "persons will attend." ) }
}
if ( newsitemobject . friendica_activities . attendno . length > 0 ) {
if ( newsitemobject . friendica_activities . attendno . length == 1 ) { attendnoText = newsitemobject . friendica_activities . attendno [ 0 ] . name + " " + qsTr ( "will not attend." ) }
else { attendnoText = newsitemobject . friendica_activities . attendno . length + " " + qsTr ( "persons will not attend." ) }
}
if ( newsitemobject . friendica_activities . attendmaybe . length > 0 ) {
if ( newsitemobject . friendica_activities . attendmaybe . length == 1 ) { attendmaybeText = newsitemobject . friendica_activities . attendmaybe [ 0 ] . name + " " + qsTr ( "may attend." ) }
else { attendmaybeText = newsitemobject . friendica_activities . attendmaybe . length + " " + qsTr ( "persons may attend." ) }
}
//var friendica_activities_self=JSON.parse(newsitemobject.friendica_activities_self);
} } catch ( e ) { print ( "Activities " + e + " " + JSON . stringify ( newsitemobject . friendica_activities ) ) }
return { likeText: likeText , dislikeText: dislikeText , attendyesText: attendyesText , attendnoText: attendnoText , attendmaybeText: attendmaybeText }
}
function showConversation ( conversationIndex , newsitemobject ) {
if ( newsitemobject . messagetype == 0 || newsitemobject . messagetype == 3 ) {
xhr . clearParams ( ) ;
xhr . setLogin ( login . username + ":" + Qt . atob ( login . password ) ) ;
xhr . setUrl ( login . server ) ;
xhr . setApi ( "/api/conversation/show" ) ;
xhr . setParam ( "id" , newsitemobject . id )
xhr . get ( ) ;
}
else {
xhr . clearParams ( ) ;
xhr . setLogin ( login . username + ":" + Qt . atob ( login . password ) ) ;
xhr . setUrl ( login . server ) ;
xhr . setApi ( "/api/direct_messages/conversation" ) ;
xhr . setParam ( "uri" , newsitemobject . statusnet_conversation_id )
xhr . get ( ) ;
}
}
Timer { id:contacttimer ; interval: 50 ; running: false ; repeat: false
onTriggered: {
root . newContacts = Newsjs . findNewContacts ( root . news , root . contactlist ) ;
root . onNewContactsChanged ( root . newContacts ) ;
Newsjs . storeNews ( login , db , root . news , root )
}
}
ListView {
id: contactView
x: mm
y: 4 * root . fontFactor * osSettings . bigFontSize
width: contactList . width - 2 * mm
height: contactList . height - 7 * root . fontFactor * osSettings . bigFontSize
clip: true
spacing: 0
property string viewtype: "conversation"
header: contactHeader
model: contactModel
delegate: Newsitem { }
}
2018-10-01 21:17:54 +02:00
BusyIndicator {
2021-05-12 21:41:34 +02:00
id: contactBusy
anchors.centerIn: parent
width: 10 * mm
height: 10 * mm
running: true
}
Component { id: contactHeader
Rectangle {
border.color: "#EEEEEE"
border.width: 1
color: "white"
width: contactView . width
height: contactView . width < 35 * root . fontFactor * osSettings . systemFontSize ? ( profileImage . height + namelabel . height + detailtext . height + 7 * mm ) : Math . max ( profileImage . height , ( buttonflow . height + namelabel . height + detailtext . height ) ) + 7 * mm
//height: wrapper.height
property var createdAtDate: new Date ( contact . created_at )
property string connectUrl: ( contact . network !== "dfrn" ) || ( contact . isFriend != 0 ) ? "" : ( "<a href='" + contact . url . replace ( "profile" , "dfrn_request" ) + "'>" + qsTr ( "Connect" ) + "</a><br>" )
Image {
id: profileImage
x: mm
y: mm
width: Math . min ( 15 * root . fontFactor * osSettings . bigFontSize , contactView . width / 2 ) //contactView.width/2
height: width
source: ( contact . profile_image != "" ) ? "file://" + contact.profile_image : contact . profile_image_url
onStatusChanged: if ( profileImage . status == Image . Error ) { source = "qrc:/images/defaultcontact.jpg" }
Connections {
target: contactList
onProfileimagesourceChanged: profileImage . source = profileimagesource
}
}
Flow { id:buttonflow
anchors.right: parent . right
anchors.rightMargin: mm
width: contactView . width - ( profileImage . width + 3 * mm )
height: ( contact . hasOwnProperty ( "acct" ) ) ? 21 * mm: 15 * mm //profileImage.height
y: mm
spacing: 4
BlueButton {
id:photobutton
height: 6 * mm
width: 8 * mm
text: "\uf03e" // "Photos"
visible: ( contact . network == "dfrn" )
onClicked: {
rootstack . currentIndex = 2 ;
bar . currentIndex = 2 ;
fotostab . phototabstatus = "Contact" ;
//fotostab.active=true;
fotoSignal ( root . login , contact ) ;
rootstackView . pop ( ) ;
}
}
BlueButton {
id:dmbutton
height: 6 * mm
width: 8 * mm
visible: ( contact . following == "true" )
text: "\uf040" //"DM"
onClicked: {
rootstack . currentIndex = 0 ;
newsSwipeview . currentIndex = 2 ;
directmessageSignal ( contact )
}
}
BlueButton {
id:eventbutton
visible: ( contact . network == "dfrn" )
height: 6 * mm
width: 8 * mm
text: "\uf073"
onClicked: {
rootstack . currentIndex = 3 ;
bar . currentIndex = 3 ;
calendartab . calendartabstatus = "Friend"
eventSignal ( contact ) ;
rootstackView . pop ( )
}
}
BlueButton {
id:approvebutton
visible: ( contact . hasOwnProperty ( "acct" ) )
height: 6 * mm
//width: implicitContentWidth+2*mm//8*mm
text: qsTr ( "Approve" )
onClicked: {
Helperjs . friendicaPostRequest ( login , "/api/v1/follow_requests/" + contact . id + "/authorize" , '' , "POST" , root , function ( returnvalue ) {
Helperjs . deleteData ( db , "friendshiprequests" , login . username , function ( ) { } , "id" , contact . id )
} )
root . friendsSignal ( ) ;
rootstackView . pop ( )
}
}
BlueButton {
id:rejectbutton
visible: ( contact . hasOwnProperty ( "acct" ) )
height: 6 * mm
//width: implicitContentWidth+2*mm//8*mm
text: qsTr ( "Reject" )
onClicked: {
Helperjs . friendicaPostRequest ( login , "/api/v1/follow_requests/" + contact . id + "/reject" , '' , "POST" , root , function ( returnvalue ) {
Helperjs . deleteData ( db , "friendshiprequests" , login . username , function ( ) { } , "id" , contact . id )
} )
root . friendsSignal ( ) ;
rootstackView . pop ( )
}
}
BlueButton {
id:ignorebutton
visible: ( contact . hasOwnProperty ( "acct" ) )
height: 6 * mm
//width: implicitContentWidth+2*mm//8*mm
text: qsTr ( "Ignore" )
onClicked: {
Helperjs . friendicaPostRequest ( login , "/api/v1/follow_requests/" + contact . id + "/ignore" , '' , "POST" , root , function ( returnvalue ) {
Helperjs . deleteData ( db , "friendshiprequests" , login . username , function ( ) { } , "id" , contact . id )
} ) ;
root . friendsSignal ( ) ;
rootstackView . pop ( )
}
}
2021-08-03 21:19:53 +02:00
BlueButton {
id:followbutton
visible: ( contact . isFriend == 0 )
height: 6 * mm
//width: implicitContentWidth+2*mm//8*mm
text: qsTr ( "Follow" )
onClicked: {
contactBusy . running = true ;
Helperjs . friendicaPostRequest ( login , "/api/v1/accounts/" + contact . id + "/follow" , '' , "POST" , root , function ( returnvalue ) {
Helperjs . updateData ( db , "contacts" , login . username , "isFriend" , 1 , function ( ) { } , "id" , contact . id )
root . friendsSignal ( login . username ) ;
rootstackView . pop ( )
// var username=login.username
//
} ) ;
}
}
BlueButton {
id:unfollowbutton
visible: ( contact . isFriend == 1 )
height: 6 * mm
//width: implicitContentWidth+2*mm//8*mm
text: qsTr ( "Unfollow" )
onClicked: {
Helperjs . friendicaPostRequest ( login , "/api/v1/accounts/" + contact . id + "/unfollow" , '' , "POST" , root , function ( returnvalue ) {
contactBusy . running = true ;
Helperjs . updateData ( db , "contacts" , login . username , "isFriend" , 0 , function ( ) { } , "id" , contact . id )
root . friendsSignal ( login . username ) ;
rootstackView . pop ( )
} ) ;
}
}
2021-05-12 21:41:34 +02:00
} //Flow end
Label {
id: namelabel
//x:mm
width: contactView . width < 35 * root . fontFactor * osSettings . systemFontSize ? contactView . width - 2 * mm: contactView . width - 17 * root . fontFactor * osSettings . bigFontSize
height: implicitHeight
text: contact . name + " (@" + contact . screen_name + ")"
wrapMode: Text . Wrap //elide:Text.ElideRight
color: "#303030"
font.pointSize: 1.2 * osSettings . bigFontSize
font.family: "Noto Sans"
anchors.top: contactView . width < 35 * root . fontFactor * osSettings . systemFontSize ? profileImage.bottom: buttonflow . bottom
anchors.margins: mm
anchors.left: contactView . width < 35 * root . fontFactor * osSettings . systemFontSize ? contactView.left: profileImage . right
}
Text {
id:detailtext
anchors.top: namelabel . bottom
anchors.left: contactView . width < 35 * root . fontFactor * osSettings . systemFontSize ? contactView.left: profileImage . right
anchors.margins: 2 * mm
//x:mm
width: contactView . width < 35 * root . fontFactor * osSettings . systemFontSize ? contactView . width - 2 * mm: contactView . width - 17 * root . fontFactor * osSettings . bigFontSize
height: implicitHeight
font.pointSize: osSettings . systemFontSize
font.family: "Noto Sans"
textFormat: Text . RichText
wrapMode: Text . Wrap
2021-08-03 21:19:53 +02:00
text: "<b>" + qsTr ( "Description" ) + ": </b> " + ( Qt . atob ( contact . description ) != "" ? contact.description: "" ) + "<br> <b>" + qsTr ( "Location" ) + ":</b> " + contact . location + "<br> <b>" + qsTr ( "Posts" ) + ":</b> " + contact . statuses_count +
2021-05-12 21:41:34 +02:00
"<br> <b>" + qsTr ( "URL" ) + ":</b> <a href='" + contact . url + "'>" + contact . url + "</a><br>" +
connectUrl + "<b>" + qsTr ( "Created at" ) + ":</b> " + createdAtDate . toLocaleString ( Qt . locale ( ) )
onLinkActivated: {
2018-10-01 21:17:54 +02:00
Qt . openUrlExternally ( link ) }
2021-05-12 21:41:34 +02:00
}
2018-10-01 21:17:54 +02:00
2021-05-12 21:41:34 +02:00
//}
}
} //Component end
2018-10-01 21:17:54 +02:00
Connections {
2021-05-12 21:41:34 +02:00
target: xhr
function onError ( data , url , api , code ) {
if ( data != "contactlist" ) { Helperjs . showMessage ( qsTr ( "Network Error" ) , "API:\n" + login . server + api + "\n Return: \n" + data , root ) ; }
contactBusy . running = false ;
}
function onSuccess ( data , api ) {
Service . processNews ( api , data )
replySignal ( "" )
}
}
Connections {
target: root
2020-11-25 21:40:17 +01:00
function onContactpostsChanged ( ) {
2021-08-03 21:19:53 +02:00
if ( root . contactposts . length > 0 && root . contactposts [ 0 ] != null ) { profileimagesource = root . contactposts [ 0 ] . friendica_author . profile_image_url_large }
2018-10-01 21:17:54 +02:00
contactBusy . running = false ;
contactModel . clear ( ) ;
var currentTime = new Date ( ) ;
2021-05-12 21:41:34 +02:00
var msg = { 'currentTime' : currentTime , 'model' : contactModel , 'news' : root . contactposts , 'options' : globaloptions } ;
2018-10-01 21:17:54 +02:00
contactWorker . sendMessage ( msg )
}
}
ListModel { id: contactModel }
WorkerScript {
id: contactWorker
source: "qrc:/js/newsworker.js"
}
2019-06-25 20:59:10 +02:00
MButton {
2021-05-12 21:41:34 +02:00
id: closeButton
anchors.top: parent . top
anchors.topMargin: 0.5 * root . fontFactor * osSettings . bigFontSize
anchors.right: parent . right
anchors.rightMargin: 1 * mm
width: 2 * root . fontFactor * osSettings . bigFontSize ;
text: "\uf057"
//font.pixelSize: 3*mm
onClicked: {
rootstackView . pop ( )
}
2018-10-01 21:17:54 +02:00
}
Component.onCompleted: {
2021-05-12 21:41:34 +02:00
xhr . clearParams ( ) ;
xhr . setLogin ( login . username + ":" + Qt . atob ( login . password ) ) ;
xhr . setUrl ( login . server ) ;
if ( contact . isFriend == 1 || contact . hasOwnProperty ( "acct" ) ) {
xhr . setApi ( "/api/statuses/user_timeline" ) ; }
else { xhr . setApi ( "/api/users/show" ) ; }
xhr . setParam ( "user_id" , contact . id )
xhr . get ( ) ;
2018-10-01 21:17:54 +02:00
}
}