upload.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. /**
  2. * @description Takes care of every action an album can handle and execute.
  3. * @copyright 2014 by Tobias Reich
  4. */
  5. upload = {}
  6. upload.show = function(title, files, callback) {
  7. upload.close(true);
  8. $('body').append(build.uploadModal(title, files));
  9. if (callback!==null&&callback!==undefined) callback();
  10. }
  11. upload.notify = function(title, text) {
  12. var popup;
  13. if (!text||text==='') text = 'You can now manage your new photo(s).';
  14. if (!window.webkitNotifications) return false;
  15. if (window.webkitNotifications.checkPermission()!==0) window.webkitNotifications.requestPermission();
  16. if (window.webkitNotifications.checkPermission()===0&&title) {
  17. popup = window.webkitNotifications.createNotification('', title, text);
  18. popup.show();
  19. }
  20. }
  21. upload.start = {
  22. local: function(files) {
  23. var albumID = album.getID(),
  24. error = false,
  25. process = function(files, file) {
  26. var formData = new FormData(),
  27. xhr = new XMLHttpRequest(),
  28. pre_progress = 0,
  29. progress = 0,
  30. finish = function() {
  31. window.onbeforeunload = null;
  32. $('#upload_files').val('');
  33. if (error===false) {
  34. // Success
  35. upload.close();
  36. upload.notify('Upload complete');
  37. } else {
  38. // Error
  39. $('.upload_message a.close').show();
  40. upload.notify('Upload complete', 'Failed to upload one or more photos.');
  41. }
  42. albums.refresh();
  43. if (album.getID()===false) lychee.goto('0');
  44. else album.load(albumID);
  45. };
  46. // Check if file is supported
  47. if (file.supported===false) {
  48. // Skip file
  49. if (file.next!==null) process(files, file.next);
  50. else {
  51. // Look for supported files
  52. // If zero files are supported, hide the upload after a delay
  53. var hasSupportedFiles = false;
  54. for (var i = 0; i < files.length; i++) {
  55. if (files[i].supported===true) {
  56. hasSupportedFiles = true;
  57. break;
  58. }
  59. }
  60. if (hasSupportedFiles===false) setTimeout(finish, 2000);
  61. }
  62. return false;
  63. }
  64. formData.append('function', 'upload');
  65. formData.append('albumID', albumID);
  66. formData.append('tags', '');
  67. formData.append(0, file);
  68. xhr.open('POST', lychee.api_path);
  69. xhr.onload = function() {
  70. var wait = false,
  71. errorText = '';
  72. file.ready = true;
  73. // Set status
  74. if (xhr.status===200&&xhr.responseText==='1') {
  75. // Success
  76. $('.upload_message .rows .row:nth-child(' + (file.num+1) + ') .status')
  77. .html('Finished')
  78. .addClass('success');
  79. } else {
  80. // Error
  81. $('.upload_message .rows .row:nth-child(' + (file.num+1) + ') .status')
  82. .html('Error')
  83. .addClass('error');
  84. if (xhr.responseText.substr(0, 6)==='Error:') errorText = xhr.responseText.substr(6) + ' Please take a look at the console of your browser for further details.';
  85. else errorText = 'Server returned an unknown response. Please take a look at the console of your browser for further details.';
  86. $('.upload_message .rows .row:nth-child(' + (file.num+1) + ') p.notice')
  87. .html(errorText)
  88. .show();
  89. // Set global error
  90. error = true;
  91. // Throw error
  92. lychee.error('Upload failed. Server returned the status code ' + xhr.status + '!', xhr, xhr.responseText);
  93. }
  94. // Check if there are file which are not finished
  95. for (var i = 0; i < files.length; i++) {
  96. if (files[i].ready===false) {
  97. wait = true;
  98. break;
  99. }
  100. }
  101. // Finish upload when all files are finished
  102. if (wait===false) finish();
  103. };
  104. xhr.upload.onprogress = function(e) {
  105. if (e.lengthComputable) {
  106. // Calculate progress
  107. progress = (e.loaded / e.total * 100 | 0);
  108. // Set progress when progress has changed
  109. if (progress>pre_progress) {
  110. $('.upload_message .rows .row:nth-child(' + (file.num+1) + ') .status').html(progress + '%');
  111. pre_progress = progress;
  112. }
  113. if (progress>=100) {
  114. // Scroll to the uploading file
  115. var scrollPos = 0;
  116. if ((file.num+1)>4) scrollPos = (file.num + 1 - 4) * 40
  117. $('.upload_message .rows').scrollTop(scrollPos);
  118. // Set status to processing
  119. $('.upload_message .rows .row:nth-child(' + (file.num+1) + ') .status').html('Processing');
  120. // Upload next file
  121. if (file.next!==null) process(files, file.next);
  122. }
  123. }
  124. };
  125. xhr.send(formData);
  126. };
  127. if (files.length<=0) return false;
  128. if (albumID===false||visible.albums()===true) albumID = 0;
  129. for (var i = 0; i < files.length; i++) {
  130. files[i].num = i;
  131. files[i].ready = false;
  132. files[i].supported = true;
  133. if (i < files.length-1) files[i].next = files[i+1];
  134. else files[i].next = null;
  135. // Check if file is supported
  136. if (files[i].type!=='image/jpeg'&&files[i].type!=='image/jpg'&&files[i].type!=='image/png'&&files[i].type!=='image/gif') {
  137. files[i].ready = true;
  138. files[i].supported = false;
  139. }
  140. }
  141. window.onbeforeunload = function() { return 'Lychee is currently uploading!'; };
  142. upload.show('Uploading', files);
  143. // Upload first file
  144. process(files, files[0]);
  145. },
  146. url: function() {
  147. var albumID = album.getID(),
  148. params,
  149. extension,
  150. buttons,
  151. link,
  152. files = [];
  153. if (albumID===false) albumID = 0;
  154. buttons = [
  155. ['Import', function() {
  156. link = $('.message input.text').val();
  157. if (link&&link.length>3) {
  158. extension = link.split('.').pop();
  159. if (extension!=='jpeg'&&extension!=='jpg'&&extension!=='png'&&extension!=='gif'&&extension!=='webp') {
  160. loadingBar.show('error', 'The file format of this link is not supported.');
  161. return false;
  162. }
  163. files[0] = {
  164. name: link,
  165. supported: true
  166. }
  167. upload.show('Importing URL', files, function() {
  168. $('.upload_message .rows .row .status').html('Importing');
  169. });
  170. params = 'importUrl&url=' + escape(encodeURI(link)) + '&albumID=' + albumID;
  171. lychee.api(params, function(data) {
  172. upload.close();
  173. upload.notify('Import complete');
  174. albums.refresh();
  175. if (album.getID()===false) lychee.goto('0');
  176. else album.load(albumID);
  177. if (data!==true) lychee.error(null, params, data);
  178. });
  179. } else loadingBar.show('error', 'Link to short or too long. Please try another one!');
  180. }],
  181. ['Cancel', function() {}]
  182. ];
  183. modal.show('Import from Link', "Please enter the direct link to a photo to import it: <input class='text' type='text' placeholder='http://' value='http://'>", buttons);
  184. },
  185. server: function() {
  186. var albumID = album.getID(),
  187. params,
  188. buttons,
  189. files = [],
  190. path;
  191. if (albumID===false) albumID = 0;
  192. buttons = [
  193. ['Import', function() {
  194. path = $('.message input.text').val();
  195. files[0] = {
  196. name: path,
  197. supported: true
  198. };
  199. upload.show('Importing from server', files, function() {
  200. $('.upload_message .rows .row .status').html('Importing');
  201. });
  202. params = 'importServer&albumID=' + albumID + '&path=' + escape(encodeURI(path));
  203. lychee.api(params, function(data) {
  204. upload.close();
  205. upload.notify('Import complete');
  206. albums.refresh();
  207. if (data==='Notice: Import only contains albums!') {
  208. if (visible.albums()) lychee.load();
  209. else lychee.goto('');
  210. }
  211. else if (album.getID()===false) lychee.goto('0');
  212. else album.load(albumID);
  213. if (data==='Notice: Import only contains albums!') return true;
  214. else if (data==='Warning: Folder empty!') lychee.error('Folder empty. No photos imported!', params, data);
  215. else if (data!==true) lychee.error(null, params, data);
  216. });
  217. }],
  218. ['Cancel', function() {}]
  219. ];
  220. modal.show('Import from Server', "This action will import all photos, folders and sub-folders which are located in the following directory. The <b>original files will be deleted</b> after the import when possible. <input class='text' type='text' maxlength='100' placeholder='Absolute path to directory' value='" + lychee.location + "uploads/import/'>", buttons);
  221. },
  222. dropbox: function() {
  223. var albumID = album.getID(),
  224. params,
  225. links = '';
  226. if (albumID===false) albumID = 0;
  227. lychee.loadDropbox(function() {
  228. Dropbox.choose({
  229. linkType: 'direct',
  230. multiselect: true,
  231. success: function(files) {
  232. for (var i = 0; i < files.length; i++) {
  233. links += files[i].link + ',';
  234. files[i] = {
  235. name: files[i].link,
  236. supported: true
  237. };
  238. }
  239. // Remove last comma
  240. links = links.substr(0, links.length-1);
  241. upload.show('Importing from Dropbox', files, function() {
  242. $('.upload_message .rows .row .status').html('Importing');
  243. });
  244. params = 'importUrl&url=' + escape(links) + '&albumID=' + albumID;
  245. lychee.api(params, function(data) {
  246. upload.close();
  247. upload.notify('Import complete');
  248. albums.refresh();
  249. if (album.getID()===false) lychee.goto('0');
  250. else album.load(albumID);
  251. if (data!==true) lychee.error(null, params, data);
  252. });
  253. }
  254. });
  255. });
  256. }
  257. }
  258. upload.close = function(force) {
  259. if (force===true) {
  260. $('.upload_overlay').remove();
  261. } else {
  262. $('.upload_overlay').removeClass('fadeIn').css('opacity', 0);
  263. setTimeout(function() { $('.upload_overlay').remove() }, 300);
  264. }
  265. }