diff --git a/.github/workflows/autoprefixer.yml b/.github/workflows/autoprefixer.yml index b860bb4..fe3d857 100644 --- a/.github/workflows/autoprefixer.yml +++ b/.github/workflows/autoprefixer.yml @@ -21,7 +21,7 @@ jobs: npm run autoprefixer - name: Create Pull Request - uses: peter-evans/create-pull-request@v6 + uses: peter-evans/create-pull-request@v7 with: branch: autoprefixer branch-suffix: timestamp diff --git a/README.md b/README.md index 9313ea7..de74760 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ For more details about the features please visit [here](https://toha-guides.netl - Deutsch - Español - 简体中文 +- 繁體中文 - हिन्दी - Italiano - 日本語 diff --git a/assets/scripts/features/index.js b/assets/scripts/features/index.js index 9682acf..9e4fb4f 100644 --- a/assets/scripts/features/index.js +++ b/assets/scripts/features/index.js @@ -10,6 +10,10 @@ if (process.env.FEATURE_DARKMODE === '1') { import('./darkmode') } +if (process.env.FEATURE_THEME === '1') { + import('./theme') +} + if (process.env.FEATURE_FLOWCHART === '1') { import('./flowchart') } diff --git a/assets/scripts/features/theme/index.js b/assets/scripts/features/theme/index.js new file mode 100644 index 0000000..3d7ae08 --- /dev/null +++ b/assets/scripts/features/theme/index.js @@ -0,0 +1,88 @@ +import * as params from '@params'; +const PERSISTENCE_KEY = 'theme-scheme' + +const themeOptions = params.theme || {} +const THEME_DARK = typeof themeOptions.dark === 'undefined' ? true : themeOptions.dark; +const THEME_LIGHT = typeof themeOptions.light === 'undefined' ? true : themeOptions.light; +const THEME_DEFAULT = typeof themeOptions.default === 'undefined' ? "system" : themeOptions.default; + +window.addEventListener('load', async () => { + const menu = document.getElementById('themeMenu') + const $icon = document.getElementById('navbar-theme-icon-svg') + if (menu == null || $icon == null) return + + const btns = menu.getElementsByTagName('a') + const iconMap = Array.from(btns).reduce((map, btn) => { + const $img = btn.getElementsByTagName('img')[0] + map[btn.dataset.scheme] = $img.src + return map + }, {}) + + + function checkScheme(scheme) { + if (THEME_LIGHT === false) return "dark" + if (THEME_DARK === false) return "light" + return scheme + } + + function loadScheme() { + return localStorage.getItem(PERSISTENCE_KEY) || loadDefaultScheme() + } + + function loadDefaultScheme() { + return THEME_DEFAULT || "system" + } + + function saveScheme(scheme) { + localStorage.setItem(PERSISTENCE_KEY, scheme) + } + + function getPreferredColorScheme() { + const isDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches; + return isDarkMode ? "dark" : "light"; + } + + function setScheme(newScheme) { + let theme = newScheme + if (newScheme === 'system') { + theme = getPreferredColorScheme() + } + // set data-theme attribute on html tag + document.querySelector("html").dataset.theme = theme; + + // update icon + $icon.src = iconMap[newScheme] + + // save preference to local storage + saveScheme(newScheme) + + setImages(theme) + } + + const checkedScheme = checkScheme(loadScheme()) + setScheme(checkedScheme) + + Array.from(menu.getElementsByTagName('a')).forEach((btn) => { + btn.addEventListener('click', () => { + const { scheme } = btn.dataset + setScheme(scheme) + }) + }) +}) + +function setImages(newScheme) { + const els = Array.from(document.getElementsByClassName('logo-holder')); + for (const el of els) { + const light = el.querySelector('.light-logo'); + const dark = el.querySelector('.dark-logo'); + + if (newScheme === "dark" && dark !== null) { + if (light !== null) light.style.display = 'none' + dark.style.display = 'inline' + } + else { + if (light !== null) light.style.display = 'inline' + if (dark !== null) dark.style.display = 'none' + } + } +} \ No newline at end of file diff --git a/assets/styles/components/cards.scss b/assets/styles/components/cards.scss index 22c9e86..40f51bd 100644 --- a/assets/styles/components/cards.scss +++ b/assets/styles/components/cards.scss @@ -22,7 +22,8 @@ } .card-img-top { - object-fit: cover; + -o-object-fit: cover; + object-fit: cover; @include transition(); } @@ -61,7 +62,8 @@ &:focus { .card-img-top { transform: scale(1.2); - object-fit: cover; + -o-object-fit: cover; + object-fit: cover; @include transition(); } } diff --git a/assets/styles/components/links.scss b/assets/styles/components/links.scss index 4372bcc..fdc0f4f 100644 --- a/assets/styles/components/links.scss +++ b/assets/styles/components/links.scss @@ -8,7 +8,8 @@ a { &:hover, &:focus { - text-decoration: get-light-color('hover-over-accent-color') underline; + -webkit-text-decoration: get-light-color('hover-over-accent-color') underline; + text-decoration: get-light-color('hover-over-accent-color') underline; color: get-light-color('hover-over-accent-color'); @include transition(); } @@ -66,7 +67,8 @@ html[data-theme='dark'] { &:hover, &:focus { - text-decoration: get-dark-color('hover-over-accent-color') underline; + -webkit-text-decoration: get-dark-color('hover-over-accent-color') underline; + text-decoration: get-dark-color('hover-over-accent-color') underline; color: get-dark-color('hover-over-accent-color'); } } diff --git a/assets/styles/components/tables.scss b/assets/styles/components/tables.scss index 0c8a069..a9b5a00 100644 --- a/assets/styles/components/tables.scss +++ b/assets/styles/components/tables.scss @@ -96,6 +96,10 @@ html[data-theme='dark'] { } } .gist { + &::-moz-selection{ + background: get-dark-color('text-color'); + color: get-dark-color('inverse-text-color'); + } &::selection{ background: get-dark-color('text-color'); color: get-dark-color('inverse-text-color'); diff --git a/assets/styles/layouts/list.scss b/assets/styles/layouts/list.scss index 56beb92..f3a33aa 100644 --- a/assets/styles/layouts/list.scss +++ b/assets/styles/layouts/list.scss @@ -1,6 +1,6 @@ -// in Hugo, Page kind can be either "section" or "page". -// if it is section, then it's a page with a list of items, for example /posts -// if it is page, then it is a single page. +/* in Hugo, Page kind can be either "section" or "page".*/ +/* if it is section, then it's a page with a list of items, for example /posts*/ +/* if it is page, then it is a single page.*/ body.kind-section, body.kind-term, body.kind-page { diff --git a/assets/styles/layouts/main.scss b/assets/styles/layouts/main.scss index eb30ce8..509c313 100644 --- a/assets/styles/layouts/main.scss +++ b/assets/styles/layouts/main.scss @@ -53,7 +53,6 @@ body { ol > ol, li > ol, li > ul { - -webkit-padding-start: 1rem; padding-inline-start: 1rem; } } diff --git a/assets/styles/sections/footer.scss b/assets/styles/sections/footer.scss index 112bfda..423de07 100644 --- a/assets/styles/sections/footer.scss +++ b/assets/styles/sections/footer.scss @@ -13,7 +13,8 @@ @include transition(); &:hover { margin-left: 5px; - text-decoration: get-light-color('muted-text-color') underline; + -webkit-text-decoration: get-light-color('muted-text-color') underline; + text-decoration: get-light-color('muted-text-color') underline; @include transition(); } } @@ -79,7 +80,8 @@ html[data-theme='dark'] { a { color: get-dark-color('muted-text-color'); &:hover { - text-decoration: get-dark-color('muted-text-color') underline; + -webkit-text-decoration: get-dark-color('muted-text-color') underline; + text-decoration: get-dark-color('muted-text-color') underline; } } diff --git a/assets/styles/sections/pdf-viewer.scss b/assets/styles/sections/pdf-viewer.scss index 44b700f..948c080 100644 --- a/assets/styles/sections/pdf-viewer.scss +++ b/assets/styles/sections/pdf-viewer.scss @@ -42,7 +42,4 @@ @keyframes spin { to { -webkit-transform: rotate(360deg); } } - @-webkit-keyframes spin { - to { -webkit-transform: rotate(360deg); } - } } \ No newline at end of file diff --git a/exampleSite/hugo.yaml b/exampleSite/hugo.yaml index 88b75b8..65ca04c 100644 --- a/exampleSite/hugo.yaml +++ b/exampleSite/hugo.yaml @@ -91,9 +91,19 @@ params: # Configure various features of this theme features: - # Enable dark theme - darkMode: + # [Deprecated] Enable dark theme + # This is a deprecated setting, but has not been removed to maintain backward compatibility + # If `theme` is set, the `darkMode` setting will be discarded. + # darkMode: + # enable: true + + # Configure theme color settings + theme: enable: true + services: + light: true # enable light theme. default "true" + dark: true # enable dark theme. default "true" + default: system # can be either light, dark or system. default "system" # Enable and configure portfolio portfolio: diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..9837fd0 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/hugo-toha/hugo-toha.github.io v0.0.0-20240730212302-83b19f7bd3b7 h1:RRonNzaf6/Ou9PqfXeKiRywkd+9KY7SVgfGBQXqXshM= +github.com/hugo-toha/hugo-toha.github.io v0.0.0-20240730212302-83b19f7bd3b7/go.mod h1:yWw1t3trnfzv4t1lA9zh5pSsI0+kqqyg58ir8/kt6zk= diff --git a/i18n/zh-tw.toml b/i18n/zh-tw.toml index 5767f9b..c571c2c 100644 --- a/i18n/zh-tw.toml +++ b/i18n/zh-tw.toml @@ -9,10 +9,10 @@ other = "文章" other = "目錄" [tags] -other = "标签" +other = "標籤" [categories] -other = "类别" +other = "類別" [at] other = "at" @@ -42,7 +42,7 @@ other = "在此輸入您的電子郵件地址" other = "輸入您的電子郵件地址,即表示您同意接受本網站的最新消息" [submit] -other = "提交" +other = "送出" [hugoAttributionText] other = "Powered by" @@ -63,10 +63,10 @@ other = "改善此頁面" other = "/" [publications] -other = "出版" +other = "著作" [taken_courses] -other = "修習課程" +other = "修課內容" [course_name] other = "課程名稱" @@ -123,4 +123,4 @@ other = "筆記" other = "免責聲明" [search] -other = "搜索" +other = "搜尋" diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index 65f6364..dc1850a 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -12,7 +12,7 @@ {{- partial "analytics.html" . -}}