// This file is part of Friendiqa // https://git.friendi.ca/lubuwest/Friendiqa // Copyright (C) 2020 Marco R. // // 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 . import QtQuick 2.0 import QtQuick.Controls 2.12 import QtQuick.Controls.Material 2.12 import "qrc:/js/news.js" as Newsjs import "qrc:/js/helper.js" as Helperjs import "qrc:/qml/genericqml" Item { id: newsitem width: newsitemobject.hasOwnProperty("indent")&&newsitemobject.indent>0?parent.width:newsitem.ListView.view.width//parent.width//newsView.width // height:toprow.height+friendicaActivities.height+controlrow.height+conversationColumn.height+1//Math.max((itemMessage.height+topFlow.height+friendicaActivities.height+4*mm),profileImage.height+user_name.height+mm) property int itemindex: index property var newsitemobject:model.newsitemobject property string attending: "" property var friendica_activities_view: getActivitiesView(model.newsitemobject) onAttendingChanged: {attendLabel.visible=true; attendLabel.text= qsTr("attending")+": "+ qsTr(attending)} signal replyto(string parent_id) function showActivityContacts(contacts){ var component = Qt.createComponent("qrc:/qml/newsqml/FriendicaActivities.qml"); var imagedialog = component.createObject(friendicaActivities,{"activitymembers": contacts}); } function pushConversation(){ if (model.newsitemobject.hasOwnProperty("currentconversation")){ rootstackView.push("qrc:/qml/newsqml/Conversation.qml",{"news": model.newsitemobject.currentconversation})} else{rootstackView.push("qrc:/qml/newsqml/Conversation.qml")}; showConversation(index,newsitemobject) } Rectangle{width:newsitem.width; height: 1; anchors.bottom: newsitem.bottom; color: Material.backgroundDimColor } Rectangle{ width:newsitem.width height:newsitem.height-1 color: Material.background Column { id:toprow width: newsitemobject.hasOwnProperty("indent")?newsitem.width-(newsitem.width/20 *(newsitemobject.indent+1)):newsitem.width//-8*mm x:newsitemobject.hasOwnProperty("indent")?newsitem.width/20*(newsitemobject.indent):0 height: newsitemobject.nsfw?5*mm:Math.min(implicitHeight,3/4*root.height) clip: true Item{id:itemHeader height: Math.max(profileImage.height+mm,topFlow.implicitHeight+mm) width: parent.width MouseArea{ anchors.fill: parent onClicked:{ showContact(newsitemobject.user)} } Image { id:profileImage source: ((newsitemobject.user.profile_image!="") && (typeof(newsitemobject.user.profile_image)=="string"))? "file://"+newsitemobject.user.profile_image : newsitemobject.user.profile_image_url x:1 y:1 width: 2*root.fontFactor*osSettings.bigFontSize height: 2*root.fontFactor*osSettings.bigFontSize //radius:mm onStatusChanged: if (profileImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"} } Flow{ id:topFlow spacing: 0.5*mm width:parent.width-8*mm anchors.left: profileImage.right anchors.margins: mm Label { id:user_name width:parent.width font.bold: true font.pointSize: osSettings.systemFontSize wrapMode: Text.WrapAtWordBoundaryOrAnywhere text: newsitemobject.user.name+" (@"+newsitemobject.user.screen_name+")"+newsitemobject.forumname } Label { id:messageTypeLabel color: Material.secondaryTextColor text: if (newsitemobject.messagetype==1){ qsTr("Direct Message")} else if(newsitemobject.messagetype==2) {" Notification"} else {qsTr("Source: ")+newsitemobject.source} font.pointSize: 0.6*osSettings.systemFontSize } Label { id:createdAtLabel color: Material.secondaryTextColor font.pointSize: 0.6*osSettings.systemFontSize horizontalAlignment: Label.AlignRight text: " \u00B7 "+getDateDiffString(newsitemobject.dateDiff) + " " +qsTr("ago") } Label { id:replytoLabel color: Material.secondaryTextColor font.pointSize: 0.6*osSettings.systemFontSize font.family: "Noto Sans" horizontalAlignment: Label.AlignRight //text: (newsitemobject.in_reply_to_status_id!="null"&&newsitemobject.in_reply_to_status_id!=null)?" \u00B7 "+qsTr("In reply to ")+newsitemobject.reply_user.screen_name:" " text: (newsitemobject.reply_user!=false&&typeof(newsitemobject.reply_user)!="undefined")?" \u00B7 "+qsTr("In reply to ")+newsitemobject.reply_user.screen_name:" " } } } MouseArea{id: itemBody width: toprow.width-2 height: itemMessage.height onClicked: {pushConversation()} Text { color: Material.primaryTextColor linkColor: Material.accentColor id: itemMessage textFormat: Text.RichText font.family: "Noto Sans" font.pointSize: osSettings.systemFontSize text: newsitemobject.statusnet_html width: toprow.width-2 height: implicitHeight wrapMode: Text.Wrap clip:true onLinkActivated:{ if(link.startsWith(root.login.server+"\/search\?tag=")){ newstab.newstabstatus="Search"; root.searchSignal(link.substring(root.login.server.length+12,link.length)) } else{Qt.openUrlExternally(link)} } Component.onCompleted:{ if (newsitemobject.imageAttachmentList.length>0){ if(newsitemobject.imageAttachmentList[0].mimetype.substring(0,5)=="image"){ var component = Qt.createComponent("qrc:/qml/newsqml/NewsImage.qml"); var imageQml = component.createObject(toprow,{"source":newsitemobject.imageAttachmentList[0].url}); } } if (newsitemobject.videoAttachmentList.length>0){ var component = Qt.createComponent("qrc:/qml/newsqml/NewsVideo.qml"); //var videoQml = component.createObject(messageColumn,{"source":newsitemobject.attachmentList[attachments].url,"mimetype":newsitemobject.attachmentList[attachments].mimetype}); var videoQml = component.createObject(toprow,{"attachment":newsitemobject.videoAttachmentList[0]}); } if (newsitemobject.hasOwnProperty("lastcomment")){ var moreComponent = Qt.createComponent("qrc:/qml/newsqml/MoreComments.qml"); var conversationQml = moreComponent.createObject(conversationColumn,{"comments":newsitemobject.newscount-1}); var commentComponent = Qt.createComponent("qrc:/qml/newsqml/Newsitem.qml"); var conversationQml = commentComponent.createObject(conversationColumn,{"newsitemobject":newsitemobject.lastcomment}); } } }} } BlueButton{ width: newsitem.width-2 height:5*mm anchors.bottom: toprow.bottom visible: toprow.implicitHeight>3/4*root.height || newsitemobject.nsfw text:"\uf078" fontColor: Material.secondaryTextColor border.color: "transparent" color: Material.backgroundColor // gradient: Gradient { // GradientStop { position: 0.0; color: "transparent" } // GradientStop { position: 0.5; color: Material.backgroundDimColor} // } radius:0 onClicked: { if (text=="\uf078"){ toprow.height=toprow.implicitHeight+6*mm;text="\uf077" } else { toprow.height=Math.min(toprow.implicitHeight,3/4*root.height); text="\uf078"; newsView.positionViewAtIndex(index,ListView.Beginning); } } } // Bottom row for activities Flow{ id:friendicaActivities anchors.top:toprow.bottom width:parent.width spacing:mm Label{color: Material.secondaryTextColor height:3.5*mm font.pointSize: 0.75*osSettings.systemFontSize text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.likeText MouseArea{ anchors.fill: parent onClicked: { showActivityContacts(newsitemobject.friendica_activities.like)} } } Label{color: Material.secondaryTextColor height:3.5*mm font.pointSize: 0.75*osSettings.systemFontSize text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.dislikeText MouseArea{ anchors.fill: parent onClicked: { showActivityContacts(newsitemobject.friendica_activities.dislike)} } } Label{color: Material.secondaryTextColor height:3.5*mm font.pointSize: 0.75*osSettings.systemFontSize text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.attendyesText MouseArea{ anchors.fill: parent onClicked: { showActivityContacts(newsitemobject.friendica_activities.attendyes)} }} Label{color: Material.secondaryTextColor height:3.5*mm font.pointSize: 0.75*osSettings.systemFontSize text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.attendnoText MouseArea{ anchors.fill: parent onClicked: { showActivityContacts(newsitemobject.friendica_activities.attendno)} } } Label{color: Material.secondaryTextColor height:3.5*mm font.pointSize: 0.75*osSettings.systemFontSize text: newsitemobject.hasOwnProperty("isLastComment")?"":friendica_activities_view.attendmaybeText MouseArea{ anchors.fill: parent onClicked: { showActivityContacts(newsitemobject.friendica_activities.attendmaybe)} } } Label{ id:attendLabel color: Material.secondaryTextColor height:3.5*mm font.pointSize: 0.75*osSettings.systemFontSize horizontalAlignment: Label.AlignRight text: (newsitemobject.friendica_activities_view.self.attending)?(qsTr("Attending: ")+ qsTr(newsitemobject.friendica_activities_view.self.attending)):"" } } //Bottom row for buttons Row{id:controlrow anchors.top:friendicaActivities.bottom height: root.fontFactor*osSettings.bigFontSize CheckBox{ id:likeCheckbox width:newsitem.width/5 height: parent.height visible: ((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3))? true:false checked:(model.newsitemobject.friendica_activities_view.self.liked==1)?true:false indicator: Rectangle{ implicitWidth: newsitem.width/5 implicitHeight:root.fontFactor*osSettings.bigFontSize color:"transparent" Text{ anchors.centerIn: parent font.pointSize: osSettings.systemFontSize font.family:fontAwesome.name color:likeCheckbox.checked?Material.primaryTextColor: Material.secondaryTextColor text:likeCheckbox.checked?"\uf118"+"!":"\uf118" } } onClicked: { if(likeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"like",newsitemobject.id,root);dislikeCheckbox.checked=false; newsitemobject.friendica_activities_view.self.liked=1; newsitem.ListView.view.model.set(index,{"newsitemobject":newsitemobject}); } else{Newsjs.like(root.login,root.db,0,"like",newsitemobject.id,root); newsitemobject.friendica_activities_view.self.liked=0; newsitem.ListView.view.model.set(index,{"newsitemobject":newsitemobject}); }} } CheckBox{ id: dislikeCheckbox width:newsitem.width/5 height: parent.height visible: ((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3))? true:false checked: (newsitemobject.friendica_activities_view.self.disliked==1)?true:false indicator: Rectangle{ implicitWidth: newsitem.width/5 implicitHeight:root.fontFactor*osSettings.bigFontSize color:"transparent" Text{ anchors.centerIn: parent font.pointSize: osSettings.systemFontSize font.family:fontAwesome.name color:dislikeCheckbox.checked?Material.primaryTextColor: Material.secondaryTextColor text: dislikeCheckbox.checked?"\uf119"+"!":"\uf119" } } onClicked: { if (dislikeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"dislike",newsitemobject.id,root);likeCheckbox.checked=false; newsitemobject.friendica_activities_view.self.disliked=1; newsitem.ListView.view.model.set(index,{"newsitemobject":newsitemobject}); } else {Newsjs.like(root.login,root.db,0,"dislike",newsitemobject.id,root); newsitemobject.friendica_activities_view.self.disliked=0; newsitem.ListView.view.model.set(index,{"newsitemobject":newsitemobject}); }} } CheckBox { id:favoritedCheckbox visible:((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3)) width: newsitem.width/5 height: parent.height indicator:Rectangle{ implicitWidth: newsitem.width/5 implicitHeight:root.fontFactor*osSettings.bigFontSize color:"transparent" Text{ anchors.centerIn: parent font.pointSize: osSettings.systemFontSize font.family:fontAwesome.name color: favoritedCheckbox.checked?Material.primaryTextColor: Material.secondaryTextColor text:"\uf005" } } checked:(newsitemobject.favorited>0) onClicked:{ if(favoritedCheckbox.checkState==Qt.Checked){ Newsjs.favorite(login,true,newsitemobject.id,root); model.newsitemobject.favorited=1} else if(favoritedCheckbox.checkState==Qt.Unchecked){ Newsjs.favorite(login,false,newsitemobject.id,root);model.newsitemobject.favorited=0} } } Rectangle{ width: newsitem.width/5 height: parent.height visible:(newsitemobject.messagetype!==2) color:"transparent" Text{ id:replysymbol color: Material.secondaryTextColor anchors.centerIn: parent font.pointSize: osSettings.systemFontSize font.family:fontAwesome.name text: "\uf112" } MouseArea{ anchors.fill:parent onClicked: { var directmessage=0; if (newsitemobject.messagetype==1){ directmessage=1} var replycomp=Qt.createComponent("qrc:/qml/newsqml/MessageSend.qml"); var conversation; if (newsitem.ListView.view==null){conversation=true} else if (newsitem.ListView.view.viewtype=="conversation"){ conversation=true newsitem.ListView.view.currentIndex=itemindex } else{ conversation=false; newsitem.ListView.view.currentIndex=itemindex }; var reply=replycomp.createObject(friendicaActivities,{parentId:newsitemobject.id,reply_to_user:newsitemobject.user.screen_name, state:"reply",conversation:conversation,textfocus:true}) } } } Rectangle{ width: newsitem.width/5 height: parent.height visible:(newsitemobject.messagetype!==2) color:"transparent" Text{ id:newsmenusymbol color: Material.secondaryTextColor anchors.centerIn: parent font.pointSize: osSettings.systemFontSize font.family:fontAwesome.name text: "\uf142" } MouseArea{ anchors.fill:parent onClicked: {newsmenu.popup()}} } } Menu { id:newsmenu width: 10*root.fontFactor*osSettings.systemFontSize delegate: MenuItem{ contentItem: Text{ font.pointSize: osSettings.systemFontSize color: Material.secondaryTextColor text: parent.text } } onAboutToShow:{if(newsitemobject.hasOwnProperty("external_url")){ insertAction(4,externalAction)} } Action { text: qsTr("Repost") onTriggered: { Newsjs.retweetNews(root.login,db,newsitemobject.id,root,function(reply){ Helperjs.showMessage("Repost",qsTr("Success!"),root) }) } } Action { text: qsTr("Conversation") onTriggered: { pushConversation(); } } Action { text: qsTr("DM") onTriggered: { root.directmessageSignal(newsitemobject.user.screen_name); } } Action { text: qsTr("Bookmark") onTriggered: { if(model.newsitemobject.favorited==0){ Newsjs.favorite(login,true,newsitemobject.id,root); model.newsitemobject.favorited=1} else if(model.newsitemobject.favorited==1){ Newsjs.favorite(login,false,newsitemobject.id,root);model.newsitemobject.favorited=0} } } Menu{ title: qsTr("Attending") width: 10*root.fontFactor*osSettings.systemFontSize delegate: MenuItem{ contentItem: Text{ font.pointSize: osSettings.systemFontSize color: Material.secondaryTextColor text: parent.text } } Action{ text:qsTr("yes") onTriggered: {Newsjs.attend(root.login,db,"yes",newsitemobject.id,root,function(){ model.newsitemobject.friendica_activities_view.self.attending="yes";attending="yes"}) } } Action{text:qsTr("maybe") onTriggered: {Newsjs.attend(root.login,db,"maybe",newsitemobject.id,root,function(){ model.newsitemobject.friendica_activities_view.self.attending="maybe";attending="maybe"}) } } Action{text:qsTr("no") onTriggered: {Newsjs.attend(root.login,db,"no",newsitemobject.id,root,function(){ model.newsitemobject.friendica_activities_view.self.attending="no";attending="no"})} } } Action { text: qsTr("Delete") onTriggered: { Newsjs.deleteNews(root.login,root.db,newsitemobject.id,newsitemobject.messagetype,root,function(reply){ var msg = {'deleteId': index, 'model': newsModel}; newsWorker.sendMessage(msg); }) } } } Column{ id:conversationColumn anchors.top:controlrow.bottom width: newsitem.width } } Action{id:externalAction text: qsTr("External") onTriggered: {Qt.openUrlExternally(newsitemobject.external_url)} } }