diff --git a/hugo.toml b/hugo.toml index 3aadce7c..f045a9bd 100644 --- a/hugo.toml +++ b/hugo.toml @@ -112,6 +112,47 @@ hasCJKLanguage = true avatar = "/image/avatar/tx7.jpg" description = "不以物喜,不以己悲" + # ---------------------------------------------------------------------------- + # 首页搜索配置 (Home Search Configuration) + # ---------------------------------------------------------------------------- + [params.home_search] + enable = true + # 搜索提示小人头像 (Search Mascot Avatar) + mascot = "/emotion/bqb/chijing.png" + # 搜索提示文案 (Search Hint Text) + hint = "点击随笔 开始搜索" + + # 时段问候语 (Time-based Greetings) + [params.home_search.greetings] + morning = "早安呀!新的一天也要元气满满哦 (*/ω\*)" # 6:00 - 11:00 + noon = "干饭人干饭魂!中午记得吃饱饱 🍚" # 11:00 - 14:00 + afternoon = "下午好!摸鱼累了就喝杯茶歇歇吧 🍵" # 14:00 - 18:00 + evening = "晚上好!今天的你辛苦啦,放松一下 🌙" # 18:00 - 22:00 + night = "还在修仙吗?早点睡对皮肤好哦 (。-ω-)zzz" # 22:00 - 6:00 + + # 节日问候语 (Holiday Greetings) - 格式: "MM-DD" = "文案" + # 已包含 2026 年农历节日对应的公历日期 + [params.home_search.holidays] + "01-01" = "元旦快乐!新的一年,新的flag立起来了吗?🎉" + "02-14" = "情人节快乐!愿你身边有人相伴 💖" + "03-08" = "女神节快乐!做自己的女王 👑" + "04-01" = "愚人节快乐!今天的话不要全信哦 🤡" + "05-01" = "劳动节快乐!给忙碌的自己放个假吧 🛠️" + "05-04" = "青年节快乐!永远年轻,永远热泪盈眶 🔥" + "06-01" = "儿童节快乐!谁还不是个宝宝呢 🎈" + "10-01" = "国庆节快乐!享受美好的假期吧 🇨🇳" + "12-25" = "Merry Christmas!圣诞快乐 🎄" + + # 2026 农历节日 (需每年更新) + "02-16" = "除夕快乐!记得吃年夜饭哦 🥟" + "02-17" = "过年好!恭喜发财,红包拿来 🧧" # 春节 + "03-03" = "元宵节快乐!吃汤圆,人团圆 🏮" + "04-05" = "清明安康。🌱" + "06-19" = "端午安康!记得吃粽子 ( ̄~ ̄) �" + "08-19" = "七夕快乐!今晚月色真美 💑" + "09-25" = "中秋快乐!月圆人更圆 🥮" + "10-19" = "重阳节安康!登高望远 🏔️" + # ---------------------------------------------------------------------------- # 留言页面友链申请示例配置 (Message Page Link Exchange Example) # ---------------------------------------------------------------------------- diff --git a/themes/Ying/assets/css/main.css b/themes/Ying/assets/css/main.css index d0be7d31..6a764d70 100644 --- a/themes/Ying/assets/css/main.css +++ b/themes/Ying/assets/css/main.css @@ -554,6 +554,7 @@ ul { flex-direction: column; align-items: stretch; gap: 16px; + text-align: left; /* Reset text align from .main center */ } .header-top { @@ -563,7 +564,7 @@ ul { gap: 16px; } -.head_author_img { +.header-avatar { display: flex; align-items: center; justify-content: center; @@ -630,43 +631,47 @@ ul { margin-bottom: 0; } -.header nav { +/* Updated Header Semantics */ +.header-menu { border-top: 1px solid #f4f4f4; transition: border-color 0.35s ease; } -.header nav ul, -.header nav li { +.header-menu ul, +.header-menu li { margin: 0; } -.header nav ul.flat { +.header-menu ul.flat { padding: 0; + /* Flexbox layout for easier spacing control */ + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 20px; /* [PC Setting] Adjust this value to change spacing between items */ } -.header nav ul.flat li { - display: inline-block; +.header-menu ul.flat li { + display: block; list-style: none; - margin-left: 0; - margin-right: 16px; - margin-top: 20px; + margin: 10px 0 0 0; text-transform: capitalize; } -.header nav ul.flat li.active a { +.header-menu ul.flat li.active a { color: #24292e; } -.header nav ul.flat li a { +.header-menu ul.flat li a { color: #586069; } -.header nav ul.flat li a:hover { +.header-menu ul.flat li a:hover { color: #646464; text-decoration: none; } -.header .site-description { +.header-info { display: flex; flex-direction: column; justify-content: center; @@ -674,32 +679,30 @@ ul { margin-top: 0; } -.header .site-description h2 { - display: none; -} - -.header .site-description nav { +.header-social { margin: 0; padding: 0; border: none; min-width: 50px; margin-bottom: 0; text-align: center; + /* Reset gap for social icons as they rely on margin */ + gap: 0; } -.header .site-description nav ul a { +.header-social a { display: inline-block; margin: 0 5px; text-decoration: none; transition: all 0.2s ease; } -.header .site-description nav ul a i { +.header-social a i { font-size: 1.15rem; vertical-align: middle; } -.header .site-description nav ul a:hover { +.header-social a:hover { color: #24292e; transform: scale(1.2); } @@ -717,23 +720,121 @@ ul { cursor: pointer; display: inline-flex; align-items: center; - gap: 8px; + gap: 3px; transition: all 0.3s ease; margin: 0; /* Reset margin */ + position: relative; /* Ensure wrapper is positioned relative to this */ } -.search-hint { - font-size: 0.75rem; - font-weight: normal; - color: #999; +/* Search Hint Wrapper */ +.search-hint-wrapper { + position: absolute; + left: 100%; + top: 50%; + transform: translateY(-50%) translateX(10px); + display: flex; + align-items: center; + gap: 8px; opacity: 0; - transform: translateX(-10px); - transition: all 0.3s ease; + visibility: hidden; + transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); + pointer-events: none; + z-index: 10; + white-space: nowrap; + margin-left: 10px; } -.section-header.normal-mode:hover .search-hint { +.search-hint-wrapper.visible { opacity: 1; - transform: translateX(0); + visibility: visible; + transform: translateY(-50%) translateX(10px); /* Match the base/hover position */ +} + +.section-header.normal-mode:hover .search-hint-wrapper { + opacity: 1; + visibility: visible; +} + +/* Mascot - Emoticon */ +.search-mascot { + width: 32px; + height: 32px; + object-fit: contain; + /* Remove shadow/border as requested */ + border: none; + box-shadow: none; + filter: none; + animation: mascot-shake 2.5s infinite ease-in-out; + transform-origin: bottom center; +} + +@keyframes mascot-shake { + 0%, 100% { transform: rotate(0deg); } + 10% { transform: rotate(5deg); } + 20% { transform: rotate(-5deg); } + 30% { transform: rotate(3deg); } + 40% { transform: rotate(-3deg); } + 50% { transform: rotate(0deg); } +} + +/* Clean Bubble Style - Mimic .barrage-bubble */ +.search-hint { + background: #000000; /* Pure Black Background */ + color: #ffffff; + padding: 7px 12px; + border-radius: 8px; + font-size: 13px; + font-weight: 600; + line-height: 1.4; + box-shadow: 0 4px 12px rgba(0,0,0,0.2); + border: none; + position: relative; + display: flex; + align-items: center; + height: auto; + min-height: auto; + white-space: nowrap; + width: fit-content; + max-width: none; + margin-top: 1px; + z-index: 10; +} + +/* Arrow - Optimized tip */ +.search-hint::before { + content: ''; + position: absolute; + top: 50%; + left: -5px; + margin-top: -5px; + width: 0; + height: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #000000; /* Match black background */ + background: transparent; + box-shadow: none; + transform: none; + filter: drop-shadow(-2px 0 2px rgba(0,0,0,0.1)); +} + +[data-theme="dark"] .search-hint { + background: #ffffff; /* White background for dark mode contrast */ + color: #000000; + border: none; + box-shadow: 0 4px 15px rgba(0,0,0,0.5); +} + +[data-theme="dark"] .search-hint::before { + background: transparent; + border-right-color: #ffffff; + border-left: none; + border-bottom: 5px solid transparent; + filter: none; +} + +[data-theme="dark"] .search-mascot { + filter: none; } .search-mode { @@ -741,85 +842,150 @@ ul { animation: fadeIn 0.3s ease; } -/* Simplified Search Styles for Essay/Shuoshuo */ +/* Modern Minimalist Search Styles - Bottom Border Only */ .search-input-group { position: relative; display: flex; align-items: center; - width: 100%; - border-bottom: 1px solid rgba(0, 0, 0, 0.1); /* Minimalist bottom border only */ + width: 100%; /* Responsive width */ + max-width: 300px; /* Maximum width for PC */ + border: none; + border-bottom: 1px solid #000000; border-radius: 0; - padding: 2px 0; + padding: 0 4px 6px 0; /* Slightly more bottom padding */ background: transparent; transition: all 0.3s ease; + box-shadow: none; +} + +.search-input-group i { + border: none; /* Ensure icons have no border */ + background: transparent; } .search-input-group:hover { - border-bottom-color: rgba(0, 0, 0, 0.3); background: transparent; + border-bottom-color: #666; } .search-input-group:focus-within { background: transparent; - border-color: transparent; - border-bottom-color: var(--theme-color, #4a90e2); + border-bottom-color: #000; box-shadow: none; - transform: none; } [data-theme="dark"] .search-input-group { - border-bottom-color: rgba(255, 255, 255, 0.1); background: transparent; + border-bottom-color: #ffffff; + box-shadow: none; } [data-theme="dark"] .search-input-group:hover { - border-bottom-color: rgba(255, 255, 255, 0.3); background: transparent; + border-bottom-color: #ccc; } [data-theme="dark"] .search-input-group:focus-within { background: transparent; - border-color: transparent; - border-bottom-color: var(--theme-color, #4a90e2); + border-bottom-color: #fff; box-shadow: none; } .search-input-group input { width: 100%; - border: none; + border: none !important; + border-radius: 0 !important; background: transparent; - padding: 5px 30px 5px 0; /* Left align text, space for close icon on right */ - font-size: 0.95rem; - color: var(--text-title-color); + padding: 0 4px !important; + padding-left: 8px !important; + padding-right: 20px !important; /* Prevent text overlap with close icon */ + font-size: 1rem; + color: #000000; outline: none; + height: 24px; + font-weight: 500; } -/* Search Icon visible */ +/* Text color on focus */ +.search-input-group:focus-within input { + color: #000; +} + +[data-theme="dark"] .search-input-group input { + color: #ffffff; +} + +[data-theme="dark"] .search-input-group:focus-within input { + color: #ffffff; +} + +/* Search Icon */ .search-icon { - color: #9ca3af; + color: #000000; font-size: 1.1rem; - margin-right: 6px; transition: color 0.3s ease; } .search-input-group:focus-within .search-icon { - color: var(--text-title-color); + color: #000000; +} + +[data-theme="dark"] .search-icon { + color: #ffffff; } [data-theme="dark"] .search-input-group:focus-within .search-icon { - color: var(--text-title-dark-color); + color: #ffffff; } -/* Close icon on the right */ +/* Close icon */ .close-icon { position: absolute; right: 0; - font-size: 1.1rem; - color: #9ca3af; + font-size: 1rem; + color: #999; cursor: pointer; transition: all 0.2s; opacity: 0; transform: scale(0.8); + display: flex; + align-items: center; + justify-content: center; + width: 20px; + height: 20px; + border-radius: 50%; +} + +.search-input-group:focus-within .close-icon { + color: #cccccc; +} + +.close-icon:hover { + background: rgba(0,0,0,0.1); + color: #000; +} + +.search-input-group:focus-within .close-icon:hover { + background: rgba(255,255,255,0.2); + color: #fff; +} + +[data-theme="dark"] .close-icon { + color: #aaa; +} + +[data-theme="dark"] .search-input-group:focus-within .close-icon { + color: #666; +} + +[data-theme="dark"] .close-icon:hover { + background: rgba(255,255,255,0.1); + color: #fff; +} + +[data-theme="dark"] .search-input-group:focus-within .close-icon:hover { + background: rgba(0,0,0,0.1); + color: #000; } .search-input-group.has-value .close-icon { @@ -827,23 +993,18 @@ ul { transform: scale(1); } -.close-icon:hover { - color: var(--theme-color, #4a90e2); -} - .search-dropdown { position: absolute; top: 100%; left: 0; right: 0; - background: rgba(255, 255, 255, 0.98); /* Less transparent for readability */ - /* backdrop-filter: blur(12px); Removed for cleaner look */ - border-radius: 4px; /* Sharper corners */ - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); /* Softer shadow */ - border: 1px solid rgba(0, 0, 0, 0.05); - margin-top: 5px; + background: #ffffff; + border-radius: 12px; + box-shadow: 0 4px 20px rgba(0,0,0,0.1); /* Soft shadow */ + border: 1px solid #f0f0f0; /* Subtle border */ + margin-top: 8px; /* Spacing from input */ overflow: hidden; - z-index: 50; + z-index: 100; opacity: 0; transform: translateY(5px); visibility: hidden; @@ -857,28 +1018,40 @@ ul { } [data-theme="dark"] .search-dropdown { - background: #1f2933; - border: 1px solid rgba(255, 255, 255, 0.05); - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); + background: #2a2a2a; + border: 1px solid #444; + box-shadow: 0 4px 20px rgba(0,0,0,0.3); } .search-result-item { - padding: 8px 10px; - border-bottom: none; /* Clean list */ + padding: 10px 14px; + border-bottom: 1px solid #f0f0f0; display: flex; flex-direction: column; transition: background-color 0.2s; } +[data-theme="dark"] .search-result-item { + border-bottom: 1px solid #333; +} + +.search-result-item:last-child { + border-bottom: none; +} + .search-result-meta { display: flex; justify-content: flex-start; /* Left align */ gap: 10px; font-size: 0.75rem; - color: #999; + color: #666; margin-top: 2px; } +[data-theme="dark"] .search-result-meta { + color: #aaa; +} + .search-result-summary-text { max-width: 80%; white-space: nowrap; @@ -888,45 +1061,45 @@ ul { .no-result { text-align: left; - color: #999; - padding: 10px; + color: #666; + padding: 12px 16px; font-size: 0.9rem; cursor: default; } -[data-theme="dark"] .search-result-item { - border-bottom: none; +[data-theme="dark"] .no-result { + color: #aaa; } .search-result-item:hover { - background: rgba(0,0,0,0.03); + background: #f5f5f5; } [data-theme="dark"] .search-result-item:hover { - background: rgba(255,255,255,0.05); + background: #1a1a1a; } .search-result-title { display: block; - font-weight: normal; /* Lighter weight */ - font-size: 0.9rem; - color: var(--text-title-color); + font-weight: 600; + font-size: 0.95rem; + color: #000000; margin-bottom: 0; } [data-theme="dark"] .search-result-title { - color: var(--text-title-dark-color); + color: #ffffff; } .search-result-date { font-size: 0.75rem; - color: #999; + color: #666; margin-right: 10px; } .search-result-summary { font-size: 0.85rem; - color: #666; + color: #444; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; @@ -935,7 +1108,7 @@ ul { } [data-theme="dark"] .search-result-summary { - color: #9ca3af; + color: #ccc; } @keyframes fadeIn { @@ -950,11 +1123,74 @@ ul { /* Mobile Adaptation */ @media (max-width: 767px) { + .searchable-header-container { + flex-wrap: wrap; + height: auto; + min-height: 40px; + } + + .section-header.normal-mode { + font-size: 1rem; + } + + /* Adjust Hint Wrapper Position for Mobile */ + .search-hint-wrapper { + position: relative; + left: auto; + top: auto; + transform: none !important; + margin-left: 8px; + opacity: 1; + } + + .search-hint-wrapper.visible { + transform: none !important; + } + + .search-mascot { + width: 28px; + height: 28px; + } + .search-hint { opacity: 1; - transform: translateX(0); - display: inline-block; - margin-left: 8px; + font-size: 12px; + padding: 5px 10px; + margin-top: 0; + white-space: normal; + max-width: 200px; + } + + /* Ensure Input Group fits and is comfortable */ + .search-input-group { + padding: 0 0 6px 0; + margin-top: 5px; + background: transparent; + width: 100%; + max-width: 280px; /* Slightly wider on mobile for better usability */ + } + + [data-theme="dark"] .search-input-group { + background: transparent; + } + + .search-input-group input { + font-size: 16px; /* 16px prevents iOS zoom entirely */ + padding-right: 20px; + height: 24px; + padding-left: 5px; + } + + .close-icon { + right: 0; + width: 20px; + height: 20px; + } + + .search-dropdown { + width: 100%; + box-shadow: 0 4px 15px rgba(0,0,0,0.1); + border: none; } } .pjax-leave { @@ -1258,6 +1494,35 @@ ul { .highlight pre::-webkit-scrollbar { display: none; } + + /* Mobile Navigation Optimization - Single Line Scrollable */ + .header-menu { + overflow-x: auto; + -webkit-overflow-scrolling: touch; /* Smooth scrolling on iOS */ + scrollbar-width: none; /* Firefox */ + margin-left: -30px; /* Extend to edges */ + margin-right: -30px; + padding-left: 30px; /* Start content aligned */ + border-top: 1px solid #f4f4f4; + } + + .header-menu::-webkit-scrollbar { + display: none; /* Hide scrollbar for Chrome/Safari */ + } + + .header-menu ul.flat { + display: flex; + flex-wrap: nowrap; /* Prevent wrapping */ + white-space: nowrap; + gap: 20px; /* Comfortable touch spacing */ + align-items: center; + padding-right: 30px; /* Ensure scrolling reaches the end with padding */ + } + + .header-menu ul.flat li { + flex: 0 0 auto; /* Do not shrink */ + margin-top: 10px; /* Maintain vertical spacing from border */ + } } /* 代码复制按钮 */ @@ -4138,7 +4403,7 @@ html[data-theme="light"] .atk-loading-spinner svg circle { /* Inline Search Styles */ .searchable-header-container { position: relative; - margin-top: 15px; + /* margin-top: 15px; */ height: 13px; display: flex; align-items: center; @@ -4156,177 +4421,7 @@ html[data-theme="light"] .atk-loading-spinner svg circle { opacity: 0.7; } -.search-hint { - font-size: 12px; - font-weight: normal; - color: #999; - margin-left: 10px; - opacity: 0; /* Hidden by default */ - transform: translateX(-5px); - transition: all 0.3s ease; - display: inline-block; - vertical-align: middle; -} -.section-header.normal-mode:hover .search-hint { - opacity: 1; - transform: translateX(0); -} - -/* Mobile: always show hint to ensure discoverability */ -@media (max-width: 768px) { - .search-hint { - opacity: 0.6; - transform: translateX(0); - } -} - -.search-mode { - width: 100%; - animation: fadeIn 0.3s ease; -} - -.search-input-group { - display: flex; - align-items: center; - background: transparent; - border-bottom: 1px solid #e5e7eb; - padding: 0 5px; - width: 100%; - max-width: 300px; - transition: all 0.3s ease; -} - -.search-input-group:focus-within { - background: transparent; - border-bottom-color: var(--text-highlight-color); - box-shadow: none; -} - -.search-input-group input { - border: none; - background: transparent; - flex: 1; - padding: 5px 5px; /* Reduced side padding */ - font-size: 14px; - outline: none; - color: #333; -} - -.search-input-group .search-icon { - color: #999; - font-size: 18px; /* Slightly larger */ - margin-right: 4px; -} - -.search-input-group .close-icon { - color: #999; - cursor: pointer; - font-size: 16px; - padding: 5px; -} - -.search-input-group .close-icon:hover { - color: #333; -} - -.search-dropdown { - position: absolute; - top: 100%; - left: 0; - width: 100%; - max-width: 300px; - background: #fff; - border-radius: 4px; - box-shadow: 0 4px 12px rgba(0,0,0,0.1); - z-index: 100; - max-height: 300px; - overflow-y: auto; - display: none; - margin-top: 5px; - border: 1px solid #eee; -} - -.search-dropdown .search-result-item { - padding: 10px 15px; - font-size: 14px; - display: block; /* Ensure it behaves like a block */ - text-decoration: none; /* Remove underline */ - color: inherit; /* Inherit text color */ - cursor: pointer; - border-left: none; /* Removed accent border */ - transition: background-color 0.2s; -} - -.search-dropdown .search-result-item:hover { - background-color: #f5f5f5; - text-decoration: none; -} - -.search-dropdown .search-result-title { - font-size: 15px; - font-weight: 600; - display: block; /* Ensure title is block to break line */ - color: #333; -} - -.search-dropdown .search-result-summary { - font-size: 12px; - -webkit-line-clamp: 1; -} - -/* Dark Mode for Inline Search */ -[data-theme="dark"] .search-input-group { - background: transparent; - border-bottom-color: #444; - box-shadow: none; -} - -[data-theme="dark"] .search-input-group:focus-within { - background: transparent; - border-bottom-color: var(--text-highlight-color); - box-shadow: none; -} - -[data-theme="dark"] .search-input-group input { - color: #e0e0e0; -} - -[data-theme="dark"] .search-input-group .search-icon { - color: #888; -} - -[data-theme="dark"] .search-input-group .close-icon { - color: #888; -} - -[data-theme="dark"] .search-input-group .close-icon:hover { - color: #fff; - background-color: transparent; -} - -[data-theme="dark"] .search-dropdown { - background: #2d2d2d; - border-color: #444; - box-shadow: 0 4px 12px rgba(0,0,0,0.3); -} - -[data-theme="dark"] .search-dropdown .search-result-item { - color: #e0e0e0; -} - -[data-theme="dark"] .search-dropdown .search-result-item:hover { - background-color: #383838; -} - -[data-theme="dark"] .search-dropdown .search-result-title { - color: #e0e0e0; -} - -@keyframes fadeIn { - from { opacity: 0; transform: translateX(-10px); } - to { opacity: 1; transform: translateX(0); } -} /* Album / Light and Shadow Page Styles - Waterfall Flow Refined */ .album-content { diff --git a/themes/Ying/assets/js/modules/barrage.js b/themes/Ying/assets/js/modules/barrage.js index 1eb91233..04a72247 100644 --- a/themes/Ying/assets/js/modules/barrage.js +++ b/themes/Ying/assets/js/modules/barrage.js @@ -93,11 +93,14 @@ const avatarEl = el.querySelector('.atk-avatar img'); if (!id || !contentEl) return null; + + // 优先获取 data-src (Artalk 懒加载),否则获取 src + const avatarSrc = avatarEl ? (avatarEl.getAttribute('data-src') || avatarEl.src) : ''; return { id: id, content: contentEl.innerText || contentEl.textContent, - avatar: avatarEl ? avatarEl.src : '', + avatar: avatarSrc, ua: null }; }).filter(Boolean); diff --git a/themes/Ying/assets/js/modules/search.js b/themes/Ying/assets/js/modules/search.js index dccb26b2..e266fa05 100644 --- a/themes/Ying/assets/js/modules/search.js +++ b/themes/Ying/assets/js/modules/search.js @@ -3,17 +3,37 @@ window.initSearch = function() { initInlineSearch(); }; +var searchLoadingPromise = null; + function loadSearchIndex() { - if (!window.searchIndex) { - return fetch('/index.json') - .then(response => response.json()) - .then(data => { - window.searchIndex = data; - return data; - }) - .catch(err => console.error('Failed to load search index:', err)); + if (window.searchIndex) { + return Promise.resolve(window.searchIndex); } - return Promise.resolve(window.searchIndex); + + if (searchLoadingPromise) { + return searchLoadingPromise; + } + + window.isSearchingLoading = true; + searchLoadingPromise = fetch('/index.json') + .then(response => { + if (!response.ok) throw new Error(response.statusText); + return response.json(); + }) + .then(data => { + window.searchIndex = data; + window.isSearchingLoading = false; + searchLoadingPromise = null; + return data; + }) + .catch(err => { + console.error('Failed to load search index:', err); + window.isSearchingLoading = false; + searchLoadingPromise = null; + return null; // Return null on error to handle gracefully + }); + + return searchLoadingPromise; } function initSearchModal() { @@ -73,11 +93,24 @@ function initSearchModal() { searchInput.addEventListener('input', function() { var query = this.value.trim().toLowerCase(); - if (!window.searchIndex || query.length === 0) { + + if (query.length === 0) { searchResults.innerHTML = '

输入关键词并回车进行搜索

'; return; } + if (!window.searchIndex) { + searchResults.innerHTML = '

索引加载中...

'; + loadSearchIndex().then(function(data) { + if (data && searchInput.value.trim().length > 0) { + searchInput.dispatchEvent(new Event('input')); + } else if (!data) { + searchResults.innerHTML = '

索引加载失败

'; + } + }); + return; + } + var results = window.searchIndex.filter(function(item) { return (item.title && item.title.toLowerCase().includes(query)) || (item.summary && item.summary.toLowerCase().includes(query)); @@ -114,16 +147,25 @@ function initInlineSearch() { var resultsContainer = document.getElementById('inline-search-results'); window.toggleSearchMode = function(show) { - if (!header || !searchContainer || !input || !resultsContainer) return; + if (!header || !searchContainer || !input || !resultsContainer) { + console.warn('Search elements missing, cannot toggle mode.'); + return; + } + var searchHint = document.querySelector('.search-hint-wrapper'); + if (show) { + if (searchHint) searchHint.style.display = 'none'; // Hide hint completely to avoid layout shifts header.style.display = 'none'; searchContainer.style.display = 'block'; input.focus(); - loadSearchIndex(); + loadSearchIndex().then(() => { + console.log('Search index loaded via toggle'); + }).catch(e => console.error('Search index load failed', e)); // Add Esc key listener document.addEventListener('keydown', escListener); } else { + if (searchHint) searchHint.style.display = ''; // Restore hint header.style.display = 'inline-flex'; searchContainer.style.display = 'none'; input.value = ''; @@ -199,7 +241,20 @@ function initInlineSearch() { return; } - if (!window.searchIndex) return; + if (!window.searchIndex) { + resultsContainer.innerHTML = '
索引加载中...
'; + resultsContainer.classList.add('show'); + + loadSearchIndex().then(function(data) { + // If data loaded successfully and user hasn't cleared input + if (data && input.value.trim().length > 0) { + input.dispatchEvent(new Event('input')); + } else if (!data) { + resultsContainer.innerHTML = '
索引加载失败
'; + } + }); + return; + } var results = window.searchIndex.filter(function(item) { return (item.title && item.title.toLowerCase().includes(query)) || @@ -207,26 +262,26 @@ function initInlineSearch() { }); if (results.length > 0) { - var html = results.slice(0, 5).map(function(item) { - return ` - - ${item.title} -
- ${item.date} - ${item.summary || ''} -
-
- `; - }).join(''); - - resultsContainer.innerHTML = html; - resultsContainer.classList.add('show'); - - // PJAX Refresh - if (window.pjax) { - window.pjax.refresh(resultsContainer); - } - } else { + var html = results.slice(0, 5).map(function(item) { + return ` + + ${item.title} +
+ ${item.date} + ${item.summary || ''} +
+
+ `; + }).join(''); + + resultsContainer.innerHTML = html; + resultsContainer.classList.add('show'); + + // PJAX Refresh + if (window.pjax) { + window.pjax.refresh(resultsContainer); + } + } else { resultsContainer.innerHTML = '
暂无相关内容
'; resultsContainer.classList.add('show'); } @@ -247,4 +302,80 @@ function initInlineSearch() { }; document.addEventListener('click', window.inlineSearchClickOutside); } + + // Manual PJAX delegation for results + resultsContainer.addEventListener('click', function(e) { + var link = e.target.closest('a'); + if (link && window.pjax) { + e.preventDefault(); + // Close search first + window.toggleSearchMode(false); + // Then navigate + window.pjax.loadUrl(link.href, { triggerElement: link }); + } + }); + + // Search Hint Typewriter Logic + var header = document.getElementById('essay-header'); + var searchHintWrapper = header ? header.querySelector('.search-hint-wrapper') : null; + var searchHintText = searchHintWrapper ? searchHintWrapper.querySelector('.search-hint') : null; + + if (searchHintWrapper && searchHintText) { + // --- Smart Greeting Logic --- + var text = window.searchHintText || "点击随笔 开始搜索"; + var now = new Date(); + var month = now.getMonth() + 1; + var day = now.getDate(); + var dateStr = (month < 10 ? '0' : '') + month + '-' + (day < 10 ? '0' : '') + day; + var hour = now.getHours(); + + // 1. Check Holidays + if (window.searchHolidays && window.searchHolidays[dateStr]) { + text = window.searchHolidays[dateStr]; + } + // 2. Check Time of Day (if greetings configured) + else if (window.searchGreetings) { + if (hour >= 6 && hour < 11 && window.searchGreetings.morning) { + text = window.searchGreetings.morning; + } else if (hour >= 11 && hour < 14 && window.searchGreetings.noon) { + text = window.searchGreetings.noon; + } else if (hour >= 14 && hour < 18 && window.searchGreetings.afternoon) { + text = window.searchGreetings.afternoon; + } else if (hour >= 18 && hour < 22 && window.searchGreetings.evening) { + text = window.searchGreetings.evening; + } else if ((hour >= 22 || hour < 6) && window.searchGreetings.night) { + text = window.searchGreetings.night; + } + } + + // Reset text content initially but keep it ready + // Pre-fill first character to avoid empty bubble on mobile (where CSS forces visibility) + if (text.length > 0) { + searchHintText.textContent = text.charAt(0); + } else { + searchHintText.textContent = ''; + } + + // Show wrapper initially + setTimeout(function() { + // Add visible class (triggers fade in on desktop) + searchHintWrapper.classList.add('visible'); + + // Typewriter effect + var i = 1; + var typeInterval = setInterval(function() { + if (i >= text.length) { + clearInterval(typeInterval); + + // Hide after 8 seconds (give more time to read greetings) + setTimeout(function() { + searchHintWrapper.classList.remove('visible'); + }, 8000); + return; + } + searchHintText.textContent = text.substring(0, i + 1); + i++; + }, 100); + }, 500); + } } diff --git a/themes/Ying/layouts/index.html b/themes/Ying/layouts/index.html index 6b7d8e42..943adf73 100644 --- a/themes/Ying/layouts/index.html +++ b/themes/Ying/layouts/index.html @@ -6,7 +6,21 @@

随笔 - 点击随笔,开始搜索 +
+ {{ if .Site.Params.home_search.mascot }} + + {{ else }} + + {{ end }} + +
+ {{ if .Site.Params.home_search.hint }} + + {{ end }}