contextMenu.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /**
  2. * @description This module is used for the context menu.
  3. * @copyright 2015 by Tobias Reich
  4. */
  5. contextMenu = {}
  6. contextMenu.add = function(e) {
  7. let items = [
  8. { title: build.iconic('image') + 'Upload Photo', fn: () => $('#upload_files').click() },
  9. { },
  10. { title: build.iconic('link-intact') + 'Import from Link', fn: upload.start.url },
  11. { title: build.iconic('dropbox', 'ionicons') + 'Import from Dropbox', fn: upload.start.dropbox },
  12. { title: build.iconic('terminal') + 'Import from Server', fn: upload.start.server },
  13. { },
  14. { title: build.iconic('folder') + 'New Album', fn: album.add }
  15. ]
  16. basicContext.show(items, e.originalEvent)
  17. upload.notify()
  18. }
  19. contextMenu.settings = function(e) {
  20. let items = [
  21. { title: build.iconic('person') + 'Change Login', fn: settings.setLogin },
  22. { title: build.iconic('sort-ascending') + 'Change Sorting', fn: settings.setSorting },
  23. { title: build.iconic('dropbox', 'ionicons') + 'Set Dropbox', fn: settings.setDropboxKey },
  24. { },
  25. { title: build.iconic('info') + 'About Lychee', fn: () => window.open(lychee.website) },
  26. { title: build.iconic('wrench') + 'Diagnostics', fn: () => window.open('plugins/Diagnostics/') },
  27. { title: build.iconic('align-left') + 'Show Log', fn: () => window.open('plugins/Log/') },
  28. { },
  29. { title: build.iconic('account-logout') + 'Sign Out', fn: lychee.logout }
  30. ]
  31. basicContext.show(items, e.originalEvent)
  32. }
  33. contextMenu.album = function(albumID, e) {
  34. // Notice for 'Merge':
  35. // fn must call basicContext.close() first,
  36. // in order to keep the selection
  37. if (albumID==='0' || albumID==='f' || albumID==='s' || albumID==='r') return false
  38. // Show merge-item when there's more than one album
  39. let showMerge = (albums.json && albums.json.albums && Object.keys(albums.json.albums).length>1)
  40. let items = [
  41. { title: build.iconic('pencil') + 'Rename', fn: () => album.setTitle([ albumID ]) },
  42. { title: build.iconic('collapse-left') + 'Merge', visible: showMerge, fn: () => { basicContext.close(); contextMenu.mergeAlbum(albumID, e) } },
  43. { title: build.iconic('trash') + 'Delete', fn: () => album.delete([ albumID ]) }
  44. ]
  45. $('.album[data-id="' + albumID + '"]').addClass('active')
  46. basicContext.show(items, e.originalEvent, contextMenu.close)
  47. }
  48. contextMenu.albumMulti = function(albumIDs, e) {
  49. multiselect.stopResize()
  50. // Automatically merge selected albums when albumIDs contains more than one album
  51. // Show list of albums otherwise
  52. let autoMerge = (albumIDs.length>1 ? true : false)
  53. // Show merge-item when there's more than one album
  54. let showMerge = (albums.json && albums.json.albums && Object.keys(albums.json.albums).length>1)
  55. let items = [
  56. { title: build.iconic('pencil') + 'Rename All', fn: () => album.setTitle(albumIDs) },
  57. { title: build.iconic('collapse-left') + 'Merge All', visible: showMerge && autoMerge, fn: () => album.merge(albumIDs) },
  58. { title: build.iconic('collapse-left') + 'Merge', visible: showMerge && !autoMerge, fn: () => { basicContext.close(); contextMenu.mergeAlbum(albumIDs[0], e) } },
  59. { title: build.iconic('trash') + 'Delete All', fn: () => album.delete(albumIDs) }
  60. ]
  61. items.push()
  62. basicContext.show(items, e.originalEvent, contextMenu.close)
  63. }
  64. contextMenu.albumTitle = function(albumID, e) {
  65. api.post('Albums::get', {}, function(data) {
  66. let items = []
  67. if (data.albums && data.num>1) {
  68. // Generate list of albums
  69. $.each(data.albums, function() {
  70. if (!this.thumbs[0]) this.thumbs[0] = 'src/images/no_cover.svg'
  71. if (this.title==='') this.title = 'Untitled'
  72. let html = lychee.html`<img class='cover' width='16' height='16' src='$${ this.thumbs[0] }'><div class='title'>$${ this.title }</div>`
  73. if (this.id!=albumID) items.push({
  74. title: html,
  75. fn: () => lychee.goto(this.id)
  76. })
  77. })
  78. items.unshift({ })
  79. }
  80. items.unshift({ title: build.iconic('pencil') + 'Rename', fn: () => album.setTitle([ albumID ]) })
  81. basicContext.show(items, e.originalEvent, contextMenu.close)
  82. })
  83. }
  84. contextMenu.mergeAlbum = function(albumID, e) {
  85. api.post('Albums::get', {}, function(data) {
  86. let items = []
  87. if (data.albums && data.num>1) {
  88. $.each(data.albums, function() {
  89. if (!this.thumbs[0]) this.thumbs[0] = 'src/images/no_cover.svg'
  90. if (this.title==='') this.title = 'Untitled'
  91. let html = lychee.html`<img class='cover' width='16' height='16' src='$${ this.thumbs[0] }'><div class='title'>$${ this.title }</div>`
  92. if (this.id!=albumID) items.push({
  93. title: html,
  94. fn: () => album.merge([ albumID, this.id ])
  95. })
  96. })
  97. }
  98. if (items.length===0) return false
  99. basicContext.show(items, e.originalEvent, contextMenu.close)
  100. })
  101. }
  102. contextMenu.photo = function(photoID, e) {
  103. // Notice for 'Move':
  104. // fn must call basicContext.close() first,
  105. // in order to keep the selection
  106. let items = [
  107. { title: build.iconic('star') + 'Star', fn: () => photo.setStar([ photoID ]) },
  108. { title: build.iconic('tag') + 'Tags', fn: () => photo.editTags([ photoID ]) },
  109. { },
  110. { title: build.iconic('pencil') + 'Rename', fn: () => photo.setTitle([ photoID ]) },
  111. { title: build.iconic('layers') + 'Duplicate', fn: () => photo.duplicate([ photoID ]) },
  112. { title: build.iconic('folder') + 'Move', fn: () => { basicContext.close(); contextMenu.move([ photoID ], e) } },
  113. { title: build.iconic('trash') + 'Delete', fn: () => photo.delete([ photoID ]) }
  114. ]
  115. $('.photo[data-id="' + photoID + '"]').addClass('active')
  116. basicContext.show(items, e.originalEvent, contextMenu.close)
  117. }
  118. contextMenu.photoMulti = function(photoIDs, e) {
  119. // Notice for 'Move All':
  120. // fn must call basicContext.close() first,
  121. // in order to keep the selection and multiselect
  122. multiselect.stopResize()
  123. let items = [
  124. { title: build.iconic('star') + 'Star All', fn: () => photo.setStar(photoIDs) },
  125. { title: build.iconic('tag') + 'Tag All', fn: () => photo.editTags(photoIDs) },
  126. { },
  127. { title: build.iconic('pencil') + 'Rename All', fn: () => photo.setTitle(photoIDs) },
  128. { title: build.iconic('layers') + 'Duplicate All', fn: () => photo.duplicate(photoIDs) },
  129. { title: build.iconic('folder') + 'Move All', fn: () => { basicContext.close(); contextMenu.move(photoIDs, e) } },
  130. { title: build.iconic('trash') + 'Delete All', fn: () => photo.delete(photoIDs) }
  131. ]
  132. basicContext.show(items, e.originalEvent, contextMenu.close)
  133. }
  134. contextMenu.photoTitle = function(albumID, photoID, e) {
  135. let items = [
  136. { title: build.iconic('pencil') + 'Rename', fn: () => photo.setTitle([ photoID ]) }
  137. ]
  138. let data = album.json
  139. if (data.content!==false && data.num>1) {
  140. items.push({ })
  141. // Generate list of albums
  142. $.each(data.content, function(index) {
  143. if (this.title==='') this.title = 'Untitled'
  144. let html = lychee.html`<img class='cover' width='16' height='16' src='$${ this.thumbUrl }'><div class='title'>$${ this.title }</div>`
  145. if (this.id!=photoID) items.push({
  146. title: html,
  147. fn: () => lychee.goto(albumID + '/' + this.id)
  148. })
  149. })
  150. }
  151. basicContext.show(items, e.originalEvent, contextMenu.close)
  152. }
  153. contextMenu.photoMore = function(photoID, e) {
  154. // Show download-item when
  155. // a) Public mode is off
  156. // b) Downloadable is 1 and public mode is on
  157. let showDownload = lychee.publicMode===false || ((album.json && album.json.downloadable && album.json.downloadable==='1') && lychee.publicMode===true)
  158. let items = [
  159. { title: build.iconic('fullscreen-enter') + 'Full Photo', fn: () => window.open(photo.getDirectLink()) },
  160. { title: build.iconic('cloud-download') + 'Download', visible: showDownload, fn: () => photo.getArchive(photoID) }
  161. ]
  162. basicContext.show(items, e.originalEvent)
  163. }
  164. contextMenu.move = function(photoIDs, e) {
  165. let items = []
  166. api.post('Albums::get', {}, function(data) {
  167. if (data.num===0) {
  168. // Show only 'Add album' when no album available
  169. items = [
  170. { title: 'New Album', fn: album.add }
  171. ]
  172. } else {
  173. // Generate list of albums
  174. $.each(data.albums, function() {
  175. if (!this.thumbs[0]) this.thumbs[0] = 'src/images/no_cover.svg'
  176. if (this.title==='') this.title = 'Untitled'
  177. let html = lychee.html`<img class='cover' width='16' height='16' src='$${ this.thumbs[0] }'><div class='title'>$${ this.title }</div>`
  178. if (this.id!=album.getID()) items.push({
  179. title: html,
  180. fn: () => photo.setAlbum(photoIDs, this.id)
  181. })
  182. })
  183. // Show Unsorted when unsorted is not the current album
  184. if (album.getID()!=='0') {
  185. items.unshift({ })
  186. items.unshift({ title: 'Unsorted', fn: () => photo.setAlbum(photoIDs, 0) })
  187. }
  188. }
  189. basicContext.show(items, e.originalEvent, contextMenu.close)
  190. })
  191. }
  192. contextMenu.sharePhoto = function(photoID, e) {
  193. let link = photo.getViewLink(photoID)
  194. let iconClass = 'ionicons'
  195. let items = [
  196. { title: `<input readonly id="link" value="${ link }">`, fn: () => {}, class: 'basicContext__item--noHover' },
  197. { },
  198. { title: build.iconic('twitter', iconClass) + 'Twitter', fn: () => photo.share(photoID, 'twitter') },
  199. { title: build.iconic('facebook', iconClass) + 'Facebook', fn: () => photo.share(photoID, 'facebook') },
  200. { title: build.iconic('envelope-closed') + 'Mail', fn: () => photo.share(photoID, 'mail') },
  201. { title: build.iconic('dropbox', iconClass) + 'Dropbox', visible: lychee.publicMode===false, fn: () => photo.share(photoID, 'dropbox') },
  202. { title: build.iconic('link-intact') + 'Direct Link', fn: () => window.open(photo.getDirectLink()) },
  203. { },
  204. { title: build.iconic('ban') + 'Make Private', visible: lychee.publicMode===false, fn: () => photo.setPublic(photoID) }
  205. ]
  206. if (lychee.publicMode===true) items.splice(7, 1)
  207. basicContext.show(items, e.originalEvent)
  208. $('.basicContext input#link').focus().select()
  209. }
  210. contextMenu.shareAlbum = function(albumID, e) {
  211. let iconClass = 'ionicons'
  212. let items = [
  213. { title: `<input readonly id="link" value="${ location.href }">`, fn: () => {}, class: 'basicContext__item--noHover' },
  214. { },
  215. { title: build.iconic('twitter', iconClass) + 'Twitter', fn: () => album.share('twitter') },
  216. { title: build.iconic('facebook', iconClass) + 'Facebook', fn: () => album.share('facebook') },
  217. { title: build.iconic('envelope-closed') + 'Mail', fn: () => album.share('mail') },
  218. { },
  219. { title: build.iconic('pencil') + 'Edit Sharing', visible: lychee.publicMode===false, fn: () => album.setPublic(albumID, true, e) },
  220. { title: build.iconic('ban') + 'Make Private', visible: lychee.publicMode===false, fn: () => album.setPublic(albumID, false) }
  221. ]
  222. if (lychee.publicMode===true) items.splice(5, 1)
  223. basicContext.show(items, e.originalEvent)
  224. $('.basicContext input#link').focus().select()
  225. }
  226. contextMenu.close = function() {
  227. if (!visible.contextMenu()) return false
  228. basicContext.close()
  229. $('.photo.active, .album.active').removeClass('active')
  230. if (visible.multiselect()) multiselect.close()
  231. }