modules/components/generators.js

  1. /**
  2. * The generators module includes functions that either return HTMLElements or HTML-formatted strings
  3. * that are used as templates for building blocks of the app.
  4. * Most functions take arguments providing content to fill these templates.
  5. * @namespace generators
  6. */
  7. module.exports = {
  8. infoCardDummy, infoCardContent,
  9. searchResult, upNextPoster, upNextTitle,
  10. confirmActionAlertBox
  11. }
  12. /**
  13. * Generates an element containing the basic html structure of a single info card.
  14. * @memberof generators
  15. * @param {'left_stack'|'middle_stack'|'right_stack'} stack Card stack it will be placed onto
  16. * @param {Number} index Position of this card in the total stack
  17. * @param {String} id Reference ID for trakt database
  18. * @returns {HTMLElement}
  19. */
  20. function infoCardDummy(stack, index, id) {
  21. let infocard = document.createElement('div')
  22. infocard.classList.add('infocard', 'shadow_b', stack)
  23. infocard.id = 'card_'+index
  24. infocard.dataset.trakt_id = id
  25. infocard.innerHTML = `
  26. <div id="infocard_close" class="btn-close black_d_b z4 elmHover" onclick="triggerInfoCardOverlay()">
  27. <img src="../../assets/icons/app/close.svg">
  28. </div>
  29. <div class="cardcontent">
  30. <div class="center">
  31. <img class="logo gray-animation" style="height: 200px" src="../../assets/icons/traktify/512x512.png">
  32. </div>
  33. </div>
  34. `
  35. return infocard
  36. }
  37. /**
  38. * Generates html-string containing all elements that are placed inside one info card.
  39. * @memberof generators
  40. * @param {Object} item
  41. * @param {Number} item.ratingPercent
  42. * @param {Number} item.seasonNumber
  43. * @param {Number} item.episodeNumber
  44. * @param {String} item.episodeTitle
  45. * @param {String} item.description
  46. * @returns {String}
  47. */
  48. function infoCardContent(item) {
  49. let html = `
  50. <div class="infocard_child black_b z4">
  51. <div id="infocard_close" class="btn-close black_d_b z4 elmHover" onclick="triggerInfoCardOverlay()">
  52. <img src="../../assets/icons/app/close.svg">
  53. </div>
  54. <div class="infocard_left">
  55. <img src="">
  56. <img src="" class="shadow_b">
  57. </div>
  58. <div class="infocard_right">
  59. <h2 class="h2 white_t" style="margin: 0 0 12px">${item.episodeTitle}</h2>
  60. <div class="horizontal_border"></div>
  61. <p class="p white_d_t" style="margin-bottom:0">${item.description}</p>
  62. ${actionButtons(item.matcher, 'card')}
  63. </div>
  64. </div>
  65. `
  66. return html
  67. }
  68. /**
  69. * Generates a html element for one search result and adds it to the sidebar.
  70. * @memberof generators
  71. * @param {Object} item
  72. * @param {String} item.img
  73. * @param {String} item.title
  74. * @param {String} item.description
  75. * @param {String} item.type
  76. * @param {Number} item.rating
  77. * @param {Number} item.id Reference ID for TMDB database
  78. * @returns {HTMLElement}
  79. */
  80. function searchResult(item) {
  81. let panel_box = document.createElement('div')
  82. panel_box.classList.add('panel_box', 'search', 'animation_slide_right')
  83. panel_box.innerHTML = `
  84. <img class="poster" src="${item.img}">
  85. <div class="panel_box_container">
  86. <h3 class="fs18 tOverflow">${item.title}</h3>
  87. <p class="tOverflow normal">${item.description}</p>
  88. <div class="poster-content">
  89. <div class="poster-content-left">
  90. <img src="../../assets/icons/app/heart.svg">
  91. <span class="fs16">${item.rating}%</span>
  92. </div>
  93. <div class="poster-content-right tC">${item.type}</div>
  94. </div>
  95. </div>
  96. `
  97. return panel_box
  98. }
  99. /**
  100. * Generates the an element for a single poster that is displayed on the up-next dashboard.
  101. * @memberof generators
  102. * @param {Object} item
  103. * @param {String} item.title
  104. * @param {String} item.subtitle
  105. * @param {Number} item.rating
  106. * @param {String} item.id Reference ID for TVDB database
  107. * @param {Number} item.season
  108. * @param {String} item.matcher
  109. * @returns {HTMLElement}
  110. */
  111. function upNextPoster(item) {
  112. let li = document.createElement('li')
  113. li.classList.add('poster', 'poster_dashboard')
  114. li.setAttribute('data_title', item.title)
  115. li.setAttribute('data_subtitle', item.subtitle)
  116. li.setAttribute('onmouseover', 'animateText(this, true)')
  117. li.setAttribute('onmouseleave', 'animateText(this, false)')
  118. let posterTile = document.createElement('div')
  119. posterTile.classList.add('hidden')
  120. posterTile.innerHTML = `
  121. <div class="poster_tile shadow_h">
  122. <div class="poster_rating">
  123. <img src="../../assets/icons/app/heart.svg"><span class="fw700 white_t">${Math.round(item.rating*10)}%</span>
  124. </div>
  125. ${actionButtons(item.matcher, 'poster')}
  126. </div>
  127. `
  128. li.appendChild(posterTile)
  129. requestAndLoadImage({
  130. parent: li,
  131. use: 'poster',
  132. type: 'season',
  133. itemId: item.id,
  134. reference: item.season,
  135. classes: ['shadow_h', 'z1'],
  136. attributes: {
  137. 'style': 'cursor:pointer',
  138. 'onclick': 'openInfoCard(this)',
  139. 'data_matcher': item.matcher
  140. }
  141. }, () => {
  142. posterTile.classList.remove('hidden')
  143. })
  144. return li
  145. }
  146. /**
  147. * Generates html-string used for the title block on the up-next dashboard.
  148. * @memberof generators
  149. * @param {Object} item
  150. * @param {String} item.title
  151. * @param {String} item.subtitle
  152. * @returns {String}
  153. */
  154. function upNextTitle(item) {
  155. let html = `
  156. <h3 class="h3 red_t tu">
  157. up next to watch
  158. </h3>
  159. <h1 class="h1 white_t tu tOverflow">
  160. ${item.title}
  161. </h1>
  162. <h1 class="h1 white_d_t tOverflow">
  163. ${item.subtitle}
  164. </h1>
  165. `
  166. return html
  167. }
  168. /**
  169. * Generates html-string containing the action buttons.
  170. * It contains three main buttons that are styled depending on the type.
  171. * @memberof generators
  172. * @param {String} matcher
  173. * @param {'poster'|'card'} modal
  174. * @returns {String}
  175. */
  176. function actionButtons(matcher, modal) {
  177. let q = "'"
  178. let html = `
  179. <div class="action_btns">
  180. <div class="action_btn play tu elmHover" onclick="playNow(this, ${q+matcher+q}, ${q+modal+q})"></div>
  181. <div class="action_btn watchlist tu elmHover" onclick="addToWatchlist(this, ${q+matcher+q}, ${q+modal+q})"></div>
  182. <div class="action_btn history tu elmHover" onclick="addToHistory(this, ${q+matcher+q}, ${q+modal+q})"></div>
  183. </div>
  184. `
  185. return html
  186. }
  187. /**
  188. * Generates element used for an alert box with a yes/no option.
  189. * Takes a callback that allows different actions depending on the clicked button.
  190. * @memberof generators
  191. * @param {Object} options Data to render in the alert box
  192. * @param {String} options.title
  193. * @param {String} options.description
  194. * @param {String} options.acceptButtonText
  195. * @param {String} options.declineButtonText
  196. * @param {Function} proceed Callback function for button clicks
  197. * @returns {HTMLElement}
  198. */
  199. function confirmActionAlertBox(options, proceed) {
  200. let box = document.createElement('div')
  201. box.classList = 'alertBox black_b shadow_h'
  202. box.innerHTML = `
  203. <h4 class="fs23 fw700 white_t">${options.title}</h4>
  204. <p class="fs18 fw200 white_d_t" style="margin-bottom:10px">${options.description}</p>
  205. <div class="alert_btns"></div>
  206. `
  207. let close = document.createElement('div')
  208. close.classList = 'btn-close black_d_b elmHover'
  209. close.innerHTML = `<img src="../../assets/icons/app/close.svg">`
  210. close.onclick = function() { proceed(false) }
  211. box.appendChild(close)
  212. let buttons = box.getElementsByClassName('alert_btns')[0]
  213. let accept = document.createElement('div')
  214. accept.classList = 'alert_btn red_b white_t elmHover'
  215. accept.innerText = options.acceptButtonText
  216. accept.onclick = function() { proceed(true) }
  217. buttons.appendChild(accept)
  218. let decline = document.createElement('div')
  219. decline.classList = 'alert_btn black_d_b white_t elmHover'
  220. decline.innerHTML = options.declineButtonText
  221. decline.onclick = function() { proceed(false) }
  222. buttons.appendChild(decline)
  223. return box
  224. }