Window.qml 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. import QtQml 2.1
  2. import QtQml.Models 2.1
  3. import QtQuick 2.9
  4. import QtQuick.Window 2.2
  5. import QtQuick.Controls 2.2
  6. import QtQuick.Layouts 1.2
  7. import QtGraphicalEffects 1.0
  8. Window {
  9. id: trayWindow
  10. visible: true
  11. width: 400
  12. height: 500
  13. color: "transparent"
  14. flags: Qt.FramelessWindowHint
  15. onActiveChanged: {
  16. if(!active) {
  17. trayWindow.hide();
  18. systrayBackend.setClosed();
  19. }
  20. }
  21. onVisibleChanged: {
  22. currentAccountAvatar.source = ""
  23. currentAccountAvatar.source = "image://avatars/currentUser"
  24. currentAccountUser.text = userModelBackend.currentUserName();
  25. currentAccountServer.text = userModelBackend.currentUserServer();
  26. trayWindowTalkButton.visible = userModelBackend.currentServerHasTalk() ? true : false;
  27. currentAccountStateIndicator.source = ""
  28. currentAccountStateIndicator.source = userModelBackend.isUserConnected(userModelBackend.currentUserId()) ? "qrc:///client/theme/colored/state-ok.svg" : "qrc:///client/theme/colored/state-offline.svg"
  29. userLineInstantiator.active = false;
  30. userLineInstantiator.active = true;
  31. }
  32. Connections {
  33. target: userModelBackend
  34. onRefreshCurrentUserGui: {
  35. currentAccountAvatar.source = ""
  36. currentAccountAvatar.source = "image://avatars/currentUser"
  37. currentAccountUser.text = userModelBackend.currentUserName();
  38. currentAccountServer.text = userModelBackend.currentUserServer();
  39. currentAccountStateIndicator.source = ""
  40. currentAccountStateIndicator.source = userModelBackend.isUserConnected(userModelBackend.currentUserId()) ? "qrc:///client/theme/colored/state-ok.svg" : "qrc:///client/theme/colored/state-offline.svg"
  41. }
  42. onNewUserSelected: {
  43. accountMenu.close();
  44. trayWindowTalkButton.visible = userModelBackend.currentServerHasTalk() ? true : false;
  45. }
  46. }
  47. Connections {
  48. target: systrayBackend
  49. onShowWindow: {
  50. accountMenu.close();
  51. trayWindow.show();
  52. trayWindow.raise();
  53. trayWindow.requestActivate();
  54. trayWindow.setX( systrayBackend.calcTrayWindowX());
  55. trayWindow.setY( systrayBackend.calcTrayWindowY());
  56. systrayBackend.setOpened();
  57. userModelBackend.fetchCurrentActivityModel();
  58. }
  59. onHideWindow: {
  60. trayWindow.hide();
  61. systrayBackend.setClosed();
  62. }
  63. }
  64. Rectangle {
  65. id: trayWindowBackground
  66. anchors.fill: parent
  67. radius: 10
  68. Rectangle {
  69. id: trayWindowHeaderBackground
  70. anchors.left: trayWindowBackground.left
  71. anchors.top: trayWindowBackground.top
  72. height: 60
  73. width: parent.width
  74. radius: 9
  75. color: "#0082c9"
  76. Rectangle {
  77. anchors.left: trayWindowHeaderBackground.left
  78. anchors.bottom: trayWindowHeaderBackground.bottom
  79. height: 30
  80. width: parent.width
  81. color: "#0082c9"
  82. }
  83. RowLayout {
  84. id: trayWindowHeaderLayout
  85. spacing: 0
  86. anchors.fill: parent
  87. Button {
  88. id: currentAccountButton
  89. Layout.preferredWidth: 220
  90. Layout.preferredHeight: (trayWindowHeaderBackground.height)
  91. display: AbstractButton.IconOnly
  92. flat: true
  93. MouseArea {
  94. id: accountBtnMouseArea
  95. anchors.fill: parent
  96. hoverEnabled: true
  97. onClicked:
  98. {
  99. syncPauseButton.text = systrayBackend.syncIsPaused() ? "Resume sync for all" : "Pause sync for all"
  100. accountMenu.open()
  101. }
  102. Menu {
  103. id: accountMenu
  104. x: (currentAccountButton.x + 2)
  105. y: (currentAccountButton.y + currentAccountButton.height + 2)
  106. width: (currentAccountButton.width - 2)
  107. closePolicy: "CloseOnPressOutside"
  108. background: Rectangle {
  109. border.color: "#0082c9"
  110. radius: 2
  111. }
  112. onClosed: {
  113. userLineInstantiator.active = false;
  114. userLineInstantiator.active = true;
  115. }
  116. Instantiator {
  117. id: userLineInstantiator
  118. model: userModelBackend
  119. delegate: UserLine {}
  120. onObjectAdded: accountMenu.insertItem(index, object)
  121. onObjectRemoved: accountMenu.removeItem(object)
  122. }
  123. MenuItem {
  124. id: addAccountButton
  125. height: 60
  126. RowLayout {
  127. width: addAccountButton.width
  128. height: addAccountButton.height
  129. spacing: 0
  130. Image {
  131. Layout.leftMargin: 8
  132. verticalAlignment: Qt.AlignCenter
  133. source: "qrc:///client/theme/black/add.svg"
  134. sourceSize.width: addAccountButton.height - 24
  135. sourceSize.height: addAccountButton.height - 24
  136. }
  137. Label {
  138. Layout.leftMargin: 10
  139. text: "Add account"
  140. color: "black"
  141. font.pixelSize: 12
  142. }
  143. Item {
  144. Layout.fillWidth: true
  145. Layout.fillHeight: true
  146. }
  147. }
  148. onClicked: userModelBackend.addAccount()
  149. }
  150. MenuSeparator { id: accountMenuSeparator }
  151. MenuItem {
  152. id: syncPauseButton
  153. onClicked: systrayBackend.pauseResumeSync()
  154. }
  155. MenuItem {
  156. text: "Open settings"
  157. onClicked: systrayBackend.openSettings()
  158. }
  159. MenuItem {
  160. text: "Help"
  161. onClicked: systrayBackend.openHelp()
  162. }
  163. MenuItem {
  164. text: "Quit Nextcloud"
  165. onClicked: systrayBackend.shutdown()
  166. }
  167. Component.onCompleted: {/*
  168. if(userModelBackend.numUsers() === 1) {
  169. accountMenuSeparator.height = 0
  170. } else {
  171. accountMenuSeparator.height = 13
  172. }*/
  173. }
  174. }
  175. }
  176. background:
  177. Item {
  178. id: leftHoverContainer
  179. height: currentAccountButton.height
  180. width: currentAccountButton.width
  181. Rectangle {
  182. width: currentAccountButton.width / 2
  183. height: currentAccountButton.height / 2
  184. color: "transparent"
  185. clip: true
  186. Rectangle {
  187. width: currentAccountButton.width
  188. height: currentAccountButton.height
  189. radius: 10
  190. color: "white"
  191. opacity: 0.2
  192. visible: accountBtnMouseArea.containsMouse
  193. }
  194. }
  195. Rectangle {
  196. width: currentAccountButton.width / 2
  197. height: currentAccountButton.height / 2
  198. anchors.bottom: leftHoverContainer.bottom
  199. color: "white"
  200. opacity: 0.2
  201. visible: accountBtnMouseArea.containsMouse
  202. }
  203. Rectangle {
  204. width: currentAccountButton.width / 2
  205. height: currentAccountButton.height / 2
  206. anchors.right: leftHoverContainer.right
  207. color: "white"
  208. opacity: 0.2
  209. visible: accountBtnMouseArea.containsMouse
  210. }
  211. Rectangle {
  212. width: currentAccountButton.width / 2
  213. height: currentAccountButton.height / 2
  214. anchors.right: leftHoverContainer.right
  215. anchors.bottom: leftHoverContainer.bottom
  216. color: "white"
  217. opacity: 0.2
  218. visible: accountBtnMouseArea.containsMouse
  219. }
  220. }
  221. RowLayout {
  222. id: accountControlRowLayout
  223. height: currentAccountButton.height
  224. width: currentAccountButton.width
  225. spacing: 0
  226. Image {
  227. id: currentAccountAvatar
  228. Layout.leftMargin: 8
  229. verticalAlignment: Qt.AlignCenter
  230. cache: false
  231. source: "image://avatars/currentUser"
  232. Layout.preferredHeight: (trayWindowHeaderBackground.height -16)
  233. Layout.preferredWidth: (trayWindowHeaderBackground.height -16)
  234. Image {
  235. id: currentAccountStateIndicator
  236. source: userModelBackend.isUserConnected(userModelBackend.currentUserId()) ? "qrc:///client/theme/colored/state-ok.svg" : "qrc:///client/theme/colored/state-offline.svg"
  237. cache: false
  238. anchors.bottom: currentAccountAvatar.bottom
  239. anchors.right: currentAccountAvatar.right
  240. sourceSize.width: 16
  241. sourceSize.height: 16
  242. }
  243. }
  244. Column {
  245. id: accountLabels
  246. spacing: 4
  247. Layout.alignment: Qt.AlignLeft
  248. Layout.leftMargin: 6
  249. Label {
  250. id: currentAccountUser
  251. width: 128
  252. text: userModelBackend.currentUserName()
  253. elide: Text.ElideRight
  254. color: "white"
  255. font.pixelSize: 12
  256. font.bold: true
  257. }
  258. Label {
  259. id: currentAccountServer
  260. width: 128
  261. text: userModelBackend.currentUserServer()
  262. elide: Text.ElideRight
  263. color: "white"
  264. font.pixelSize: 10
  265. }
  266. }
  267. Image {
  268. Layout.alignment: Qt.AlignRight
  269. verticalAlignment: Qt.AlignCenter
  270. Layout.margins: 8
  271. source: "qrc:///client/theme/white/caret-down.svg"
  272. sourceSize.width: 20
  273. sourceSize.height: 20
  274. }
  275. }
  276. }
  277. Item {
  278. id: trayWindowHeaderSpacer
  279. Layout.fillWidth: true
  280. }
  281. Button {
  282. id: openLocalFolderButton
  283. Layout.alignment: Qt.AlignRight
  284. display: AbstractButton.IconOnly
  285. Layout.preferredWidth: (trayWindowHeaderBackground.height)
  286. Layout.preferredHeight: (trayWindowHeaderBackground.height)
  287. flat: true
  288. icon.source: "qrc:///client/theme/white/folder.svg"
  289. icon.color: "transparent"
  290. MouseArea {
  291. id: folderBtnMouseArea
  292. anchors.fill: parent
  293. hoverEnabled: true
  294. onClicked:
  295. {
  296. userModelBackend.openCurrentAccountLocalFolder();
  297. }
  298. }
  299. background:
  300. Rectangle {
  301. color: folderBtnMouseArea.containsMouse ? "white" : "transparent"
  302. opacity: 0.2
  303. }
  304. }
  305. Button {
  306. id: trayWindowTalkButton
  307. Layout.alignment: Qt.AlignRight
  308. display: AbstractButton.IconOnly
  309. Layout.preferredWidth: (trayWindowHeaderBackground.height)
  310. Layout.preferredHeight: (trayWindowHeaderBackground.height)
  311. flat: true
  312. visible: userModelBackend.currentServerHasTalk() ? true : false
  313. icon.source: "qrc:///client/theme/white/talk-app.svg"
  314. icon.color: "transparent"
  315. MouseArea {
  316. id: talkBtnMouseArea
  317. anchors.fill: parent
  318. hoverEnabled: true
  319. onClicked:
  320. {
  321. userModelBackend.openCurrentAccountTalk();
  322. }
  323. }
  324. background:
  325. Rectangle {
  326. color: talkBtnMouseArea.containsMouse ? "white" : "transparent"
  327. opacity: 0.2
  328. }
  329. }
  330. Button {
  331. id: trayWindowAppsButton
  332. Layout.alignment: Qt.AlignRight
  333. display: AbstractButton.IconOnly
  334. Layout.preferredWidth: (trayWindowHeaderBackground.height)
  335. Layout.preferredHeight: (trayWindowHeaderBackground.height)
  336. flat: true
  337. icon.source: "qrc:///client/theme/white/more-apps.svg"
  338. icon.color: "transparent"
  339. MouseArea {
  340. id: appsBtnMouseArea
  341. anchors.fill: parent
  342. hoverEnabled: true
  343. onClicked:
  344. {
  345. userModelBackend.openCurrentAccountServer();
  346. }
  347. }
  348. background:
  349. Item {
  350. id: rightHoverContainer
  351. height: trayWindowAppsButton.height
  352. width: trayWindowAppsButton.width
  353. Rectangle {
  354. width: trayWindowAppsButton.width / 2
  355. height: trayWindowAppsButton.height / 2
  356. color: "white"
  357. opacity: 0.2
  358. visible: appsBtnMouseArea.containsMouse
  359. }
  360. Rectangle {
  361. width: trayWindowAppsButton.width / 2
  362. height: trayWindowAppsButton.height / 2
  363. anchors.bottom: rightHoverContainer.bottom
  364. color: "white"
  365. opacity: 0.2
  366. visible: appsBtnMouseArea.containsMouse
  367. }
  368. Rectangle {
  369. width: trayWindowAppsButton.width / 2
  370. height: trayWindowAppsButton.height / 2
  371. anchors.bottom: rightHoverContainer.bottom
  372. anchors.right: rightHoverContainer.right
  373. color: "white"
  374. opacity: 0.2
  375. visible: appsBtnMouseArea.containsMouse
  376. }
  377. Rectangle {
  378. id: rightHoverContainerClipper
  379. anchors.right: rightHoverContainer.right
  380. width: trayWindowAppsButton.width / 2
  381. height: trayWindowAppsButton.height / 2
  382. color: "transparent"
  383. clip: true
  384. Rectangle {
  385. width: trayWindowAppsButton.width
  386. height: trayWindowAppsButton.height
  387. anchors.right: rightHoverContainerClipper.right
  388. radius: 10
  389. color: "white"
  390. opacity: 0.2
  391. visible: appsBtnMouseArea.containsMouse
  392. }
  393. }
  394. }
  395. }
  396. }
  397. } // Rectangle trayWindowHeaderBackground
  398. ListView {
  399. id: activityListView
  400. anchors.top: trayWindowHeaderBackground.bottom
  401. width: trayWindowBackground.width
  402. height: trayWindowBackground.height - trayWindowHeaderBackground.height
  403. clip: true
  404. model: activityModel
  405. delegate: RowLayout {
  406. id: activityItem
  407. width: activityListView.width
  408. height: trayWindowHeaderLayout.height
  409. spacing: 0
  410. Image {
  411. id: activityIcon
  412. Layout.leftMargin: 6
  413. Layout.preferredWidth: 48
  414. Layout.preferredHeight: 48
  415. verticalAlignment: Qt.AlignCenter
  416. source: "qrc:///client/theme/black/state-sync.svg"
  417. sourceSize.height: 48
  418. sourceSize.width: 48
  419. }
  420. Column {
  421. id: activityTextColumn
  422. Layout.leftMargin: 6
  423. spacing: 4
  424. Layout.alignment: Qt.AlignLeft
  425. Text {
  426. id: activityTextTitle
  427. text: subject
  428. width: 220
  429. elide: Text.ElideRight
  430. font.pointSize: 9
  431. }
  432. Text {
  433. id: activityTextInfo
  434. text: path
  435. width: 220
  436. elide: Text.ElideRight
  437. font.pointSize: 8
  438. }
  439. }
  440. Item {
  441. id: activityItemFiller
  442. Layout.fillWidth: true
  443. }
  444. Button {
  445. id: activityButton1
  446. Layout.preferredWidth: activityItem.height
  447. Layout.preferredHeight: activityItem.height
  448. Layout.alignment: Qt.AlignRight
  449. flat: true
  450. hoverEnabled: false
  451. visible: (path === "") ? false : true
  452. display: AbstractButton.IconOnly
  453. icon.source: "qrc:///client/resources/files.svg"
  454. icon.color: "transparent"
  455. onClicked:
  456. {
  457. Qt.openUrlExternally(path)
  458. }
  459. }
  460. Button {
  461. Layout.preferredWidth: activityItem.height
  462. Layout.preferredHeight: activityItem.height
  463. Layout.alignment: Qt.AlignRight
  464. flat: true
  465. hoverEnabled: false
  466. display: AbstractButton.IconOnly
  467. icon.source: "qrc:///client/resources/public.svg"
  468. icon.color: "transparent"
  469. }
  470. }
  471. add: Transition {
  472. NumberAnimation { properties: "y"; from: -60; duration: 100; easing.type: Easing.Linear }
  473. }
  474. remove: Transition {
  475. NumberAnimation { property: "opacity"; from: 1.0; to: 0; duration: 100 }
  476. }
  477. removeDisplaced: Transition {
  478. SequentialAnimation {
  479. PauseAnimation { duration: 100}
  480. NumberAnimation { properties: "y"; duration: 100; easing.type: Easing.Linear }
  481. }
  482. }
  483. displaced: Transition {
  484. NumberAnimation { properties: "y"; duration: 100; easing.type: Easing.Linear }
  485. }
  486. focus: true
  487. }
  488. } // Rectangle trayWindowBackground
  489. }