diff --git a/_config.yml b/_config.yml index 97fd865b..06e79bc5 100644 --- a/_config.yml +++ b/_config.yml @@ -468,6 +468,27 @@ capsule: server: netease # 播放列表的服务商。netease:网易云 / tencent:腾讯 / kugou:酷狗 / xiami:小米 / baidu:百度 : Music service provider. netease: Netease Cloud / tencent: Tencent / kugou: Kugou / xiaomi: Xiaomi / baidu: Baidu type: playlist # 播放列表的类型。song:单曲 / playlist:歌单 / album:专辑 / artist:歌手 : Type of playlist. song: Single / playlist: Playlist / album: Album / artist: Singer +# 友链鱼塘 +# Links fish pond +moments: + enable: false # 是否开启鱼塘 / Whether to enable fish pond + api: # https://blog.wzsco.top/circle/ # api地址 / api address + error_img: https://bu.dusays.com/2023/11/08/654af68b25bb8.jpg # 加载失败显示图片 / Loading failed display image + sort_rule: created # 排序规则:created:按创建时间排序 / updated:按更新时间排序 : Sort rule: created: Sort by creation time / updated: Sort by update time + expire_days: 1 # 缓存过期时间(天),默认为1天 / Cache expiration time (days), default is 1 day + page_init_number: 10 # 页面初始化加载数量,默认为10条 / Page initialization loading quantity, default is 10 + page_turning_number: 5 # 页面翻页加载数量,默认为5条 / Page turning loading quantity, default is 5 + angle: true # 鱼塘随机文章 / Fish pond random article + appjs: https://cdn.cbd.int/solitude-source@1.0.3/js/fcircle.min.js # 鱼塘js / Fish pond js + bundlejs: https://cdn.cbd.int/solitude-source/js/moment/bundle.min.js # 鱼塘js / Fish pond js + randompostjs: https://cdn.cbd.int/solitude-source/js/moment/random_post.min.js # 鱼塘js / Fish pond js + +# 相册 +# album +album: + enable: false # 是否开启相册 / Whether to enable album + limit: 6 # 单行显示图片数量 / Number of pictures displayed in a single line + # ------------------------- # 文章页、页面配置 # post、page settings @@ -542,6 +563,35 @@ post: api: https://img2color.wzsco.top/api?img= # api地址 / api address time: 43200000 # api取色间隔(毫秒),默认为12小时 / api color interval (milliseconds), default is 12 hours +keyboard: + enable: false # 是否开启键盘控制 / Whether to enable keyboard control + # 键盘控制配置 + # Keyboard control configuration + list: + # name: 按键名称 + # name: Key name + # key: 按键 + # key: Key + # func: 方法 + # func: Function + # sco: sco内置方法 + # sco: sco built-in method + # url: 跳转链接 + # url: Jump link +# - name: 关闭快捷键功能 +# key: K +# func: keyboard +# - name: 打开中控台 +# key: A +# sco: showConsole +# - name: 播放/暂停音乐 +# key: M +# sco: musicToggle +# - name: 打开友情链接 +# key: L +# url: '/links/' + + # ------------------------- # 自定义主题 @@ -722,6 +772,11 @@ search: enable: false # algolia, local type: algolia + # 推荐标签 + # Recommended tags + tags: + # - Solitude + # - Hexo algolia: # hits: # per_page: 6 diff --git a/languages/en-US.yml b/languages/en-US.yml index d9484c82..b13ac594 100755 --- a/languages/en-US.yml +++ b/languages/en-US.yml @@ -71,7 +71,7 @@ search: head: noscript: Please enable JavaScript to view the site - console: 'Program: Hexo | Theme: Hexo-Theme-Solitude | Author: WangZhuoSco、YiFeng | Github: https://github.com/DuoSco/Hexo-theme-solitude | Version: v1.4.1 😄' + console: 'Program: Hexo | Theme: Hexo-Theme-Solitude | Author: WangZhuoSco、YiFeng | Github: https://github.com/DuoSco/Hexo-theme-solitude | Version: v1.4.2 😄' aside: postcount: 'Posts :' @@ -93,6 +93,7 @@ console: tag_title: Find interesting areas switch_darkmode: Day and night switching switch_hideAside: Sidebar display control + switch_keyboard: Keyboard operation switch_music: Music switch archive_unit: Posts diff --git a/languages/zh-CN.yml b/languages/zh-CN.yml index 9536d7c8..7017feed 100755 --- a/languages/zh-CN.yml +++ b/languages/zh-CN.yml @@ -70,7 +70,7 @@ search: head: noscript: 开启JavaScript才能访问本站哦~ - console: '程序:Hexo | 主题:Hexo-Theme-Solitude | 作者:王卓Sco、亦封 | Github: https://github.com/DuoSco/Hexo-theme-solitude | 版本:v1.4.1 😄' + console: '程序:Hexo | 主题:Hexo-Theme-Solitude | 作者:王卓Sco、亦封 | Github: https://github.com/DuoSco/Hexo-theme-solitude | 版本:v1.4.2 😄' aside: postcount: '文章总数 :' @@ -92,6 +92,7 @@ console: tag_title: 寻找感兴趣的领域 switch_darkmode: 昼夜切换 switch_hideAside: 边栏显示控制 + switch_keyboard: 键盘快捷键 switch_music: 音乐开关 archive_unit: 篇 diff --git a/layout/includes/console.pug b/layout/includes/console.pug index cdd6378e..959acc21 100644 --- a/layout/includes/console.pug +++ b/layout/includes/console.pug @@ -30,6 +30,10 @@ div#console div.console-btn-item#consoleHideAside a.asideSwitch(onclick="sco.switchHideAside()", title=_p('console.switch_hideAside'), href="javascript:void(0);") i.scoicon.sco-side-bar-fill + if theme.keyboard.enable + div.console-btn-item#consoleKeyboard(onclick="sco.switchKeyboard()") + a.keyboardSwitch(title=_p('console.switch_keyboard'), href="javascript:void(0);") + i.scoicon.sco-keyboard-box-fill if theme.capsule.enable div.console-btn-item#consoleMusic(onclick="sco.musicToggle()") a.music-switch(title=_p('console.switch_music'), href="javascript:void(0);") diff --git a/layout/includes/head/config.pug b/layout/includes/head/config.pug index 23be6b3b..25f9c87d 100644 --- a/layout/includes/head/config.pug +++ b/layout/includes/head/config.pug @@ -15,7 +15,7 @@ apiKey: config.algolia.apiKey, indexName: config.algolia.indexName, hits: { - per_page: theme?.search?.algolia_search?.hits?.per_page || 10 + per_page: theme?.search?.algolia?.hits?.per_page || 10 } }) break; diff --git a/layout/includes/inject/body.pug b/layout/includes/inject/body.pug index 444c2a2c..e5236548 100644 --- a/layout/includes/inject/body.pug +++ b/layout/includes/inject/body.pug @@ -3,6 +3,9 @@ div script(src=url_for(theme.cdn.main)) + if theme.album.enable + script(src=url_for(theme.cdn.macy_js)) + mixin katex link(rel="stylesheet", href=url_for(theme.cdn.katex)) if theme.katex.copytex @@ -84,11 +87,6 @@ div if theme.music.enable script(src=url_for(theme.cdn.music_js)) - // gallery - if theme.gallery - script(src=url_for(theme.cdn.fj_gallery)) - link(rel="stylesheet", href=url_for(theme.cdn.fj_gallery_css)) - // pace 胶囊加载条(Capsule loading bar) if theme.loading.pace script(src=url_for(theme.cdn.pace_js)) @@ -108,6 +106,9 @@ div != item div#js-pjax + if page.type === 'album' && theme.album.enable + script. + initGallery() if page.type === 'says' && theme.says.enable script. window.addEventListener('resize', utils.throttle(function () { diff --git a/layout/includes/keyboard.pug b/layout/includes/keyboard.pug new file mode 100644 index 00000000..5183a34c --- /dev/null +++ b/layout/includes/keyboard.pug @@ -0,0 +1,65 @@ +- const list = theme.keyboard.list || [] +#keyboard-tips + .keyboardTitle= '博客快捷键' + .keyboardList + each item in list + .keyboardItem + .keyGroup + .key= 'Shift' + .key= item.key + .keyContent + .content= item.name +script. + const keyboard_addKeyup = (e) => { + if (e.key === 'Shift') { + document.getElementById('keyboard-tips').classList.remove('show'); + } + } + + const keyboard_addKeydown = (e) => { + const keyboards = !{JSON.stringify(list)}; + if (e.keyCode === 16) { + document.getElementById('keyboard-tips').classList.add('show'); + } + + for (let i = 0; i < keyboards.length; i++) { + if (keyboards[i].url) { + if (keyboards[i].url.startsWith('http')) { + if (e.key === keyboards[i].key) { + window.open(keyboards[i].url); + } + } else { + if (e.key === keyboards[i].key) { + pjax.loadUrl(keyboards[i].url); + } + } + } else if (keyboards[i].sco) { + if (e.key === keyboards[i].key) { + sco[keyboards[i].sco](); + } + } else if (keyboards[i].func) { + if (e.key === keyboards[i].key) { + window[keyboards[i].func](); + } + } + } + } + + function openKeyboard() { + + window.addEventListener('keyup', keyboard_addKeyup); + + window.addEventListener('keydown', keyboard_addKeydown); + } + function closeKeyboard() { + + window.removeEventListener('keyup', keyboard_addKeyup); + + window.removeEventListener('keydown', keyboard_addKeydown); + } + + var sco_keyboards = localStorage.getItem('keyboard') === 'true' + if (sco_keyboards) { + openKeyboard(); + document.getElementById('consoleKeyboard').classList.add('on'); + } \ No newline at end of file diff --git a/layout/includes/layout.pug b/layout/includes/layout.pug index 759cde81..367bfa2d 100644 --- a/layout/includes/layout.pug +++ b/layout/includes/layout.pug @@ -15,6 +15,10 @@ html(lang=config.language, data-theme="light") // sidebar include ./sidebar.pug + // keyboard + if theme.keyboard.enable + include ./keyboard.pug + #body-wrap(class = is_post() ? 'post' : 'page') include ./header.pug diff --git a/layout/includes/page/album.pug b/layout/includes/page/album.pug new file mode 100644 index 00000000..36dc17cf --- /dev/null +++ b/layout/includes/page/album.pug @@ -0,0 +1,56 @@ +include ../widgets/page/banner + +- var gallery = site.data.gallery.gallery +- var album = gallery.find(item => item.album = page.album) +- var {limit} = theme.album + +if album + #album + #sco-container + if album.json + script. + function initGallery() { + let macy = Macy({ container: '#sco-container', trueOrder: false, waitForImages: true, margin: 5, columns: !{limit}, breakAt: { 1200: 5, 940: 3, 520: 2, 400: 1 }}) + macy.runOnImageLoad(function () { + setTimeout(function () { + GLOBAL_CONFIG.lightbox && utils.lightbox(document.querySelectorAll(".sco-gallery-item img")); + macy.recalculate(true) + }, 500); + }, true) + } + (async function () { + await fetch('!{url_for(album.json)}') + .then(res => res.json()) + .then(data => { + let html = '' + data = data.sort((a, b) => b.date - a.date) + data.forEach(item => { + html += ` + + ` + }) + document.querySelector('#sco-container').innerHTML = html + GLOBAL_CONFIG.lazyload.enable && utils.lazyloadImg(); + initGallery() + }) + })() + + else + each item in album.items.sort((a, b) => b.date - a.date) + .sco-gallery-item + span.locate= item.locate + img.sco-gallery-image(src=item.image, alt=item.content) + script. + function initGallery(){ + let macy = Macy({ container: '#sco-container', trueOrder: false, waitForImages: true, margin: 5, columns: !{limit}, breakAt: { 1200: 5, 940: 3, 520: 2, 400: 1 }}) + macy.runOnImageLoad(function () { + setTimeout(function () { + GLOBAL_CONFIG.lightbox && utils.lightbox(document.querySelectorAll(".sco-gallery-item img")); + macy.recalculate(true) + }, 500); + }, true) + } + document.addEventListener('DOMContentLoaded', initGallery); \ No newline at end of file diff --git a/layout/includes/page/gallery.pug b/layout/includes/page/gallery.pug new file mode 100644 index 00000000..5df3a834 --- /dev/null +++ b/layout/includes/page/gallery.pug @@ -0,0 +1,11 @@ +include ../widgets/page/banner + +- var gallery = site.data.gallery.gallery + +if theme.album.enable && gallery + #gallery + each item in gallery + .gallery-item(onclick="pjax.loadUrl('/" + item.album + "/')") + img.cover(src=item.cover) + span.title= item.class_name + span.desc= item.descr \ No newline at end of file diff --git a/layout/includes/page/links.pug b/layout/includes/page/links.pug index 10c73c5e..4964bd75 100644 --- a/layout/includes/page/links.pug +++ b/layout/includes/page/links.pug @@ -1,5 +1,7 @@ .flink#banners include ../widgets/page/links/banner +if theme.moments.angle + include ../widgets/page/moments/angle .flink#article-container each data in site.data.links.links h2= data.class_name + " (" + data.link_list.length + ")" diff --git a/layout/includes/page/moment.pug b/layout/includes/page/moment.pug new file mode 100644 index 00000000..459687ec --- /dev/null +++ b/layout/includes/page/moment.pug @@ -0,0 +1,28 @@ +include ../widgets/page/banner +if theme.moments.angle + include ../widgets/page/moments/angle + +.title-h2-a + .title-h2-a-left + h2(style="padding-top: 0;margin:0.6rem 0 0.6rem;") 🐟 鱼塘 + .title-h2-a-right + span 以下内容自动生成,未经过审核 + +div#hexo-circle-of-friends-root +script. + let UserConfig = { + // 填写你的api地址 + private_api_url: '!{theme.moments.api}', + // 默认加载文章数 + page_init_number: !{theme.moments.page_init_number}, + // 点击加载更多时,一次最多加载几篇文章,默认10 + page_turning_number: !{theme.moments.page_turning_number}, + // 头像加载失败时,默认头像地址 + error_img: '!{theme.moments.error_img}', + // 进入页面时第一次的排序规则 + sort_rule: '!{theme.moments.sort_rule}', + // 本地文章缓存数据过期时间(天) + expire_days: !{theme.moments.expire_days}, + } +script(src=url_for(theme.moments.appjs)) +script(src=url_for(theme.moments.bundlejs)) \ No newline at end of file diff --git a/layout/includes/widgets/page/moments/angle.pug b/layout/includes/widgets/page/moments/angle.pug new file mode 100644 index 00000000..98bae2ee --- /dev/null +++ b/layout/includes/widgets/page/moments/angle.pug @@ -0,0 +1,19 @@ +.title-h2-a + .title-h2-a-left + h2(style="padding-top: 0;margin:0.6rem 0 0.6rem;") 🎣 钓鱼 + a#random-post-start(href="javascript:fetchRandomPost();", style="transition-duration: 0.3s; transform: rotate(63000deg); opacity: 1;", data-pjax-state="") + i.scoicon.sco-restart-line + .title-h2-a-right + if page.type !== 'links' + a.random-post-all(href="/links/", data-pjax-state="") 全部友链 + +#random-post + +script. + var fdata = { + apiurl: "#{theme.moments.api}", + defaultFish: 100, + hungryFish: 100, + } + +script(src=url_for(theme.moments.randompostjs)) \ No newline at end of file diff --git a/layout/includes/widgets/page/says/local.pug b/layout/includes/widgets/page/says/local.pug index e10f4826..9b894a5f 100644 --- a/layout/includes/widgets/page/says/local.pug +++ b/layout/includes/widgets/page/says/local.pug @@ -26,7 +26,7 @@ each item in site.data.essay.essay_list.slice(0, theme.says.strip) if item.video.player video(src=item.video.player controls="controls" style="object-fit: cover;") if item.video.bilibili - iframe(src='//player.bilibili.com/player.html?autop-lay=0&bvid=' + item.video.bilibili scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true") + iframe(src='//player.bilibili.com/player.html?auto-play=0&bvid=' + item.video.bilibili scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true") if theme.says.style === 1 hr diff --git a/layout/includes/widgets/third-party/search/algolia-search.pug b/layout/includes/widgets/third-party/search/algolia-search.pug index e2639c8e..8481f79f 100644 --- a/layout/includes/widgets/third-party/search/algolia-search.pug +++ b/layout/includes/widgets/third-party/search/algolia-search.pug @@ -1,15 +1,20 @@ -div#algolia-search - div.search-dialog - div.search-dialog__title#algolia-search-title=__('nav.search') - div#algolia-input-panel - div#algolia-search-input - div#search-results - div#algolia-hits - div#algolia-tips - div#algolia-pagination - div#algolia-stats - i.scoicon.sco-algolia-fill - span.algolia-tips-text='Algolia 提供搜索服务' - span.search-close-button - i.scoicon.sco-close-fill - div#search-mask \ No newline at end of file +#algolia-search + .search-dialog + .algolia-navbar + .search-dialog__title#algolia-search-title=__('nav.search') + .algolia-tips + i.scoicon.sco-algolia-fill + span.algolia-tips-text='Algolia' + span.search-close-button + i.scoicon.sco-close-fill + #algolia-input-panel + #algolia-search-input + #search-results + #algolia-hits + each tag in theme.search.tags || [] + a.tag-list(href='/tags/' + tag + '/')=tag + + #algolia-tips + #algolia-pagination + #algolia-stats + #search-mask \ No newline at end of file diff --git a/layout/includes/widgets/third-party/search/local-search.pug b/layout/includes/widgets/third-party/search/local-search.pug index daa5b88c..8fb5d9df 100644 --- a/layout/includes/widgets/third-party/search/local-search.pug +++ b/layout/includes/widgets/third-party/search/local-search.pug @@ -8,6 +8,9 @@ div.search-box input.search-box-input#search-input(type="text", autocomplete="off", spellcheck="false", autocorrect="off", autocapitalize="off", placeholder=__('search.placeholder')) div#search-results + #search-hits + each tag in theme.search.tags || [] + a.tag-list(href='/tags/' + tag + '/')=tag div#search-pagination div#search-tips div#search-mask \ No newline at end of file diff --git a/layout/page.pug b/layout/page.pug index 3dfa5f5a..b35299e1 100644 --- a/layout/page.pug +++ b/layout/page.pug @@ -20,11 +20,17 @@ block content include includes/page/equipment when 'rss' include includes/page/rss + when 'moment' + include includes/page/moment when 'douban' include includes/widgets/page/banner include includes/page/default when 'music' include includes/page/music + when 'gallery' + include includes/page/gallery + when 'album' + include includes/page/album default include includes/page/default if page.comment diff --git a/package.json b/package.json index 1c26fa87..253859dd 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hexo-theme-solitude", - "version": "1.4.1", + "version": "1.4.2", "description": "A beautiful, powerful, and efficient Hexo theme developed by the DuoSco team", "main": "package.json", "scripts": { diff --git a/plugins.yml b/plugins.yml index 33e3ac32..94ca54a8 100644 --- a/plugins.yml +++ b/plugins.yml @@ -13,7 +13,7 @@ pjax: twikoo: name: twikoo file: dist/twikoo.all.min.js - version: 1.6.29 + version: 1.6.31 waline_js: name: '@waline/client' file: dist/waline.js @@ -106,4 +106,8 @@ fancyapps_ui: fancyapps_css: name: fancyapps-ui file: dist/fancybox/fancybox.min.css - version: 5.0.33 \ No newline at end of file + version: 5.0.33 +macy_js: + name: macy + file: dist/macy.min.js + version: 2.5.1 \ No newline at end of file diff --git a/source/css/_global/index.styl b/source/css/_global/index.styl index e44a3bb6..029e6129 100644 --- a/source/css/_global/index.styl +++ b/source/css/_global/index.styl @@ -54,8 +54,4 @@ --card-box-shadow 0 3px 8px 6px rgba(7, 17, 27, 0.06) --card-hover-box-shadow 0 3px 8px 6px rgba(7, 17, 27, 0.15) --offset 0px - --hlscrollbar-bg #121212 - - +maxWidth768() - --style-border 0px solid var(--sco-none) - --style-border-hover 0px solid var(--sco-main) \ No newline at end of file + --hlscrollbar-bg #121212 \ No newline at end of file diff --git a/source/css/_layout/basic.styl b/source/css/_layout/basic.styl index acb55273..0d720f3f 100644 --- a/source/css/_layout/basic.styl +++ b/source/css/_layout/basic.styl @@ -192,7 +192,6 @@ button img border-style none - border-radius 8px max-width 100% transition all .2s ease 0s -webkit-user-drag none diff --git a/source/css/_mode/index.styl b/source/css/_mode/index.styl index 01a2a4dc..eba4a6c1 100644 --- a/source/css/_mode/index.styl +++ b/source/css/_mode/index.styl @@ -86,4 +86,9 @@ --style-border-forever 2px solid var(--sco-main) --sco-navbg var(--sco-theme-op) --sco-hl-bg $hl_bg_light - --sco-hltools-bg $hltools_bg_light \ No newline at end of file + --sco-hltools-bg $hltools_bg_light + +:root + +maxWidth768() + --style-border 0px solid var(--sco-none) + --style-border-hover 0px solid var(--sco-main) \ No newline at end of file diff --git a/source/css/_page/gallery/index.styl b/source/css/_page/gallery/index.styl new file mode 100644 index 00000000..f85836f2 --- /dev/null +++ b/source/css/_page/gallery/index.styl @@ -0,0 +1,96 @@ +#gallery + width 100% + display flex + flex-wrap wrap + justify-content start + padding 10px 0 + + .gallery-item + overflow hidden + border var(--style-border-always) + border-radius 12px + position relative + display flex + height 250px + width calc(100% / 3 - 10px) + cursor pointer + + &:hover + .cover + filter brightness(0.5) blur(2px) + transition all .3s + + .title::after + width 100% + transition all .3s + + .desc + left 10% + transition left .35s + text-wrap unset + + .cover + width 100% + object-fit cover + transition all 0.3s + + .title + position absolute + top 10% + left 10% + font-weight 700 + font-size 32px + color var(--sco-white) + + &::after + top 55px + width 0 + left 0 + height 3px + background var(--sco-white) + content "" + border-radius 1px + position absolute + transition all .3s + + .desc + position absolute + top 35% + left 100% + width 80% + color var(--sco-white) + font-size 1.1em + transition left .35s + letter-spacing 1px + text-wrap break-word + +#album + margin 22px auto 0 + + .locate + display flex + position absolute + left 8px + top 8px + padding 4px 6px + border-radius 8px + background var(--sco-black-op) + font-size 12px + color var(--sco-white) + transition .3s + z-index 1 + user-select none + + #sco-container + margin-top 22px + + .sco-gallery-item + margin-bottom 24px + overflow hidden + border-radius 8px + transition all .3s + + .sco-gallery-image + width 100% + display block + height auto \ No newline at end of file diff --git a/source/css/_page/index.styl b/source/css/_page/index.styl index ac0ef090..1cfb03f9 100644 --- a/source/css/_page/index.styl +++ b/source/css/_page/index.styl @@ -10,7 +10,8 @@ @import "rss.styl" -@import "moment.styl" +if hexo-config('moments.enable') + @import "moment.styl" if hexo-config('says.enable') @import "says.styl" @@ -21,6 +22,9 @@ if hexo-config('says.enable') @import "links.styl" +if hexo-config('album.enable') + @import "gallery/index.styl" + @import "about/index.styl" if hexo-config('music.enable') diff --git a/source/css/_page/moment.styl b/source/css/_page/moment.styl index 2965d542..17e110e6 100644 --- a/source/css/_page/moment.styl +++ b/source/css/_page/moment.styl @@ -150,7 +150,9 @@ width: fit-content .cf-article .cf-img-avatar - border-radius 50% + border-radius 50% !important + right -30px!important + bottom -30px!important #page .title-h2-a @@ -165,7 +167,7 @@ font-weight: 700 &:hover - color: var(--sco-hovertext) + color: var(--sco-main) .title-h2-a-left display: flex diff --git a/source/css/_widgets/_comment/twikoo.styl b/source/css/_widgets/_comment/twikoo.styl index 4d29a049..ab722205 100644 --- a/source/css/_widgets/_comment/twikoo.styl +++ b/source/css/_widgets/_comment/twikoo.styl @@ -122,15 +122,15 @@ .el-button--primary border-color var(--sco-fontcolor) !important color var(--sco-card-bg) !important - border-radius 4px !important + border-radius 12px !important box-shadow var(--sco-shadow-black) transition .3s width 5rem position absolute - top -53px + top -44px right 0 margin-left .5rem !important - height 32px + height 34px .el-button--primary.is-disabled, .el-button--primary.is-disabled:active, @@ -140,15 +140,15 @@ .tk-row-actions-start position absolute - top -100px + top -84px left 17px @media screen and (max-width: 768px) .tk-submit .el-button--primary width 5rem - height 132px - top -161px + height 122px + top -132px .tk-row-actions-start top -210px @@ -169,14 +169,14 @@ margin-left 0 !important .tk-row.actions - margin-bottom .5rem !important + margin-bottom 0 !important margin-left 0 !important - margin-top .5rem !important + margin-top 0 !important justify-content space-around !important .tk-meta-input position relative !important - margin-top .8rem + margin-top 8px width calc(100% - 5.5rem) .tk-content @@ -224,12 +224,13 @@ .tk-comments-container > .tk-comment - margin-top 0 !important - margin-bottom .5rem !important + margin-top 0!important + margin-bottom 0.5rem!important background var(--sco-card-bg) transition .3s border-radius 12px - padding .5rem 0 0 + padding 0 + padding-top 0.5rem border none border-top var(--style-border-dashed) @@ -283,6 +284,7 @@ .tk-meta-input .el-input .el-input-group__prepend + box-shadow none border-radius 12px 0 0 12px -webkit-user-select none @@ -302,7 +304,6 @@ .el-input margin-left 0 !important width 100% !important - margin-bottom 8px .tk-icon position absolute @@ -322,6 +323,7 @@ img.tk-avatar-img .el-input.el-input--small.el-input-group.el-input-group--prepend border-radius 12px background var(--sco-secondbg) + border var(--style-border-always) .el-input.el-input--small.el-input-group.el-input-group--prepend:nth-child(1):before content '输入QQ号会自动获取昵称和头像' @@ -365,15 +367,16 @@ img.tk-avatar-img .el-input-group__append, .el-input-group__prepend background-color var(--sco-card-bg) !important color var(--sco-fontcolor) !important - border-color var(--sco-card-border) !important - border var(--style-border-always) !important + border 0 !important font-weight 700 .el-input__inner background var(--sco-secondbg) !important - border 1px solid var(--sco-card-border) !important + border 0 !important color var(--sco-fontcolor) !important padding-left 8px + height 32px + line-height 32px border-radius 12px .page @@ -412,7 +415,7 @@ img.tk-avatar-img border-radius 8px !important .el-button:hover - background var(--sco-main) !important + background var(--sco-black) !important color var(--sco-white) !important .el-button.tk-preview diff --git a/source/css/_widgets/_mixins/keyboard.styl b/source/css/_widgets/_mixins/keyboard.styl new file mode 100644 index 00000000..d875891e --- /dev/null +++ b/source/css/_widgets/_mixins/keyboard.styl @@ -0,0 +1,59 @@ +#keyboard-tips + position fixed + top 80px + left 20px + z-index 999 + background var(--sco-maskbgdeep) + border-radius 12px + border var(--style-border) + padding 20px + display flex + flex-direction column + backdrop-filter saturate(180%) blur(20px) + transform translateZ(0) + pointer-events none + box-shadow var(--sco-shadow-border) + opacity 0 + transition .3s + + &.show + opacity 1 + transition .1s + + .keyboardTitle + font-size 12px + color var(--sco-secondtext) + line-height 1 + + .keyboardList + display flex + flex-direction column + margin-top 8px + + .keyboardItem + display flex + margin-top 4px + + .keyGroup + display flex + align-items center + width 90px + + .key + padding 0.2em 0.4em + font-family inherit + background-color var(--sco-card-bg) + color var(--sco-fontcolor) + border var(--style-border) + border-color var(--sco-secondtext) + border-bottom 2px solid var(--sco-secondtext) + box-shadow var(--sco-shadow-border) + border-radius 0.25rem + overflow-wrap break-word + overflow-x auto + font-weight 500 + font-size .875em + margin-right 4px + vertical-align baseline + line-height 1 + height 24px \ No newline at end of file diff --git a/source/css/_widgets/_search/algolia-search.styl b/source/css/_widgets/_search/algolia-search.styl index 054af7b7..769ff570 100644 --- a/source/css/_widgets/_search/algolia-search.styl +++ b/source/css/_widgets/_search/algolia-search.styl @@ -12,10 +12,13 @@ border var(--style-border) transition 0.3s border-radius 8px + animation slide-in .6s ease 0s 1 normal none running &:hover border var(--style-border-hover) box-shadow var(--sco-shadow-theme) + +maxWidth768() + border none +maxWidth768() top 0 @@ -23,20 +26,35 @@ margin 0 width 100% height 100% + border 0 + + .algolia-navbar + display flex + align-items center + margin-bottom 8px + + .algolia-tips + color var(--sco-secondtext) + right 0 + margin-left auto + opacity .8 .search-close-button - position absolute - top 0.8rem - right 1rem - color var(--sco-gray) + color var(--sco-secondtext) font-size 1.4em line-height 1 cursor pointer - transition color .2s ease-in-out 0s + padding 4px + border-radius 50px + margin-left 4px + transition .3s &:hover color var(--sco-main) + .algolia-tips-text + margin-left .4rem + #algolia-input-panel margin-bottom 8px @@ -65,7 +83,7 @@ visibility hidden #search-results - padding 8px + padding-top 8px max-height calc(80vh - 130px) overflow-y auto @@ -134,18 +152,9 @@ right 0 margin auto - #algolia-stats - margin-bottom 10px - color var(--sco-gray) - font-size .8rem - font-weight bold - .algolia-tips-text margin-left .4rem - #algolia-search-results - padding-top 8px - #search-mask position fixed inset 0 @@ -155,4 +164,16 @@ backdrop-filter blur(12px) -webkit-backdrop-filter blur(12px) transform translateZ(0) - background var(--sco-maskbgdeep) \ No newline at end of file + background var(--sco-maskbgdeep) + +#algolia-hits + .tag-list + padding 4px 8px + border-radius 8px + margin-right 0.5rem + margin-top 0.5rem + border var(--style-border-always) + + &:hover + background var(--sco-main) + color var(--sco-white) \ No newline at end of file diff --git a/source/css/_widgets/_search/local-search.styl b/source/css/_widgets/_search/local-search.styl index 92fe4750..38651062 100644 --- a/source/css/_widgets/_search/local-search.styl +++ b/source/css/_widgets/_search/local-search.styl @@ -12,10 +12,13 @@ border var(--style-border) transition 0.3s border-radius 8px + animation slide-in .6s ease 0s 1 normal none running &:hover border var(--style-border-hover) box-shadow var(--sco-shadow-theme) + +maxWidth768() + border none +maxWidth768() top 0 @@ -23,6 +26,7 @@ margin 0 width 100% height 100% + border 0 .search-dialog-title font-weight 700 @@ -116,7 +120,7 @@ max-width 100% width 100% padding-top 8px - margin-bottom 8px + padding-bottom 8px input height 100% @@ -138,4 +142,16 @@ backdrop-filter blur(12px) -webkit-backdrop-filter blur(12px) transform translateZ(0) - background var(--sco-maskbgdeep) \ No newline at end of file + background var(--sco-maskbgdeep) + +#search-hits + .tag-list + padding 4px 8px + border-radius 8px + margin-right 0.5rem + margin-top 0.5rem + border var(--style-border-always) + + &:hover + background var(--sco-main) + color var(--sco-white) \ No newline at end of file diff --git a/source/css/_widgets/_tags/link.styl b/source/css/_widgets/_tags/link.styl index af8191d5..1fe6e2b2 100644 --- a/source/css/_widgets/_tags/link.styl +++ b/source/css/_widgets/_tags/link.styl @@ -8,7 +8,7 @@ border-width 1px !important margin-top 1rem - &:hover + /#article-container a.tag-Link:not(.headerlink):hover border var(--style-border-hover) .tag-link-tips diff --git a/source/css/_widgets/index.styl b/source/css/_widgets/index.styl index 6fb3f20e..4d740269 100644 --- a/source/css/_widgets/index.styl +++ b/source/css/_widgets/index.styl @@ -4,6 +4,10 @@ // 手机端侧边栏 @import "_mixins/sidebar.styl" +// keyboard(键盘) +if hexo-config('keyboard.enable') + @import "_mixins/keyboard.styl" + // article-sort (归档) @import "_mixins/article-sort.styl" diff --git a/source/css/index.styl b/source/css/index.styl index 85642e21..5ed30e03 100644 --- a/source/css/index.styl +++ b/source/css/index.styl @@ -12,5 +12,4 @@ if hexo-config('css_prefix') // widgets @import '_widgets/index.styl' -// dark @import '_mode/*' \ No newline at end of file diff --git a/source/img/avatar.png b/source/img/avatar.png deleted file mode 100644 index 941b2213..00000000 Binary files a/source/img/avatar.png and /dev/null differ diff --git a/source/js/covercolor/api.js b/source/js/covercolor/api.js index 1b424e3f..c970ceb7 100644 --- a/source/js/covercolor/api.js +++ b/source/js/covercolor/api.js @@ -2,12 +2,17 @@ const coverColor = () => { const path = document.getElementById("post-cover")?.src; if (path) { handleApiColor(path); + } else { + document.documentElement.style.setProperty('--sco-main', 'var(--sco-theme)'); + document.documentElement.style.setProperty('--sco-main-op', 'var(--sco-theme-op)'); + document.documentElement.style.setProperty('--sco-main-op-deep', 'var(--sco-theme-op-deep)'); + document.documentElement.style.setProperty('--sco-main-none', 'var(--sco-theme-none)'); + initThemeColor() } } function handleApiColor(path) { const cacheGroup = JSON.parse(localStorage.getItem('Solitude')) || {}; - console.log(cacheGroup) if (cacheGroup.postcolor && cacheGroup.postcolor[path]) { const color = cacheGroup.postcolor[path].value; const [r, g, b] = color.match(/\w\w/g).map(x => parseInt(x, 16)); @@ -26,14 +31,13 @@ function img2color(src) { const [r, g, b] = color.match(/\w\w/g).map(x => parseInt(x, 16)); setThemeColors(color, r, g, b); const expirationTime = Date.now() + coverColorConfig.time; - const cacheGroup = saveToLocal.get('Solitude') || {}; + const cacheGroup = JSON.parse(localStorage.getItem('Solitude')) || {}; cacheGroup.postcolor = cacheGroup.postcolor || {}; cacheGroup.postcolor[src] = {value: color, expiration: expirationTime}; localStorage.setItem('Solitude', JSON.stringify(cacheGroup)); }) .catch(error => { console.error('请检查API是否正常!\n' + error); - setThemeColors(); }); } @@ -45,14 +49,14 @@ function setThemeColors(value, r = null, g = null, b = null) { document.documentElement.style.setProperty('--sco-main-none', value + '00'); if (r && g && b) { - var brightness = Math.round(((parseInt(r) * 299) + (parseInt(g) * 587) + (parseInt(b) * 114)) / 1000); + let brightness = Math.round(((parseInt(r) * 299) + (parseInt(g) * 587) + (parseInt(b) * 114)) / 1000); if (brightness < 125) { - var cardContents = document.getElementsByClassName('card-content'); + let cardContents = document.getElementsByClassName('card-content'); for (let i = 0; i < cardContents.length; i++) { cardContents[i].style.setProperty('--sco-card-bg', 'var(--sco-white)'); } - var authorInfo = document.getElementsByClassName('author-info__sayhi'); + let authorInfo = document.getElementsByClassName('author-info__sayhi'); for (let i = 0; i < authorInfo.length; i++) { authorInfo[i].style.setProperty('background', 'var(--sco-white-op)'); authorInfo[i].style.setProperty('color', 'var(--sco-white)'); diff --git a/source/js/covercolor/local.js b/source/js/covercolor/local.js index 5f803451..4abd788b 100644 --- a/source/js/covercolor/local.js +++ b/source/js/covercolor/local.js @@ -1,21 +1,26 @@ -function coverColor() { +const coverColor = () => { const path = document.getElementById("post-cover")?.src; - if (path) { localColor(path); + } else { + document.documentElement.style.setProperty('--sco-main', 'let(--sco-theme)'); + document.documentElement.style.setProperty('--sco-main-op', 'let(--sco-theme-op)'); + document.documentElement.style.setProperty('--sco-main-op-deep', 'let(--sco-theme-op-deep)'); + document.documentElement.style.setProperty('--sco-main-none', 'let(--sco-theme-none)'); + initThemeColor() } } -function localColor(path) { +const localColor = (path) => { const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = function () { const canvas = document.createElement("canvas"); - canvas.width = this.width; - canvas.height = this.height; + canvas.width = img.width; + canvas.height = img.height; const ctx = canvas.getContext("2d"); - ctx.drawImage(this, 0, 0); - const data = ctx.getImageData(0, 0, this.width, this.height).data; + ctx.drawImage(img, 0, 0); + const data = ctx.getImageData(0, 0, img.width, img.height).data; const {r, g, b} = calculateRGB(data); let value = rgbToHex(r, g, b); if (getContrastYIQ(value) === "light") { @@ -23,9 +28,26 @@ function localColor(path) { } setThemeColors(value, r, g, b); }; + img.onerror = function () { + console.error('图片加载失败'); + }; img.src = path; } +function calculateRGB(data) { + let r = 0, g = 0, b = 0; + const step = 5; + for (let i = 0; i < data.length; i += 4 * step) { + r += data[i]; + g += data[i + 1]; + b += data[i + 2]; + } + r = Math.floor(r / (data.length / 4 / step)); + g = Math.floor(g / (data.length / 4 / step)); + b = Math.floor(b / (data.length / 4 / step)); + return {r, g, b}; +} + function rgbToHex(r, g, b) { return "#" + [r, g, b].map(x => x.toString(16).padStart(2, '0')).join(''); } @@ -47,12 +69,12 @@ function LightenDarkenColor(col, amt) { } function getContrastYIQ(hexcolor) { - var colorrgb = colorRgb(hexcolor); - var colors = colorrgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); - var red = colors[1]; - var green = colors[2]; - var blue = colors[3]; - var brightness = (red * 299) + (green * 587) + (blue * 114); + let colorrgb = colorRgb(hexcolor); + let colors = colorrgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); + let red = colors[1]; + let green = colors[2]; + let blue = colors[3]; + let brightness = (red * 299) + (green * 587) + (blue * 114); brightness = brightness / 255000; return brightness >= 0.5 ? "light" : "dark"; } @@ -82,4 +104,57 @@ function colorRgb(str) { } else { return sColor; } +} + +function setThemeColors(value, r = null, g = null, b = null) { + const cardContents = document.getElementsByClassName('card-content'); + const authorInfo = document.getElementsByClassName('author-info__sayhi'); + + if (value) { + document.documentElement.style.setProperty('--sco-main', value); + document.documentElement.style.setProperty('--sco-main-op', value + '23'); + document.documentElement.style.setProperty('--sco-main-op-deep', value + 'dd'); + document.documentElement.style.setProperty('--sco-main-none', value + '00'); + + if (r && g && b) { + let brightness = Math.round(((parseInt(r) * 299) + (parseInt(g) * 587) + (parseInt(b) * 114)) / 1000); + for (let i = 0; i < cardContents.length; i++) { + cardContents[i].style.setProperty('--sco-card-bg', 'let(--sco-white)'); + } + + for (let i = 0; i < authorInfo.length; i++) { + authorInfo[i].style.setProperty('background', 'let(--sco-white-op)'); + authorInfo[i].style.setProperty('color', 'let(--sco-white)'); + } + } + + document.getElementById("coverdiv").classList.add("loaded"); + initThemeColor(); + } else { + document.documentElement.style.setProperty('--sco-main', 'let(--sco-theme)'); + document.documentElement.style.setProperty('--sco-main-op', 'let(--sco-theme-op)'); + document.documentElement.style.setProperty('--sco-main-op-deep', 'let(--sco-theme-op-deep)'); + document.documentElement.style.setProperty('--sco-main-none', 'let(--sco-theme-none)'); + initThemeColor(); + } +} + +function initThemeColor() { + const currentTop = window.scrollY || document.documentElement.scrollTop; + let themeColor; + if (currentTop > 0) { + themeColor = getComputedStyle(document.documentElement).getPropertyValue('--sco-card-bg'); + } else if (PAGE_CONFIG.is_post) { + themeColor = getComputedStyle(document.documentElement).getPropertyValue('--sco-main'); + } else { + themeColor = getComputedStyle(document.documentElement).getPropertyValue('--sco-background'); + } + changeThemeColor(themeColor); +} + +function changeThemeColor(color) { + const meta = document.querySelector('meta[name="theme-color"]'); + if (meta) { + meta.setAttribute('content', color); + } } \ No newline at end of file diff --git a/source/js/main.js b/source/js/main.js index a1b8e909..96e29252 100644 --- a/source/js/main.js +++ b/source/js/main.js @@ -281,6 +281,20 @@ let sco = { htmlClassList.toggle("hide-aside"); htmlClassList.contains("hide-aside") ? document.querySelector("#consoleHideAside").classList.add("on") : document.querySelector("#consoleHideAside").classList.remove("on"); }, + switchKeyboard: function() { + sco_keyboards = !sco_keyboards; + const consoleKeyboard = document.querySelector("#consoleKeyboard"); + if (sco_keyboards) { + consoleKeyboard.classList.add("on"); + openKeyboard() + localStorage.setItem("keyboard", true); + } else { + closeKeyboard() + consoleKeyboard.classList.remove("on"); + localStorage.setItem("keyboard", false); + document.getElementById('keyboard-tips')?.classList.remove('show') + } + }, initConsoleState: function () { document.documentElement.classList.contains("hide-aside") ? document.querySelector("#consoleHideAside").classList.add("on") : document.querySelector("#consoleHideAside").classList.remove("on") }, @@ -672,7 +686,7 @@ let sco = { element.value = "donotreply@examp.com"; element.dispatchEvent(new Event("input")); }); - } + }, } class hightlight { diff --git a/source/js/search/algolia.js b/source/js/search/algolia.js index 739ee3fa..cdcc6666 100644 --- a/source/js/search/algolia.js +++ b/source/js/search/algolia.js @@ -1,8 +1,10 @@ +let openSearch + window.addEventListener("load", () => { const $searchMask = document.getElementById("search-mask"); const $searchDialog = document.querySelector("#algolia-search .search-dialog"); - const openSearch = () => { + openSearch = () => { utils.animateIn($searchMask, "to_show 0.5s"); $searchDialog.style.display = "block"; setTimeout(() => { @@ -68,7 +70,7 @@ window.addEventListener("load", () => { }); const configure = instantsearch.widgets.configure({ - hitsPerPage: algolia.hits.per_page ?? 5, + hitsPerPage: algolia.hits.per_page || 5, }); const searchBox = instantsearch.widgets.searchBox({ diff --git a/source/js/search/local.js b/source/js/search/local.js index 5134ce36..c6a2befc 100644 --- a/source/js/search/local.js +++ b/source/js/search/local.js @@ -1,8 +1,10 @@ +let openSearch + window.onload = () => { let idx, store = []; const $searchMask = document.getElementById("search-mask"); const $searchDialog = document.querySelector("#local-search .search-dialog"); - const openSearch = () => { + openSearch = () => { utils.animateIn($searchMask, "to_show 0.5s"); $searchDialog.style.display = "block"; setTimeout(() => { diff --git a/source/js/utils.js b/source/js/utils.js index dc484a7e..dafe2f2c 100644 --- a/source/js/utils.js +++ b/source/js/utils.js @@ -243,5 +243,5 @@ const utils = { window.fancyboxRun = true } } - }, + } } \ No newline at end of file