Mayx's Home Page
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
7.4 KiB

  1. ---
  2. layout: default
  3. ---
  4. <small><time class="date dt-published" datetime="{{ page.date | date_to_xmlschema }}">{{ page.date | date: "%-d %B %Y" }}</time> - 字数统计:{% if page.layout == "encrypt" %}God Knows {% else %}{{ page.content | strip_html | strip_newlines | remove: " " | size }} - 阅读大约需要{{ page.content | strip_html | strip_newlines | remove: "" | size | divided_by: 350 | plus: 1 }}分钟{% endif %} - Hits: <span id="{{ page.url }}" class="visitors">Loading...</span></small>
  5. <h1 class="p-name">{{ page.title }}</h1>
  6. <p class="view">by <a class="p-author h-card" href="//github.com/{{ page.author | default: "Mabbs" }}">{{ page.author | default: site.author }}</a></p>
  7. <div id="outdate" style="display:none;">
  8. <hr /><p>
  9. 这是一篇创建于 <span id="outime"></span> 天前的文章,其中的信息可能已经有所发展或是发生改变。
  10. </p>
  11. </div>
  12. <script>
  13. daysold = Math.floor((new Date().getTime() - new Date("{{ page.date | date_to_rfc822 }}").getTime()) / (24 * 60 * 60 * 1000));
  14. if (daysold > 90) {
  15. document.getElementById("outdate").style.display = "block";
  16. document.getElementById("outime").innerHTML = daysold;
  17. }
  18. </script>
  19. <hr />
  20. {% if page.layout != "encrypt" %}
  21. <b>AI摘要</b>
  22. <p id="ai-output">{% assign ai_cache = site.data.ai-cache[page.url] %}{% if ai_cache %}{{ ai_cache }}{% else %}正在生成中……{% endif %}</p>
  23. {% unless ai_cache %}
  24. <!--[if IE]>
  25. <script>document.getElementById("ai-output").innerHTML="这个文章的AI摘要还没有缓存……IE看不了哦~";</script>
  26. <![endif]-->
  27. <!--[if !IE]> -->
  28. <script>
  29. async function sha(str) {
  30. const encoder = new TextEncoder();
  31. const data = encoder.encode(str);
  32. const hashBuffer = await crypto.subtle.digest("SHA-256", data);
  33. const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array
  34. const hashHex = hashArray
  35. .map((b) => b.toString(16).padStart(2, "0"))
  36. .join(""); // convert bytes to hex string
  37. return hashHex;
  38. }
  39. async function ai_gen(){
  40. var postContent = "文章标题:" + {{ page.title | jsonify }} + ";文章内容:" + {{ page.content | strip_html | strip_newlines | jsonify }};
  41. var postContentSign = await sha(postContent);
  42. var outputContainer = document.getElementById("ai-output");
  43. $.get(BlogAPI + "/is_uploaded?id={{ page.url }}&sign=" + postContentSign, function (data) {
  44. if (data == "yes") {
  45. $.get(BlogAPI + "/get_summary?id={{ page.url }}&sign=" + postContentSign, function (data2) {
  46. outputContainer.textContent = data2;
  47. });
  48. } else {
  49. $.post(BlogAPI + "/upload_blog?id={{ page.url }}", postContent, function (data) {
  50. $.get(BlogAPI + "/get_summary?id={{ page.url }}&sign=" + postContentSign);
  51. const evSource = new EventSource(BlogAPI + "/summary?id={{ page.url }}");
  52. outputContainer.textContent = "";
  53. evSource.onmessage = (event) => {
  54. if (event.data == "[DONE]") {
  55. evSource.close();
  56. return;
  57. } else {
  58. const data = JSON.parse(event.data);
  59. if (data.response) {
  60. outputContainer.textContent += data.response;
  61. }
  62. }
  63. }
  64. });
  65. }
  66. });
  67. }
  68. ai_gen();
  69. </script>
  70. <!-- <![endif]-->
  71. {% endunless %}
  72. <hr />
  73. {% endif %}
  74. {% if page.layout != "encrypt" %}
  75. {% include toc.html html=content sanitize=true h_max=3 %}
  76. <hr />
  77. {% endif %}
  78. {% if page.layout == "encrypt" %} {{content}} {% else %} <main class="post-content e-content" role="main">{% capture a_post_content %}{% include anchor_headings.html html=content beforeHeading=true anchorBody="<svg class='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='32' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>" %}{% endcapture %}{{ a_post_content | replace: '<br />', '</p><p>' }}</main> {% endif %}
  79. {% if page.tags %}
  80. <small style="display: block">tags: {% for tag in page.tags %}<a rel="category tag" class="p-category" href="/search.html?keyword={{ tag | url_encode | replace: '+', '%20' }}"><em>{{ tag }}</em></a>{% unless forloop.last %} - {% endunless %}{% endfor %} <span style="float: right;"><a href="{% if site.github %}{{ site.github.repository_url }}{% else %}https://gitlab.com/mayx/mayx.gitlab.io{% endif %}/tree/master/{{ page.path }}">查看原始文件</a></span></small>
  81. {% endif %}
  82. {% if page.layout != "encrypt" %}
  83. <h4 style="border-bottom: 1px solid #e5e5e5;margin: 2em 0 5px;">推荐文章</h4>
  84. <p id="suggest-container">Loading...</p>
  85. <script>
  86. var suggest = $("#suggest-container");
  87. $.get(BlogAPI + "/suggest?id={{ page.url }}&update=" + lastUpdated.valueOf(), function (data) {
  88. if (data.length) {
  89. getSearchJSON(function (search) {
  90. suggest.empty();
  91. var searchMap = {};
  92. for (var i = 0; i < search.length; i++) {
  93. searchMap[search[i].url] = search[i];
  94. }
  95. var tooltip = $('<div class="content-tooltip"></div>').appendTo('body').hide();
  96. for (var j = 0; j < data.length; j++) {
  97. var item = searchMap[data[j].id];
  98. if (item) {
  99. var link = $('<a href="' + item.url + '">' + item.title + '</a>');
  100. var contentPreview = item.content.substring(0, 100);
  101. if (item.content.length > 100) {
  102. contentPreview += "……";
  103. }
  104. link.hover(
  105. function(e) {
  106. tooltip.text($(this).data('content'))
  107. .css({
  108. top: e.pageY + 10,
  109. left: e.pageX + 10
  110. })
  111. .show();
  112. },
  113. function() {
  114. tooltip.hide();
  115. }
  116. ).mousemove(function(e) {
  117. tooltip.css({
  118. top: e.pageY + 10,
  119. left: e.pageX + 10
  120. });
  121. }).data('content', contentPreview);
  122. suggest.append(link);
  123. suggest.append(' - ' + item.date + '<br />');
  124. }
  125. }
  126. });
  127. } else {
  128. suggest.html("暂无推荐文章……");
  129. }
  130. });
  131. </script>
  132. {% endif %}
  133. <br />
  134. <div class="pagination">
  135. {% if page.previous.url %}
  136. <span class="prev">
  137. <a href="{{ page.previous.url | relative_url }}">
  138. 上一篇:{{ page.previous.title }}
  139. </a>
  140. </span>
  141. {% endif %}
  142. <br />
  143. {% if page.next.url %}
  144. <span class="next">
  145. <a href="{{ page.next.url | relative_url }}">
  146. 下一篇:{{ page.next.title }}
  147. </a>
  148. </span>
  149. {% endif %}
  150. </div>
  151. <!--[if !IE]> -->
  152. <link rel="stylesheet" href="/assets/css/gitalk.css">
  153. <script src="/assets/js/gitalk.min.js"></script>
  154. <div id="gitalk-container"></div>
  155. <script>
  156. var gitalk = new Gitalk({
  157. clientID: '36557aec4c3cb04f7ac6',
  158. clientSecret: 'ac32993299751cb5a9ba81cf2b171cca65879cdb',
  159. repo: 'mabbs.github.io',
  160. owner: 'Mabbs',
  161. admin: ['Mabbs'],
  162. id: '{{ page.id }}', // Ensure uniqueness and length less than 50
  163. distractionFreeMode: false, // Facebook-like distraction free mode
  164. proxy: "https://cors-anywhere.mayx.eu.org/?https://github.com/login/oauth/access_token"
  165. })
  166. gitalk.render('gitalk-container')
  167. </script>
  168. <!-- <![endif]-->