Skip to content

Commit

Permalink
feat: blog index done, dark-theme WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
maicss committed Nov 16, 2023
1 parent 02d1a98 commit 3ba0916
Show file tree
Hide file tree
Showing 16 changed files with 640 additions and 107 deletions.
13 changes: 0 additions & 13 deletions .vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -105,19 +105,6 @@ export default defineConfig({
],
},
],

// This sidebar gets displayed when a user
// is on `config` directory.
"/blog/": [
{
text: "Config",
items: [
{ text: "Index", link: "/config/" },
{ text: "Three", link: "/config/three" },
{ text: "Four", link: "/config/four" },
],
},
],
},
socialLinks: [{ icon: "github", link: "https://github.com/maicss" }],
footer: {
Expand Down
60 changes: 55 additions & 5 deletions .vitepress/theme/BlogIndex.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,64 @@
<script setup lang="ts">
import { useData } from 'vitepress'
import Article from './Article.vue'
import { data } from './blog.data'
import {ref, computed} from 'vue'
const { frontmatter } = useData()
const PRE_PAGE = 15
const pageTotal = Math.ceil(data.length/PRE_PAGE)
const pageCurrent = ref(1)
const currentPagePosts = computed(() => data.slice((pageCurrent.value - 1) * PRE_PAGE, pageCurrent.value * PRE_PAGE))
const changePage = (page:number|'prev'|'next') => {
if (page === 'prev') {
if (pageCurrent.value !== 1) {
pageCurrent.value = pageCurrent.value - 1
}
} else if (page === 'next') {
if (pageCurrent.value !== pageTotal) {
pageCurrent.value = pageCurrent.value + 1
}
} else {
pageCurrent.value = page
}
}
</script>

<template>
<div class="antialiased dark:bg-slate-900">
<main class="max-w-3xl mx-auto px-4 sm:px-6 xl:max-w-5xl xl:px-0">
<Article />
<main class="max-w-3xl mx-auto px-4 sm:px-6 xl:max-w-5xl xl:px-0 pt-10">
<ul>
<li v-for="item in currentPagePosts" :key="item.url" class="mb-4 hover:scale-105 cursor-pointer overflow-hidden duration-150">
<a :href="item.url" class="flex gap-x-4 h-44 rounded-lg border overflow-hidden blog-index-list-item line-clamp-6 no-underline">
<img :src="'./images/' + item.image" alt="" class="flex-[1_4] object-center object-cover">
<div v-html="item.excerpt" class="prose dark:prose-invert flex-[3_4] py-2 pr-2 h-full overflow-hidden"></div>
</a>
</li>
</ul>
<div class="pagination my-8 select-none" v-if="pageTotal > 1">
<ul class="flex gap-x-4 justify-center items-center">
<li class="bordered rounded w-8 h-8 bg-slate-100 flex justify-center items-center cursor-pointer hover:text-sky-400" @click="changePage('prev')">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z" fill="currentColor" /></svg>
</li>
<li v-for="index in pageTotal" class="bordered rounded w-8 h-8 bg-slate-100 flex justify-center items-center cursor-pointer" :class="[pageCurrent === index ? ' bg-sky-300 text-white' : 'text-black hover:text-sky-300']" @click="changePage(index)">{{ index }}</li>
<li class="bordered rounded w-8 h-8 bg-slate-100 flex justify-center items-center cursor-pointer hover:text-sky-400" @click="changePage('next')">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" fill="currentColor" /></svg>
</li>
</ul>
</div>
</main>
</div>
</template>
</template>

<style>
.blog-index-list-item.no-underline {
text-decoration: none;
}
.vp-doc .header-anchor:before {
content: ''
}
</style>
6 changes: 6 additions & 0 deletions .vitepress/theme/BlogLayout.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<template>
<div>blog index</div>
<!-- <ul>
<li v-for=""></li>
</ul> -->
</template>
143 changes: 73 additions & 70 deletions .vitepress/theme/GiscusLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<script setup lang="ts">
import { useData, useRoute, useRouter } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import { nextTick, onMounted, ref, watch, provide} from 'vue';
import { nextTick, onMounted, ref, watch, provide } from 'vue';
import BlogIndex from './BlogIndex.vue';
const { Layout } = DefaultTheme
const { page, frontmatter, isDark } = useData()
Expand All @@ -14,48 +14,48 @@ const router = useRouter()
const NoCommentPages = ['/', '/pyqt/', '/blog/']
const mountComment = ref(false)

// const
onMounted(() => {
import('giscus')
handleCommentComponent()
});

const handleCommentComponent = () => {
mountComment.value = !NoCommentPages.includes(route.path) || frontmatter.value?.comment || !page.value.isNotFound
const showComment = !NoCommentPages.includes(route.path) && frontmatter.value?.comment !== false && page.value.isNotFound !== true
mountComment.value = showComment
}

const enableTransitions = () =>
'startViewTransition' in document &&
window.matchMedia('(prefers-reduced-motion: no-preference)').matches

provide('toggle-appearance', async ({ clientX: x, clientY: y }: MouseEvent) => {
if (!enableTransitions()) {
isDark.value = !isDark.value
return
}

const clipPath = [
`circle(0px at ${x}px ${y}px)`,
`circle(${Math.hypot(
Math.max(x, innerWidth - x),
Math.max(y, innerHeight - y)
)}px at ${x}px ${y}px)`
]

await document.startViewTransition(async () => {
isDark.value = !isDark.value
await nextTick()
}).ready

document.documentElement.animate(
{ clipPath: isDark.value ? clipPath.reverse() : clipPath },
{
duration: 300,
easing: 'ease-in',
pseudoElement: `::view-transition-${isDark.value ? 'old' : 'new'}(root)`
}
)
})
// const enableTransitions = () =>
// 'startViewTransition' in document &&
// window.matchMedia('(prefers-reduced-motion: no-preference)').matches
//
// provide('toggle-appearance', async ({ clientX: x, clientY: y }: MouseEvent) => {
// if (!enableTransitions()) {
// isDark.value = !isDark.value
// return
// }
//
// const clipPath = [
// `circle(0px at ${x}px ${y}px)`,
// `circle(${Math.hypot(
// Math.max(x, innerWidth - x),
// Math.max(y, innerHeight - y)
// )}px at ${x}px ${y}px)`
// ]

// await document.startViewTransition(async () => {
// isDark.value = !isDark.value
// await nextTick()
// }).ready

// document.documentElement.animate(
// { clipPath: isDark.value ? clipPath.reverse() : clipPath },
// {
// duration: 300,
// easing: 'ease-in',
// pseudoElement: `::view-transition-${isDark.value ? 'old' : 'new'}(root)`
// }
// )
// })

router.onBeforeRouteChange = async (to) => {
if (document.startViewTransition) {
Expand All @@ -64,43 +64,31 @@ router.onBeforeRouteChange = async (to) => {
}

watch(() => route.path, () => {
nextTick().then(() => {
handleCommentComponent()
nextTick().then(handleCommentComponent).then(() => {
if (mountComment.value) {
document.querySelector('#giscus')!.setAttribute('theme', isDark.value ? 'transparent_dark' : 'light')
}
})
})

watch([isDark], () => {
document.querySelector('#giscus')!.setAttribute('theme', isDark.value ? 'transparent_dark' : 'light')
if (mountComment.value) {
document.querySelector('#giscus')!.setAttribute('theme', isDark.value ? 'transparent_dark' : 'light')
}
})
</script>

<template>
<Layout>
<template #doc-bottom>
<div class="giscus-container" v-if="mountComment">
<giscus-widget
v-pre
id="giscus"
repo="maicss/website"
repoid="R_kgDOKnduBQ"
category="Announcements"
categoryid="DIC_kwDOKnduBc4Cas0c"
mapping="pathname"
term="Welcome to Maicss' site"
strict="0"
:reactionsenabled="true"
emitmetadata="0"
inputposition="top"
theme="light"
lang="zh-CN"
>
<p>Loading comments...</p>
</giscus-widget>
<giscus-widget v-pre id="giscus" repo="maicss/website" repoid="R_kgDOKnduBQ" category="Announcements"
categoryid="DIC_kwDOKnduBc4Cas0c" mapping="pathname" term="Welcome to Maicss' site" strict="0"
:reactionsenabled="true" emitmetadata="0" inputposition="top" theme="light" lang="zh-CN">
<p>Loading comments...</p>
</giscus-widget>
</div>
</template>
<template #doc-top v-if="route.path === '/blog/'">
<BlogIndex/>
</template>
</Layout>
<div class="progress"></div>
</template>
Expand All @@ -115,7 +103,7 @@ watch([isDark], () => {
}
}

::view-transition-old(root),
/* ::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
Expand All @@ -137,28 +125,40 @@ watch([isDark], () => {

.VPSwitchAppearance .check {
transform: none !important;
}
} */

/** page transition */
#app {
/* #app {
view-transition-name: app;
}

@keyframes fade-in {
from { opacity: 0; transform-origin: bottom center; transform: rotate(-5deg); }
from {
opacity: 0;
transform-origin: bottom center;
transform: rotate(-5deg);
}
}

@keyframes fade-out {
to { opacity: 0; transform-origin: bottom center; transform: rotate(5deg); }
to {
opacity: 0;
transform-origin: bottom center;
transform: rotate(5deg);
}
}
::view-transition-old(app) {
*/
/* ::view-transition-old(app) { */
/* animation-name: fade-out; */
/* Ease-out Back. Overshoots. */
animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
::view-transition-new(app) {
/* animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275);
} */

/* ::view-transition-new(app) { */
/* animation-name: fade-in; */
/* Ease-out Back. Overshoots. */
animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
/* animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275);
} */

.progress {
height: 2px;
Expand All @@ -172,14 +172,17 @@ watch([isDark], () => {
animation: scaleProgress auto linear;
animation-timeline: scroll(root);
}

@keyframes scaleProgress {
0% {
transform: scaleX(0);
}

100% {
transform: scaleX(1);
}
}

/* @keyframes colorChange {
0% {
background-color: rgb(145, 203, 92);
Expand Down
3 changes: 3 additions & 0 deletions .vitepress/theme/blog.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ export { data }

export default createContentLoader('/pages/blog/*.md', {
excerpt: '<!--more-->',
render: false,
transform(raw): Post[] {
return raw
.filter(({url}) => url !== '/blog/')
.map(({ url, frontmatter, excerpt }) => ({
title: frontmatter.title,
url,
excerpt,
image: frontmatter.image,
date: formatDate(frontmatter.date)
}))
.sort((a, b) => b.date.time - a.date.time)
Expand Down
4 changes: 4 additions & 0 deletions .vitepress/theme/custom.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

* {
scrollbar-width: thin;
}
Expand Down
3 changes: 2 additions & 1 deletion .vitepress/theme/index.mts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import DefaultTheme from 'vitepress/theme'
import type { Theme } from 'vitepress'
import './custom.css'
import GiscusLayout from './GiscusLayout.vue'
import BlogIndex from './BlogIndex.vue'

export default {
extends: DefaultTheme,
Layout: GiscusLayout,
enhanceApp({app}) {
// app.component('giscus-widget', )
app.component('BlogIndex', BlogIndex)
}
} satisfies Theme
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ based on [VitePress](https://vitepress.dev/)

> 参考链接 https://github.com/vuejs/blog/tree/main/.vitepress
- [ ] 文章中英文空格
- [ ] 滚动条定制
- [x] 文章中英文空格
- [x] 滚动条定制
- [ ] 文章用词等校准
- [ ] pyqt5
- [ ] pyqt6
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
},
"type": "module",
"devDependencies": {
"@tailwindcss/typography": "^0.5.10",
"tailwindcss": "^3.3.5",
"vitepress": "1.0.0-rc.25",
"zhlint": "^0.7.1"
},
Expand Down
Loading

0 comments on commit 3ba0916

Please sign in to comment.