RosterPage.qml 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. import QtQuick 1.1
  2. import meegim 1.0
  3. MyPage {
  4. id: rosterPage
  5. objectName: "rosterPage"
  6. property string selectedName: ""
  7. Connections {
  8. target: muc
  9. onInvitationMucReceived: {
  10. dlgInviteMUC.dlgShowHide()
  11. }
  12. }
  13. Connections {
  14. target: xmppClient
  15. onConnectingChanged: {
  16. if( xmppClient.stateConnect == XmppClient.Connecting ) {
  17. console.log( "QML: RosterPage: connestion ... called statConnection()" )
  18. statConnection()
  19. } else if ( xmppClient.stateConnect == XmppClient.Connected ) {
  20. statConnected()
  21. console.log("QML: RosterPage: connected ... called statConnected()")
  22. } else if ( xmppClient.stateConnect == XmppClient.Disconnect ) {
  23. statDisonnected()
  24. console.log("QML: RosterPage: disconnectd ... called statDisonnected()")
  25. }
  26. }
  27. onStatusChanged: {
  28. console.log( "QML: RosterPage: onStatusChanged:" + xmppClient.status )
  29. setStatusStatus( xmppClient.status, xmppClient.statusText )
  30. }
  31. onStatusTextChanged: {
  32. console.log( "QML: RosterPage: onStatusTextChanged:" + xmppClient.statusText )
  33. setStatusStatus( xmppClient.status, xmppClient.statusText )
  34. }
  35. onErrorHappened: {
  36. setStatusStatus( xmppClient.status, xmppClient.statusText )
  37. }
  38. onSubscriptionReceived: {
  39. console.log( "QML: RosterPage: ::onSubscriptionReceived: [" + bareJid + "]" )
  40. createInfoPanel( "", "Subscription received \n from "+bareJid, 5000, "lightblue" )
  41. dlgSubscribes.addBareJid( bareJid )
  42. }
  43. }
  44. function statConnection() {
  45. connectingRect.opacity = 0.4
  46. }
  47. function statConnected() {
  48. connectingRect.opacity = 0
  49. }
  50. function statDisonnected() {
  51. connectingRect.opacity = 0
  52. }
  53. function setStatusStatus( status, statText ) {
  54. var resSet = dlgMyStatus.setStatus( status, statText )
  55. if( !resSet ) {
  56. return;
  57. }
  58. //console.log("<***>setStatusStatus: [" + status + "] [" + statText + "]")
  59. //console.log("setStatusStatus: XmppClient.Online: [" + XmppClient.Online + "]")
  60. if( (status == XmppClient.Online) || (status == XmppClient.Chat) ) {
  61. toolBarButtonPresence.icon = "qrc:/qml/images/bar_presence_online.png"
  62. console.log( "toolBarButtonPresence.icon: " + toolBarButtonPresence.icon )
  63. } else if( (status == XmppClient.Away) || (status == XmppClient.XA) ) {
  64. toolBarButtonPresence.icon = "qrc:/qml/images/bar_presence_away.png"
  65. } else if( status == XmppClient.DND ) {
  66. toolBarButtonPresence.icon = "qrc:/qml/images/bar_presence_busy.png"
  67. } else if( status == XmppClient.Offline ) {
  68. toolBarButtonPresence.icon = "qrc:/qml/images/bar_presence_offline.png"
  69. }
  70. }
  71. Component.onCompleted: {
  72. /* блокировка ориентации */
  73. main.appOrientation = main.orPortrait
  74. setStatusStatus( xmppClient.status, xmppClient.statusText )
  75. if( main.invRoomJid != "" )
  76. {
  77. dlgInviteMUC.dlgShowHide()
  78. }
  79. }
  80. DialogQuery {
  81. id: dlgInviteMUC
  82. title: "Invitation"
  83. text: "Invitation to\n" + invRoomJid
  84. textButtonOk: qsTr("Accept")
  85. textButtonCancel: qsTr("Reject")
  86. inverseMouseArea: false
  87. onClickedOk: {
  88. if( invRoomJid != "" ) {
  89. //xmppClient.addMucRoster( invRoomJid, muc.subjectRoom ) //add muc to roster
  90. //muc.jidRoom = invRoomJid //enter to muc
  91. rosterPage.closePage( "qrc:/qml/MucLoginPage.qml" )
  92. }
  93. dlgShowHide()
  94. //invRoomJid = ""
  95. //invIniterJid = ""
  96. }
  97. onClickedCancel: {
  98. dlgShowHide()
  99. invRoomJid = ""
  100. invIniterJid = ""
  101. }
  102. }
  103. /*******************************************************************************/
  104. colorPage: "white"
  105. property int __selectedContactItemType: 0
  106. Component {
  107. id: componentRosterItem
  108. HorizontalGradient {
  109. id: wrapper
  110. clip: true
  111. width: listViewRoster.width
  112. height: 90
  113. //border.color: "blue"
  114. ListView.onAdd: ParallelAnimation {
  115. NumberAnimation {
  116. target: wrapper
  117. property: "opacity"
  118. from: 0; to: 1
  119. duration: 600
  120. easing.type: Easing.InOutQuad
  121. }
  122. NumberAnimation {
  123. target: wrapper;
  124. property: "scale";
  125. duration: 600;
  126. from: 0.01; to: 1
  127. easing.type: Easing.InOutQuad
  128. }
  129. }
  130. ListView.onRemove: ParallelAnimation {
  131. NumberAnimation {
  132. target: wrapper
  133. property: "opacity"
  134. from: 1; to: 0
  135. duration: 600
  136. easing.type: Easing.InOutQuad
  137. }
  138. NumberAnimation {
  139. target: wrapper;
  140. property: "scale";
  141. duration: 600;
  142. from: 1; to: 0.01
  143. easing.type: Easing.InOutQuad
  144. }
  145. }
  146. /*ListView.onFlickingChanged: {
  147. console.log( index + ") =>" + pos.x + " " + pos.y )
  148. }*/
  149. Image {
  150. id: imgPresence
  151. //source: contactPicStatus
  152. source: contactItemType == 0 ? contactPicStatus : "qrc:/qml/images/muc.png"
  153. anchors.verticalCenter: parent.verticalCenter
  154. anchors.left: parent.left
  155. anchors.leftMargin: 7
  156. Text {
  157. id: txtUnreadMsg
  158. text: contactUnreadMsg
  159. font.pixelSize: 22
  160. anchors.centerIn: parent
  161. visible: contactUnreadMsg != 0
  162. z: 1
  163. }
  164. Image {
  165. id: imgNewMsg
  166. source: "qrc:/qml/images/message.png"
  167. anchors.centerIn: parent
  168. smooth: true
  169. scale: 0.8
  170. visible: contactUnreadMsg != 0
  171. SequentialAnimation {
  172. running: contactUnreadMsg != 0
  173. loops: Animation.Infinite
  174. NumberAnimation {
  175. target: imgNewMsg
  176. property: "opacity"
  177. from: 1; to: 0.4
  178. duration: 1300
  179. easing.type: Easing.InOutQuad
  180. }
  181. NumberAnimation {
  182. target: imgNewMsg
  183. property: "opacity"
  184. from: 0.4; to: 1
  185. duration: 1300
  186. easing.type: Easing.InOutQuad
  187. }
  188. }
  189. } //imgNewMsg
  190. } //imgPresence
  191. HorizontalGradient {
  192. z: 1
  193. id: wrapperTxtJid
  194. anchors.left: imgPresence.right
  195. anchors.leftMargin: 5
  196. anchors.top: parent.top
  197. anchors.topMargin: 1
  198. height: parent.height/2 - 2
  199. width: contactItemType == 0 ? parent.width - (imgPresence.width + imgPresence.anchors.leftMargin) - (imgAvatar.width + imgAvatar.anchors.rightMargin) - 5 : parent.width - (imgPresence.width + imgPresence.anchors.leftMargin)
  200. gradient: Gradient {
  201. GradientStop { color: "transparent"; position: 0 }
  202. GradientStop { color: "transparent"; position: 0.8 }
  203. GradientStop { color: "white"; position: 0.96 }
  204. GradientStop { color: "white"; position: 1 }
  205. }
  206. }
  207. Item {
  208. anchors.verticalCenter: wrapperTxtJid.verticalCenter
  209. anchors.left: wrapperTxtJid.left
  210. height: wrapperTxtJid.height
  211. width: wrapperTxtJid.width
  212. clip: true
  213. Text {
  214. id: txtJid
  215. clip: true
  216. //text: (contactName === "" ? contactJid : contactName) + (contactResource !== "" ? "/" + contactResource : "")
  217. text: (contactName === "" ? contactJid : contactName)
  218. font.pixelSize: 28
  219. anchors.verticalCenter: parent.verticalCenter
  220. anchors.left: parent.left
  221. }
  222. }
  223. HorizontalGradient {
  224. z: 1
  225. id: wrapperTxtStatus
  226. anchors.left: imgPresence.right
  227. anchors.leftMargin: 5
  228. anchors.top: wrapperTxtJid.bottom
  229. anchors.topMargin: 1
  230. height: parent.height/2 - 2
  231. width: contactItemType == 0 ? parent.width - (imgPresence.width + imgPresence.anchors.leftMargin) - (imgAvatar.width + imgAvatar.anchors.rightMargin) - 5 : parent.width - (imgPresence.width + imgPresence.anchors.leftMargin)
  232. gradient: Gradient {
  233. GradientStop { color: "transparent"; position: 0 }
  234. GradientStop { color: "transparent"; position: 0.8 }
  235. GradientStop { color: "white"; position: 0.96 }
  236. GradientStop { color: "white"; position: 1 }
  237. }
  238. }
  239. Item {
  240. anchors.verticalCenter: wrapperTxtStatus.verticalCenter
  241. anchors.left: wrapperTxtStatus.left
  242. height: wrapperTxtStatus.height
  243. width: wrapperTxtStatus.width
  244. clip: true
  245. Text {
  246. id: txtStatus
  247. text: contactTextStatus
  248. font.pixelSize: 22
  249. color: "gray"
  250. anchors.verticalCenter: parent.verticalCenter
  251. anchors.left: parent.left
  252. }
  253. }
  254. Image {
  255. id: imgAvatar
  256. smooth: true
  257. height: 80
  258. width: 80
  259. anchors.right: parent.right
  260. anchors.rightMargin: 5
  261. anchors.verticalCenter: parent.verticalCenter
  262. source: contactPicAvatar === "" ? "qrc:/qml/images/avatar.png" : contactPicAvatar
  263. Image {
  264. anchors.centerIn: parent
  265. source: "qrc:/qml/images/meego_frame_80.png"
  266. }
  267. visible: contactItemType == 0 ? true : false
  268. }
  269. gradient: Gradient {
  270. GradientStop{ id: posGr1; color: "white"; position: 0 }
  271. GradientStop{ id: posGr5; color: "white"; position: 0 }
  272. GradientStop{ id: posGr2; color: "white"; position: 0 }
  273. GradientStop{ id: posGr3; color: "white"; position: 0 }
  274. GradientStop{ id: posGr4; color: "white"; position: 1 }
  275. }
  276. states: State {
  277. name: "Current"
  278. when: (wrapper.ListView.isCurrentItem && (xmppClient.chatJid != "") )
  279. PropertyChanges { target: posGr1; position: 0 }
  280. PropertyChanges { target: posGr1; color: "white" }
  281. PropertyChanges { target: posGr5; position: 0.04 }
  282. PropertyChanges { target: posGr5; color: "lightblue" }
  283. PropertyChanges { target: posGr2; position: 0.3 }
  284. PropertyChanges { target: posGr2; color: "lightblue" }
  285. PropertyChanges { target: posGr3; position: 0.7 }
  286. PropertyChanges { target: imgPresence; anchors.leftMargin: 15 }
  287. }
  288. transitions: Transition {
  289. NumberAnimation { properties: "position"; duration: 300 }
  290. NumberAnimation { properties: "anchors.leftMargin"; duration: 300 }
  291. }
  292. MouseArea {
  293. id: mouseAreaItem;
  294. anchors.fill: parent
  295. onClicked: {
  296. wrapper.ListView.view.currentIndex = index
  297. xmppClient.chatJid = contactJid
  298. selectedName = contactName
  299. __selectedContactItemType = contactItemType
  300. }
  301. onDoubleClicked: {
  302. wrapper.ListView.view.currentIndex = index
  303. xmppClient.chatJid = contactJid
  304. //xmppClient.openChat( contactJid ) //команда в С++ -> открыть чат //это уже делается в окне сообщений
  305. __selectedContactItemType = contactItemType
  306. if( contactItemType == 0 ) {
  307. rosterPage.closePage( "qrc:/qml/MessagesPage.qml" )
  308. } else {
  309. rosterPage.closePage( "qrc:/qml/MucPage.qml" )
  310. }
  311. }
  312. onPressAndHold: {
  313. wrapper.ListView.view.currentIndex = index
  314. xmppClient.chatJid = contactJid
  315. selectedName = contactName
  316. }
  317. }
  318. } //Rectangle
  319. }
  320. ListView {
  321. id: listViewRoster
  322. anchors.top: parent.top
  323. anchors.bottom: toolBar.top
  324. anchors.left: parent.left
  325. anchors.right: parent.right
  326. clip: true
  327. delegate: componentRosterItem
  328. model: xmppClient.roster
  329. /*section {
  330. property: "contactGroup"
  331. criteria: ViewSection.FullString
  332. delegate: Rectangle {
  333. color: "lightgray"
  334. width: parent.width
  335. height: 40
  336. Text {
  337. //anchors.verticalCenter: parent.verticalCenter
  338. anchors.centerIn: parent
  339. text: section
  340. font.pixelSize: 28
  341. }
  342. }
  343. }*/
  344. }
  345. /********************************( Диалог переключения статуса )************************************/
  346. DialogMyStatus {
  347. id: dlgMyStatus
  348. onMyStatusChange: {
  349. /* TODO: здесь нужна проверка на аккаунт */
  350. if( settings.accounts.count() == 0 ) {
  351. console.log( ">>> need to create an account" )
  352. dlgInfo.title = "Error"
  353. dlgInfo.text = "Need to create an account"
  354. dlgInfo.show()
  355. return
  356. } else if( ! main._existDefaultAccount ) {
  357. console.log(">>> need to check by default")
  358. dlgInfo.title = "Error"
  359. dlgInfo.text = "Choose account by default"
  360. dlgInfo.show()
  361. return
  362. }
  363. toolBarButtonPresence.icon = "qrc:/qml/images/bar_presence_unknown.png"
  364. xmppClient.keepAlive = settings.keepAliveInterval
  365. xmppClient.reconnectOnError = settings.reconnectWhenError
  366. xmppClient.setMyPresence( dlgMyStatus.myStatusSet, dlgMyStatus.myTextStatus )
  367. settings.saveStatusText( dlgMyStatus.myTextStatus )
  368. }
  369. }
  370. /*******/
  371. DialogInfo {
  372. id: dlgInfo
  373. fontTextSize: 26
  374. }
  375. DialogQuery {
  376. id: dlgQueryRemove
  377. onClickedOk: {
  378. xmppClient.removeContact( xmppClient.chatJid )
  379. }
  380. title: qsTr("Remove contact")
  381. /*onClickedCancel: {
  382. dlgQueryRemove.hide()
  383. }*/
  384. }
  385. DialogEdit {
  386. id: dlgRenameContact
  387. title: qsTr("Rename contact")
  388. onClickedOk: {
  389. if( dlgRenameContact.textEdit != "" ) {
  390. xmppClient.renameContact( xmppClient.chatJid, dlgRenameContact.textEdit )
  391. }
  392. }
  393. }
  394. DialogSubscribes {
  395. id: dlgSubscribes
  396. }
  397. /*******/
  398. DialogOptionsRoster {
  399. id: dlgRosterOptions
  400. isOnline: xmppClient.stateConnect == XmppClient.Online ? true : false
  401. onItemClicked:
  402. {
  403. if( dlgRosterOptions.itemSelected == "accounts" )
  404. {
  405. rosterPage.closePage( "qrc:/qml/AccountsPage.qml" )
  406. }
  407. else if( dlgRosterOptions.itemSelected == "contactadd" )
  408. {
  409. if( xmppClient.stateConnect == XmppClient.Online ) {
  410. rosterPage.closePage( "qrc:/qml/AddContactPage.qml" )
  411. }
  412. }
  413. else if( ( dlgRosterOptions.itemSelected == "contactremove" ) && ( xmppClient.stateConnect == XmppClient.Online ) && (xmppClient.chatJid != "") )
  414. {
  415. dlgQueryRemove.text = qsTr("Remove") + " " + xmppClient.chatJid + " ?"
  416. dlgQueryRemove.dlgShowHide()
  417. }
  418. else if( ( dlgRosterOptions.itemSelected == "contactedit" ) && ( xmppClient.stateConnect == XmppClient.Online ) && (xmppClient.chatJid != "") )
  419. {
  420. dlgRenameContact.textEdit = selectedName
  421. dlgRenameContact.text = qsTr("Rename") + " " + xmppClient.chatJid
  422. dlgRenameContact.show()
  423. }
  424. else if( dlgRosterOptions.itemSelected == "quit" )
  425. {
  426. Qt.quit()
  427. }
  428. else if( (dlgRosterOptions.itemSelected == "vcard") && ( xmppClient.chatJid != "" ) )
  429. {
  430. rosterPage.closePage( "qrc:/qml/VCardPage.qml" )
  431. }
  432. else if( dlgRosterOptions.itemSelected == "myvcard" )
  433. {
  434. if( xmppClient.stateConnect == XmppClient.Online )
  435. {
  436. main.requestMyVCard = true
  437. rosterPage.closePage( "qrc:/qml/VCardPage.qml" )
  438. }
  439. }
  440. else if( dlgRosterOptions.itemSelected == "about" )
  441. {
  442. rosterPage.closePage( "qrc:/qml/AboutPage.qml" )
  443. }
  444. else if( dlgRosterOptions.itemSelected == "offlinejid" )
  445. {
  446. xmppClient.showOffline = !xmppClient.showOffline
  447. }
  448. else if( dlgRosterOptions.itemSelected == "settings" )
  449. {
  450. rosterPage.closePage( "qrc:/qml/SettingsPage.qml" )
  451. }
  452. else if( dlgRosterOptions.itemSelected == "contactsubscribe" )
  453. {
  454. dlgInfo.text = qsTr("Sent authorization to ")+xmppClient.chatJid
  455. var r = xmppClient.subscribe( xmppClient.chatJid )
  456. if( r == true ) { dlgInfo.show(); }
  457. }
  458. else if( dlgRosterOptions.itemSelected == "contactunsubscribe" )
  459. {
  460. //dlgInfo.text = "Authorization has been removed"
  461. var r = xmppClient.unsubscribe( xmppClient.chatJid )
  462. //if( r == true ) { dlgInfo.show(); }
  463. }
  464. else if( dlgRosterOptions.itemSelected == "subscribes" )
  465. {
  466. if( dlgRosterOptions.state == "visible" ) {
  467. dlgRosterOptions.dlgShowHide()
  468. }
  469. dlgSubscribes.dlgShowHide();
  470. }
  471. else if( dlgRosterOptions.itemSelected == "enterroom" )
  472. {
  473. if( xmppClient.stateConnect == XmppClient.Online ) {
  474. rosterPage.closePage( "qrc:/qml/MucLoginPage.qml" )
  475. }
  476. }
  477. }
  478. }
  479. /********************************( Toolbar )************************************/
  480. ToolBar {
  481. id: toolBar
  482. ToolButton {
  483. id: toolBarButtonPresence
  484. icon: "qrc:/qml/images/bar_presence_offline.png"
  485. anchors.left: parent.left
  486. anchors.leftMargin: (0.5*(parent.width/4) - 0.5*toolBarButtonPresence.width)
  487. onClicked: {
  488. if( dlgRosterOptions.state == "visible" ) {
  489. dlgRosterOptions.dlgShowHide()
  490. }
  491. dlgMyStatus.dlgShowHide()
  492. }
  493. pauseAnim: 500
  494. }
  495. ToolButton {
  496. id: toolBarButtonOptions
  497. icon: "qrc:/qml/images/bar_options.png"
  498. anchors.left: parent.left
  499. anchors.leftMargin: (1.5*(parent.width/4) - 0.5*toolBarButtonOptions.width)
  500. onClicked: {
  501. if( dlgMyStatus.state == "visible" ) {
  502. dlgMyStatus.dlgShowHide()
  503. }
  504. dlgRosterOptions.dlgShowHide()
  505. }
  506. pauseAnim: 600
  507. }
  508. ToolButton {
  509. id: toolBarButtonChats
  510. icon: "qrc:/qml/images/bar_open_chats.png"
  511. anchors.left: parent.left
  512. anchors.leftMargin: (2.5*(parent.width/4) - 0.5*toolBarButtonChats.width)
  513. onClicked: {
  514. rosterPage.closePage( "qrc:/qml/ChatsPage.qml" )
  515. }
  516. pauseAnim: 700
  517. }
  518. ToolButton {
  519. id: toolBarButtonDialog
  520. icon: "qrc:/qml/images/bar_messages.png"
  521. anchors.left: parent.left
  522. anchors.leftMargin: (3.5*(parent.width/4) - 0.5*toolBarButtonDialog.width)
  523. onClicked: {
  524. if( xmppClient.chatJid != "" ) {
  525. //rosterPage.closePage( "qrc:/qml/MessagesPage.qml" ) //TODO: разделение на muc и chat.
  526. if( __selectedContactItemType == 0 ) {
  527. rosterPage.closePage( "qrc:/qml/MessagesPage.qml" )
  528. } else {
  529. rosterPage.closePage( "qrc:/qml/MucPage.qml" )
  530. }
  531. }
  532. //main.createInfoPanel( "", "xxx --- xxx", 4000, "grey" )
  533. }
  534. pauseAnim: 800
  535. }
  536. }
  537. /*********************************************************************/
  538. /*********************************************************************/
  539. Rectangle {
  540. id: connectingRect
  541. z: 3
  542. anchors.top: parent.top
  543. anchors.bottom: toolBar.top
  544. anchors.left: parent.left
  545. anchors.right: parent.right
  546. color: "black"
  547. //opacity: main.connectionState == main.conConnecting ? 0.4 : 0
  548. opacity: xmppClient.stateConnect == XmppClient.Connecting ? 0.4 : 0
  549. Behavior on opacity { NumberAnimation { duration: 400 } }
  550. }
  551. }