valaxy 0.13.11 → 0.14.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/client/App.vue CHANGED
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { computed, onBeforeMount, provide, ref } from 'vue'
2
+ import { computed, provide, ref } from 'vue'
3
3
  import { useHead, useSeoMeta } from '@vueuse/head'
4
4
  // @ts-expect-error virtual module
5
5
  import ValaxyUserApp from '/@valaxyjs/UserAppVue'
@@ -66,11 +66,6 @@ useSeoMeta({
66
66
 
67
67
  const onContentUpdated = ref()
68
68
  provide('onContentUpdated', onContentUpdated)
69
-
70
- onBeforeMount(() => {
71
- // for browser with nav bar height
72
- document.documentElement.style.setProperty('--app-height', `${window.innerHeight}px`)
73
- })
74
69
  </script>
75
70
 
76
71
  <template>
@@ -1,3 +1,5 @@
1
+ import type { MaybeRef } from '@vueuse/core'
2
+ import { computed, unref } from 'vue'
1
3
  import type { Post } from '../..'
2
4
  import { useSiteStore } from '../stores'
3
5
 
@@ -5,126 +7,148 @@ export interface BaseCategory {
5
7
  total: number
6
8
  }
7
9
 
8
- export interface ParentCategory extends BaseCategory {
9
- children: Categories
10
- }
11
-
12
- export interface PostCategory extends BaseCategory {
13
- posts: Post[]
10
+ export interface CategoryList {
11
+ /**
12
+ * category name
13
+ */
14
+ name: string
15
+ /**
16
+ * total posts
17
+ */
18
+ total: number
19
+ children: (Post | CategoryList)[]
14
20
  }
21
+ export type Category = CategoryList
22
+ export type Categories = (Post | CategoryList)[]
15
23
 
16
- export type Category = ParentCategory | PostCategory
17
-
18
- // export type Categories = Map<string, Post[] | Category>
19
- export type Categories = Map<string, Category>
20
-
21
- export const isParentCategory = (category: any): category is ParentCategory => category.children
24
+ // todo write unit test
25
+ export const isCategoryList = (category: any): category is CategoryList => category.children
22
26
 
23
27
  /**
24
28
  * get categories from posts
29
+ * category: A/B/C
30
+ * {
31
+ * name: 'A',
32
+ * total: 1,
33
+ * children: [
34
+ * {
35
+ * name: 'B'
36
+ * total: 1,
37
+ * children: [{ name: 'C', total: 1, children: [{ title: '' }] }]
38
+ * }
39
+ * ]
40
+ * }
25
41
  * @returns
26
42
  */
27
- export function useCategory(category?: string, posts: Post[] = []): ParentCategory {
28
- if (!posts.length) {
29
- const site = useSiteStore()
30
- posts = site.postList
31
- }
43
+ export function useCategory(category?: MaybeRef<string>, posts: Post[] = []) {
44
+ return computed(() => {
45
+ const categories = unref(category)
32
46
 
33
- const categoryMap: Category = {
34
- total: posts.length,
35
- children: new Map([
36
- ['Uncategorized', { total: 0, posts: [] }],
37
- ]),
38
- }
47
+ if (!posts.length) {
48
+ const site = useSiteStore()
49
+ posts = site.postList
50
+ }
51
+
52
+ const categoryList: CategoryList = {
53
+ name: 'All',
54
+ total: posts.length,
55
+ children: [
56
+ { name: 'Uncategorized', total: 0, children: [] },
57
+ ],
58
+ }
59
+
60
+ const uncategorized = categoryList.children.find(item => item.name === 'Uncategorized')!
39
61
 
40
- const uncategorized = categoryMap.children.get('Uncategorized') as PostCategory
41
-
42
- posts.forEach((post: Post) => {
43
- if (post.categories) {
44
- if (Array.isArray(post.categories)) {
45
- const len = post.categories.length
46
-
47
- let c: ParentCategory = categoryMap
48
- post.categories.forEach((category, i) => {
49
- if (i === len - 1) {
50
- if (c.children.has(category)) {
51
- const cur = c.children.get(category) as PostCategory
52
- if (cur.posts) {
53
- cur.total += 1
54
- cur.posts!.push(post)
62
+ posts.forEach((post: Post) => {
63
+ if (post.categories) {
64
+ if (Array.isArray(post.categories)) {
65
+ const len = post.categories.length
66
+
67
+ let curCategoryList: CategoryList = categoryList
68
+ let parentCategory: CategoryList = curCategoryList
69
+
70
+ post.categories.forEach((categoryName, i) => {
71
+ curCategoryList.total += 1
72
+ curCategoryList = (curCategoryList.children.find(item => item.name === categoryName)) as CategoryList
73
+
74
+ if (!curCategoryList) {
75
+ curCategoryList = {
76
+ name: categoryName,
77
+ total: 0,
78
+ children: [],
55
79
  }
80
+ parentCategory.children.push(curCategoryList)
56
81
  }
57
- else {
58
- c.children?.set(category, {
59
- total: 1,
60
- posts: [post],
61
- })
82
+
83
+ if (i === len - 1) {
84
+ curCategoryList.children.push(post)
85
+ curCategoryList.total += 1
62
86
  }
87
+
88
+ parentCategory = curCategoryList
89
+ })
90
+ }
91
+ else {
92
+ // for string
93
+ const categoryName = post.categories
94
+ const curCategory = categoryList.children.find(item => item.name === categoryName)
95
+ if (curCategory) {
96
+ curCategory.total += 1
97
+ curCategory.children.push(post)
63
98
  }
64
99
  else {
65
- if (c.children?.has(category)) {
66
- const cur = c.children.get(category) as ParentCategory
67
- cur.total += 1
68
- c = cur
69
- }
70
- else {
71
- const temp = {
72
- total: 1,
73
- children: new Map(),
74
- }
75
- c.children?.set(category, temp)
76
- c = temp
77
- }
100
+ categoryList.children.push({
101
+ name: categoryName,
102
+ total: 1,
103
+ children: [post],
104
+ })
78
105
  }
79
- })
106
+ }
80
107
  }
81
108
  else {
82
- // for string
83
- const category = post.categories
84
- if (categoryMap.children.has(category)) {
85
- const cur = categoryMap.children.get(category) as PostCategory
86
- cur.total += 1
87
- cur.posts.push(post)
109
+ uncategorized.total += 1
110
+ uncategorized.children.push(post)
111
+ }
112
+ })
113
+
114
+ // `top` had been sorted in routes
115
+
116
+ // clear uncategorized
117
+ if (uncategorized!.total === 0)
118
+ categoryList.children.shift()
119
+
120
+ if (!categories) {
121
+ return categoryList
122
+ }
123
+ else {
124
+ let curCategoryList = categoryList
125
+ const categoryArr = categories.split('/')
126
+ for (const categoryName of categoryArr) {
127
+ const tempCList = curCategoryList.children.find(item => item.name === categoryName)
128
+ if (tempCList && tempCList.children) {
129
+ curCategoryList = tempCList as CategoryList
88
130
  }
89
131
  else {
90
- categoryMap.children.set(category, {
91
- total: 1,
92
- posts: [post],
93
- })
132
+ console.warn(`Do not have category: ${category}`)
133
+ return categoryList
94
134
  }
95
135
  }
96
- }
97
- else {
98
- uncategorized.total += 1
99
- uncategorized.posts.push(post)
136
+ return curCategoryList
100
137
  }
101
138
  })
139
+ }
102
140
 
103
- categoryMap.children.forEach((child) => {
104
- if ('posts' in child)
105
- child.posts.sort((a, b) => (b.top || 0) - (a.top || 0))
106
- })
107
-
108
- // clear uncategorized
109
- if (uncategorized!.total === 0)
110
- categoryMap.children?.delete('Uncategorized')
141
+ /**
142
+ * remove item from category
143
+ * @param categoryList
144
+ * @param categoryName
145
+ */
146
+ export function removeItemFromCategory(categoryList: CategoryList, categoryName: string) {
147
+ if (isCategoryList(categoryList)) {
148
+ const categoryArr = categoryName.split('/')
149
+ // todo loop find
150
+ const categoryListItemIndex = categoryList.children.findIndex(item => item.name === categoryArr[0])
111
151
 
112
- if (!category) {
113
- return categoryMap
114
- }
115
- else {
116
- const categoryItem = categoryMap.children.get(category)
117
- if (categoryItem) {
118
- return {
119
- total: categoryItem?.total,
120
- children: new Map([
121
- [category, categoryItem],
122
- ]),
123
- }
124
- }
125
- else {
126
- console.warn(`Do not have category: ${category}`)
127
- return categoryMap
128
- }
152
+ categoryList.children.splice(categoryListItemIndex, 1)
129
153
  }
130
154
  }
@@ -2,7 +2,7 @@ import { useRoute } from 'vue-router'
2
2
  import { computed, inject } from 'vue'
3
3
  import { isClient } from '@vueuse/core'
4
4
 
5
- import type { PageData, Post } from '../../types'
5
+ import type { PageData, Post } from '../..'
6
6
  import { useSiteConfig } from '../config'
7
7
 
8
8
  export function useFrontmatter() {
@@ -7,7 +7,7 @@ import { ref } from 'vue'
7
7
  * @param target
8
8
  * @returns
9
9
  */
10
- export function useInvisibleElement(target: Ref<HTMLElement>) {
10
+ export function useInvisibleElement(target: Ref<HTMLElement | undefined>) {
11
11
  const isVisible = ref(false)
12
12
  const { top } = useElementBounding(target)
13
13
  useIntersectionObserver(target, ([{ isIntersecting }]) => {
@@ -1,12 +1,12 @@
1
- import type { Ref } from 'vue'
1
+ import type { ComputedRef } from 'vue'
2
2
  import { computed } from 'vue'
3
3
  import { useRoute, useRouter } from 'vue-router'
4
4
  import { useI18n } from 'vue-i18n'
5
- import type { Post } from '../..'
5
+ import type { Post } from 'valaxy'
6
6
  import { sortByDate } from '../utils'
7
7
  import { useSiteStore } from '../stores'
8
8
 
9
- export const usePostTitle = (post: Ref<Post>) => {
9
+ export const usePostTitle = (post: ComputedRef<Post>) => {
10
10
  const { locale } = useI18n()
11
11
  return computed(() => {
12
12
  const lang = locale.value === 'zh-CN' ? 'zh' : locale.value
package/client/main.ts CHANGED
@@ -10,7 +10,11 @@ import 'uno.css'
10
10
 
11
11
  import setupMain from './setup/main'
12
12
 
13
- const routes = setupLayouts(__DEV__ ? generatedRoutes : generatedRoutes.filter(i => !i.meta?.frontmatter.draft))
13
+ const routes = setupLayouts(__DEV__
14
+ ? generatedRoutes
15
+ : generatedRoutes.filter(i =>
16
+ !i.meta?.frontmatter.draft && !i.meta?.frontmatter.hide,
17
+ ))
14
18
 
15
19
  // https://github.com/antfu/vite-ssg
16
20
  export const createApp = ViteSSG(
@@ -1,16 +1,18 @@
1
1
  @use "../mixins" as *;
2
2
 
3
3
  $banner-animation-duration: 1s;
4
- $line-animation-duration: 0.4s;
5
4
  $char-animation-duration: 0.4s;
6
5
 
7
6
  #banner {
7
+ --banner-line-height: 0;
8
+ --line-animation-duration: 0.4s;
9
+
8
10
  position: relative;
9
11
  display: flex;
10
12
  flex-direction: column;
11
13
  align-items: center;
12
14
  width: 100%;
13
- height: var(--app-height, 100vh);
15
+ height: var(--banner-height, 100vh);
14
16
  }
15
17
 
16
18
  .banner-char-container {
@@ -19,6 +21,18 @@ $char-animation-duration: 0.4s;
19
21
  align-items: center;
20
22
  }
21
23
 
24
+ .banner-line-container {
25
+ position: relative;
26
+ display: flex;
27
+ flex-direction: column;
28
+ align-items: center;
29
+ height: var(--banner-line-height);
30
+
31
+ &.bottom {
32
+ justify-content: end;
33
+ }
34
+ }
35
+
22
36
  .vertical-line {
23
37
  &-top,
24
38
  &-bottom {
@@ -27,14 +41,13 @@ $char-animation-duration: 0.4s;
27
41
  width: 1px;
28
42
  height: 0;
29
43
  animation-name: extend-line;
30
- animation-duration: $line-animation-duration;
44
+ animation-duration: var(--line-animation-duration);
31
45
  animation-fill-mode: forwards;
32
46
  animation-timing-function: ease-in;
33
47
  }
34
48
 
35
49
  &-bottom {
36
- position: absolute;
37
- bottom: 0;
50
+ flex-direction: column-reverse;
38
51
  }
39
52
  }
40
53
 
@@ -76,7 +89,7 @@ $char-animation-duration: 0.4s;
76
89
  border-right-width: 0px;
77
90
  animation-name: char-move-left;
78
91
  animation-duration: $char-animation-duration;
79
- animation-delay: $line-animation-duration;
92
+ animation-delay: var(--line-animation-duration);
80
93
  animation-fill-mode: forwards;
81
94
  animation-timing-function: ease-out;
82
95
  }
@@ -87,7 +100,7 @@ $char-animation-duration: 0.4s;
87
100
  border-left-width: 0px;
88
101
  animation-name: char-move-right;
89
102
  animation-duration: $char-animation-duration;
90
- animation-delay: $line-animation-duration;
103
+ animation-delay: var(--line-animation-duration);
91
104
  animation-fill-mode: forwards;
92
105
  animation-timing-function: ease-out;
93
106
  }