main.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /**
  2. * @description Used to view single photos with view.php
  3. * @copyright 2015 by Tobias Reich
  4. */
  5. // Sub-implementation of lychee -------------------------------------------------------------- //
  6. let lychee = {}
  7. lychee.content = $('.content')
  8. lychee.getEventName = function() {
  9. let touchendSupport = (/Android|iPhone|iPad|iPod/i).test(navigator.userAgent || navigator.vendor || window.opera) && ('ontouchend' in document.documentElement)
  10. let eventName = (touchendSupport===true ? 'touchend' : 'click')
  11. return eventName
  12. }
  13. lychee.escapeHTML = function(html = '') {
  14. // Ensure that html is a string
  15. html += ''
  16. // Escape all critical characters
  17. html = html.replace(/&/g, '&')
  18. .replace(/</g, '&lt;')
  19. .replace(/>/g, '&gt;')
  20. .replace(/"/g, '&quot;')
  21. .replace(/'/g, '&#039;')
  22. .replace(/`/g, '&#96;')
  23. return html
  24. }
  25. lychee.html = function(literalSections, ...substs) {
  26. // Use raw literal sections: we don’t want
  27. // backslashes (\n etc.) to be interpreted
  28. let raw = literalSections.raw
  29. let result = ''
  30. substs.forEach((subst, i) => {
  31. // Retrieve the literal section preceding
  32. // the current substitution
  33. let lit = raw[i]
  34. // If the substitution is preceded by a dollar sign,
  35. // we escape special characters in it
  36. if (lit.slice(-1)==='$') {
  37. subst = lychee.escapeHTML(subst)
  38. lit = lit.slice(0, -1)
  39. }
  40. result += lit
  41. result += subst
  42. })
  43. // Take care of last literal section
  44. // (Never fails, because an empty template string
  45. // produces one literal section, an empty string)
  46. result += raw[raw.length - 1]
  47. return result
  48. }
  49. // Sub-implementation of photo -------------------------------------------------------------- //
  50. let photo = {}
  51. photo.share = function(photoID, service) {
  52. let link = ''
  53. let url = location.toString()
  54. switch (service) {
  55. case 'twitter':
  56. link = `https://twitter.com/share?url=${ encodeURI(url) }`
  57. break
  58. case 'facebook':
  59. link = `http://www.facebook.com/sharer.php?u=${ encodeURI(url) }`
  60. break
  61. case 'mail':
  62. link = `mailto:?subject=&body=${ encodeURI(url) }`
  63. break
  64. default:
  65. link = ''
  66. break
  67. }
  68. if (link!=='') location.href = link
  69. }
  70. photo.getDirectLink = function() {
  71. return $('#imageview img').attr('src').replace(/"/g,'').replace(/url\(|\)$/ig, '')
  72. }
  73. // Sub-implementation of contextMenu -------------------------------------------------------------- //
  74. let contextMenu = {}
  75. contextMenu.sharePhoto = function(photoID, e) {
  76. let iconClass = 'ionicons'
  77. let items = [
  78. { title: build.iconic('twitter', iconClass) + 'Twitter', fn: () => photo.share(photoID, 'twitter') },
  79. { title: build.iconic('facebook', iconClass) + 'Facebook', fn: () => photo.share(photoID, 'facebook') },
  80. { title: build.iconic('envelope-closed') + 'Mail', fn: () => photo.share(photoID, 'mail') },
  81. { title: build.iconic('link-intact') + 'Direct Link', fn: () => window.open(photo.getDirectLink(), '_newtab') }
  82. ]
  83. basicContext.show(items, e.originalEvent)
  84. }
  85. // Main -------------------------------------------------------------- //
  86. let loadingBar = { show() {}, hide() {} }
  87. let imageview = $('#imageview')
  88. $(document).ready(function() {
  89. // Save ID of photo
  90. let photoID = gup('p')
  91. // Event Name
  92. let eventName = lychee.getEventName()
  93. // Set API error handler
  94. api.onError = error
  95. // Share
  96. header.dom('#button_share').on(eventName, function(e) {
  97. contextMenu.sharePhoto(photoID, e)
  98. })
  99. // Infobox
  100. header.dom('#button_info').on(eventName, sidebar.toggle)
  101. // Load photo
  102. loadPhotoInfo(photoID)
  103. })
  104. const loadPhotoInfo = function(photoID) {
  105. let params = {
  106. photoID,
  107. albumID : 0,
  108. password : ''
  109. }
  110. api.post('Photo::get', params, function(data) {
  111. if (data==='Warning: Photo private!' || data==='Warning: Wrong password!') {
  112. $('body').append(build.no_content('question-mark'))
  113. $('body').removeClass('view')
  114. header.dom().remove()
  115. return false
  116. }
  117. // Set title
  118. if (!data.title) data.title = 'Untitled'
  119. document.title = 'Lychee - ' + data.title
  120. header.dom('.header__title').html(lychee.escapeHTML(data.title))
  121. // Render HTML
  122. imageview.html(build.imageview(data, true))
  123. imageview.find('.arrow_wrapper').remove()
  124. imageview.addClass('fadeIn').show()
  125. // Render Sidebar
  126. let structure = sidebar.createStructure.photo(data)
  127. let html = sidebar.render(structure)
  128. sidebar.dom('.sidebar__wrapper').html(html)
  129. sidebar.bind()
  130. })
  131. }
  132. const error = function(errorThrown, params, data) {
  133. console.error({
  134. description : errorThrown,
  135. params : params,
  136. response : data
  137. })
  138. loadingBar.show('error', errorThrown)
  139. }