upload.js 9.1 KB

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