upload.js 9.2 KB

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