feat: add waline i18n & sync comments

This commit is contained in:
radishzzz 2025-03-06 22:19:34 +00:00
parent fa148ca0c5
commit c2ebc78045
12 changed files with 172 additions and 101 deletions

View file

@ -59,6 +59,6 @@ function setupThemeToggle() {
}
// Initialize click event (on first load or page transition)
document.addEventListener('astro:after-swap', setupThemeToggle)
setupThemeToggle()
document.addEventListener('astro:after-swap', setupThemeToggle)
</script>

View file

@ -1,37 +1,48 @@
---
import { themeConfig } from '@/config'
import { getWalineLang } from '@/utils/ui'
const {
serverURL = '',
emoji = [],
searchGif = false,
search = false,
imageUploader = false,
} = themeConfig.comment?.waline ?? {}
---
{serverURL && (
<>
<link rel="stylesheet" href="https://unpkg.com/@waline/client@v3/dist/waline.css" />
<div id="waline"></div>
<script
is:inline
type="module"
define:vars={{ serverURL, emoji, searchGif, imageUploader }}
>
import { init } from 'https://unpkg.com/@waline/client@v3/dist/waline.js'
init({
el: '#waline',
serverURL,
lang: 'zh',
emoji,
dark: 'auto',
requiredMeta: ['nick'],
imageUploader: false,
highlighter: false,
texRenderer: false,
search: searchGif,
reaction: false,
})
</script>
</>
)}
const currentPath = Astro.url.pathname
const defaultLocale = themeConfig.global.locale
const walineLang = getWalineLang(currentPath, defaultLocale)
const walineConfigJson = JSON.stringify({
serverURL,
lang: walineLang,
emoji,
search,
imageUploader,
});
---
<div id="waline" data-config={walineConfigJson}></div>
<script>
import { init } from '@waline/client'
import '@waline/client/style'
function initWaline() {
const walineEl = document.getElementById('waline')
const walineConfig = JSON.parse(walineEl?.dataset.config || '{}')
init({
el: '#waline',
path: window.location.pathname.replace(/^\/([a-z]{2}(-[a-z]{2})?)\//, '/'),
dark: 'auto',
requiredMeta: ['nick'],
highlighter: false,
texRenderer: false,
reaction: [],
...walineConfig,
})
}
initWaline()
document.addEventListener('astro:after-swap', initWaline)
</script>

View file

View file

@ -26,8 +26,8 @@ function initScrollbar() {
}
}
document.addEventListener('astro:after-swap', initScrollbar)
initScrollbar()
document.addEventListener('astro:after-swap', initScrollbar)
</script>
<style is:global>

View file

@ -43,9 +43,13 @@ export const themeConfig: ThemeConfig = {
comment: {
waline: {
serverURL: 'https://comment.radishzz.cc', // Waline server URL
emoji: ['https://unpkg.com/@waline/emojis@1.2.0/tw-emoji'], // see more at https://waline.js.org/en/guide/features/emoji.html
searchGif: false, // whether to enable GIF search
imageUploader: false, // whether to enable image uploader
emoji: [
'https://unpkg.com/@waline/emojis@1.2.0/tw-emoji',
// 'https://unpkg.com/@waline/emojis@1.2.0/bmoji',
// see more at https://waline.js.org/en/guide/features/emoji.html
],
search: false, // whether to enable GIF search
imageUploader: false, // whether to enable image uploader. BUG
},
},
// COMMENT SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END

View file

@ -1,4 +1,5 @@
---
import Waline from '@/components/Comments/Waline.astro'
import Layout from '@/layouts/Layout.astro'
import { checkSlugDuplication } from '@/utils/content'
import { generateMultiLangPostPaths } from '@/utils/i18n'
@ -28,4 +29,5 @@ const { Content, remarkPluginFrontmatter } = await post.render()
</time>
<Content />
</article>
<Waline />
</Layout>

View file

@ -1,9 +1,9 @@
---
import Waline from '@/components/Comments/Waline.astro'
import Layout from '@/layouts/Layout.astro'
import { checkSlugDuplication } from '@/utils/content'
import { generatePostPaths } from '@/utils/i18n'
import { getCollection } from 'astro:content'
import Waline from '@/components/Comments/Waline.astro'
export async function getStaticPaths() {
const posts = await getCollection('posts')

View file

@ -40,7 +40,7 @@ export interface ThemeConfig {
waline?: {
serverURL?: string
emoji?: string[]
searchGif?: boolean
search?: boolean
imageUploader?: boolean
}
}

View file

@ -7,6 +7,18 @@ export const langMap: Record<string, string[]> = {
'es': ['es-ES'],
'ru': ['ru-RU'],
}
// Waline Language Map
// see more at https://waline.js.org/guide/i18n.html
export const walineLocaleMap: Record<string, string> = {
'zh': 'zh-CN',
'zh-tw': 'zh-TW',
'ja': 'jp-JP', // Waline uses jp-JP not ja-JP
'en': 'en-US',
'es': 'es-ES',
'ru': 'ru-RU',
}
// Standard Language Code
export const langCode = Object.values(langMap).flat()
// Abbreviated Language Code
@ -44,3 +56,19 @@ export const ui = {
about: 'О себе',
},
}
/**
* Get the language code of Waline
* @param currentPath Current page path
* @param defaultLocale Default language
* @returns Corresponding Waline language code
*/
export function getWalineLang(currentPath: string, defaultLocale: string): string {
// Extract language code from path
const pathLang = Object.keys(walineLocaleMap).find(code =>
currentPath.startsWith(`/${code}/`),
)
// Return found path language or default language
const lang = pathLang || defaultLocale
return walineLocaleMap[lang as keyof typeof walineLocaleMap]
}