_view--javascript.js 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021
  1. "use strict";
  2. var _templateObject = _taggedTemplateLiteral(["<svg class='iconic $", "'><use xlink:href='#$", "' /></svg>"], ["<svg class='iconic $", "'><use xlink:href='#$", "' /></svg>"]),
  3. _templateObject2 = _taggedTemplateLiteral(["<div class='divider'><h1>$", "</h1></div>"], ["<div class='divider'><h1>$", "</h1></div>"]),
  4. _templateObject3 = _taggedTemplateLiteral(["<div id='$", "' class='edit'>", "</div>"], ["<div id='$", "' class='edit'>", "</div>"]),
  5. _templateObject4 = _taggedTemplateLiteral(["<div id='multiselect' style='top: $", "px; left: $", "px;'></div>"], ["<div id='multiselect' style='top: $", "px; left: $", "px;'></div>"]),
  6. _templateObject5 = _taggedTemplateLiteral(["\n\t <div class='album' data-id='$", "'>\n\t <img src='$", "' width='200' height='200' alt='Photo thumbnail' data-overlay='false' draggable='false'>\n\t <img src='$", "' width='200' height='200' alt='Photo thumbnail' data-overlay='false' draggable='false'>\n\t <img src='$", "' srcset='$", " 1.5x' width='200' height='200' alt='Photo thumbnail' data-overlay='$", "' draggable='false'>\n\t <div class='overlay'>\n\t <h1 title='$", "'>$", "</h1>\n\t <a>$", "</a>\n\t </div>\n\t "], ["\n\t <div class='album' data-id='$", "'>\n\t <img src='$", "' width='200' height='200' alt='Photo thumbnail' data-overlay='false' draggable='false'>\n\t <img src='$", "' width='200' height='200' alt='Photo thumbnail' data-overlay='false' draggable='false'>\n\t <img src='$", "' srcset='$", " 1.5x' width='200' height='200' alt='Photo thumbnail' data-overlay='$", "' draggable='false'>\n\t <div class='overlay'>\n\t <h1 title='$", "'>$", "</h1>\n\t <a>$", "</a>\n\t </div>\n\t "]),
  7. _templateObject6 = _taggedTemplateLiteral(["\n\t\t <div class='badges'>\n\t\t <a class='badge $", " icn-star'>", "</a>\n\t\t <a class='badge $", " icn-share'>", "</a>\n\t\t <a class='badge $", "'>", "</a>\n\t\t <a class='badge $", "'>", "</a>\n\t\t <a class='badge $", "'>", "</a>\n\t\t </div>\n\t\t "], ["\n\t\t <div class='badges'>\n\t\t <a class='badge $", " icn-star'>", "</a>\n\t\t <a class='badge $", " icn-share'>", "</a>\n\t\t <a class='badge $", "'>", "</a>\n\t\t <a class='badge $", "'>", "</a>\n\t\t <a class='badge $", "'>", "</a>\n\t\t </div>\n\t\t "]),
  8. _templateObject7 = _taggedTemplateLiteral(["\n\t <div class='photo' data-album-id='$", "' data-id='$", "'>\n\t <img src='$", "' srcset='$", " 1.5x' width='200' height='200' alt='Photo thumbnail' draggable='false'>\n\t <div class='overlay'>\n\t <h1 title='$", "'>$", "</h1>\n\t "], ["\n\t <div class='photo' data-album-id='$", "' data-id='$", "'>\n\t <img src='$", "' srcset='$", " 1.5x' width='200' height='200' alt='Photo thumbnail' draggable='false'>\n\t <div class='overlay'>\n\t <h1 title='$", "'>$", "</h1>\n\t "]),
  9. _templateObject8 = _taggedTemplateLiteral(["<a><span title='Camera Date'>", "</span>$", "</a>"], ["<a><span title='Camera Date'>", "</span>$", "</a>"]),
  10. _templateObject9 = _taggedTemplateLiteral(["<a>$", "</a>"], ["<a>$", "</a>"]),
  11. _templateObject10 = _taggedTemplateLiteral(["\n\t\t <div class='badges'>\n\t\t <a class='badge $", " icn-star'>", "</a>\n\t\t <a class='badge $", " icn-share'>", "</a>\n\t\t </div>\n\t\t "], ["\n\t\t <div class='badges'>\n\t\t <a class='badge $", " icn-star'>", "</a>\n\t\t <a class='badge $", " icn-share'>", "</a>\n\t\t </div>\n\t\t "]),
  12. _templateObject11 = _taggedTemplateLiteral(["<img id='image' class='$", "' src='$", "' draggable='false'>"], ["<img id='image' class='$", "' src='$", "' draggable='false'>"]),
  13. _templateObject12 = _taggedTemplateLiteral(["<img id='image' class='$", "' src='$", "' srcset='$", " 1920w, $", " $", "w' draggable='false'>"], ["<img id='image' class='$", "' src='$", "' srcset='$", " 1920w, $", " $", "w' draggable='false'>"]),
  14. _templateObject13 = _taggedTemplateLiteral(["\n\t <h1>$", "</h1>\n\t <div class='rows'>\n\t "], ["\n\t <h1>$", "</h1>\n\t <div class='rows'>\n\t "]),
  15. _templateObject14 = _taggedTemplateLiteral(["\n\t\t <div class='row'>\n\t\t <a class='name'>$", "</a>\n\t\t <a class='status'></a>\n\t\t <p class='notice'></p>\n\t\t </div>\n\t\t "], ["\n\t\t <div class='row'>\n\t\t <a class='name'>$", "</a>\n\t\t <a class='status'></a>\n\t\t <p class='notice'></p>\n\t\t </div>\n\t\t "]),
  16. _templateObject15 = _taggedTemplateLiteral(["<a class='tag'>$", "<span data-index='$", "'>", "</span></a>"], ["<a class='tag'>$", "<span data-index='$", "'>", "</span></a>"]),
  17. _templateObject16 = _taggedTemplateLiteral(["$", "", ""], ["$", "", ""]),
  18. _templateObject17 = _taggedTemplateLiteral(["<span class='attr_$", "'>$", "</span>"], ["<span class='attr_$", "'>$", "</span>"]),
  19. _templateObject18 = _taggedTemplateLiteral(["\n\t\t\t <tr>\n\t\t\t <td>$", "</td>\n\t\t\t <td>", "</td>\n\t\t\t </tr>\n\t\t\t "], ["\n\t\t\t <tr>\n\t\t\t <td>$", "</td>\n\t\t\t <td>", "</td>\n\t\t\t </tr>\n\t\t\t "]),
  20. _templateObject19 = _taggedTemplateLiteral(["\n\t\t <div class='sidebar__divider'>\n\t\t <h1>$", "</h1>\n\t\t </div>\n\t\t <div id='tags'>\n\t\t <div class='attr_$", "'>", "</div>\n\t\t ", "\n\t\t </div>\n\t\t "], ["\n\t\t <div class='sidebar__divider'>\n\t\t <h1>$", "</h1>\n\t\t </div>\n\t\t <div id='tags'>\n\t\t <div class='attr_$", "'>", "</div>\n\t\t ", "\n\t\t </div>\n\t\t "]);
  21. function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
  22. function gup(b) {
  23. b = b.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
  24. var a = "[\\?&]" + b + "=([^&#]*)";
  25. var d = new RegExp(a);
  26. var c = d.exec(window.location.href);
  27. if (c === null) return '';else return c[1];
  28. }
  29. /**
  30. * @description This module is used to generate HTML-Code.
  31. * @copyright 2015 by Tobias Reich
  32. */
  33. build = {};
  34. build.iconic = function (icon) {
  35. var classes = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];
  36. var html = '';
  37. html += lychee.html(_templateObject, classes, icon);
  38. return html;
  39. };
  40. build.divider = function (title) {
  41. var html = '';
  42. html += lychee.html(_templateObject2, title);
  43. return html;
  44. };
  45. build.editIcon = function (id) {
  46. var html = '';
  47. html += lychee.html(_templateObject3, id, build.iconic('pencil'));
  48. return html;
  49. };
  50. build.multiselect = function (top, left) {
  51. return lychee.html(_templateObject4, top, left);
  52. };
  53. build.album = function (data) {
  54. var html = '';
  55. var _lychee$retinize = lychee.retinize(data.thumbs[0]);
  56. var retinaThumbUrl = _lychee$retinize.path;
  57. var isPhoto = _lychee$retinize.isPhoto;
  58. html += lychee.html(_templateObject5, data.id, data.thumbs[2], data.thumbs[1], data.thumbs[0], retinaThumbUrl, isPhoto, data.title, data.title, data.sysdate);
  59. if (lychee.publicMode === false) {
  60. html += lychee.html(_templateObject6, data.star === '1' ? 'badge--visible' : '', build.iconic('star'), data.public === '1' ? 'badge--visible' : '', build.iconic('eye'), data.unsorted === '1' ? 'badge--visible' : '', build.iconic('list'), data.recent === '1' ? 'badge--visible' : '', build.iconic('clock'), data.password === '1' ? 'badge--visible' : '', build.iconic('lock-locked'));
  61. }
  62. html += '</div>';
  63. return html;
  64. };
  65. build.photo = function (data) {
  66. var html = '';
  67. var _lychee$retinize2 = lychee.retinize(data.thumbUrl);
  68. var retinaThumbUrl = _lychee$retinize2.path;
  69. html += lychee.html(_templateObject7, data.album, data.id, data.thumbUrl, retinaThumbUrl, data.title, data.title);
  70. if (data.cameraDate === '1') html += lychee.html(_templateObject8, build.iconic('camera-slr'), data.sysdate);else html += lychee.html(_templateObject9, data.sysdate);
  71. html += "</div>";
  72. if (lychee.publicMode === false) {
  73. html += lychee.html(_templateObject10, data.star === '1' ? 'badge--visible' : '', build.iconic('star'), data.public === '1' && album.json.public !== '1' ? 'badge--visible' : '', build.iconic('eye'));
  74. }
  75. html += "</div>";
  76. return html;
  77. };
  78. build.imageview = function (data, visibleControls) {
  79. var html = '';
  80. var hasMedium = data.medium !== '';
  81. if (hasMedium === false) {
  82. html += lychee.html(_templateObject11, visibleControls === true ? '' : 'full', data.url);
  83. } else {
  84. html += lychee.html(_templateObject12, visibleControls === true ? '' : 'full', data.url, data.medium, data.url, data.width);
  85. }
  86. html += "\n\t <div class='arrow_wrapper arrow_wrapper--previous'><a id='previous'>" + build.iconic('caret-left') + "</a></div>\n\t <div class='arrow_wrapper arrow_wrapper--next'><a id='next'>" + build.iconic('caret-right') + "</a></div>\n\t ";
  87. return html;
  88. };
  89. build.no_content = function (typ) {
  90. var html = '';
  91. html += "\n\t <div class='no_content fadeIn'>\n\t " + build.iconic(typ) + "\n\t ";
  92. switch (typ) {
  93. case 'magnifying-glass':
  94. html += "<p>No results</p>";
  95. break;
  96. case 'eye':
  97. html += "<p>No public albums</p>";
  98. break;
  99. case 'cog':
  100. html += "<p>No configuration</p>";
  101. break;
  102. case 'question-mark':
  103. html += "<p>Photo not found</p>";
  104. break;
  105. }
  106. html += "</div>";
  107. return html;
  108. };
  109. build.uploadModal = function (title, files) {
  110. var html = '';
  111. html += lychee.html(_templateObject13, title);
  112. var i = 0;
  113. while (i < files.length) {
  114. var file = files[i];
  115. if (file.name.length > 40) file.name = file.name.substr(0, 17) + '...' + file.name.substr(file.name.length - 20, 20);
  116. html += lychee.html(_templateObject14, file.name);
  117. i++;
  118. }
  119. html += "</div>";
  120. return html;
  121. };
  122. build.tags = function (tags) {
  123. var html = '';
  124. if (tags !== '') {
  125. tags = tags.split(',');
  126. tags.forEach(function (tag, index, array) {
  127. html += lychee.html(_templateObject15, tag, index, build.iconic('x'));
  128. });
  129. } else {
  130. html = "<div class='empty'>No Tags</div>";
  131. }
  132. return html;
  133. };
  134. /**
  135. * @description This module communicates with Lychee's API
  136. * @copyright 2015 by Tobias Reich
  137. */
  138. api = {
  139. path: 'php/index.php',
  140. onError: null
  141. };
  142. api.post = function (fn, params, callback) {
  143. loadingBar.show();
  144. params = $.extend({ function: fn }, params);
  145. var success = function success(data) {
  146. setTimeout(loadingBar.hide, 100);
  147. // Catch errors
  148. if (typeof data === 'string' && data.substring(0, 7) === 'Error: ') {
  149. api.onError(data.substring(7, data.length), params, data);
  150. return false;
  151. }
  152. callback(data);
  153. };
  154. var error = function error(jqXHR, textStatus, errorThrown) {
  155. api.onError('Server error or API not found.', params, errorThrown);
  156. };
  157. $.ajax({
  158. type: 'POST',
  159. url: api.path,
  160. data: params,
  161. dataType: 'json',
  162. success: success,
  163. error: error
  164. });
  165. };
  166. /**
  167. * @description This module takes care of the header.
  168. * @copyright 2015 by Tobias Reich
  169. */
  170. header = {
  171. _dom: $('.header')
  172. };
  173. header.dom = function (selector) {
  174. if (selector == null || selector === '') return header._dom;
  175. return header._dom.find(selector);
  176. };
  177. header.bind = function () {
  178. // Event Name
  179. var eventName = lychee.getEventName();
  180. header.dom('.header__title').on(eventName, function (e) {
  181. if ($(this).hasClass('header__title--editable') === false) return false;
  182. if (visible.photo()) contextMenu.photoTitle(album.getID(), photo.getID(), e);else contextMenu.albumTitle(album.getID(), e);
  183. });
  184. header.dom('#button_share').on(eventName, function (e) {
  185. if (photo.json.public === '1' || photo.json.public === '2') contextMenu.sharePhoto(photo.getID(), e);else photo.setPublic(photo.getID(), e);
  186. });
  187. header.dom('#button_share_album').on(eventName, function (e) {
  188. if (album.json.public === '1') contextMenu.shareAlbum(album.getID(), e);else album.setPublic(album.getID(), true, e);
  189. });
  190. header.dom('#button_signin').on(eventName, lychee.loginDialog);
  191. header.dom('#button_settings').on(eventName, contextMenu.settings);
  192. header.dom('#button_info_album').on(eventName, sidebar.toggle);
  193. header.dom('#button_info').on(eventName, sidebar.toggle);
  194. header.dom('.button_add').on(eventName, contextMenu.add);
  195. header.dom('#button_more').on(eventName, function (e) {
  196. contextMenu.photoMore(photo.getID(), e);
  197. });
  198. header.dom('#button_move').on(eventName, function (e) {
  199. contextMenu.move([photo.getID()], e);
  200. });
  201. header.dom('.header__hostedwith').on(eventName, function () {
  202. window.open(lychee.website);
  203. });
  204. header.dom('#button_trash_album').on(eventName, function () {
  205. album.delete([album.getID()]);
  206. });
  207. header.dom('#button_trash').on(eventName, function () {
  208. photo.delete([photo.getID()]);
  209. });
  210. header.dom('#button_archive').on(eventName, function () {
  211. album.getArchive(album.getID());
  212. });
  213. header.dom('#button_star').on(eventName, function () {
  214. photo.setStar([photo.getID()]);
  215. });
  216. header.dom('#button_back_home').on(eventName, function () {
  217. lychee.goto();
  218. });
  219. header.dom('#button_back').on(eventName, function () {
  220. lychee.goto(album.getID());
  221. });
  222. header.dom('.header__search').on('keyup click', function () {
  223. search.find($(this).val());
  224. });
  225. header.dom('.header__clear').on(eventName, function () {
  226. header.dom('.header__search').focus();
  227. search.reset();
  228. });
  229. return true;
  230. };
  231. header.show = function () {
  232. clearTimeout($(window).data('timeout'));
  233. lychee.imageview.removeClass('full');
  234. header.dom().removeClass('header--hidden');
  235. return true;
  236. };
  237. header.hide = function (e) {
  238. var delay = arguments.length <= 1 || arguments[1] === undefined ? 500 : arguments[1];
  239. if (visible.photo() && !visible.sidebar() && !visible.contextMenu() && basicModal.visible() === false) {
  240. clearTimeout($(window).data('timeout'));
  241. $(window).data('timeout', setTimeout(function () {
  242. lychee.imageview.addClass('full');
  243. header.dom().addClass('header--hidden');
  244. }, delay));
  245. return true;
  246. }
  247. return false;
  248. };
  249. header.setTitle = function () {
  250. var title = arguments.length <= 0 || arguments[0] === undefined ? 'Untitled' : arguments[0];
  251. var $title = header.dom('.header__title');
  252. var html = lychee.html(_templateObject16, title, build.iconic('caret-bottom'));
  253. $title.html(html);
  254. return true;
  255. };
  256. header.setMode = function (mode) {
  257. if (mode === 'albums' && lychee.publicMode === true) mode = 'public';
  258. switch (mode) {
  259. case 'public':
  260. header.dom().removeClass('header--view');
  261. header.dom('.header__toolbar--albums, .header__toolbar--album, .header__toolbar--photo').removeClass('header__toolbar--visible');
  262. header.dom('.header__toolbar--public').addClass('header__toolbar--visible');
  263. return true;
  264. break;
  265. case 'albums':
  266. header.dom().removeClass('header--view');
  267. header.dom('.header__toolbar--public, .header__toolbar--album, .header__toolbar--photo').removeClass('header__toolbar--visible');
  268. header.dom('.header__toolbar--albums').addClass('header__toolbar--visible');
  269. return true;
  270. break;
  271. case 'album':
  272. var albumID = album.getID();
  273. header.dom().removeClass('header--view');
  274. header.dom('.header__toolbar--public, .header__toolbar--albums, .header__toolbar--photo').removeClass('header__toolbar--visible');
  275. header.dom('.header__toolbar--album').addClass('header__toolbar--visible');
  276. // Hide download button when album empty
  277. if (album.json.content === false) $('#button_archive').hide();else $('#button_archive').show();
  278. // Hide download button when not logged in and album not downloadable
  279. if (lychee.publicMode === true && album.json.downloadable === '0') $('#button_archive').hide();
  280. if (albumID === 's' || albumID === 'f' || albumID === 'r') {
  281. $('#button_info_album, #button_trash_album, #button_share_album').hide();
  282. } else if (albumID === '0') {
  283. $('#button_info_album, #button_share_album').hide();
  284. $('#button_trash_album').show();
  285. } else {
  286. $('#button_info_album, #button_trash_album, #button_share_album').show();
  287. }
  288. return true;
  289. break;
  290. case 'photo':
  291. header.dom().addClass('header--view');
  292. header.dom('.header__toolbar--public, .header__toolbar--albums, .header__toolbar--album').removeClass('header__toolbar--visible');
  293. header.dom('.header__toolbar--photo').addClass('header__toolbar--visible');
  294. return true;
  295. break;
  296. }
  297. return false;
  298. };
  299. header.setEditable = function (editable) {
  300. var $title = header.dom('.header__title');
  301. // Hide editable icon when not logged in
  302. if (lychee.publicMode === true) editable = false;
  303. if (editable) $title.addClass('header__title--editable');else $title.removeClass('header__title--editable');
  304. return true;
  305. };
  306. /**
  307. * @description This module is used to check if elements are visible or not.
  308. * @copyright 2015 by Tobias Reich
  309. */
  310. visible = {};
  311. visible.albums = function () {
  312. if (header.dom('.header__toolbar--public').hasClass('header__toolbar--visible')) return true;
  313. if (header.dom('.header__toolbar--albums').hasClass('header__toolbar--visible')) return true;
  314. return false;
  315. };
  316. visible.album = function () {
  317. if (header.dom('.header__toolbar--album').hasClass('header__toolbar--visible')) return true;
  318. return false;
  319. };
  320. visible.photo = function () {
  321. if ($('#imageview.fadeIn').length > 0) return true;
  322. return false;
  323. };
  324. visible.search = function () {
  325. if (search.hash != null) return true;
  326. return false;
  327. };
  328. visible.sidebar = function () {
  329. if (sidebar.dom().hasClass('active') === true) return true;
  330. return false;
  331. };
  332. visible.sidebarbutton = function () {
  333. if (visible.photo()) return true;
  334. if (visible.album() && $('#button_info_album:visible').length > 0) return true;
  335. return false;
  336. };
  337. visible.header = function () {
  338. if (header.dom().hasClass('header--hidden') === true) return false;
  339. return true;
  340. };
  341. visible.contextMenu = function () {
  342. return basicContext.visible();
  343. };
  344. visible.multiselect = function () {
  345. if ($('#multiselect').length > 0) return true;
  346. return false;
  347. };
  348. /**
  349. * @description This module takes care of the sidebar.
  350. * @copyright 2015 by Tobias Reich
  351. */
  352. sidebar = {
  353. _dom: $('.sidebar'),
  354. types: {
  355. DEFAULT: 0,
  356. TAGS: 1
  357. },
  358. createStructure: {}
  359. };
  360. sidebar.dom = function (selector) {
  361. if (selector == null || selector === '') return sidebar._dom;
  362. return sidebar._dom.find(selector);
  363. };
  364. sidebar.bind = function () {
  365. // This function should be called after building and appending
  366. // the sidebars content to the DOM.
  367. // This function can be called multiple times, therefore
  368. // event handlers should be removed before binding a new one.
  369. // Event Name
  370. var eventName = lychee.getEventName();
  371. sidebar.dom('#edit_title').off(eventName).on(eventName, function () {
  372. if (visible.photo()) photo.setTitle([photo.getID()]);else if (visible.album()) album.setTitle([album.getID()]);
  373. });
  374. sidebar.dom('#edit_description').off(eventName).on(eventName, function () {
  375. if (visible.photo()) photo.setDescription(photo.getID());else if (visible.album()) album.setDescription(album.getID());
  376. });
  377. sidebar.dom('#edit_tags').off(eventName).on(eventName, function () {
  378. photo.editTags([photo.getID()]);
  379. });
  380. sidebar.dom('#tags .tag span').off(eventName).on(eventName, function () {
  381. photo.deleteTag(photo.getID(), $(this).data('index'));
  382. });
  383. return true;
  384. };
  385. sidebar.toggle = function () {
  386. if (visible.sidebar() || visible.sidebarbutton()) {
  387. header.dom('.button--info').toggleClass('active');
  388. lychee.content.toggleClass('content--sidebar');
  389. sidebar.dom().toggleClass('active');
  390. return true;
  391. }
  392. return false;
  393. };
  394. sidebar.setSelectable = function () {
  395. var selectable = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];
  396. // Attributes/Values inside the sidebar are selectable by default.
  397. // Selection needs to be deactivated to prevent an unwanted selection
  398. // while using multiselect.
  399. if (selectable === true) sidebar.dom().removeClass('notSelectable');else sidebar.dom().addClass('notSelectable');
  400. };
  401. sidebar.changeAttr = function (attr) {
  402. var value = arguments.length <= 1 || arguments[1] === undefined ? '-' : arguments[1];
  403. var dangerouslySetInnerHTML = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2];
  404. if (attr == null || attr === '') return false;
  405. // Set a default for the value
  406. if (value == null || value === '') value = '-';
  407. // Escape value
  408. if (dangerouslySetInnerHTML === false) value = lychee.escapeHTML(value);
  409. // Set new value
  410. sidebar.dom('.attr_' + attr).html(value);
  411. return true;
  412. };
  413. sidebar.createStructure.photo = function (data) {
  414. if (data == null || data === '') return false;
  415. var editable = false;
  416. var exifHash = data.takestamp + data.make + data.model + data.shutter + data.aperture + data.focal + data.iso;
  417. var structure = {};
  418. var _public = '';
  419. // Enable editable when user logged in
  420. if (lychee.publicMode === false) editable = true;
  421. // Set value for public
  422. switch (data.public) {
  423. case '0':
  424. _public = 'No';
  425. break;
  426. case '1':
  427. _public = 'Yes';
  428. break;
  429. case '2':
  430. _public = 'Yes (Album)';
  431. break;
  432. default:
  433. _public = '-';
  434. break;
  435. }
  436. structure.basics = {
  437. title: 'Basics',
  438. type: sidebar.types.DEFAULT,
  439. rows: [{ title: 'Title', value: data.title, editable: editable }, { title: 'Uploaded', value: data.sysdate }, { title: 'Description', value: data.description, editable: editable }]
  440. };
  441. structure.image = {
  442. title: 'Image',
  443. type: sidebar.types.DEFAULT,
  444. rows: [{ title: 'Size', value: data.size }, { title: 'Format', value: data.type }, { title: 'Resolution', value: data.width + ' x ' + data.height }]
  445. };
  446. // Only create tags section when user logged in
  447. if (lychee.publicMode === false) {
  448. structure.tags = {
  449. title: 'Tags',
  450. type: sidebar.types.TAGS,
  451. value: build.tags(data.tags),
  452. editable: editable
  453. };
  454. } else {
  455. structure.tags = {};
  456. }
  457. // Only create EXIF section when EXIF data available
  458. if (exifHash !== '0') {
  459. structure.exif = {
  460. title: 'Camera',
  461. type: sidebar.types.DEFAULT,
  462. rows: [{ title: 'Captured', value: data.takedate }, { title: 'Make', value: data.make }, { title: 'Type/Model', value: data.model }, { title: 'Shutter Speed', value: data.shutter }, { title: 'Aperture', value: data.aperture }, { title: 'Focal Length', value: data.focal }, { title: 'ISO', value: data.iso }]
  463. };
  464. } else {
  465. structure.exif = {};
  466. }
  467. structure.sharing = {
  468. title: 'Sharing',
  469. type: sidebar.types.DEFAULT,
  470. rows: [{ title: 'Public', value: _public }]
  471. };
  472. // Construct all parts of the structure
  473. structure = [structure.basics, structure.image, structure.tags, structure.exif, structure.sharing];
  474. return structure;
  475. };
  476. sidebar.createStructure.album = function (data) {
  477. if (data == null || data === '') return false;
  478. var editable = false;
  479. var structure = {};
  480. var _public = '';
  481. var hidden = '';
  482. var downloadable = '';
  483. var password = '';
  484. // Enable editable when user logged in
  485. if (lychee.publicMode === false) editable = true;
  486. // Set value for public
  487. switch (data.public) {
  488. case '0':
  489. _public = 'No';
  490. break;
  491. case '1':
  492. _public = 'Yes';
  493. break;
  494. default:
  495. _public = '-';
  496. break;
  497. }
  498. // Set value for hidden
  499. switch (data.visible) {
  500. case '0':
  501. hidden = 'Yes';
  502. break;
  503. case '1':
  504. hidden = 'No';
  505. break;
  506. default:
  507. hidden = '-';
  508. break;
  509. }
  510. // Set value for downloadable
  511. switch (data.downloadable) {
  512. case '0':
  513. downloadable = 'No';
  514. break;
  515. case '1':
  516. downloadable = 'Yes';
  517. break;
  518. default:
  519. downloadable = '-';
  520. break;
  521. }
  522. // Set value for password
  523. switch (data.password) {
  524. case '0':
  525. password = 'No';
  526. break;
  527. case '1':
  528. password = 'Yes';
  529. break;
  530. default:
  531. password = '-';
  532. break;
  533. }
  534. structure.basics = {
  535. title: 'Basics',
  536. type: sidebar.types.DEFAULT,
  537. rows: [{ title: 'Title', value: data.title, editable: editable }, { title: 'Description', value: data.description, editable: editable }]
  538. };
  539. structure.album = {
  540. title: 'Album',
  541. type: sidebar.types.DEFAULT,
  542. rows: [{ title: 'Created', value: data.sysdate }, { title: 'Images', value: data.num }]
  543. };
  544. structure.share = {
  545. title: 'Share',
  546. type: sidebar.types.DEFAULT,
  547. rows: [{ title: 'Public', value: _public }, { title: 'Hidden', value: hidden }, { title: 'Downloadable', value: downloadable }, { title: 'Password', value: password }]
  548. };
  549. // Construct all parts of the structure
  550. structure = [structure.basics, structure.album, structure.share];
  551. return structure;
  552. };
  553. sidebar.render = function (structure) {
  554. if (structure == null || structure === '') return false;
  555. var html = '';
  556. var renderDefault = function renderDefault(section) {
  557. var _html = '';
  558. _html += "\n\t\t <div class='sidebar__divider'>\n\t\t <h1>" + section.title + "</h1>\n\t\t </div>\n\t\t <table>\n\t\t ";
  559. section.rows.forEach(function (row) {
  560. var value = row.value;
  561. // Set a default for the value
  562. if (value === '' || value == null) value = '-';
  563. // Wrap span-element around value for easier selecting on change
  564. value = lychee.html(_templateObject17, row.title.toLowerCase(), value);
  565. // Add edit-icon to the value when editable
  566. if (row.editable === true) value += ' ' + build.editIcon('edit_' + row.title.toLowerCase());
  567. _html += lychee.html(_templateObject18, row.title, value);
  568. });
  569. _html += "\n\t\t </table>\n\t\t ";
  570. return _html;
  571. };
  572. var renderTags = function renderTags(section) {
  573. var _html = '';
  574. var editable = '';
  575. // Add edit-icon to the value when editable
  576. if (section.editable === true) editable = build.editIcon('edit_tags');
  577. _html += lychee.html(_templateObject19, section.title, section.title.toLowerCase(), section.value, editable);
  578. return _html;
  579. };
  580. structure.forEach(function (section) {
  581. if (section.type === sidebar.types.DEFAULT) html += renderDefault(section);else if (section.type === sidebar.types.TAGS) html += renderTags(section);
  582. });
  583. return html;
  584. };
  585. /**
  586. * @description Used to view single photos with view.php
  587. * @copyright 2015 by Tobias Reich
  588. */
  589. // Sub-implementation of lychee -------------------------------------------------------------- //
  590. var lychee = {};
  591. lychee.content = $('.content');
  592. lychee.escapeHTML = function () {
  593. var html = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];
  594. // Ensure that html is a string
  595. html += '';
  596. // Escape all critical characters
  597. html = html.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;').replace(/`/g, '&#96;');
  598. return html;
  599. };
  600. lychee.html = function (literalSections) {
  601. // Use raw literal sections: we don’t want
  602. // backslashes (\n etc.) to be interpreted
  603. var raw = literalSections.raw;
  604. var result = '';
  605. for (var _len = arguments.length, substs = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  606. substs[_key - 1] = arguments[_key];
  607. }
  608. substs.forEach(function (subst, i) {
  609. // Retrieve the literal section preceding
  610. // the current substitution
  611. var lit = raw[i];
  612. // If the substitution is preceded by a dollar sign,
  613. // we escape special characters in it
  614. if (lit.slice(-1) === '$') {
  615. subst = lychee.escapeHTML(subst);
  616. lit = lit.slice(0, -1);
  617. }
  618. result += lit;
  619. result += subst;
  620. });
  621. // Take care of last literal section
  622. // (Never fails, because an empty template string
  623. // produces one literal section, an empty string)
  624. result += raw[raw.length - 1];
  625. return result;
  626. };
  627. lychee.getEventName = function () {
  628. var touchendSupport = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent || navigator.vendor || window.opera) && 'ontouchend' in document.documentElement;
  629. var eventName = touchendSupport === true ? 'touchend' : 'click';
  630. return eventName;
  631. };
  632. // Sub-implementation of photo -------------------------------------------------------------- //
  633. var photo = {};
  634. photo.share = function (photoID, service) {
  635. var url = location.toString();
  636. switch (service) {
  637. case 'twitter':
  638. window.open("https://twitter.com/share?url=" + encodeURI(url));
  639. break;
  640. case 'facebook':
  641. window.open("http://www.facebook.com/sharer.php?u=" + encodeURI(url));
  642. break;
  643. case 'mail':
  644. location.href = "mailto:?subject=&body=" + encodeURI(url);
  645. break;
  646. }
  647. };
  648. photo.getDirectLink = function () {
  649. return $('#imageview img').attr('src').replace(/"/g, '').replace(/url\(|\)$/ig, '');
  650. };
  651. // Sub-implementation of contextMenu -------------------------------------------------------------- //
  652. var contextMenu = {};
  653. contextMenu.sharePhoto = function (photoID, e) {
  654. var iconClass = 'ionicons';
  655. var items = [{ title: build.iconic('twitter', iconClass) + 'Twitter', fn: function fn() {
  656. return photo.share(photoID, 'twitter');
  657. } }, { title: build.iconic('facebook', iconClass) + 'Facebook', fn: function fn() {
  658. return photo.share(photoID, 'facebook');
  659. } }, { title: build.iconic('envelope-closed') + 'Mail', fn: function fn() {
  660. return photo.share(photoID, 'mail');
  661. } }, { title: build.iconic('link-intact') + 'Direct Link', fn: function fn() {
  662. return window.open(photo.getDirectLink(), '_newtab');
  663. } }];
  664. basicContext.show(items, e.originalEvent);
  665. };
  666. // Main -------------------------------------------------------------- //
  667. var loadingBar = {
  668. show: function show() {},
  669. hide: function hide() {}
  670. };
  671. var imageview = $('#imageview');
  672. $(document).ready(function () {
  673. // Save ID of photo
  674. var photoID = gup('p');
  675. // Set API error handler
  676. api.onError = error;
  677. // Share
  678. header.dom('#button_share').on('click', function (e) {
  679. contextMenu.sharePhoto(photoID, e);
  680. });
  681. // Infobox
  682. header.dom('#button_info').on('click', sidebar.toggle);
  683. // Load photo
  684. loadPhotoInfo(photoID);
  685. });
  686. var loadPhotoInfo = function loadPhotoInfo(photoID) {
  687. var params = {
  688. photoID: photoID,
  689. albumID: 0,
  690. password: ''
  691. };
  692. api.post('Photo::get', params, function (data) {
  693. if (data === 'Warning: Photo private!' || data === 'Warning: Wrong password!') {
  694. $('body').append(build.no_content('question-mark'));
  695. $('body').removeClass('view');
  696. header.dom().remove();
  697. return false;
  698. }
  699. // Set title
  700. if (!data.title) data.title = 'Untitled';
  701. document.title = 'Lychee - ' + data.title;
  702. header.dom('.header__title').html(lychee.escapeHTML(data.title));
  703. // Render HTML
  704. imageview.html(build.imageview(data, true));
  705. imageview.find('.arrow_wrapper').remove();
  706. imageview.addClass('fadeIn').show();
  707. // Render Sidebar
  708. var structure = sidebar.createStructure.photo(data);
  709. var html = sidebar.render(structure);
  710. sidebar.dom('.sidebar__wrapper').html(html);
  711. sidebar.bind();
  712. });
  713. };
  714. var error = function error(errorThrown, params, data) {
  715. console.error({
  716. description: errorThrown,
  717. params: params,
  718. response: data
  719. });
  720. loadingBar.show('error', errorThrown);
  721. };