diff options
| -rw-r--r-- | config/_default/params.yaml | 2 | ||||
| -rw-r--r-- | content/posts/weekly/50.md | 14 | ||||
| -rw-r--r-- | content/posts/weekly/51.md | 24 | ||||
| -rw-r--r-- | layouts/_partials/posts/action-menu.html | 8 | ||||
| -rw-r--r-- | layouts/_partials/posts/action-menu/comment-button.html | 65 | ||||
| -rw-r--r-- | layouts/_partials/posts/action-menu/comment-section.html | 8 | ||||
| -rw-r--r-- | layouts/_partials/posts/action-menu/like-button.html | 122 | ||||
| -rw-r--r-- | layouts/_partials/scripts.html | 8 | ||||
| -rw-r--r-- | layouts/_partials/scripts/action-menu-js.html | 205 | ||||
| -rw-r--r-- | layouts/_partials/scripts/littlefoot-js.html | 1 |
10 files changed, 224 insertions, 233 deletions
diff --git a/config/_default/params.yaml b/config/_default/params.yaml index 896c5714..bd3a3f87 100644 --- a/config/_default/params.yaml +++ b/config/_default/params.yaml @@ -5,8 +5,6 @@ mainSections: - fictions - library favicon: /favicon.png -externalJSFIles: - - /js/littlefoot.js footerExternalLinks: - name: GitHub link: https://github.com/BigCoke233/geek-death-project diff --git a/content/posts/weekly/50.md b/content/posts/weekly/50.md index 29259cce..4e075567 100644 --- a/content/posts/weekly/50.md +++ b/content/posts/weekly/50.md @@ -8,14 +8,18 @@ tags: - 烹饪 - 生活 categories: 稻草人周刊 -date: 2025-10-11T23:32:00 -draft: true +date: 2025-10-13T08:36:00 +draft: false toc: true -banner: -endnotes: --- +{{< music cover="https://image.guhub.cn/uPic/2025/10/Where_Is_My_Husband!_-_Raye.png" title="WHERE IS MY HUSBAND!" artist="Raye" apple="https://music.apple.com/cn/album/where-is-my-husband/1838737596?i=1838737598" spotify="https://open.spotify.com/album/01sqwTOTrN9gaYQc1rr6Zw" netease="https://music.163.com/#/song?id=2747347844" >}} +> Baby, where the hell is my husband? +> +> What is taking him so long to find me? + +很癫很饿的一首歌。看完歌词我突然意识到,在如今的流行歌曲里,「Baby」俨然成为了一个没有实意的感叹词,算是很有意思的语言现象。 <!--more--> @@ -137,5 +141,3 @@ main { #烹饪 #生活 -## ⁂ · 星群 - diff --git a/content/posts/weekly/51.md b/content/posts/weekly/51.md new file mode 100644 index 00000000..c23e50ea --- /dev/null +++ b/content/posts/weekly/51.md @@ -0,0 +1,24 @@ +--- +title: 稻草人周刊 Vol. 51 +subtitle: +tags: +categories: 稻草人周刊 +date: 2025-10-13T09:19:00 +draft: true +toc: true +--- + +{{< music cover="https://image.guhub.cn/uPic/2025/10/Where_Is_My_Husband!_-_Raye.png" title="WHERE IS MY HUSBAND!" artist="Raye" apple="https://music.apple.com/cn/album/where-is-my-husband/1838737596?i=1838737598" spotify="https://open.spotify.com/album/01sqwTOTrN9gaYQc1rr6Zw" netease="https://music.163.com/#/song?id=2747347844" >}} + + +<!--more--> + +--- + +## ↯ · 当下 + +- 把 IntelliJ IDEA 卸载了,一方面是它真的太重了,另一方面是最近写代码的时候遇到好几个莫名其妙的问题,完全不知道怎么排查。如果不用图形界面的话,就完全不会有这些问题,所以我就全面转向 Zed 编辑器和命令行工具了。自己需要写 Java 代码的时间其实相对较少,用得更多的语言是 JavaScript、Lua 还有偶尔的 Go 语言,这些语言我都能够用一个简单轻量的编辑器,加上本身就足够好用、清晰的命令行工具搭建开发环境。 + + 明明 Spring Boot 的 `mvn spring-boot:run` 和 JavaScript 的 `npm run dev` 一样好用,命令行排查问题也更方便、加载速度也更快,真不知道为什么非要用一个又贵又难用的图形界面工具。 + +## ⋈︎ · 连接 diff --git a/layouts/_partials/posts/action-menu.html b/layouts/_partials/posts/action-menu.html index fed2def8..ae19873a 100644 --- a/layouts/_partials/posts/action-menu.html +++ b/layouts/_partials/posts/action-menu.html @@ -8,11 +8,5 @@ {{ partial "posts/action-menu/info-links" . }} </div> <!-- Like Count Display --> - <div id="organ-farm" class="flex flex-wrap gap-4 hidden animate-duration-200"></div> - <!-- Comment Section --> - <div class="overflow-hidden my-4"> - <div class="mt-4 hidden animate-duration-200" id="comments-section"> - {{ partial "posts/comment.html" . }} - </div> - </div> + {{ partial "posts/action-menu/comment-section" . }} </div> diff --git a/layouts/_partials/posts/action-menu/comment-button.html b/layouts/_partials/posts/action-menu/comment-button.html index bc079a4f..d646ca27 100644 --- a/layouts/_partials/posts/action-menu/comment-button.html +++ b/layouts/_partials/posts/action-menu/comment-button.html @@ -5,3 +5,68 @@ class="brightness-40 flex-shrink-0 dark:brightness-70 dark:contrast-120" /> <span class="text-xs font-bold text-gray-600 min-w-4 text-center bg-white/90 rounded-xl px-1.5 py-0.5 shadow-sm dark:text-gray-400 dark:bg-black/70" id="comment-count">...</span> </button> + +<script> +// initialize button features and comment count +document.addEventListener('DOMContentLoaded', () => { + + function initButtonFeature() { + const commentsToggle = document.getElementById('comments-toggle'); + const commentsSection = document.getElementById('comments-section'); + + if (!commentsToggle || !commentsSection) return; + + // click on toggle + commentsToggle.addEventListener('click', function() { + const isHidden = commentsSection.classList.contains('hidden'); + const entranceAnimation = 'animate-slide-in-down'; + const exitAnimation = 'animate-slide-out-up'; + + if (isHidden) { + // swtich on + commentsSection.classList.remove('hidden', exitAnimation); + commentsSection.classList.add(entranceAnimation); + } else { + // switch off + commentsSection.classList.remove(entranceAnimation); + commentsSection.classList.add(exitAnimation); + setTimeout(() => { + commentsSection.classList.add('hidden'); + }, 200); + } + }); + } + + function initCommentCount() { + const commentCountEl = document.getElementById('comment-count'); + if (!commentCountEl) return; + + const observer = new MutationObserver(() => { + // check if giscus is loaded + const giscusIframe = document.querySelector('iframe.giscus-frame'); + if (!giscusIframe) return; + + giscusIframe.addEventListener('load', () => { + // receive message from giscus iframe + window.addEventListener('message', function(event) { + if (event.origin !== 'https://giscus.app') return; + const giscusData = event.data; + if (giscusData.giscus?.discussion) { + const discussion = giscusData.giscus.discussion; + const totalComments = (discussion.totalCommentCount || 0) + (discussion.totalReplyCount || 0); + // set comment count + commentCountEl.textContent = totalComments.toString(); + // if no discussion found, set to 0 + } else commentCountEl.textContent = '0'; + }); + }); + + observer.disconnect(); + }); + observer.observe(document.body, { childList: true, subtree: true }); + } + + initButtonFeature(); + initCommentCount(); +}); +</script> diff --git a/layouts/_partials/posts/action-menu/comment-section.html b/layouts/_partials/posts/action-menu/comment-section.html new file mode 100644 index 00000000..be99487a --- /dev/null +++ b/layouts/_partials/posts/action-menu/comment-section.html @@ -0,0 +1,8 @@ +<!-- Comment Count Display --> +<div id="organ-farm" class="flex flex-wrap gap-4 hidden animate-duration-200"></div> +<!-- Comment Section --> +<div class="overflow-hidden my-4"> + <div class="mt-4 hidden animate-duration-200" id="comments-section"> + {{ partial "posts/comment.html" . }} + </div> +</div> diff --git a/layouts/_partials/posts/action-menu/like-button.html b/layouts/_partials/posts/action-menu/like-button.html index c4c50c91..c9e793b8 100644 --- a/layouts/_partials/posts/action-menu/like-button.html +++ b/layouts/_partials/posts/action-menu/like-button.html @@ -1,17 +1,18 @@ +{{ $pageID := .File.UniqueID | urlize }} <!-- 点赞按钮 --> -<div class="relative" id="like-container-{{ .File.UniqueID | urlize }}"> +<div class="relative" id="like-container-{{ $pageID }}"> <button class="dark:invert flex items-center justify-center gap-1.5 min-w-12 h-12 px-2 border-none bg-transparent text-gray-600 cursor-pointer relative transition-all duration-200 hover:bg-black/5 hover:rounded-lg group animate-count-infinite" - onclick="sendLike('{{ .File.UniqueID | urlize }}')" - id="like-btn-{{ .File.UniqueID | urlize }}" + onclick="sendLike('{{ $pageID }}')" + id="like-btn-{{ $pageID }}" title="{{ T "actionMenu.like" }}" data-liked-title="{{ T "actionMenu.liked" }}" data-tooltip> <img src="/img/heart-organ.svg" width="20" height="20" alt="{{ T "actionMenu.like" }}" - class="brightness-40 flex-shrink-0 transition-all duration-300 dark:brightness-70 dark:contrast-120" id="like-icon-{{ .File.UniqueID | urlize }}" /> - <span class="text-xs font-bold text-gray-600 min-w-4 text-center bg-white/90 rounded-xl px-1.5 py-0.5 shadow-sm dark:text-gray-400 dark:bg-black/70" id="like-count-{{ .File.UniqueID | urlize }}">...</span> + class="brightness-40 flex-shrink-0 transition-all duration-300 dark:brightness-70 dark:contrast-120" id="like-icon-{{ $pageID }}" /> + <span class="text-xs font-bold text-gray-600 min-w-4 text-center bg-white/90 rounded-xl px-1.5 py-0.5 shadow-sm dark:text-gray-400 dark:bg-black/70" id="like-count-{{ $pageID }}">...</span> </button> </div> @@ -24,3 +25,114 @@ color: #8B0000 !important; } </style> + +<script> +document.addEventListener('DOMContentLoaded', () => { + // get page ID to fetch and update like data + const pageId = "{{ $pageID }}"; + + // get required elements + const elements = { + count: document.getElementById("like-count-" + pageId), + btn: document.getElementById("like-btn-" + pageId), + container: document.getElementById("like-container-" + pageId), + icon: document.getElementById("like-icon-" + pageId) + }; + + // return if no page ID found or not in production or no elements + if ( + !pageId || window.location.host !== 'www.geedea.pro' || + !elements.count || !elements.btn || !elements.container + ) return; + + function setLikedState() { + // update classes + elements.icon?.classList.add('liked-heart'); + elements.icon?.classList.add('animate-heart-beat'); + elements.count?.classList.add('liked-count'); + elements.btn.disabled = true; + elements.container.classList.add('liked'); + // update tooltip + elements.btn.setAttribute('title', + elements.container.classList.contains('liked') + ? elements.btn.getAttribute('data-liked-title') + : '为这篇文章献上心脏' + ); + } + + async function fetchLikes() { + try { + const response = await fetch("https://like.guhub.cn/like/" + pageId); + const data = await response.json(); + elements.count.innerText = data.likes ?? 0; + if (localStorage.getItem("liked_" + pageId)) { + setLikedState(); + updateOrganFarm(data.likes); + } + } catch(e) { + console.log(e); + elements.count.innerText = "❌"; + } + } + + window.sendLike = async function(pageId) { + if (localStorage.getItem("liked_" + pageId)) return; + + try { + const response = await fetch("https://like.guhub.cn/like/" + pageId, { method: "POST" }); + const data = await response.json(); + localStorage.setItem("liked_" + pageId, "1"); + elements.count.innerText = data.likes ?? 1; + updateOrganFarm(data.likes); + setLikedState(); + } catch(e) { + console.log(e); + alert("点赞失败,请稍后再试"); + } + }; + + function updateOrganFarm(count) { + const organFarm = document.getElementById("organ-farm"); + const organCount = count || parseInt(elements.count.innerText); + const organImages = [ + "https://image.guhub.cn/picgo2025/oragn-3.png", + "https://image.guhub.cn/picgo2025/organ-1.png", + "https://image.guhub.cn/picgo2025/organ-2.png" + ]; + + if (!organFarm) return; + if (organFarm.classList.contains("hidden")) { + organFarm.classList.remove("hidden"); + organFarm.classList.add("animate-slide-in-down"); + } + + organFarm.innerHTML = ""; + for (let i = 0; i < organCount; i++) { + const img = document.createElement("img"); + img.className = "transition hover:scale-150 dark:invert"; + + const sizeRange = [6, 10]; + const size = Math.floor(Math.random() * (sizeRange[1] - sizeRange[0] + 1)) + sizeRange[0]; + img.classList.add(`w-${size}`, `h-${size}`); + + img.src = organImages[Math.floor(Math.random() * organImages.length)]; + // randomly offset and rotate + img.classList.add("rotate-" + Math.floor(Math.random() * 5)); + img.classList.add("translate-x-" + Math.floor(Math.random() * 5)); + img.classList.add("translate-y-" + Math.floor(Math.random() * 5)); + img.classList.add("opacity" + (100 - Math.floor(Math.random() * 3)*10)); + + organFarm.appendChild(img); + } + } + + // fetch likes when action menu is visible + const observer = new IntersectionObserver((entries, obs) => { + if (entries[0].isIntersecting) { + fetchLikes(); + obs.disconnect(); + } + }); + observer.observe(document.getElementById("action-menu")); +}); +</script> diff --git a/layouts/_partials/scripts.html b/layouts/_partials/scripts.html index 2b84ea3c..bc43802d 100644 --- a/layouts/_partials/scripts.html +++ b/layouts/_partials/scripts.html @@ -6,15 +6,7 @@ <script>{{ .Content | safeJS }}</script> {{ end }} -{{- range .Site.Params.externalJSFiles }} - <script src="{{ $.Site.Params.staticPrefix }}{{ . | relURL }}"></script> -{{- end }} - {{ partial "scripts/toc-js" . }} {{ partial "scripts/littlefoot-js" . }} {{ partial "scripts/libra-js" . }} {{ partial "scripts/aplayer-js" . }} - -{{ if .File }} - {{ partial "scripts/action-menu-js" (.File.UniqueID | urlize) }} -{{ end }} diff --git a/layouts/_partials/scripts/action-menu-js.html b/layouts/_partials/scripts/action-menu-js.html deleted file mode 100644 index df1c498c..00000000 --- a/layouts/_partials/scripts/action-menu-js.html +++ /dev/null @@ -1,205 +0,0 @@ -{{ $pageId := . }} -<script defer> -/** - * ================= - * Initialize all Action Menu features - * - comment toggle - * - comment count - * - like - * ================= - */ - -/** - * ================= - * Toggle Comment Section - * ================= - */ - -function initializeComments() { - const commentsToggle = document.getElementById('comments-toggle'); - const commentsSection = document.getElementById('comments-section'); - - if (!commentsToggle || !commentsSection) return; - - // click on toggle - commentsToggle.addEventListener('click', function() { - const isHidden = commentsSection.classList.contains('hidden'); - const entranceAnimation = 'animate-slide-in-down'; - const exitAnimation = 'animate-slide-out-up'; - - if (isHidden) { - // swtich on - commentsSection.classList.remove('hidden', exitAnimation); - commentsSection.classList.add(entranceAnimation); - } else { - // switch off - commentsSection.classList.remove(entranceAnimation); - commentsSection.classList.add(exitAnimation); - setTimeout(() => { - commentsSection.classList.add('hidden'); - }, 200); - } - }); -} - -/** - * ================= - * Fetch and set Comment Count - * ================= - */ - -function initializeCommentCount() { - const commentCountEl = document.getElementById('comment-count'); - if (!commentCountEl) return; - - const observer = new MutationObserver(() => { - // check if giscus is loaded - const giscusIframe = document.querySelector('iframe.giscus-frame'); - if (!giscusIframe) return; - - giscusIframe.addEventListener('load', () => { - // receive message from giscus iframe - window.addEventListener('message', function(event) { - if (event.origin !== 'https://giscus.app') return; - const giscusData = event.data; - if (giscusData.giscus?.discussion) { - const discussion = giscusData.giscus.discussion; - const totalComments = (discussion.totalCommentCount || 0) + (discussion.totalReplyCount || 0); - // set comment count - commentCountEl.textContent = totalComments.toString(); - // if no discussion found, set to 0 - } else commentCountEl.textContent = '0'; - }); - }); - - observer.disconnect(); - }); - observer.observe(document.body, { childList: true, subtree: true }); -} - -/** - * ================= - * Initialize like functionality - * ================= - */ - -function initializeLikes(pageId) { - if (window.location.host !== 'www.geedea.pro') return; - - const elements = { - count: document.getElementById("like-count-" + pageId), - btn: document.getElementById("like-btn-" + pageId), - container: document.getElementById("like-container-" + pageId), - icon: document.getElementById("like-icon-" + pageId) - }; - - if (!elements.count || !elements.btn || !elements.container) return; - - function setLikedState() { - // update classes - elements.icon?.classList.add('liked-heart'); - elements.icon?.classList.add('animate-heart-beat'); - elements.count?.classList.add('liked-count'); - elements.btn.disabled = true; - elements.container.classList.add('liked'); - // update tooltip - elements.btn.setAttribute('title', - elements.container.classList.contains('liked') - ? elements.btn.getAttribute('data-liked-title') - : '为这篇文章献上心脏' - ); - } - - async function fetchLikes() { - try { - const response = await fetch("https://like.guhub.cn/like/" + pageId); - const data = await response.json(); - elements.count.innerText = data.likes ?? 0; - if (localStorage.getItem("liked_" + pageId)) { - setLikedState(); - updateOrganFarm(data.likes); - } - } catch(e) { - console.log(e); - elements.count.innerText = "❌"; - } - } - - window.sendLike = async function(pageId) { - if (localStorage.getItem("liked_" + pageId)) return; - - try { - const response = await fetch("https://like.guhub.cn/like/" + pageId, { method: "POST" }); - const data = await response.json(); - localStorage.setItem("liked_" + pageId, "1"); - elements.count.innerText = data.likes ?? 1; - updateOrganFarm(data.likes); - setLikedState(); - } catch(e) { - console.log(e); - alert("点赞失败,请稍后再试"); - } - }; - - function updateOrganFarm(count) { - const organFarm = document.getElementById("organ-farm"); - const organCount = count || parseInt(elements.count.innerText); - const organImages = [ - "https://image.guhub.cn/picgo2025/oragn-3.png", - "https://image.guhub.cn/picgo2025/organ-1.png", - "https://image.guhub.cn/picgo2025/organ-2.png" - ]; - - if (!organFarm) return; - if (organFarm.classList.contains("hidden")) { - organFarm.classList.remove("hidden"); - organFarm.classList.add("animate-slide-in-down"); - } - - organFarm.innerHTML = ""; - for (let i = 0; i < organCount; i++) { - const img = document.createElement("img"); - img.className = "transition hover:scale-150 dark:invert"; - - const sizeRange = [6, 10]; - const size = Math.floor(Math.random() * (sizeRange[1] - sizeRange[0] + 1)) + sizeRange[0]; - img.classList.add(`w-${size}`, `h-${size}`); - - img.src = organImages[Math.floor(Math.random() * organImages.length)]; - // randomly offset and rotate - img.classList.add("rotate-" + Math.floor(Math.random() * 5)); - img.classList.add("translate-x-" + Math.floor(Math.random() * 5)); - img.classList.add("translate-y-" + Math.floor(Math.random() * 5)); - img.classList.add("opacity" + (100 - Math.floor(Math.random() * 3)*10)); - - organFarm.appendChild(img); - } - } - - // fetch likes when action menu is visible - const observer = new IntersectionObserver((entries, obs) => { - if (entries[0].isIntersecting) { - fetchLikes(); - obs.disconnect(); - } - }); - observer.observe(document.getElementById("action-menu")); -} - -/** - * ================= - * Load features after DOMContentLoaded - * ================= - */ - -function initializeFeatures() { - const pageId = "{{ $pageId }}"; - if (!pageId) return; - - initializeComments(); - initializeLikes(pageId); - initializeCommentCount(); -} - -document.addEventListener('DOMContentLoaded', initializeFeatures); -</script> diff --git a/layouts/_partials/scripts/littlefoot-js.html b/layouts/_partials/scripts/littlefoot-js.html index 69c9ce14..8ce2b721 100644 --- a/layouts/_partials/scripts/littlefoot-js.html +++ b/layouts/_partials/scripts/littlefoot-js.html @@ -1,3 +1,4 @@ +<script src="/js/littlefoot.js"></script> <script> littlefoot.littlefoot({ dismissOnUnhover: true, |
