album.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. /**
  2. * @description Takes care of every action an album can handle and execute.
  3. * @copyright 2015 by Tobias Reich
  4. */
  5. album = {
  6. json: null
  7. }
  8. album.getID = function() {
  9. var id = null;
  10. if (photo.json) id = photo.json.album;
  11. else if (album.json) id = album.json.id;
  12. // Search
  13. if ($.isNumeric(id)===false) id = $('.album:hover, .album.active').attr('data-id');
  14. if ($.isNumeric(id)===false) id = $('.photo:hover, .photo.active').attr('data-album-id');
  15. if ($.isNumeric(id)===true) return id;
  16. else return false;
  17. }
  18. album.load = function(albumID, refresh) {
  19. var startTime,
  20. params,
  21. durationTime,
  22. waitTime;
  23. password.get(albumID, function() {
  24. if (!refresh) {
  25. lychee.animate('.album, .photo', 'contentZoomOut');
  26. lychee.animate('#content .divider', 'fadeOut');
  27. }
  28. startTime = new Date().getTime();
  29. params = {
  30. albumID,
  31. password: password.value
  32. }
  33. api.post('Album::get', params, function(data) {
  34. if (data==='Warning: Album private!') {
  35. if (document.location.hash.replace('#', '').split('/')[1]!=undefined) {
  36. // Display photo only
  37. lychee.setMode('view');
  38. } else {
  39. // Album not public
  40. lychee.content.show();
  41. lychee.goto('');
  42. }
  43. return false;
  44. }
  45. if (data==='Warning: Wrong password!') {
  46. album.load(albumID, refresh);
  47. return false;
  48. }
  49. album.json = data;
  50. // Calculate delay
  51. durationTime = (new Date().getTime() - startTime);
  52. if (durationTime>300) waitTime = 0;
  53. else waitTime = 300 - durationTime;
  54. // Skip delay when refresh is true
  55. // Skip delay when opening a blank Lychee
  56. if (refresh===true) waitTime = 0;
  57. if (!visible.albums()&&!visible.photo()&&!visible.album()) waitTime = 0;
  58. setTimeout(function() {
  59. view.album.init();
  60. if (!refresh) {
  61. lychee.animate('.album, .photo', 'contentZoomIn');
  62. header.setMode('album');
  63. }
  64. }, waitTime);
  65. });
  66. });
  67. }
  68. album.parse = function() {
  69. if (!album.json.title) album.json.title = 'Untitled';
  70. }
  71. album.add = function() {
  72. var action;
  73. action = function(data) {
  74. var isNumber,
  75. title = data.title;
  76. basicModal.close();
  77. isNumber = function(n) {
  78. return !isNaN(parseFloat(n)) && isFinite(n)
  79. }
  80. if (title.length===0) title = 'Untitled';
  81. api.post('Album::add', { title }, function(data) {
  82. // Avoid first album to be true
  83. if (data===true) data = 1;
  84. if (data!==false&&isNumber(data)) {
  85. albums.refresh();
  86. lychee.goto(data);
  87. } else {
  88. lychee.error(null, params, data);
  89. }
  90. });
  91. }
  92. basicModal.show({
  93. body: "<p>Enter a title for the new album: <input class='text' data-name='title' type='text' maxlength='30' placeholder='Title' value='Untitled'></p>",
  94. buttons: {
  95. action: {
  96. title: 'Create Album',
  97. fn: action
  98. },
  99. cancel: {
  100. title: 'Cancel',
  101. fn: basicModal.close
  102. }
  103. }
  104. });
  105. }
  106. album.delete = function(albumIDs) {
  107. var action = {},
  108. cancel = {},
  109. msg = '',
  110. albumTitle = '';
  111. if (!albumIDs) return false;
  112. if (albumIDs instanceof Array===false) albumIDs = [albumIDs];
  113. action.fn = function() {
  114. var params;
  115. basicModal.close();
  116. params = {
  117. albumIDs: albumIDs.join()
  118. }
  119. api.post('Album::delete', params, function(data) {
  120. if (visible.albums()) {
  121. albumIDs.forEach(function(id) {
  122. albums.json.num--;
  123. view.albums.content.delete(id);
  124. delete albums.json.albums[id];
  125. });
  126. } else {
  127. albums.refresh();
  128. lychee.goto('');
  129. }
  130. if (data!==true) lychee.error(null, params, data);
  131. });
  132. }
  133. if (albumIDs.toString()==='0') {
  134. action.title = 'Clear Unsorted';
  135. cancel.title = 'Keep Unsorted';
  136. msg = "<p>Are you sure you want to delete all photos from 'Unsorted'?<br>This action can't be undone!</p>";
  137. } else if (albumIDs.length===1) {
  138. action.title = 'Delete Album and Photos';
  139. cancel.title = 'Keep Album';
  140. // Get title
  141. if (album.json) albumTitle = album.json.title;
  142. else if (albums.json) albumTitle = albums.json.albums[albumIDs].title;
  143. msg = "<p>Are you sure you want to delete the album '" + albumTitle + "' and all of the photos it contains? This action can't be undone!</p>";
  144. } else {
  145. action.title = 'Delete Albums and Photos';
  146. cancel.title = 'Keep Albums';
  147. msg = "<p>Are you sure you want to delete all " + albumIDs.length + " selected albums and all of the photos they contain? This action can't be undone!</p>";
  148. }
  149. basicModal.show({
  150. body: msg,
  151. buttons: {
  152. action: {
  153. title: action.title,
  154. fn: action.fn,
  155. class: 'red'
  156. },
  157. cancel: {
  158. title: cancel.title,
  159. fn: basicModal.close
  160. }
  161. }
  162. });
  163. }
  164. album.setTitle = function(albumIDs) {
  165. var oldTitle = '',
  166. input = '',
  167. msg = '',
  168. action;
  169. if (!albumIDs) return false;
  170. if (albumIDs instanceof Array===false) albumIDs = [albumIDs];
  171. if (albumIDs.length===1) {
  172. // Get old title if only one album is selected
  173. if (album.json) oldTitle = album.json.title;
  174. else if (albums.json) oldTitle = albums.json.albums[albumIDs].title;
  175. if (!oldTitle) oldTitle = '';
  176. oldTitle = oldTitle.replace("'", '&apos;');
  177. }
  178. action = function(data) {
  179. var params,
  180. newTitle = data.title;
  181. basicModal.close();
  182. // Remove html from input
  183. newTitle = lychee.removeHTML(newTitle);
  184. // Set to Untitled when empty
  185. newTitle = (newTitle==='') ? 'Untitled' : newTitle;
  186. if (visible.album()) {
  187. album.json.title = newTitle;
  188. view.album.title();
  189. if (albums.json) {
  190. var id = albumIDs[0];
  191. albums.json.albums[id].title = newTitle;
  192. }
  193. } else if (visible.albums()) {
  194. albumIDs.forEach(function(id) {
  195. albums.json.albums[id].title = newTitle;
  196. view.albums.content.title(id);
  197. });
  198. }
  199. params = {
  200. albumIDs: albumIDs.join(),
  201. title: newTitle
  202. }
  203. api.post('Album::setTitle', params, function(data) {
  204. if (data!==true) lychee.error(null, params, data);
  205. });
  206. }
  207. input = "<input class='text' data-name='title' type='text' maxlength='30' placeholder='Title' value='" + oldTitle + "'>";
  208. if (albumIDs.length===1) msg = "<p>Enter a new title for this album: " + input + "</p>";
  209. else msg = "<p>Enter a title for all " + albumIDs.length + " selected albums: " + input +"</p>";
  210. basicModal.show({
  211. body: msg,
  212. buttons: {
  213. action: {
  214. title: 'Set Title',
  215. fn: action
  216. },
  217. cancel: {
  218. title: 'Cancel',
  219. fn: basicModal.close
  220. }
  221. }
  222. });
  223. }
  224. album.setDescription = function(albumID) {
  225. var oldDescription = album.json.description.replace("'", '&apos;'),
  226. action;
  227. action = function(data) {
  228. var params,
  229. description = data.description;
  230. basicModal.close();
  231. // Remove html from input
  232. description = lychee.removeHTML(description);
  233. if (visible.album()) {
  234. album.json.description = description;
  235. view.album.description();
  236. }
  237. params = {
  238. albumID,
  239. description
  240. }
  241. api.post('Album::setDescription', params, function(data) {
  242. if (data!==true) lychee.error(null, params, data);
  243. });
  244. }
  245. basicModal.show({
  246. body: "<p>Please enter a description for this album: <input class='text' data-name='description' type='text' maxlength='800' placeholder='Description' value='" + oldDescription + "'></p>",
  247. buttons: {
  248. action: {
  249. title: 'Set Description',
  250. fn: action
  251. },
  252. cancel: {
  253. title: 'Cancel',
  254. fn: basicModal.close
  255. }
  256. }
  257. });
  258. }
  259. album.setPublic = function(albumID, modal, e) {
  260. var params,
  261. password = '';
  262. albums.refresh();
  263. if (modal===true) {
  264. let msg = '',
  265. text = '',
  266. action = {};
  267. action.fn = function() {
  268. // Current function without showing the modal
  269. album.setPublic(album.getID(), false, e);
  270. };
  271. // Album public = Editing a shared album
  272. if (album.json.public==='1') {
  273. action.title = 'Edit Sharing';
  274. text = 'The sharing-properties of this album will be changed to the following:';
  275. } else {
  276. action.title = 'Share Album';
  277. text = 'This album will be shared with the following properties:';
  278. }
  279. msg = `
  280. <p class='less'>${ text }</p>
  281. <form>
  282. <div class='choice'>
  283. <label>
  284. <input type='checkbox' name='visible'>
  285. <span class='checkbox'>${ build.iconic('check') }</span>
  286. <span class='label'>Visible</span>
  287. </label>
  288. <p>Listed to visitors of your Lychee.</p>
  289. </div>
  290. <div class='choice'>
  291. <label>
  292. <input type='checkbox' name='downloadable'>
  293. <span class='checkbox'>${ build.iconic('check') }</span>
  294. <span class='label'>Downloadable</span>
  295. </label>
  296. <p>Visitors of your Lychee can download this album.</p>
  297. </div>
  298. <div class='choice'>
  299. <label>
  300. <input type='checkbox' name='password'>
  301. <span class='checkbox'>${ build.iconic('check') }</span>
  302. <span class='label'>Password protected</span>
  303. </label>
  304. <p>Only accessible with a valid password.</p>
  305. <input class='text' data-name='password' type='password' placeholder='password' value=''>
  306. </div>
  307. </form>
  308. `
  309. basicModal.show({
  310. body: msg,
  311. buttons: {
  312. action: {
  313. title: action.title,
  314. fn: action.fn
  315. },
  316. cancel: {
  317. title: 'Cancel',
  318. fn: basicModal.close
  319. }
  320. }
  321. });
  322. // Active visible by default (public = 0)
  323. if ((album.json.public==='1'&&album.json.visible==='1')||
  324. (album.json.public==='0')) $('.basicModal .choice input[name="visible"]').click();
  325. if (album.json.downloadable==='1') $('.basicModal .choice input[name="downloadable"]').click();
  326. $('.basicModal .choice input[name="password"]').on('change', function() {
  327. if ($(this).prop('checked')===true) $('.basicModal .choice input[data-name="password"]').show().focus();
  328. else $('.basicModal .choice input[data-name="password"]').hide();
  329. });
  330. return true;
  331. }
  332. // Set data
  333. if (basicModal.visible()) {
  334. // Visible modal => Set album public
  335. album.json.public = '1';
  336. // Set visible
  337. if ($('.basicModal .choice input[name="visible"]:checked').length===1) album.json.visible = '1';
  338. else album.json.visible = '0';
  339. // Set downloadable
  340. if ($('.basicModal .choice input[name="downloadable"]:checked').length===1) album.json.downloadable = '1';
  341. else album.json.downloadable = '0';
  342. // Set password
  343. if ($('.basicModal .choice input[name="password"]:checked').length===1) {
  344. password = $('.basicModal .choice input[data-name="password"]').val();
  345. album.json.password = '1';
  346. } else {
  347. password = '';
  348. album.json.password = '0';
  349. }
  350. // Modal input has been processed, now it can be closed
  351. basicModal.close();
  352. } else {
  353. // Modal not visible => Set album private
  354. album.json.public = '0';
  355. }
  356. // Set data and refresh view
  357. if (visible.album()) {
  358. album.json.visible = (album.json.public==='0') ? '0' : album.json.visible;
  359. album.json.downloadable = (album.json.public==='0') ? '0' : album.json.downloadable;
  360. album.json.password = (album.json.public==='0') ? '0' : album.json.password;
  361. view.album.public();
  362. view.album.visible();
  363. view.album.downloadable();
  364. view.album.password();
  365. if (album.json.public==='1') contextMenu.shareAlbum(albumID, e);
  366. }
  367. params = {
  368. albumID,
  369. public: album.json.public,
  370. password: password,
  371. visible: album.json.visible,
  372. downloadable: album.json.downloadable
  373. }
  374. api.post('Album::setPublic', params, function(data) {
  375. if (data!==true) lychee.error(null, params, data);
  376. });
  377. }
  378. album.share = function(service) {
  379. var link = '',
  380. url = location.href;
  381. switch (service) {
  382. case 0:
  383. link = 'https://twitter.com/share?url=' + encodeURI(url);
  384. break;
  385. case 1:
  386. link = 'http://www.facebook.com/sharer.php?u=' + encodeURI(url) + '&t=' + encodeURI(album.json.title);
  387. break;
  388. case 2:
  389. link = 'mailto:?subject=' + encodeURI(album.json.title) + '&body=' + encodeURI(url);
  390. break;
  391. default:
  392. link = '';
  393. break;
  394. }
  395. if (link.length>5) location.href = link;
  396. }
  397. album.getArchive = function(albumID) {
  398. var link,
  399. url = api.path + '?function=Album::getArchive&albumID=' + albumID;
  400. if (location.href.indexOf('index.html')>0) link = location.href.replace(location.hash, '').replace('index.html', url);
  401. else link = location.href.replace(location.hash, '') + url;
  402. if (lychee.publicMode===true) link += '&password=' + password.value;
  403. location.href = link;
  404. }