valaxy-theme-yun 0.28.0-beta.6 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/App.vue +1 -3
- package/components/YunCategory.vue +2 -2
- package/components/YunLayoutPostTag.vue +2 -2
- package/components/YunPostCategories.vue +2 -2
- package/components/YunPostMeta.vue +2 -2
- package/components/YunPostTags.vue +2 -2
- package/composables/helper.ts +42 -20
- package/layouts/categories.vue +2 -2
- package/layouts/tags.vue +3 -2
- package/package.json +4 -4
- package/pages/posts/index.vue +0 -1
- package/components/YunDebug.vue +0 -51
package/App.vue
CHANGED
|
@@ -55,14 +55,12 @@ onMounted(() => {
|
|
|
55
55
|
document.documentElement.style.setProperty('--vh', `${window.innerHeight * 0.01}px`)
|
|
56
56
|
app.showLoading = false
|
|
57
57
|
})
|
|
58
|
-
|
|
59
|
-
const isDev = import.meta.env.DEV
|
|
60
58
|
</script>
|
|
61
59
|
|
|
62
60
|
<template>
|
|
63
61
|
<TooltipProvider>
|
|
64
62
|
<YunStratoApp v-if="yun.isStrato" />
|
|
65
|
-
<
|
|
63
|
+
<ValaxyDebug />
|
|
66
64
|
|
|
67
65
|
<YunPageHeaderGradient />
|
|
68
66
|
<YunNavMenu />
|
|
@@ -25,7 +25,7 @@ const router = useRouter()
|
|
|
25
25
|
|
|
26
26
|
const collapse = ref(props.collapsable)
|
|
27
27
|
const { t } = useI18n()
|
|
28
|
-
const { $
|
|
28
|
+
const { $tCategory } = useValaxyI18n()
|
|
29
29
|
|
|
30
30
|
const postCollapseElRef = ref<HTMLElement>()
|
|
31
31
|
const { show } = useInvisibleElement(postCollapseElRef)
|
|
@@ -75,7 +75,7 @@ const motionVariants = props.level === 1
|
|
|
75
75
|
@click="jumpToDisplayCategory(parentKey)"
|
|
76
76
|
>
|
|
77
77
|
<span>
|
|
78
|
-
{{ category.name === 'Uncategorized' ? t('category.uncategorized') : $
|
|
78
|
+
{{ category.name === 'Uncategorized' ? t('category.uncategorized') : $tCategory(category.name) }}
|
|
79
79
|
</span>
|
|
80
80
|
<span class="rounded-full px-1.5 bg-black/5 shadow-sm op-60" text="xs">
|
|
81
81
|
{{ category.total }}
|
|
@@ -8,7 +8,7 @@ const props = defineProps<{
|
|
|
8
8
|
count: number
|
|
9
9
|
}>()
|
|
10
10
|
|
|
11
|
-
const { $
|
|
11
|
+
const { $tTag } = useValaxyI18n()
|
|
12
12
|
|
|
13
13
|
const motionVariants = yunSpringVariants({ i: props.i || 0, delay: 25 })
|
|
14
14
|
</script>
|
|
@@ -19,7 +19,7 @@ const motionVariants = yunSpringVariants({ i: props.i || 0, delay: 25 })
|
|
|
19
19
|
inline-flex my="2" p="1"
|
|
20
20
|
class="post-tag cursor-pointer items-baseline leading-4"
|
|
21
21
|
>
|
|
22
|
-
<span inline-flex>#{{ $
|
|
22
|
+
<span inline-flex>#{{ $tTag(title) }}</span>
|
|
23
23
|
<span inline-flex text="xs">[{{ count }}]</span>
|
|
24
24
|
</span>
|
|
25
25
|
</template>
|
|
@@ -6,7 +6,7 @@ defineProps<{
|
|
|
6
6
|
categories: Post['categories']
|
|
7
7
|
}>()
|
|
8
8
|
|
|
9
|
-
const { $
|
|
9
|
+
const { $tCategory } = useValaxyI18n()
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<template>
|
|
@@ -22,7 +22,7 @@ const { $t } = useValaxyI18n()
|
|
|
22
22
|
>
|
|
23
23
|
<div m="x-1" inline-flex i-ri-folder-2-line />
|
|
24
24
|
<span>
|
|
25
|
-
{{ Array.isArray(categories) ? categories.map($
|
|
25
|
+
{{ Array.isArray(categories) ? categories.map($tCategory).join(' / ') : $tCategory(categories || '') }}
|
|
26
26
|
</span>
|
|
27
27
|
</RouterLink>
|
|
28
28
|
</template>
|
|
@@ -3,8 +3,6 @@ import type { Post } from 'valaxy'
|
|
|
3
3
|
import { useSiteConfig } from 'valaxy'
|
|
4
4
|
import { useI18n } from 'vue-i18n'
|
|
5
5
|
|
|
6
|
-
// @TODO: add edit by vscode directly when dev
|
|
7
|
-
|
|
8
6
|
defineProps<{
|
|
9
7
|
// FrontMatter
|
|
10
8
|
frontmatter: Post
|
|
@@ -54,6 +52,8 @@ const siteConfig = useSiteConfig()
|
|
|
54
52
|
</div>
|
|
55
53
|
|
|
56
54
|
<YunWalineMeta />
|
|
55
|
+
|
|
56
|
+
<ValaxyOpenInEditor />
|
|
57
57
|
</div>
|
|
58
58
|
</div>
|
|
59
59
|
</template>
|
|
@@ -6,7 +6,7 @@ defineProps<{
|
|
|
6
6
|
tags: Post['tags']
|
|
7
7
|
}>()
|
|
8
8
|
|
|
9
|
-
const { $
|
|
9
|
+
const { $tTag } = useValaxyI18n()
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<template>
|
|
@@ -22,7 +22,7 @@ const { $t } = useValaxyI18n()
|
|
|
22
22
|
border
|
|
23
23
|
hover="bg-blue-500 text-white"
|
|
24
24
|
>
|
|
25
|
-
<span>{{ $
|
|
25
|
+
<span>{{ $tTag(tag) }}</span>
|
|
26
26
|
</RouterLink>
|
|
27
27
|
</div>
|
|
28
28
|
</template>
|
package/composables/helper.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isClient, useEventListener } from '@vueuse/core'
|
|
2
|
-
import { onMounted, ref
|
|
2
|
+
import { onMounted, ref } from 'vue'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* fetch data from source, and random
|
|
@@ -9,27 +9,49 @@ import { onMounted, ref, watch } from 'vue'
|
|
|
9
9
|
export function useRandomData<T>(source: string | T[], random = false) {
|
|
10
10
|
const data = ref<T[]>()
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
async function fetchData(url: string) {
|
|
13
|
+
if (!isClient)
|
|
14
|
+
return
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const res = await fetch(url)
|
|
18
|
+
if (!res.ok)
|
|
16
19
|
return
|
|
17
|
-
rawData = (await
|
|
20
|
+
const rawData = (await res.json() as T[]) || []
|
|
21
|
+
data.value = random ? rawData.toSorted(() => Math.random() - 0.5) : rawData
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// Network or JSON parse failure — leave data unchanged
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (typeof source === 'string') {
|
|
29
|
+
// Defer URL fetching to onMounted to prevent hydration mismatch.
|
|
30
|
+
// During SSG, the fetch is skipped (data stays undefined → empty list).
|
|
31
|
+
// If the fetch runs during hydration via an immediate watcher, data would
|
|
32
|
+
// update before hydration completes, causing a DOM mismatch error.
|
|
33
|
+
//
|
|
34
|
+
// Note: `source` is a plain parameter (not reactive), so no watch is needed.
|
|
35
|
+
// Callers pass `props.links` / `props.girls` which are stable for the
|
|
36
|
+
// component's lifetime.
|
|
37
|
+
if (isClient) {
|
|
38
|
+
onMounted(() => fetchData(source))
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// For static array data, set the initial value directly so SSR and client
|
|
43
|
+
// render the same content (original order, no random).
|
|
44
|
+
// Random sorting is deferred to onMounted below.
|
|
45
|
+
data.value = source as T[]
|
|
46
|
+
|
|
47
|
+
// Apply random sorting only after hydration is complete
|
|
48
|
+
if (random && isClient) {
|
|
49
|
+
onMounted(() => {
|
|
50
|
+
if (data.value) {
|
|
51
|
+
data.value = data.value.toSorted(() => Math.random() - 0.5)
|
|
52
|
+
}
|
|
53
|
+
})
|
|
18
54
|
}
|
|
19
|
-
else { rawData = source }
|
|
20
|
-
|
|
21
|
-
// Always use original order during initial render to avoid hydration mismatch.
|
|
22
|
-
// Random sorting is deferred to onMounted (see below).
|
|
23
|
-
data.value = rawData
|
|
24
|
-
}, { immediate: true })
|
|
25
|
-
|
|
26
|
-
// Apply random sorting only after hydration is complete
|
|
27
|
-
if (random && isClient) {
|
|
28
|
-
onMounted(() => {
|
|
29
|
-
if (data.value) {
|
|
30
|
-
data.value = data.value.toSorted(() => Math.random() - 0.5)
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
55
|
}
|
|
34
56
|
|
|
35
57
|
return {
|
package/layouts/categories.vue
CHANGED
|
@@ -36,7 +36,7 @@ const posts = computed(() => {
|
|
|
36
36
|
return list
|
|
37
37
|
})
|
|
38
38
|
|
|
39
|
-
const { $tO } = useValaxyI18n()
|
|
39
|
+
const { $tO, $tCategory } = useValaxyI18n()
|
|
40
40
|
|
|
41
41
|
useSchemaOrg([
|
|
42
42
|
defineWebPage({
|
|
@@ -76,7 +76,7 @@ useSchemaOrg([
|
|
|
76
76
|
<YunCard v-if="curCategory" class="post-collapse-container" m="t-4" w="full">
|
|
77
77
|
<YunPageHeader
|
|
78
78
|
m="t-10"
|
|
79
|
-
:title="curCategory === 'Uncategorized' ? t('category.uncategorized') : curCategory.split('/').join(' / ')"
|
|
79
|
+
:title="curCategory === 'Uncategorized' ? t('category.uncategorized') : curCategory.split('/').map($tCategory).join(' / ')"
|
|
80
80
|
icon="i-ri-folder-open-line"
|
|
81
81
|
/>
|
|
82
82
|
<YunPostCollapse w="full" m="b-4" p="x-20 lt-sm:x-5" :posts="posts" />
|
package/layouts/tags.vue
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import { defineWebPage, useSchemaOrg } from '@unhead/schema-org/vue'
|
|
3
|
-
import { useFrontmatter, useInvisibleElement, usePostTitle, useSiteStore } from 'valaxy'
|
|
3
|
+
import { useFrontmatter, useInvisibleElement, usePostTitle, useSiteStore, useValaxyI18n } from 'valaxy'
|
|
4
4
|
import { computed, ref } from 'vue'
|
|
5
5
|
import { useI18n } from 'vue-i18n'
|
|
6
6
|
import { useRoute, useRouter } from 'vue-router'
|
|
@@ -18,6 +18,7 @@ const router = useRouter()
|
|
|
18
18
|
const themeConfig = useThemeConfig()
|
|
19
19
|
|
|
20
20
|
const { t } = useI18n()
|
|
21
|
+
const { $tTag } = useValaxyI18n()
|
|
21
22
|
const frontmatter = useFrontmatter()
|
|
22
23
|
const { tags, getTagStyle } = useYunTags({
|
|
23
24
|
primary: themeConfig.value.colors.primary,
|
|
@@ -100,7 +101,7 @@ const tagArr = computed(() => [...tags.value].sort())
|
|
|
100
101
|
|
|
101
102
|
<template #main-nav-before>
|
|
102
103
|
<YunCard v-if="curTag" ref="collapse" m="t-4" w="full">
|
|
103
|
-
<YunPageHeader :title="curTag" icon="i-ri-hashtag" />
|
|
104
|
+
<YunPageHeader :title="$tTag(curTag)" icon="i-ri-hashtag" />
|
|
104
105
|
<YunPostCollapse w="full" m="b-4" p="x-20 lt-sm:x-5" :posts="posts" />
|
|
105
106
|
</YunCard>
|
|
106
107
|
</template>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "valaxy-theme-yun",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.28.0
|
|
4
|
+
"version": "0.28.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"email": "me@yunyoujun.cn",
|
|
7
7
|
"name": "YunYouJun",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@ctrl/tinycolor": "^4.2.0",
|
|
26
26
|
"@explosions/fireworks": "^0.2.0",
|
|
27
27
|
"@iconify-json/ant-design": "^1.2.5",
|
|
28
|
-
"@iconify-json/simple-icons": "^1.2.
|
|
28
|
+
"@iconify-json/simple-icons": "^1.2.75",
|
|
29
29
|
"@vueuse/motion": "^3.0.3",
|
|
30
30
|
"animejs": "^4.3.6",
|
|
31
31
|
"gsap": "^3.14.2",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/animejs": "^3.1.13",
|
|
36
|
-
"valaxy
|
|
37
|
-
"valaxy": "0.
|
|
36
|
+
"valaxy": "0.28.0",
|
|
37
|
+
"valaxy-addon-waline": "0.2.1"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"release": "bumpp && pnpm publish"
|
package/pages/posts/index.vue
CHANGED
package/components/YunDebug.vue
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { computed, ref } from 'vue'
|
|
3
|
-
import { useYunAppStore } from '../stores'
|
|
4
|
-
|
|
5
|
-
const yun = useYunAppStore()
|
|
6
|
-
|
|
7
|
-
const infoList = computed(() => {
|
|
8
|
-
return [
|
|
9
|
-
{
|
|
10
|
-
label: 'xs',
|
|
11
|
-
value: yun.size.isXs,
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
label: 'sm',
|
|
15
|
-
value: yun.size.isSm,
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
label: 'md',
|
|
19
|
-
value: yun.size.isMd,
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
label: 'lg',
|
|
23
|
-
value: yun.size.isLg,
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
label: 'xl',
|
|
27
|
-
value: yun.size.isXl,
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
label: '2xl',
|
|
31
|
-
value: yun.size.is2xl,
|
|
32
|
-
},
|
|
33
|
-
]
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
const show = ref(true)
|
|
37
|
-
</script>
|
|
38
|
-
|
|
39
|
-
<template>
|
|
40
|
-
<div
|
|
41
|
-
v-if="show"
|
|
42
|
-
class="bg-black/50 fixed bottom-20 left-2 p-2 gap-1 rounded z-9999"
|
|
43
|
-
text="xs white" flex="~ col"
|
|
44
|
-
@click="show = false"
|
|
45
|
-
>
|
|
46
|
-
<div v-for="item in infoList" :key="item.label" class="gap-2 inline-flex">
|
|
47
|
-
<span class="w-6" font="bold">{{ item.label }}: </span>
|
|
48
|
-
<span>{{ item.value ? '✅' : '❌' }}</span>
|
|
49
|
-
</div>
|
|
50
|
-
</div>
|
|
51
|
-
</template>
|