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.

versionstabview.js 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * Copyright (c) 2015
  3. *
  4. * This file is licensed under the Affero General Public License version 3
  5. * or later.
  6. *
  7. * See the COPYING-README file.
  8. *
  9. */
  10. import ItemTemplate from './templates/item.handlebars'
  11. import Template from './templates/template.handlebars';
  12. (function() {
  13. /**
  14. * @memberof OCA.Versions
  15. */
  16. var VersionsTabView = OCA.Files.DetailTabView.extend(/** @lends OCA.Versions.VersionsTabView.prototype */{
  17. id: 'versionsTabView',
  18. className: 'tab versionsTabView',
  19. _template: null,
  20. $versionsContainer: null,
  21. events: {
  22. 'click .revertVersion': '_onClickRevertVersion'
  23. },
  24. initialize: function() {
  25. OCA.Files.DetailTabView.prototype.initialize.apply(this, arguments)
  26. this.collection = new OCA.Versions.VersionCollection()
  27. this.collection.on('request', this._onRequest, this)
  28. this.collection.on('sync', this._onEndRequest, this)
  29. this.collection.on('update', this._onUpdate, this)
  30. this.collection.on('error', this._onError, this)
  31. this.collection.on('add', this._onAddModel, this)
  32. },
  33. getLabel: function() {
  34. return t('files_versions', 'Versions')
  35. },
  36. getIcon: function() {
  37. return 'icon-history'
  38. },
  39. nextPage: function() {
  40. if (this._loading) {
  41. return
  42. }
  43. if (this.collection.getFileInfo() && this.collection.getFileInfo().isDirectory()) {
  44. return
  45. }
  46. this.collection.fetch()
  47. },
  48. _onClickRevertVersion: function(ev) {
  49. var self = this
  50. var $target = $(ev.target)
  51. var fileInfoModel = this.collection.getFileInfo()
  52. var revision
  53. if (!$target.is('li')) {
  54. $target = $target.closest('li')
  55. }
  56. ev.preventDefault()
  57. revision = $target.attr('data-revision')
  58. var versionModel = this.collection.get(revision)
  59. versionModel.revert({
  60. success: function() {
  61. // reset and re-fetch the updated collection
  62. self.$versionsContainer.empty()
  63. self.collection.setFileInfo(fileInfoModel)
  64. self.collection.reset([], { silent: true })
  65. self.collection.fetch()
  66. self.$el.find('.versions').removeClass('hidden')
  67. // update original model
  68. fileInfoModel.trigger('busy', fileInfoModel, false)
  69. fileInfoModel.set({
  70. size: versionModel.get('size'),
  71. mtime: versionModel.get('timestamp') * 1000,
  72. // temp dummy, until we can do a PROPFIND
  73. etag: versionModel.get('id') + versionModel.get('timestamp')
  74. })
  75. },
  76. error: function() {
  77. fileInfoModel.trigger('busy', fileInfoModel, false)
  78. self.$el.find('.versions').removeClass('hidden')
  79. self._toggleLoading(false)
  80. OC.Notification.show(t('files_version', 'Failed to revert {file} to revision {timestamp}.',
  81. {
  82. file: versionModel.getFullPath(),
  83. timestamp: OC.Util.formatDate(versionModel.get('timestamp') * 1000)
  84. }),
  85. {
  86. type: 'error'
  87. }
  88. )
  89. }
  90. })
  91. // spinner
  92. this._toggleLoading(true)
  93. fileInfoModel.trigger('busy', fileInfoModel, true)
  94. },
  95. _toggleLoading: function(state) {
  96. this._loading = state
  97. this.$el.find('.loading').toggleClass('hidden', !state)
  98. },
  99. _onRequest: function() {
  100. this._toggleLoading(true)
  101. },
  102. _onEndRequest: function() {
  103. this._toggleLoading(false)
  104. this.$el.find('.empty').toggleClass('hidden', !!this.collection.length)
  105. },
  106. _onAddModel: function(model) {
  107. var $el = $(this.itemTemplate(this._formatItem(model)))
  108. this.$versionsContainer.append($el)
  109. $el.find('.has-tooltip').tooltip()
  110. },
  111. template: function(data) {
  112. return Template(data)
  113. },
  114. itemTemplate: function(data) {
  115. return ItemTemplate(data)
  116. },
  117. setFileInfo: function(fileInfo) {
  118. if (fileInfo) {
  119. this.render()
  120. this.collection.setFileInfo(fileInfo)
  121. this.collection.reset([], { silent: true })
  122. this.nextPage()
  123. } else {
  124. this.render()
  125. this.collection.reset()
  126. }
  127. },
  128. _formatItem: function(version) {
  129. var timestamp = version.get('timestamp') * 1000
  130. var size = version.has('size') ? version.get('size') : 0
  131. var preview = OC.MimeType.getIconUrl(version.get('mimetype'))
  132. var img = new Image()
  133. img.onload = function() {
  134. $('li[data-revision=' + version.get('id') + '] .preview').attr('src', version.getPreviewUrl())
  135. }
  136. img.src = version.getPreviewUrl()
  137. return _.extend({
  138. versionId: version.get('id'),
  139. formattedTimestamp: OC.Util.formatDate(timestamp),
  140. relativeTimestamp: OC.Util.relativeModifiedDate(timestamp),
  141. millisecondsTimestamp: timestamp,
  142. humanReadableSize: OC.Util.humanFileSize(size, true),
  143. altSize: n('files', '%n byte', '%n bytes', size),
  144. hasDetails: version.has('size'),
  145. downloadUrl: version.getDownloadUrl(),
  146. downloadIconUrl: OC.imagePath('core', 'actions/download'),
  147. downloadName: version.get('name'),
  148. revertIconUrl: OC.imagePath('core', 'actions/history'),
  149. previewUrl: preview,
  150. revertLabel: t('files_versions', 'Restore'),
  151. canRevert: (this.collection.getFileInfo().get('permissions') & OC.PERMISSION_UPDATE) !== 0
  152. }, version.attributes)
  153. },
  154. /**
  155. * Renders this details view
  156. */
  157. render: function() {
  158. this.$el.html(this.template({
  159. emptyResultLabel: t('files_versions', 'No other versions available')
  160. }))
  161. this.$el.find('.has-tooltip').tooltip()
  162. this.$versionsContainer = this.$el.find('ul.versions')
  163. this.delegateEvents()
  164. },
  165. /**
  166. * Returns true for files, false for folders.
  167. * @param {FileInfo} fileInfo fileInfo
  168. * @returns {bool} true for files, false for folders
  169. */
  170. canDisplay: function(fileInfo) {
  171. if (!fileInfo) {
  172. return false
  173. }
  174. return !fileInfo.isDirectory()
  175. }
  176. })
  177. OCA.Versions = OCA.Versions || {}
  178. OCA.Versions.VersionsTabView = VersionsTabView
  179. })()