Skip to content

Commit

Permalink
feat: add footer link feature
Browse files Browse the repository at this point in the history
  • Loading branch information
bennyxguo committed Aug 16, 2023
1 parent bd5b862 commit 8e29f0b
Show file tree
Hide file tree
Showing 14 changed files with 257 additions and 34 deletions.
23 changes: 22 additions & 1 deletion _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,14 @@ site:
police_beian:
number: ''
link: ''
started_date: # Start date of the blog YYY-MM-DD / 博客开始运行日期
# Start date of the blog YYY-MM-DD
# 博客开始运行日期
started_date:
# Path unique identifier (文章 URL 唯一标识)
# uid: use unique ID
# slug: use generated slug base on title
# (Default is 'slug')
pathSlug: 'slug'

#! ---------------------------------------------------------------
#! Authors Configs
Expand Down Expand Up @@ -190,3 +197,17 @@ aurora_bot:
injects:
scripts:
css:

#! ---------------------------------------------------------------
#! Footer links
#! ---------------------------------------------------------------
footer_links:
- title: # main title
links:
- title: # link title
url: # URL link
- title: # link title
url: # URL link
- title: Friends # link of friends mode / 友链模式
mode: 'links'

7 changes: 5 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
</div>
<div id="loading-bar-wrapper" :class="loadingBarClass"></div>
</div>
<FooterLink :links="themeConfig.footerLinks.data" />
<Footer :style="cssVariables" />
<div class="App-Mobile-sidebar" v-if="isMobile">
<div id="App-Mobile-Profile" class="App-Mobile-wrapper">
Expand Down Expand Up @@ -60,13 +61,14 @@ import { useLightBoxStore } from '@/stores/lightbox'
import { useMetaStore } from '@/stores/meta'
import { useSearchStore } from './stores/search'
import HeaderMain from '@/components/Header/src/Header.vue'
import Footer from '@/components/Footer.vue'
import Footer from '@/components/Footer/Footer.vue'
import Navigator from '@/components/Navigator.vue'
import MobileMenu from '@/components/MobileMenu.vue'
import Dia from '@/components/Dia.vue'
import defaultCover from '@/assets/default-cover.jpg'
import { useI18n } from 'vue-i18n'
import VueEasyLightbox from 'vue-easy-lightbox'
import FooterLink from './components/Footer/FooterLink.vue'
export default defineComponent({
name: 'App',
Expand All @@ -76,7 +78,8 @@ export default defineComponent({
Navigator,
MobileMenu,
Dia,
VueEasyLightbox
VueEasyLightbox,
FooterLink
},
setup() {
const appStore = useAppStore()
Expand Down
2 changes: 1 addition & 1 deletion src/components/Button/PrimaryButton.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<a
class="py-2 px-3 text-white flex items-center justify-center z-10 transition cursor-pointer rounded-xl font-semibold select-none"
class="py-1 px-3 text-white flex items-center justify-center z-10 transition cursor-pointer rounded-xl font-semibold select-none"
:style="gradientBackground"
>
{{ text }}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Button/SecondaryButton.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<a
class="py-2 px-3 text-ob-bright flex items-center justify-center z-10 transition cursor-pointer rounded-xl bg-ob-deep-900 border-solid border-ob-bright border-t-2 border-b-2 border-r-2 border-l-2 opacity-80 select-none"
class="py-1 px-3 text-ob-bright flex items-center justify-center z-10 transition cursor-pointer rounded-xl bg-ob-deep-900 border-solid border-ob-bright border-t-2 border-b-2 border-r-2 border-l-2 opacity-80 select-none"
>
{{ text }}
</a>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template>
<div id="footer" class="relative w-full pt-1" :style="gradientBackground">
<span class="bg-ob-deep-900 flex justify-center">
<span class="bg-ob-deep-800 flex justify-center">
<div
class="bg-ob-deep-900 rounded-lg max-w-10/12 lg:max-w-screen-2xl text-sm text-ob-normal w-full py-6 px-6 grid grid-rows-1 lg:grid-rows-none lg:grid-cols-4 justify-center items-center gap-8"
class="bg-ob-deep-800 rounded-lg max-w-10/12 lg:max-w-screen-2xl text-sm text-ob-normal w-full py-6 px-6 grid grid-rows-1 lg:grid-rows-none lg:grid-cols-4 justify-center items-center gap-8"
>
<div
class="flex flex-col lg:flex-row gap-6 lg:gap-12 row-span-1 lg:col-span-3 text-center lg:text-left"
Expand Down
148 changes: 148 additions & 0 deletions src/components/Footer/FooterLink.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<template>
<div
v-if="links"
id="footer-link"
class="flex flex-col items-center py-8 bg-ob-deep-900"
>
<div class="footer-link-divider" :style="gradientBackground">
<div class="footer-link-img-wrapper">
<img v-show="avatar" :class="avatarClass" :src="avatar" alt="avatar" />
</div>
</div>

<div
class="flex flex-row flex-wrap justify-start md:justify-center bg-ob-deep-900 rounded-lg max-w-10/12 lg:max-w-screen-2xl text-normal text-ob-normal w-full py-6 px-6 items-start gap-8 md:gap-10 xl:gap-16"
>
<div v-for="link of links" class="flex flex-col">
<div class="flex mb-4 items-center">
<h3 class="text-ob-dim font-bold mr-2">{{ link.title }}</h3>
<SvgIcon
v-if="link.mode === 'links'"
@click="refreshLinkData"
icon-class="reload"
:class="loadingSvgClasses"
/>
</div>
<ul v-if="!link.mode" class="flex flex-col gap-1">
<li v-for="sub of link.links" class="cursor-pointer">
<a :href="sub.url" target="_blank">{{ sub.title }}</a>
</li>
</ul>
<ul v-if="link.mode === 'links' && linksData" class="flex flex-col">
<li v-for="avatar of linksData" class="cursor-pointer">
<a :href="avatar.link" target="_blank">{{ avatar.nick }}</a>
</li>
</ul>
<ul v-if="link.mode === 'links' && loadingLinks" class="flex flex-col">
<li v-for="i in 5" class="cursor-pointer">
<ob-skeleton :count="1" height="22px" width="7.5rem" />
</li>
</ul>
</div>
</div>
</div>
</template>

<script lang="ts">
import { Link } from '@/models/Article.class'
import { FooterLink } from '@/models/ThemeConfig.class'
import { useAppStore } from '@/stores/app'
import { useArticleStore } from '@/stores/article'
import { PropType, computed, defineComponent, onMounted, ref, watch } from 'vue'
import SvgIcon from '@/components/SvgIcon/index.vue'
export default defineComponent({
name: 'ARFooterLink',
components: { SvgIcon },
props: {
links: Array as PropType<FooterLink[]>
},
setup() {
const appStore = useAppStore()
const articleStore = useArticleStore()
const loadingLinks = ref<boolean>(true)
const linksData = ref<Link[]>([])
const bloggers = ref<Link[][]>([])
const refreshLinkData = () => {
loadingLinks.value = true
linksData.value = []
setTimeout(() => {
const recordSet = new Set()
let friendsCount = bloggers.value.length < 5 ? bloggers.value.length : 5
while (friendsCount > 0) {
const pair = bloggers.value[Math.floor(Math.random() * 24)]
const blogger = pair[Math.floor(Math.random() * 2)]
if (!recordSet.has(blogger.nick)) {
recordSet.add(blogger.nick)
linksData.value.push(blogger)
friendsCount--
}
}
loadingLinks.value = false
}, 1000)
}
const fetchLinks = async () => {
const linksArticle = await articleStore.fetchArticle('friends')
if (linksArticle && linksArticle.avatarWall) {
bloggers.value = linksArticle.avatarWall
refreshLinkData()
}
}
watch(
() => appStore.configReady,
(newValue, oldValue) => {
if (!oldValue && newValue && appStore.themeConfig.menu.menus['Links']) {
fetchLinks()
}
}
)
onMounted(() => {
if (appStore.themeConfig.menu.menus['Links']) {
fetchLinks()
}
})
return {
avatarClass: computed(() => {
return {
'footer-link-avatar': true,
[appStore.themeConfig.theme.profile_shape]: true
}
}),
gradientBackground: computed(() => {
return { background: appStore.themeConfig.theme.header_gradient_css }
}),
avatar: computed(() => appStore.themeConfig.site.avatar),
loadingSvgClasses: computed(() => ({
'cursor-pointer': true,
'animate-spin': loadingLinks.value
})),
refreshLinkData,
loadingLinks,
linksData
}
}
})
</script>

<style lang="scss">
.footer-link-divider {
@apply flex h-1 w-2/3 lg:w-2/5 mt-4 mb-8 relative opacity-70 rounded-full shadow-xl;
/* .footer-link-img-wrapper {
border: 2rem solid var(--background-primary);
} */
.footer-link-avatar {
@apply m-0 h-10 w-10 shadow-xl absolute rounded-full box-content;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border: 0.8rem solid var(--background-primary);
background: var(--background-primary);
}
}
</style>
11 changes: 8 additions & 3 deletions src/components/Link/LinkBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<Title
title="settings.links-slogan"
icon="friends"
text-size="text-2xl"
text-size="text-3xl"
paddings="pb-2"
margins="mb-0 mt-0"
/>
Expand Down Expand Up @@ -62,14 +62,15 @@
</template>

<script lang="ts">
import { PropType, defineComponent } from 'vue'
import { PropType, computed, defineComponent } from 'vue'
import LinkAvatar from '@/components/Link/LinkAvatar.vue'
import { Title } from '@/components/Title'
import { useI18n } from 'vue-i18n'
import PrimaryButton from '@/components/Button/PrimaryButton.vue'
import SecondaryButton from '@/components/Button/SecondaryButton.vue'
import { Link } from '@/models/Article.class'
import { useCommonStore } from '@/stores/common'
import { useAppStore } from '@/stores/app'
export default defineComponent({
name: 'ARLinkBox',
Expand Down Expand Up @@ -104,7 +105,11 @@ export default defineComponent({
}, 6000)
}
return { applyClicked, randomJump, t }
return {
applyClicked,
randomJump,
t
}
}
})
</script>
Expand Down
1 change: 0 additions & 1 deletion src/components/LoadingSkeleton/Skeleton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { SkeletonStyle } from './SkeletonTheme.vue'
const isEmptyVNode = (children: any) => {
if (!children) return true
const firstNode = children()[0]
console.log('firstNode', firstNode)
let str = firstNode.text
if (str) {
// remove all line-break and space character
Expand Down
6 changes: 5 additions & 1 deletion src/components/Sidebar/src/Toc.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<template>
<Sticky :stickyTop="32" endingElId="footer" dynamicElClass="#sticky-sidebar">
<Sticky
:stickyTop="32"
endingElId="footer-link"
dynamicElClass="#sticky-sidebar"
>
<div id="sticky-sidebar">
<transition name="fade-slide-y" mode="out-in">
<div v-show="showToc" class="sidebar-box mb-4">
Expand Down
Loading

0 comments on commit 8e29f0b

Please sign in to comment.