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.

ConfigTab.qml 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  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.Dialogs 1.2
  33. import QtQuick.Controls 1.2
  34. import "qrc:/js/service.js" as Service
  35. import "qrc:/js/layout.js" as Layoutjs
  36. import "qrc:/js/helper.js" as Helperjs
  37. import "qrc:/qml/configqml"
  38. import "qrc:/qml/genericqml"
  39. StackView{
  40. id: configStack
  41. anchors.fill:parent
  42. initialItem: Flickable{
  43. width:root.width-5*mm
  44. height:root.height-12*mm
  45. contentHeight: configBackground.height
  46. boundsBehavior: Flickable.StopAtBounds
  47. Rectangle{
  48. id:configBackground
  49. color: "white"
  50. width:parent.width
  51. height:Math.max(90*mm,root.height-12*mm)
  52. property var users:[]
  53. property bool registeredUser: true
  54. property var userdata: ({})
  55. function setServericon(server){
  56. try {Helperjs.friendicaWebRequest(server+"/api/statusnet/config",configBackground, function (obj){
  57. var serverdata = JSON.parse(obj);
  58. servericon.visible=true;
  59. servericon.source=serverdata.site.logo})} catch(e){print(e)}
  60. }
  61. BlueButton{
  62. id:userButton
  63. text:qsTr("User")
  64. y:mm
  65. width: root.width/2
  66. onClicked:{
  67. var useritems="";
  68. for (var i=0;i<configBackground.users.length;i++){
  69. useritems=useritems+"MenuItem{text:'"+configBackground.users[i].username+
  70. "'; onTriggered: {Service.readConfig(db,function(obj){
  71. configBackground.registeredUser=true;
  72. userButton.text=obj.username;
  73. servername.text=obj.server;
  74. configBackground.setServericon(obj.server);
  75. username.text= obj.username;
  76. password.text=Qt.atob(obj.password);
  77. imagestore.text=obj.imagestore;
  78. maxNews.value=obj.maxnews;
  79. newsTypeField.text=obj.newsViewType;
  80. if( obj.isActive==0){userButton.fontColor='black'} else {userButton.fontColor='grey'}
  81. },'username','"+configBackground.users[i].username+"')}}"
  82. }
  83. var menuString="import QtQuick.Controls 1.4;import 'qrc:/js/service.js' as Service; Menu {"+useritems+"}";
  84. var userlistObject=Qt.createQmlObject(menuString,configBackground,"usermenuOutput")
  85. userlistObject.popup() }
  86. }
  87. Text {
  88. text: qsTr("Server")
  89. font.pixelSize:3*mm
  90. x: 4*mm; y: 10*mm
  91. }
  92. Text {
  93. text: qsTr("Nickname")
  94. font.pixelSize:3*mm
  95. x: 4*mm; y: 20*mm
  96. }
  97. Text {
  98. text: qsTr("Password")
  99. font.pixelSize:3*mm
  100. x: 4*mm; y: 30*mm
  101. }
  102. Text {
  103. text: qsTr("Image dir.")
  104. font.pixelSize:3*mm
  105. x: 4*mm; y: 40*mm
  106. }
  107. Text {
  108. text: qsTr("Max. News")
  109. font.pixelSize:3*mm
  110. x: 4*mm; y: 50*mm
  111. }
  112. Text {
  113. text: qsTr("News as")
  114. font.pixelSize:3*mm
  115. x: 4*mm; y: 60*mm
  116. }
  117. Text {
  118. text: qsTr("Sync Interval (0=None)")
  119. font.pixelSize:3*mm
  120. //visible: false
  121. x: 4*mm; y: 70*mm; //width:35*mm;wrapMode: Text.Wrap
  122. }
  123. // Text {
  124. // text: qsTr("Show Website")
  125. // x: 4*mm; y:80*mm; width: 20*mm
  126. // }
  127. Image{
  128. id:servericon
  129. x:4*mm;y:13.5*mm
  130. width:5*mm; height: 5*mm
  131. visible: false
  132. source:""
  133. MouseArea{
  134. anchors.fill:parent
  135. onClicked:{
  136. Service.showServerConfig(servername.text, configBackground, function(configString){
  137. var serverconfigObject=Qt.createQmlObject(configString,configBackground,"serverconfigOutput");})
  138. }
  139. }
  140. }
  141. BlueButton{
  142. id:serverSearchButton
  143. text:"\uf002"
  144. x:4*mm
  145. y:13.5*mm
  146. width: 5*mm; height:5*mm
  147. visible: servericon.visible?false:true
  148. onClicked:{Qt.openUrlExternally(Qt.resolvedUrl("https://dir.friendica.social/servers"))}
  149. }
  150. Rectangle{color: "light grey"; x: 10*mm; y: 13.5*mm; width: root.width-12*mm; height: 5*mm;}
  151. Flickable {
  152. id: servernameFlickable
  153. x: 10*mm; y: 13.5*mm; width: root.width-12*mm; height: 5*mm;
  154. contentWidth: servername.paintedWidth
  155. contentHeight: servername.paintedHeight
  156. clip: true
  157. TextEdit {
  158. id: servername
  159. width: servernameFlickable.width
  160. height: servernameFlickable.height
  161. focus: true
  162. font.pixelSize:3*mm
  163. text:"https://..."
  164. onEditingFinished:{
  165. if((servername.text).substring(0,14) =="https://...http"){
  166. serverstring.text= (serverstring.text).substring(11)
  167. }
  168. configBackground.setServericon(servername.text)
  169. }
  170. onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,servernameFlickable)
  171. }
  172. }
  173. Rectangle{
  174. color: "light grey"
  175. x: 4*mm; y: 23.5*mm; width: root.width-14*mm; height: 5*mm;
  176. TextInput {
  177. id: username
  178. anchors.fill: parent
  179. font.pixelSize:3*mm
  180. selectByMouse: true
  181. onEditingFinished:{
  182. if (username.text.indexOf('@')>-1){
  183. Helperjs.showMessage(qsTr("Error"),qsTr("Nicknames containing @ symbol currently not supported"),configBackground)
  184. }
  185. // Helperjs.friendicaWebRequest(servername.text+'/api/users/show?screen_name='+username.text,configBackground,function(obj){
  186. // var screennametest=JSON.parse(obj);
  187. // if (screennametest.hasOwnProperty('status')){
  188. // Helperjs.showMessage(qsTr("Error"),qsTr("Nickname not registered at given server!"),configBackground);
  189. // configBackground.registeredUser=false;
  190. // }else{configBackground.registeredUser=true}
  191. // });
  192. // }
  193. }
  194. }
  195. }
  196. BlueButton {
  197. x: root.width-9*mm; y: 23.5*mm; width:7*mm
  198. text: "\uf234"
  199. onClicked: {
  200. configStack.push({item:"qrc:/qml/configqml/RegisterPage.qml",properties:{url:servername.text+"/register?nickname="+username.getText(0,username.length)}})
  201. }
  202. }
  203. Rectangle{
  204. color: "light grey"
  205. x: 4*mm; y: 33.5*mm; width: root.width-6*mm; height: 5*mm;
  206. TextInput {
  207. id: password
  208. anchors.fill: parent
  209. font.pixelSize:3*mm
  210. selectByMouse: true
  211. echoMode: TextInput.PasswordEchoOnEdit
  212. }
  213. }
  214. Rectangle{color: "light grey"; x: 4*mm; y: 43.5*mm; width: root.width-14*mm; height: 5*mm;}
  215. Flickable {
  216. id: imagestoreFlickable
  217. x: 4*mm; y: 43.5*mm; width: root.width-14*mm; height: 5*mm;
  218. clip: true
  219. TextInput {
  220. id: imagestore
  221. width: imagestoreFlickable.width
  222. height: imagestoreFlickable.height
  223. font.pixelSize:3*mm
  224. wrapMode: TextEdit.NoWrap
  225. onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,imagestoreFlickable)
  226. }
  227. }
  228. FileDialog {
  229. id: imagestoreDialog
  230. title: "Please choose a directory"
  231. folder: shortcuts.pictures
  232. selectFolder: true
  233. onAccepted: {
  234. var imagestoreString=imagestoreDialog.folder.toString();
  235. imagestoreString=imagestoreString.replace(/^(file:\/{2})/,"")+"/"
  236. imagestore.text=imagestoreString
  237. }
  238. }
  239. BlueButton {
  240. x: root.width-9*mm; y: 43.5*mm; width: 7*mm; height: 5*mm;
  241. text: "..."
  242. onClicked:
  243. {imagestoreDialog.open()}
  244. }
  245. Slider{ id: maxNews
  246. x:19*mm; y: 53.5*mm;width: root.width/2;height:5*mm
  247. minimumValue: 0;maximumValue:2000; stepSize: 100
  248. }
  249. Rectangle{color: "light grey"; x: 4*mm; y: 53.5*mm; width: 9*mm; height: 5*mm;
  250. TextEdit{id:maxNewsText;
  251. anchors.fill: parent
  252. font.pixelSize:3*mm
  253. verticalAlignment:TextEdit.AlignRight
  254. text:maxNews.value
  255. focus: true
  256. selectByMouse: true
  257. }
  258. }
  259. Rectangle{
  260. x: 4*mm; y: 63.5*mm; width: newsTypeField.contentWidth+2*mm; height: 5*mm;
  261. color:"light grey"
  262. Text{
  263. id: newsTypeField
  264. anchors.fill: parent
  265. font.pixelSize:3*mm
  266. text:"Conversations"
  267. }
  268. MouseArea{
  269. anchors.fill:parent
  270. onClicked:newstypemenu.popup()
  271. }
  272. }
  273. Slider{ id: messageIntervalSlider
  274. x:22*mm; y: 73.5*mm;width: root.width/2;height:5*mm
  275. minimumValue: 0;maximumValue:120; stepSize: 15
  276. }
  277. Rectangle{
  278. x: 4*mm; y: 73.5*mm; width: 9*mm; height: 5*mm;
  279. TextEdit{
  280. id: messageIntervalField
  281. anchors.fill: parent
  282. font.pixelSize:3*mm
  283. verticalAlignment:TextEdit.AlignRight
  284. text:messageIntervalSlider.value
  285. focus: true
  286. selectByMouse: true
  287. }
  288. }
  289. Text{x: 14*mm; y: 73.5*mm; width: 5*mm; height: 5*mm;
  290. font.pixelSize:3*mm
  291. text:qsTr("Min.")
  292. }
  293. // CheckBox{
  294. // id:showwebsiteCheckbox
  295. // x:35*mm;y:80*mm
  296. // onClicked:{
  297. // if (checked==true){
  298. // Service.updateglobaloptions(root.db,"showWebsiteForLinks","true")
  299. // root.globaloptions.showWebsiteForLinks="true"
  300. // }
  301. // else {
  302. // Service.updateglobaloptions(root.db,"showWebsiteForLinks","false")
  303. // root.globaloptions.showWebsiteForLinks="false"
  304. // }
  305. // }
  306. // }
  307. BlueButton {
  308. x: 4*mm; y: 83.5*mm
  309. text: qsTr("Confirm")
  310. onClicked:{
  311. 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};
  312. var errormessage="";
  313. if (servername.text==""){errormessage=qsTr("No server given! ")}
  314. else if (username.text==""){errormessage+=qsTr("No nickname given! ")}
  315. else if ((configBackground.registeredUser==false)){errormessage+=qsTr("Nickname not registered at given server! ")}
  316. else if (password.text=="") {errormessage+=qsTr("No password given! ")}
  317. else if (imagestore.text=="") {errormessage+=qsTr("No image directory given!")}
  318. else if (maxNewsText.text=="") {errormessage+=qsTr("No maximum news number given!")}
  319. else {errormessage=""}
  320. if (errormessage=="") {
  321. Helperjs.friendicaRequest(userconfig,"/api/account/verify_credentials?skip_status=true",root,function(obj){
  322. var credentials=JSON.parse(obj);
  323. if (credentials.hasOwnProperty('status')){
  324. Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root)
  325. }
  326. else{
  327. filesystem.Directory=userconfig.imagestore;
  328. filesystem.makeDir("contacts");
  329. filesystem.makeDir("albums");
  330. Service.storeConfig(db,userconfig);
  331. Service.readConfig(db,function(userconfig){
  332. Helperjs.readData(db,"config","",function(storedUsers){
  333. storedUsers.sort(function(obj1, obj2) {
  334. return obj1.isActive - obj2.isActive;
  335. });
  336. configBackground.users=storedUsers});
  337. userButton.color="black"
  338. //reset values
  339. root.login=userconfig;
  340. root.news=[];
  341. },"isActive",0);
  342. Service.requestProfile(userconfig,db,root,function(nc){root.newContacts=nc});
  343. if(osSettings.osType=="Android" && userconfig.timerInterval !=0){
  344. alarm.setAlarm(userconfig.timerInterval);
  345. }
  346. Helperjs.showMessage(qsTr("Success"),qsTr("Name")+": "+credentials.name+"\nScreen Name: "+credentials.screen_name,root)
  347. }
  348. });
  349. }
  350. else {Helperjs.showMessage(qsTr("Error"), errormessage,root)}
  351. }}
  352. BlueButton {
  353. x: root.width/2+2*mm; y: mm; width: 5*mm; height: 5*mm;
  354. text: "-"
  355. onClicked:{
  356. var userconfig={server: servername.text, username: username.text, password: Qt.btoa(password.text)};
  357. Service.deleteConfig(db,userconfig,function(){
  358. filesystem.Directory=imagestore.text+"contacts";
  359. filesystem.rmDir();
  360. filesystem.Directory=imagestore.text+"albums";
  361. filesystem.rmDir();
  362. configBackground.registeredUser=true;
  363. servername.text="https://...";
  364. servericon.visible=false;
  365. servericon.source="";
  366. username.text="";
  367. password.text="";
  368. imagestore.text="";
  369. maxNews.value=0;
  370. newsTypeField.text="Conversations";
  371. messageIntervalSlider.value=30;
  372. userButton.text=qsTr("User");
  373. Helperjs.readData(db,"config","",function(storedUsers){
  374. storedUsers.sort(function(obj1, obj2) {
  375. return obj1.isActive - obj2.isActive;
  376. })
  377. configBackground.users=storedUsers;})
  378. })
  379. }}
  380. BlueButton {
  381. x: root.width/2+8*mm; y: mm; width: 5*mm; height: 5*mm;
  382. text: "+"
  383. onClicked:{
  384. configBackground.registeredUser=true;
  385. servername.text="https://..."
  386. servericon.visible=false;
  387. servericon.source="";
  388. username.text=""
  389. password.text=""
  390. imagestore.text=""
  391. maxNews.value=0
  392. newsTypeField.text="Conversations"
  393. messageIntervalSlider.value=30
  394. userButton.text=qsTr("User")
  395. }
  396. }
  397. BlueButton {
  398. x: root.width/2+14*mm; y: mm; width: 5*mm; height: 5*mm;
  399. text: "?"
  400. onClicked:{
  401. configStack.push({item:"qrc:/qml/configqml/InfoBox.qml"});
  402. }
  403. }
  404. Menu {
  405. id:newstypemenu
  406. MenuItem {
  407. text: qsTr("Timeline")
  408. onTriggered: {newsTypeField.text="Timeline"}
  409. }
  410. MenuItem {
  411. text: qsTr("Conversations")
  412. onTriggered: {newsTypeField.text="Conversations"}
  413. }
  414. }
  415. Component.onCompleted: {
  416. try{Helperjs.readData(db,"config","",function(storedUsers){
  417. storedUsers.sort(function(obj1, obj2) {
  418. return obj1.isActive - obj2.isActive;
  419. })
  420. configBackground.users=storedUsers;
  421. Service.readConfig(db,function(obj){
  422. userButton.text=obj.username;
  423. servername.text=obj.server;
  424. configBackground.setServericon(obj.server);
  425. username.text= obj.username;
  426. password.text=Qt.atob(obj.password);
  427. imagestore.text=obj.imagestore;
  428. maxNews.value=obj.maxnews;
  429. newsTypeField.text=obj.newsViewType;
  430. messageIntervalSlider.value=obj.timerInterval;
  431. if( obj.isActive==0){userButton.fontColor='black'} else {userButton.fontColor='grey'}},"isActive",0
  432. )
  433. })
  434. // Service.readGlobaloptions(db,function(go){
  435. // if (root.globaloptions.showWebsiteForLinks!="false"){showwebsiteCheckbox.checked=true}
  436. // })
  437. }
  438. catch (e){print(e)
  439. Helperjs.friendicaWebRequest("https://dir.friendica.social/servers/surprise",configBackground,function(html){
  440. var bpos=html.indexOf("baseurl");
  441. var baseurl=html.substring(html.indexOf("http",bpos),html.indexOf('"',html.indexOf("http",bpos)));
  442. servername.text=baseurl
  443. })}
  444. }
  445. }
  446. }
  447. }