archive.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <?php
  2. requirePHPLib('form');
  3. if (!UOJContext::userid())
  4. $blogs_cond = "is_draft = false";
  5. else
  6. $blogs_cond = "poster = '".UOJContext::userid()."' and is_draft = false";
  7. if (!UOJContext::hasBlogPermission()) {
  8. $blogs_cond .= " and is_hidden = false";
  9. }
  10. $display_blogs_cond = $blogs_cond;
  11. if (isset($_GET['tag'])) {
  12. $blog_tag_required = $_GET['tag'];
  13. $display_blogs_cond .= " and '".DB::escape($blog_tag_required)."' in (select tag from blogs_tags where blogs_tags.blog_id = blogs.id)";
  14. } else {
  15. $blog_tag_required = null;
  16. }
  17. $blogs_pag = new Paginator(array(
  18. 'col_names' => array('*'),
  19. 'table_name' => 'blogs',
  20. 'cond' => $display_blogs_cond,
  21. 'tail' => 'order by post_time desc',
  22. 'page_len' => 10
  23. ));
  24. $all_tags = DB::selectAll("select distinct tag from blogs_tags where blog_id in (select id from blogs where $blogs_cond)");
  25. requireLib('mathjax');
  26. requireLib('hljs');
  27. ?>
  28. <?php echoUOJPageHeader('日志') ?>
  29. <div class="row">
  30. <div class="col-md-3">
  31. <?php if (UOJContext::hasBlogPermission()): ?>
  32. <div class="btn-group d-flex">
  33. <a href="<?=HTML::blog_url(UOJContext::userid(), '/post/new/write')?>" class="btn btn-primary"><span class="glyphicon glyphicon-edit"></span> 写新博客</a>
  34. <a href="<?=HTML::blog_url(UOJContext::userid(), '/slide/new/write')?>" class="btn btn-primary"><span class="glyphicon glyphicon-edit"></span> 写新幻灯片</a>
  35. </div>
  36. <?php endif ?>
  37. <div class="card border-info top-buffer-sm">
  38. <div class="card-header bg-info">标签</div>
  39. <div class="card-body">
  40. <?php if ($all_tags): ?>
  41. <?php foreach ($all_tags as $tag): ?>
  42. <?php echoBlogTag($tag['tag']) ?>
  43. <?php endforeach ?>
  44. <?php else: ?>
  45. <div class="text-muted">暂无</div>
  46. <?php endif ?>
  47. </div>
  48. </div>
  49. </div>
  50. <div class="col-md-9 blog-list">
  51. <?php if (!$blog_tag_required): ?>
  52. <?php if ($blogs_pag->isEmpty()): ?>
  53. <div class="text-muted">此人很懒,什么博客也没留下。</div>
  54. <?php else: ?>
  55. <?php foreach ($blogs_pag->get() as $blog): ?>
  56. <?php echoBlog($blog, array('is_preview' => true)) ?>
  57. <?php endforeach ?>
  58. <div class="text-right text-muted" style="display: none;">共 <?= $blogs_pag->n_rows ?> 篇博客</div>
  59. <?php endif ?>
  60. <?php else: ?>
  61. <?php if ($blogs_pag->isEmpty()): ?>
  62. <div class="alert alert-danger">
  63. 没有找到包含 “<?= HTML::escape($blog_tag_required) ?>” 标签的博客:
  64. </div>
  65. <?php else: ?>
  66. <div class="alert alert-success" style="">
  67. 共找到 <?= $blogs_pag->n_rows ?> 篇包含 “<?= HTML::escape($blog_tag_required) ?>” 标签的博客:
  68. </div>
  69. <?php foreach ($blogs_pag->get() as $blog): ?>
  70. <?php echoBlog($blog, array('is_preview' => true)) ?>
  71. <?php endforeach ?>
  72. <?php endif ?>
  73. <?php endif ?>
  74. </div>
  75. <script>
  76. (function () {
  77. let currentPage = 1, isLoading = false, hasMore = true;
  78. const blogList = document.querySelector('.blog-list');
  79. const itemSelector = '.blog-item';
  80. const tag = (new URLSearchParams(window.location.search)).get('tag');
  81. if (blogList.querySelectorAll('.blog-item').length < 10)
  82. hasMore = false;
  83. function extractSummary(html) {
  84. const div = document.createElement('div');
  85. div.innerHTML = html;
  86. let text = div.textContent || div.innerText || '';
  87. text = text.replace(/\s+/g, ' ').trim();
  88. return text;
  89. }
  90. function collapseArticle(post) {
  91. const content = post.querySelector('.blog-content');
  92. const divorig = post.querySelector('.blog-content-orig');
  93. const divsummary = post.querySelector('.blog-content-summary');
  94. let summary = extractSummary(divorig.innerHTML);
  95. const maxLen = 150;
  96. if (summary.length < maxLen) return;
  97. summary = summary.slice(0, maxLen) + '……';
  98. divsummary.innerHTML = summary;
  99. divsummary.style.display = 'block';
  100. divorig.style.display = 'none';
  101. content.classList.add('collapsed');
  102. content.addEventListener('click', () => {
  103. divsummary.style.display = 'none';
  104. divorig.style.display = 'block';
  105. content.classList.remove('collapsed');
  106. content.classList.add('expand');
  107. });
  108. }
  109. document.querySelectorAll('.blog-item').forEach(collapseArticle);
  110. async function loadPage(page) {
  111. if (isLoading || !hasMore) return;
  112. isLoading = true;
  113. const url = !tag ? `/?page=${page}` : `/?page=${page}&tag=${tag}`;
  114. try {
  115. const resp = await fetch(url);
  116. const html = await resp.text();
  117. const parser = new DOMParser();
  118. const doc = parser.parseFromString(html, 'text/html');
  119. const items = doc.querySelectorAll(itemSelector);
  120. if (items.length == 0) {
  121. hasMore = false;
  122. return;
  123. }
  124. items.forEach(item => { blogList.appendChild(item); collapseArticle(item); });
  125. if (items.length < 10)
  126. hasMore = false;
  127. MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
  128. hljs.highlightAll();
  129. $('body').uoj_highlight();
  130. } catch (err) {
  131. console.log('加载失败', err);
  132. } finally {
  133. isLoading = false;
  134. }
  135. }
  136. window.addEventListener('scroll', () => {
  137. const scrollTop = document.documentElement.scrollTop;
  138. const windowHeight = window.innerHeight;
  139. const docHeight = document.documentElement.scrollHeight;
  140. if (scrollTop + windowHeight >= docHeight - 200 && !isLoading && hasMore)
  141. loadPage(++currentPage);
  142. });
  143. })();
  144. </script>
  145. </div>
  146. <?php echoUOJPageFooter() ?>