main.js 4.4 KB

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