contextMenu.js 12 KB

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