detail.ejs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <!DOCTYPE html>
  2. <html lang="<%= lang %>">
  3. <head>
  4. <%- include('common-meta') %>
  5. <link rel="stylesheet" href="/stylesheets/styles.css">
  6. <link rel="stylesheet" href="/stylesheets/header.css">
  7. <link rel="stylesheet" href="/stylesheets/detail.css">
  8. <script type="text/javascript"
  9. src="https://platform-api.sharethis.com/js/sharethis.js#property=67e0d66a54a3d000192a4615&product=inline-share-buttons&source=platform"
  10. async="async"></script>
  11. <script type="application/ld+json">
  12. {
  13. "@context": "https://schema.org",
  14. "@type": "CreativeWork",
  15. "name": "<%= translate.printableColoringPage[lang] %>: <%= detail.title %>",
  16. "description": "<%= detail.desc %>",
  17. "url": "https://art.pcoloring.com<%= uri %>",
  18. "image": "<%= detail.thumb %>",
  19. "category": "<%= detail.tags[0] %>",
  20. "keywords": "coloring page, <%= detail.title %>, color by number, paint by number, free, printable, <%= detail.tags.join() %>",
  21. "contentRating": "General Audience",
  22. "mainEntityOfPage": "https://art.pcoloring.com<%= uri %>",
  23. "publisher": {
  24. "@type": "Organization",
  25. "name": "JCCY",
  26. "logo": {
  27. "@type": "ImageObject",
  28. "url": "https://art.pcoloring.com/assets/icon/icon.webp"
  29. }
  30. },
  31. "offers": {
  32. "@type": "Offer",
  33. "priceCurrency": "USD",
  34. "price": "0.00",
  35. "eligibleRegion": {
  36. "@type": "Place",
  37. "name": "Worldwide"
  38. },
  39. "url": "https://art.pcoloring.com<%= uri %>"
  40. },
  41. "author": {
  42. "@type": "Person",
  43. "name": "<%= detail.user.username %>"
  44. },
  45. "datePublished": "<%= detail.publishTime %>"
  46. }
  47. </script>
  48. </head>
  49. <!-- Google tag (gtag.js) -->
  50. <script async src="https://www.googletagmanager.com/gtag/js?id=G-JBGGVGLHTP"></script>
  51. <script>
  52. window.dataLayer = window.dataLayer || [];
  53. function gtag() { dataLayer.push(arguments); }
  54. gtag('js', new Date());
  55. gtag('config', 'G-JBGGVGLHTP');
  56. </script>
  57. <body>
  58. <%- include('header') %>
  59. <div class="details">
  60. <div class="poster"><img src="<%= detail.thumb %>" alt="<%= detail.title %>"></div>
  61. <div class="description">
  62. <div style="display: flex; justify-content: space-between;">
  63. <h1>
  64. <%= detail.title %>
  65. </h1>
  66. <div class="sharethis-inline-share-buttons"></div>
  67. </div>
  68. <% if (detail.totalStartCount> 0) { %>
  69. <div style="color:gray;">
  70. <%=detail.totalStartCount%>
  71. <%= translate.interested[lang] %>
  72. </div>
  73. <% } %>
  74. <p>
  75. <%= translate.artist[lang] %>: <a href="/<%= lang %>/artist/<%= detail.user._id %>"
  76. class="tag-button">
  77. <%= detail.user.username %>
  78. </a>
  79. </p>
  80. <p>
  81. <%= translate.publishTime[lang] %>: <%= detail.publishTime %>
  82. </p>
  83. <p>
  84. <%= translate.tag[lang] %>:
  85. <% detail.tags.forEach(tag=> { %>
  86. <a href="/<%= lang %>/tag/<%= tag %>" class="tag-button">
  87. <%= tag %>
  88. </a>
  89. <% }); %>
  90. </p>
  91. <p>
  92. <%= detail.copy ?? detail.desc %>
  93. </p>
  94. <div class="button-wrapper">
  95. <a href="/play/<%= detail._id %>" class="play-button">
  96. <%= translate.play[lang] %>
  97. </a>
  98. <a id="appBtn" class="play-button" style="background-color: darkolivegreen;">
  99. <%= translate.playOnApp[lang] %>
  100. </a>
  101. <a href="/download/pdf/page/<%= detail._id %>" class="play-button"
  102. style="background-color: lightseagreen;">
  103. <%= translate.download[lang] %>
  104. </a>
  105. <a id="printBtn" onclick="printImage('<%= detail._id %>')" class="play-button"
  106. style="background-color: black;">
  107. <%= translate.print[lang] %>
  108. </a>
  109. </div>
  110. </div>
  111. </div>
  112. <p style=" display: flex; justify-content: center; color: #777; font-size: 18px; font-weight: 500;">
  113. <%= translate.mayYouLike[lang] %>:
  114. </p>
  115. <div class="content" style="margin-bottom: 40px;">
  116. <div class="image-grid">
  117. <% relates.forEach(item=> { %>
  118. <div class="image-card">
  119. <a href="<%= item.uri %>"><img src="<%= item.thumb %>" alt="<%= item.title %>"></a>
  120. <div class="card-title">
  121. <%= item.title %>
  122. </div>
  123. </div>
  124. <% }); %>
  125. </div>
  126. </div>
  127. <!-- <%- include('pagination') %> -->
  128. <script>
  129. function isMobileDevice() {
  130. return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
  131. }
  132. window.onload = function () {
  133. if (isMobileDevice()) {
  134. const printBtn = document.getElementById('printBtn');
  135. printBtn.style.display = 'none'; // 移动端隐藏打印按钮
  136. }
  137. };
  138. document.getElementById('appBtn').addEventListener('click', function () {
  139. const userAgent = navigator.userAgent || navigator.vendor || window.opera;
  140. // Android 检测
  141. if (/android/i.test(userAgent)) {
  142. window.open('https://play.google.com/store/apps/details?id=com.pcoloring.art.puzzle.color.by.number', '_blank');
  143. }
  144. // iOS 检测
  145. else if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
  146. window.open('https://apps.apple.com/gb/app/art-number-coloring-book/id1575480118', '_blank');
  147. }
  148. // 其他操作系统(例如桌面)
  149. else {
  150. // 可以显示一个提示,或者跳转到通用的下载页面
  151. console.log('无法确定操作系统,或者为桌面操作系统');
  152. window.open('https://pcoloring.com/anc/', '_blank');
  153. }
  154. });
  155. async function printImage(id) {
  156. try {
  157. const response = await fetch(`/download/pdf/${id}`);
  158. if (!response.ok) {
  159. throw new Error(`HTTP error! status: ${response.status}`);
  160. }
  161. const pdfBlob = await response.blob();
  162. const pdfUrl = URL.createObjectURL(pdfBlob);
  163. const printWindow = window.open(pdfUrl, '_blank');
  164. printWindow.onload = () => {
  165. printWindow.print();
  166. };
  167. URL.revokeObjectURL(pdfUrl); // 释放 URL 对象
  168. } catch (error) {
  169. console.error('Error printing image:', error);
  170. }
  171. }
  172. </script>
  173. </body>
  174. </html>