v0.6.4 contact search

This commit is contained in:
LubuWest 2022-03-01 21:59:21 +01:00
commit 5032c78de1
57 changed files with 2218 additions and 2252 deletions

View file

@ -1,177 +0,0 @@
// This file is part of Friendiqa
// https://git.friendi.ca/lubuwest/Friendiqa
// Copyright (C) 2020 Marco R. <thomasschmidt45@gmx.net>
//
// 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
import QtQuick.Controls 2.12
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!=0)?"":( "<a href='"+contact.url.replace("profile","dfrn_request") +"'>"+qsTr("Connect")+"</a><br>")
Rectangle {
id: wrapper
width:root.width-2*mm //friendsTabView.width;
height:root.height-20*mm// friendsTabView.height-15*mm
border.color: "grey"
color:"white"
radius: 0.5*mm
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: root.width-6*mm //friendsTabView.width-4*mm
height: 3*mm
text: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{
id: detailsrectangle
anchors.top: namelabel.bottom
anchors.topMargin: 2*mm
ScrollView{
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
//frameVisible: true
id:namelabelflickable
width: root.width-10*mm
height:root.height-50*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> "+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
MButton{
id:photobutton
height: 6*mm
width: 8*mm
text: "\uf03e" // "Photos"
visible:(contact.network=="dfrn")
onClicked:{
fotostab.phototabstatus="Contact";
root.currentIndex=2;
fotostab.active=true;
root.fotoSignal(contact) ;
contactLargeComponent.destroy();
}
}
MButton{
id:messagebutton
height: 6*mm
width: 8*mm
text: "\uf0e6" //"Messages"
onClicked:{
root.currentIndex=0;
//newstab.active=true;
root.messageSignal(contact) ;
contactLargeComponent.destroy();
}
}
MButton{
id:dmbutton
visible: (contact.following=="true")
height: 6*mm
width: 8*mm
text: "\uf040" //"DM"
onClicked:{
root.currentIndex=0;
root.directmessageSignal(contact.screen_name);
contactLargeComponent.destroy();
}
}
MButton{
id:eventbutton
visible:(contact.network=="dfrn")
height: 6*mm
width: 8*mm
text:"\uf073" //Events
onClicked:{
root.currentIndex=3;
calendartab.active=true;
calendartab.calendartabstatus="Friend"
root.eventSignal(contact);
contactLargeComponent.destroy();
}
}
MButton{
id: closeButton
height: 6*mm
width: 8*mm
text: "\uf057" //"close"
onClicked:{contactLargeComponent.destroy();
}
}
}
}
}
}

View file

@ -31,11 +31,12 @@
import QtQuick 2.11
import QtQuick.Controls 2.12
import QtQuick.Controls.Material 2.12
import QtQuick.Layouts 1.11
import QtQuick.LocalStorage 2.0
import "qrc:/js/helper.js" as Helperjs
//import "qrc:/js/news.js" as Newsjs
import "qrc:/js/service.js" as Service
import "qrc:/js/news.js" as Newsjs
import "qrc:/qml/contactqml"
import "qrc:/qml/genericqml"
@ -44,14 +45,16 @@ Item{
Layout.fillWidth:true
Layout.fillHeight: true
function showContacts(contact){
try {contactsModel.clear()} catch(e){print(e)};
Helperjs.readData(db, "contacts",root.login.username,function(contactsobject){
try {contactsModel.clear()} catch(e){};
Newsjs.listFriends(login,db,function(contactsobject){
for (var j=0;j<contactsobject.length;j++){
contactsobject[j].description=Qt.atob(contactsobject[j].description);
contactsobject[j].name=Qt.atob(contactsobject[j].name);
if(Helperjs.getCount(db,login,"contacts","screen_name",contactsobject[j].screen_name)>1){
contactsobject[j].screen_name=contactsobject[j].screen_name+"+"+contactsobject[j].cid
}
contactsModel.append({"contact":contactsobject[j]});
}
},"isFriend",0,"screen_name ASC");
},searchText.text,-1);
}
MButton {
id: cleanButton
@ -61,17 +64,40 @@ Item{
anchors.right: parent.right
onClicked: {
Service.cleanContacts(root.login,root.db,function(){
try {contactsModel.clear()} catch(e){print(e)};
Helperjs.readData(db, "contacts",root.login.username,function(contactsobject){
for (var j=0;j<contactsobject.length;j++){
contactsobject[j].description=Qt.atob(contactsobject[j].description);
contactsobject[j].name=Qt.atob(contactsobject[j].name);
contactsModel.append({"contact":contactsobject[j]});
}
},"isFriend",0,"screen_name ASC");
showContacts()
// try {contactsModel.clear()} catch(e){print(e)};
// Helperjs.readData(db, "contacts",root.login.username,function(contactsobject){
// for (var j=0;j<contactsobject.length;j++){
// contactsobject[j].description=Qt.atob(contactsobject[j].description);
// contactsobject[j].name=Qt.atob(contactsobject[j].name);
// contactsModel.append({"contact":contactsobject[j]});
// }
// },"isFriend",0,"screen_name ASC");
})
}
}
Rectangle {
id:searchComponent
x: mm; y:mm
color: Material.backgroundColor
radius:0.5*mm
width: 10*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
TextField {
id: searchText
color: Material.primaryTextColor
focus: true
font.pointSize: osSettings.systemFontSize
wrapMode: Text.Wrap
anchors.fill:parent
selectByMouse: true
cursorVisible: false
placeholderText: "\uf0b0"
onTextChanged: {showContacts(root.login.username)}
}
}
ListView {
id: contactsView
x:mm

View file

@ -0,0 +1,169 @@
// This file is part of Friendiqa
// https://git.friendi.ca/lubuwest/Friendiqa
// Copyright (C) 2020 Marco R. <thomasschmidt45@gmx.net>
//
// 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.11
import QtQuick.Controls 2.12
import QtQuick.Controls.Material 2.12
import QtQuick.Layouts 1.11
import QtQuick.LocalStorage 2.0
import "qrc:/js/helper.js" as Helperjs
import "qrc:/js/service.js" as Service
import "qrc:/js/news.js" as Newsjs
import "qrc:/qml/contactqml"
import "qrc:/qml/genericqml"
Page{
id: contactsSearchPage
function search(term){
contactSearchBusy.running=true;
try {contactsSearchModel.clear()} catch(e){};
xhr.clearParams();
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setUrl(login.server);
xhr.setApi("/api/v1/accounts/search");
xhr.setParam("q",term);
xhr.setParam("limit",99)
xhr.get();
}
Connections{
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);}
contactSearchBusy.running=false;
}
function onSuccess(data,api){
if (api=="/api/v1/accounts/search" && data!=""){
try{var searchlist = JSON.parse(data);}catch(e){print("Error "+e)}
contactSearchBusy.running=false;
if (Array.isArray(searchlist)){
searchlist.sort(function(a,b){
if (a.group > b.group) {
return -1;
}
if (a.group < b.group) {
return 1;
}
return 0
})
for (let i=0;i<searchlist.length;i++){
if (searchlist[i].id!="0"){
if (searchlist[i].note!=null){
searchlist[i].description=searchlist[i].note;}
else{searchlist[i].description=""}
searchlist[i].name=(searchlist[i].display_name);
searchlist[i].screen_name=searchlist[i].username;
searchlist[i].location="";
searchlist[i].profile_image=""
searchlist[i].profile_image_url=searchlist[i].avatar;
searchlist[i].curIndex=contactsSearchModel.count;
let contactType="";
if (searchlist[i].group){contactType=qsTr("Forum")}
//else if (contactlist[i].bot){contactType=qsTr("Bot")}
else{contactType=qsTr("Person")}
contactsSearchModel.append({"contact":searchlist[i],"contactType":contactType});
}
}
}
}
}
}
MButton {
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"
onClicked: {
rootstackView.pop()
}
}
Search{
y:0.5*root.fontFactor*osSettings.bigFontSize;
x:1.5*root.fontFactor*osSettings.systemFontSize;
width:root.width-(7*root.fontFactor*osSettings.systemFontSize+mm);
height: 2.5*root.fontFactor*osSettings.systemFontSize;
color:Material.dialogColor
selfdestroying:false
}
BusyIndicator{
id: contactSearchBusy
anchors.centerIn:parent
width:10*mm
height: 10*mm
running: false
}
Component {
id: sectionHeading
Rectangle {
width: contactsSearchView.width
height: childrenRect.height
color: Material.backgroundColor
required property string section
Text {
color: Material.secondaryTextColor
text: parent.section
font.bold: true
font.pointSize: osSettings.bigFontSize
}
}
}
ListView {
id: contactsSearchView
x:mm
y:4*root.fontFactor*osSettings.bigFontSize;
width:root.width-2*mm
height: root.height-7*root.fontFactor*osSettings.bigFontSize;
spacing: 2
clip: true
function processContactSelection(contactobject){contactobject.searchContact=true;showContact(contactobject)}
model: contactsSearchModel
delegate: ContactComponent { }
section.property: "contactType"
section.criteria: ViewSection.FullString
section.delegate: sectionHeading
}
ListModel{id: contactsSearchModel}
// Component.onCompleted: {
// friendsTabView.contactsSignal.connect(showContacts);
// showContacts()
// }
}

View file

@ -46,7 +46,7 @@ Item{
property int currentContact: 0
function showFriends(contact){
try {friendsModel.clear()} catch(e){print(e)};
try {friendsModel.clear()} catch(e){};
Helperjs.readData(db,"friendshiprequests",login.username,function(friendrequestsobject){
for (var i=0;i<friendrequestsobject.length;i++){
if (friendrequestsobject[i].note!=null){
@ -61,18 +61,18 @@ Item{
friendsModel.append({"contact":friendrequestsobject[i],"contactType":qsTr("Friend Requests")});
}
});
Helperjs.readData(db,"contacts",login.username,function(friendsobject){
Newsjs.listFriends(login,db,function(friendsobject){
for (var i=0;i<friendsobject.length;i++){
if(friendsobject[i].description!=""){
friendsobject[i].description=Qt.atob(friendsobject[i].description);}
friendsobject[i].name=Qt.atob(friendsobject[i].name);
if(Helperjs.getCount(db,login,"contacts","screen_name",friendsobject[i].screen_name)>1){
friendsobject[i].screen_name=friendsobject[i].screen_name+"+"+friendsobject[i].cid
}
friendsModel.append({"contact":friendsobject[i],"contactType":qsTr("Friends")});
}
},"isFriend",1,"screen_name ASC");
},(searchText.text==""?searchText.preeditText:searchText.text));
}
Connections{
target:xhr
function onDownloaded(type,url,filename,i){
@ -84,6 +84,7 @@ Item{
}
}
}
MButton {
id: updateFriendsButton
text: "\uf021"
@ -95,6 +96,7 @@ Item{
Helperjs.deleteData(root.db,"friendshiprequests",root.login.username,function(){});
updatenews.setDatabase();
updatenews.login();
updatenews.setSyncAll(false);
updatenews.friendrequests();
//root.contactLoadType="friends";
Newsjs.requestFriends(root.login,db,root,function(nc){
@ -115,12 +117,34 @@ Item{
value: friendsGridTab.currentContact/root.newContacts.length
}
Rectangle {
id:searchComponent
x: mm; y:mm
color: Material.backgroundColor
radius:0.5*mm
width: 10*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
TextField {
id: searchText
color: Material.primaryTextColor
focus: true
font.pointSize: osSettings.systemFontSize
wrapMode: Text.Wrap
anchors.fill:parent
selectByMouse: true
cursorVisible: false
placeholderText: "\uf0b0"
onTextChanged: if (text.length>0){showFriends(root.login.username)}
onPreeditTextChanged: {if (preeditText.length>0){showFriends(root.login.username)}}
}
}
Component {
id: sectionHeading
Rectangle {
width: friendsView.width
height: childrenRect.height
color: Material.dialogColor //color: "lightsteelblue"
color: Material.backgroundColor
required property string section
Text {
color: Material.secondaryTextColor
@ -131,6 +155,28 @@ Item{
}
}
//GridView {
Component { id:headerComponent
Rectangle{
color: Material.dialogColor
width:friendsView.width
height:6*mm
Text{
color: Material.primaryTextColor
font.pointSize: osSettings.bigFontSize
anchors.centerIn: parent
text:"\uf234"
}
MouseArea{
anchors.fill:parent
onClicked:{
rootstackView.push("qrc:/qml/contactqml/ContactsSearchPage.qml")
}
}
}
}
ListView{
id: friendsView
x:mm
@ -145,6 +191,7 @@ Item{
// }
model: friendsModel
delegate: ContactComponent { }
header:headerComponent
section.property: "contactType"
section.criteria: ViewSection.FullString
section.delegate: sectionHeading

View file

@ -65,38 +65,38 @@ Rectangle {
TabBar {
id: friendsbar
width: osSettings.osType=="Android"?parent.width-2*osSettings.bigFontSize:parent.width
height: 9*mm
x: osSettings.osType=="Android"?2*osSettings.bigFontSize:0
width: osSettings.osType=="Android"?parent.width-2*root.fontFactor*osSettings.bigFontSize:parent.width
height: 2*root.fontFactor*osSettings.bigFontSize
x: osSettings.osType=="Android"?2*root.fontFactor*osSettings.bigFontSize:0
visible: !wideScreen
position:TabBar.Header
currentIndex: 1
TabButton {
text: qsTr("Me")
font.pointSize: osSettings.systemFontSize
height: 7*mm
height: 1.7*root.fontFactor*osSettings.bigFontSize//7*mm
}
TabButton {
text: qsTr("Friends")
font.pointSize: osSettings.systemFontSize
height: 7*mm
height: 1.7*root.fontFactor*osSettings.bigFontSize//7*mm
}
TabButton {
text: qsTr("Contacts")
font.pointSize: osSettings.systemFontSize
height: 7*mm
height: 1.7*root.fontFactor*osSettings.bigFontSize//7*mm
}
TabButton {
text: qsTr("Groups")
font.pointSize: osSettings.systemFontSize
height: 7*mm
height: 1.7*root.fontFactor*osSettings.bigFontSize//7*mm
}
}
LeftDrawerLinux{
id:leftDrawer
visible: wideScreen&&rootstackView.depth<2
width: visible?osSettings.systemFontSize*15:0
width: visible?root.fontFactor*osSettings.systemFontSize*15:0
height: root.height-bar.height
}

View file

@ -56,16 +56,8 @@ Item {
height: parent.height-mm
radius: 0.5*mm
border.color: "grey"
color:Material.backgroundColor//"white"
color:Material.backgroundColor
// Image {
// id: photoImage
// x:1
// y:1
// width: 10*mm
// height:10*mm
// source:"qrc:/images/defaultcontact.jpg"
// }
Rectangle{
id:namelabelRect
x: 1
@ -147,112 +139,7 @@ Item {
delegate: ContactComponent { }// groupMember
function processContactSelection(contactobject){showContactdetails(contactobject)}
}
ListModel{id: groupModel}
// Component {
// id:groupMember
// Rectangle{
// width:parent.width
// height:6*mm
// Rectangle{id:memberrectangle
// border.color: "#EEEEEE"
// border.width: 1
// width:parent.width-12*mm
// height:6*mm
// Image {
// id: memberImage
// x:1
// y:1
// width: 5*mm
// height:5*mm
// source:(groupmember.isFriend==1)? "file://"+groupmember.profile_image :groupmember.profile_image_url
// onStatusChanged: if (photoImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"}
// }
// Text{
// font.pixelSize: 3*mm
// anchors.left: memberImage.right
// anchors.margins: 1*mm
// width:parent.width-1
// text:groupmember.name
// }
// MouseArea{
// anchors.fill: parent
// onClicked:{
//// root.currentIndex=1;
//// friendstab.active=true;
//// root.contactdetailsSignal(groupmember)
// root.currentIndex=0;
// root.contactdetailsSignal(groupmember)
// }
// }
// // BlueButton{
// // anchors.left: memberrectangle.right
// // anchors.margins: 1*mm
// // text: "\uf056"
// // onClicked:{
// // groupModel.remove(index)
// // }
// // }
// }
// }
// }
// Row{
// anchors.top: groupListView.bottom
// anchors.topMargin: mm
// spacing: mm
// }
// BlueButton{
// id: addMembers
// text:"\uf234"
// onClicked: {
// Newsjs.listFriends(root.login,root.db,function(userdata){
// var newlistcontacts=[];
// for (var n in userdata){
// if (groupmembers.indexOf(userdata[n].id)==-1){
// newlistcontacts.push(userdata[n])
// }
// }
// var component = Qt.createComponent("qrc:/qml/contactqml/Contactlist.qml");
// var contactlistobject = component.createObject(groupListView,{"possibleUsers":newlistcontacts});
// })
// }
// }
// BlueButton{
// id: updateButton
// text: "\uf0ee"
// onClicked:{
// var groupobject={};
// var groupmembers=[];
// for (var i=0;i<groupModel.count;i++){groupmembers.push(groupModel.get(i).groupmember)}
// try{ groupobject.id=group.gid} catch(e){};
// try{ groupobject.new=group.new} catch(e){};
// if (namelabel.text==""){
// Helperjs.showMessage(qsTr("Error"),qsTr("No name given"),root)}
// else {
// groupobject.name=namelabel.text;
// groupobject.user=groupmembers;
// updateGroup(login,db,groupobject)
// groupComponent.state="";
// }
// }
// }
// BlueButton{
// id: deleteButton
// text: "\uf056"
// onClicked:{
// Newsjs.deleteGroup(root.login,root.db,root,group,function(){
// groupComponent.state="";
// groupsModel.remove(index)})
// }
// }
}
Component.onCompleted:{if(group.new){groupComponent.state="large"}}
}
@ -262,12 +149,7 @@ Item {
name: "large"
PropertyChanges { target: groupComponent; height: groupsView.height - 6*root.fontFactor*osSettings.bigFontSize }
PropertyChanges { target: namelabel; font.pointSize: 1.2*osSettings.bigFontSize; readOnly:false}
//PropertyChanges { target: namelabelRect; height: 2*osSettings.bigFontSize}
PropertyChanges { target: closeButton; visible: true}
//PropertyChanges { target: groupComponent; z: 2 }
//PropertyChanges { target: wrapper; width:groupsView.width-2*mm;height:groupsView.height -2*mm-1}
//PropertyChanges { target: photoImage; width:15*mm;height:15*mm }
//PropertyChanges { target:groupComponent.GridView.view ;contentY:groupComponent.y;contentX:groupComponent.x;interactive:false}
PropertyChanges { target: detailsrectangle; visible:true }
PropertyChanges { target: infobutton; visible: false}
}

View file

@ -76,17 +76,17 @@ Item{
}
}
}
MButton {
id: updateGroupsButton
text: "\uf021"
anchors.top: parent.top
anchors.topMargin: mm
anchors.right: parent.right
anchors.rightMargin: mm
onClicked: {
Newsjs.requestGroups(root.login,root.db,root,function(){
groupsGridTab.showGroups(root.login.username)})}
}
// MButton {//requestGroups() not working with Friendica 02/2022
// id: updateGroupsButton
// text: "\uf021"
// anchors.top: parent.top
// anchors.topMargin: mm
// anchors.right: parent.right
// anchors.rightMargin: mm
// onClicked: {
// Newsjs.requestGroups(root.login,root.db,root,function(){
// groupsGridTab.showGroups(root.login.username)})}
// }
// BlueButton {
// id: newGroupButton
// text: "\uf234"
@ -103,7 +103,7 @@ Item{
x:mm
y:updateGroupsButton.height+4*mm
width:groupsGridTab.width-2*mm
height:groupsGridTab.height-updateGroupsButton.height-2*mm
height:groupsGridTab.height-2*mm//-updateGroupsButton.height
clip: true
// cellHeight: 16*mm
// cellWidth: 17*mm