Qt/QML App for Friendiqa
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

NewsTab.qml 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. // This file is part of Friendiqa
  2. // https://git.friendi.ca/lubuwest/Friendiqa
  3. // Copyright (C) 2017 Marco R. <thomasschmidt45@gmx.net>
  4. //
  5. // This program is free software: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation, either version 3 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // In addition, as a special exception, the copyright holders give
  11. // permission to link the code of portions of this program with the
  12. // OpenSSL library under certain conditions as described in each
  13. // individual source file, and distribute linked combinations including
  14. // the two.
  15. //
  16. // You must obey the GNU General Public License in all respects for all
  17. // of the code used other than OpenSSL. If you modify file(s) with this
  18. // exception, you may extend this exception to your version of the
  19. // file(s), but you are not obligated to do so. If you do not wish to do
  20. // so, delete this exception statement from your version. If you delete
  21. // this exception statement from all source files in the program, then
  22. // also delete it here.
  23. //
  24. // This program is distributed in the hope that it will be useful,
  25. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  26. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27. // GNU General Public License for more details.
  28. //
  29. // You should have received a copy of the GNU General Public License
  30. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  31. import QtQuick 2.7
  32. import QtQuick.Controls 1.4
  33. import QtQuick.Controls 2.3 as QC2
  34. //import QtQuick.Controls.Styles 2.3
  35. import QtQuick.Dialogs 1.3
  36. import "qrc:/qml/genericqml"
  37. import "qrc:/js/news.js" as Newsjs
  38. import "qrc:/js/helper.js" as Helperjs
  39. import "qrc:/js/service.js" as Service
  40. import AndroidNative 1.0
  41. Item {
  42. Connections{
  43. target:newstab
  44. onNewstabstatusChanged:{
  45. newstabstatusButton.text= qsTr(newstab.newstabstatus)
  46. }
  47. }
  48. Connections{
  49. target:xhr
  50. onError:{
  51. Helperjs.showMessage(qsTr("Network Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root);
  52. }
  53. onSuccess:{
  54. // downloadNotice.text=downloadNotice.text+ "\n xhr finished "+Date.now();
  55. Service.processNews(api,data);
  56. }
  57. }
  58. // Connections{
  59. // target:xhr
  60. // onError:{
  61. // Helperjs.showMessage(qsTr("Network Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root);
  62. // }
  63. // onSuccess:{
  64. // if (api=="/api/statuses/friends_timeline"){
  65. // // downloadNotice.text=downloadNotice.text+ "\n xhr finished "+Date.now();
  66. // //Service.processNews(api,data);
  67. // if(login.newsViewType=="Timeline"){
  68. // Newsjs.newsfromdb(db,login.username,function(dbnews){showNews(dbnews)})}
  69. // else{Newsjs.chatsfromdb(db,login.username,function(dbnews){
  70. // showNews(dbnews);
  71. // })}
  72. // }
  73. // }
  74. // }
  75. Timer {id:replytimer; interval: 1000; running: false; repeat: false
  76. onTriggered: {
  77. if(newstab.newstabstatus=="Conversation"){
  78. showConversation(newsStack.timelineIndex-1,newsModel.get(0).newsitemobject)}
  79. else{
  80. Service.updateView(newstab.newstabstatus)
  81. }
  82. }
  83. }
  84. Timer {id:contacttimer; interval: 50; running: false; repeat: false
  85. onTriggered: {
  86. // downloadNotice.text=downloadNotice.text + "\n contactTimer start "+ Date.now()
  87. root.newContacts=Newsjs.findNewContacts(root.news,root.contactlist);
  88. Newsjs.storeNews(login,db,root.news,root)
  89. }
  90. }
  91. function showNews(newsToShow){
  92. try{
  93. if (newsStack.depth>1){newsStack.pop()}
  94. }catch(e){}
  95. newsBusy.running=false;
  96. var currentTime= new Date();
  97. // downloadNotice.text=downloadNotice.text + "\n shownews start "+ Date.now();
  98. //print("appendnews "+newsStack.appendNews +JSON.stringify(newsToShow))
  99. var msg = {'currentTime': currentTime, 'model': newsModel,'news':newsToShow,'method':newsStack.updateMethodNews, 'options':globaloptions};
  100. newsWorker.sendMessage(msg);
  101. //newsStack.appendNews=false
  102. }
  103. function showConversation(conversationIndex,newsitemobject){
  104. if(newsitemobject.messagetype==0){
  105. xhr.clearParams();
  106. xhr.setLogin(login.username+":"+Qt.atob(login.password));
  107. xhr.setUrl(login.server);
  108. xhr.setApi("/api/conversation/show");
  109. xhr.setParam("id",newsitemobject.id)
  110. xhr.get();
  111. }
  112. else{
  113. xhr.clearParams();
  114. xhr.setLogin(login.username+":"+Qt.atob(login.password));
  115. xhr.setUrl(login.server);
  116. xhr.setApi("/api/direct_messages/conversation");
  117. xhr.setParam("uri",newsitemobject.statusnet_conversation_id)
  118. xhr.get();
  119. }
  120. }
  121. function showContact(contact){
  122. newstab.newstabstatus="Contact";
  123. newsStack.push({item:"qrc:/qml/newsqml/ContactPage.qml",properties:{"contact": contact}});
  124. }
  125. function search(term){//print("Search "+term)
  126. if (term!=""){
  127. newstab.newstabstatus="Search";
  128. newsBusy.running=true;
  129. newsStack.updateMethodNews="refresh";
  130. xhr.setLogin(login.username+":"+Qt.atob(login.password));
  131. xhr.setUrl(login.server);
  132. xhr.setApi("/api/search");
  133. xhr.clearParams();
  134. xhr.setParam("q",term)
  135. xhr.get();}
  136. newsView.anchors.topMargin=7*mm
  137. }
  138. function onFriendsMessages(friend){
  139. newstab.newstabstatus="Contact"
  140. Newsjs.newsfromdb(db,root.login.username, function(dbnews){
  141. if (dbnews.length==0){
  142. Newsjs.newsfromdb(db,login.username,function(forumnews){
  143. showNews(forumnews)
  144. },friend.url)
  145. }
  146. else showNews(dbnews)
  147. },friend.id)
  148. }
  149. function onDirectMessage(friend){
  150. //newstab.newstabstatus="SendMessage" ,"login":login ,
  151. newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"reply_to_user": friend,"directmessage":1, "login":root.login}});
  152. }
  153. function sendUrls(urls){print(root.currentIndex==0);
  154. if((urls.length==1)&&(newsStack.depth<2)){
  155. newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"attachImageURLs":urls}})
  156. }
  157. }
  158. function sendtext(text){
  159. if(text&&(newsStack.depth<2)){
  160. if (text.subject=="undefined"){text.subject=""}
  161. if(text.plaintext.lastIndexOf(".jpg")>-1 || text.plaintext.lastIndexOf(".jpeg")>-1 || text.plaintext.lastIndexOf(".png")>-1 || text.plaintext.lastIndexOf(".gif")>-1){
  162. text.plaintext="<a href="+text.plaintext+"><img src="+text.plaintext+"></a>"}
  163. newsStack.push({item:"qrc:/qml/newsqml/MessageSend.qml",properties:{"bodyMessage":text.subject+"\n"+text.plaintext}})
  164. }
  165. }
  166. StackView{
  167. id: newsStack
  168. anchors.fill:parent
  169. property string updateMethodNews: "refresh"
  170. property var allchats: ({})
  171. initialItem:Rectangle {
  172. id:newslistRectangle
  173. y:1
  174. color: "white"
  175. BlueButton{
  176. id:newstabstatusButton
  177. anchors.top: parent.top
  178. anchors.topMargin: 0.5*mm
  179. text: qsTr(newstab.newstabstatus)
  180. onClicked: {newstabmenu.popup(2*mm,6*mm)}
  181. QC2.Menu{id:newstabmenu
  182. width: 40*mm
  183. delegate:QC2.MenuItem{
  184. contentItem: Text{
  185. font.pixelSize: 3.5*mm
  186. text:parent.text
  187. }
  188. background: Rectangle {
  189. implicitWidth: 40*mm; implicitHeight: 5*mm
  190. color: "#ffffff"
  191. border.color: "grey"
  192. }
  193. }
  194. QC2.Action {
  195. text: qsTr("Timeline")
  196. onTriggered: {
  197. newstab.newstabstatus="Timeline";
  198. //newsModel.clear();
  199. try{ Newsjs.newsfromdb(root.db,root.login.username, function(dbnews){
  200. showNews(dbnews)
  201. })}catch(e){Helperjs.showMessage("Error",e,root)}}
  202. }
  203. QC2.Action {
  204. text: qsTr("Conversations")
  205. onTriggered:{
  206. //newsModel.clear();
  207. newstab.newstabstatus="Conversations";
  208. Newsjs.chatsfromdb(db,root.login.username,function(news){showNews(news)})
  209. }
  210. }
  211. QC2.Action {
  212. text: qsTr("Favorites")
  213. onTriggered:{
  214. newsStack.updateMethodNews="refresh";
  215. newstab.newstabstatus="Favorites";
  216. Service.updateView("Favorites")
  217. }
  218. }
  219. QC2.Action {
  220. text: qsTr("Replies")
  221. onTriggered:{
  222. newsStack.updateMethodNews="refresh";
  223. newstab.newstabstatus="Replies";
  224. Service.updateView("Replies")
  225. }
  226. }
  227. QC2.Action {
  228. text: qsTr("Public timeline")
  229. onTriggered:{
  230. newsStack.updateMethodNews="refresh";
  231. newstab.newstabstatus="Public Timeline";
  232. Service.updateView("Public Timeline")
  233. }
  234. }
  235. QC2.Action {
  236. text: qsTr("Direct Messages")
  237. onTriggered:{
  238. newsStack.updateMethodNews="refresh";
  239. newstab.newstabstatus="Direct Messages";
  240. Service.updateView("Direct Messages")
  241. }
  242. }
  243. QC2.Action {
  244. text: qsTr("Notifications")
  245. onTriggered:{
  246. newsStack.updateMethodNews="refresh";
  247. newstab.newstabstatus="Notifications";
  248. Service.updateView("Notifications")
  249. }
  250. }
  251. QC2.Action {
  252. text: qsTr("Group news")
  253. onTriggered:
  254. {
  255. newsStack.updateMethodNews="refresh";
  256. Service.showGroups();
  257. }
  258. }
  259. QC2.Action {
  260. text: qsTr("Quit")
  261. onTriggered:{
  262. Service.cleanNews(root.db,function(){
  263. Service.cleanContacts(root.login,root.db,function(){
  264. Qt.quit()})
  265. })
  266. }
  267. }
  268. }
  269. }
  270. Row{
  271. spacing: mm
  272. anchors.top: parent.top
  273. anchors.topMargin: 0.5*mm
  274. anchors.right: parent.right
  275. BlueButton {
  276. id: searchButton
  277. text: "\uf002"
  278. onClicked: {
  279. newsView.anchors.topMargin=18*mm;
  280. var component = Qt.createComponent("qrc:/qml/genericqml/Search.qml");
  281. var searchItem = component.createObject(newsStack,{y:8*mm,width:root.width,height: 8*mm});
  282. }
  283. }
  284. BlueButton {
  285. id: newMessageButton
  286. text: "\uf040"
  287. onClicked: {
  288. var groups=[];
  289. Helperjs.readData(root.db,"groups",root.login.username,function(groupobject){
  290. groups=groupobject
  291. });
  292. newstab.newstabstatus="SendMessage";
  293. Helperjs.readData(root.db,"contacts",root.login.username,function(friends){
  294. newsStack.push("qrc:/qml/newsqml/MessageSend.qml",{"contacts": friends,"login":root.login})
  295. },"isFriend",1);
  296. }
  297. }
  298. // BlueButton {
  299. // id: quitButton
  300. // text: "\uf08b"
  301. // onClicked: {Service.cleanNews(root.db,function(){
  302. // Service.cleanContacts(root.login,root.db,function(){
  303. // Qt.quit() })
  304. // })}
  305. // }
  306. BlueButton {
  307. id: update
  308. text: "\uf021"
  309. onClicked: {
  310. if (newstab.newstabstatus=="Timeline"){
  311. newsStack.updateMethodNews="append"
  312. } else {newsStack.updateMethodNews="refresh"}
  313. //root.contactLoadType="news";
  314. Service.updateView(newstab.newstabstatus)
  315. }
  316. }
  317. }
  318. Component { id:footerComponent
  319. Rectangle{
  320. border.color: "#EEEEEE"
  321. border.width: 1
  322. width:newsView.width
  323. height:6*mm
  324. Text{
  325. font.pixelSize: 1.5*mm
  326. anchors.centerIn: parent
  327. text:qsTr("More")
  328. }
  329. MouseArea{anchors.fill:parent
  330. onClicked:{
  331. var currentTime= new Date();
  332. var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at;
  333. if(newstab.newstabstatus=="Timeline"){
  334. Newsjs.newsfromdb(root.db,root.login.username, function(news){
  335. var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true, 'options':globaloptions};
  336. newsWorker.sendMessage(msg);
  337. },false,lastnews_id)}
  338. if(newstab.newstabstatus=="Conversations"){
  339. Newsjs.chatsfromdb(root.db,root.login.username, function(news){
  340. var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true, 'options':globaloptions};
  341. newsWorker.sendMessage(msg);
  342. },lastnews_id)}
  343. // else if(newstab.newstabstatus=="Contact"){
  344. // Newsjs.newsfromdb(root.db,root.login.username, function(news){
  345. // var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true};
  346. // newsWorker.sendMessage(msg);
  347. // },newsModel.get(newsModel.count-1).newsitemobject.uid,lastnews_id)}
  348. else if (newstab.newstabstatus=="Notifications"){}
  349. else{
  350. //newsStack.appendNews=true;
  351. xhr.setParam("max_id",newsModel.get(newsModel.count-1).newsitemobject.id-1);
  352. xhr.get()
  353. }}
  354. }
  355. }
  356. }
  357. ListView {
  358. id: newsView
  359. anchors.fill: parent
  360. anchors.topMargin: 7*root.mm
  361. anchors.leftMargin: 3*root.mm; anchors.rightMargin: root.mm
  362. anchors.bottomMargin: 1*root.mm
  363. clip: true
  364. spacing: 0
  365. footer: footerComponent
  366. model: newsModel
  367. delegate: Newsitem{}
  368. //onContentYChanged:{if(contentY<-8*mm&&contentY>(-8*mm-1)){print("refreshing");
  369. onDragEnded:{if(contentY<-5*mm){
  370. var onlynew=true;
  371. Service.updateView(newstab.newstabstatus)
  372. }}
  373. }
  374. ListModel{id: newsModel}
  375. WorkerScript {
  376. id: newsWorker
  377. source: "qrc:/js/newsworker.js"
  378. }
  379. BusyIndicator{
  380. id: newsBusy
  381. anchors.horizontalCenter: newsView.horizontalCenter
  382. anchors.top:newsView.top
  383. anchors.topMargin: 2*mm
  384. width:10*mm
  385. height: 10*mm
  386. }
  387. Rectangle{
  388. id:downloadNotice
  389. property alias text: noticeText.text
  390. color:"white"
  391. border.color:"grey"
  392. z:1
  393. anchors.horizontalCenter: newsView.horizontalCenter
  394. anchors.bottom:newsView.bottom
  395. anchors.bottomMargin: 2*mm
  396. width: noticeText.width+2*mm
  397. height: noticeText.height+2*mm
  398. visible: (downloadNotice.text!="")
  399. Text{
  400. id:noticeText
  401. color: "grey"
  402. anchors.centerIn: parent
  403. width: contentWidth
  404. height: contentHeight
  405. font.pixelSize: 2*mm
  406. text:""
  407. }
  408. }
  409. Component.onCompleted: {
  410. root.messageSignal.connect(onFriendsMessages);
  411. root.directmessageSignal.connect(onDirectMessage);
  412. root.contactdetailsSignal.connect(showContact);
  413. root.newsSignal.connect(showNews);
  414. root.uploadSignal.connect(sendUrls);
  415. root.sendtextSignal.connect(sendtext);
  416. try{newsModel.clear()} catch(e){}
  417. // xhr.setLogin(login.username+":"+Qt.atob(login.password));
  418. // xhr.setUrl(login.server);
  419. if(root.news.length>0){showNews(root.news)}
  420. else{ newstab.newstabstatus=login.newsViewType;
  421. if(login.newsViewType=="Timeline"){Newsjs.newsfromdb(db,login.username,function(dbnews){showNews(dbnews)})}
  422. else{Newsjs.chatsfromdb(db,login.username,function(dbnews){
  423. showNews(dbnews);
  424. })}
  425. }
  426. }
  427. }
  428. }
  429. }