diff --git a/.vitepress/CODE_OF_CONDUCT/__og_image__/og.png b/.vitepress/CODE_OF_CONDUCT/__og_image__/og.png new file mode 100644 index 0000000..c8f5de6 Binary files /dev/null and b/.vitepress/CODE_OF_CONDUCT/__og_image__/og.png differ diff --git a/.vitepress/README/__og_image__/og.png b/.vitepress/README/__og_image__/og.png new file mode 100644 index 0000000..c8f5de6 Binary files /dev/null and b/.vitepress/README/__og_image__/og.png differ diff --git a/.vitepress/config/en.ts b/.vitepress/config/en.ts index 639ee61..f88dca7 100644 --- a/.vitepress/config/en.ts +++ b/.vitepress/config/en.ts @@ -1,7 +1,8 @@ import type { DefaultTheme, LocaleConfig } from 'vitepress' -import type { Theme } from '../theme/types' +import type { CustomConfig, Theme } from '../theme/types' import { sections } from '../theme/plugins/section' import 'dotenv/config' +import { baseHelper } from '../theme/utils' export const SITE_NAME = 'Kotatsu Website' export const META_DESCRIPTION = 'A simple and convenient open source manga reader from and for the community, where you can find and read your favorite manga easier than ever.' @@ -61,10 +62,7 @@ export const config: LocaleConfig = { pattern: 'https://github.com/KotatsuApp/website/edit/main/website/:path', text: 'Suggest changes to this page', }, - footer: { - message: "GPL-3.0 Licensed | Privacy policy", - copyright: `Copyright © 2020 - ${new Date().getFullYear()} Kotatsu Developers`, - }, + footer: baseHelper(getFooter(), ''), sections: sections }, @@ -226,4 +224,27 @@ function getNav(): DefaultTheme.NavItem[] { activeMatch: "/news/" } ] +} + +function getFooter(): CustomConfig['footer'] { + return { + qrcodeTitle: 'Telegram Group', + qrcodeMessage: 'Contact us on Telegram', + qrcodeLink: 'https://t.me/kotatsuapp', + navigation: [ + { + title: 'Legal', + items: [ + { + text: 'Privacy', + link: '/privacy/', + }, + { + text: 'DMCA disclaimer', + link: '/dmca/', + }, + ], + }, + ], + } } \ No newline at end of file diff --git a/.vitepress/config/index.ts b/.vitepress/config/index.ts index ddcfaf3..d056d2c 100644 --- a/.vitepress/config/index.ts +++ b/.vitepress/config/index.ts @@ -16,6 +16,7 @@ import shortcodes from "./shortcodes" import generateOgImages from "./hooks/generateOgImages" import generateMeta from "./hooks/generateMeta" +import Unocss from 'unocss/vite' const SITE_HOST = 'https://kotatsu.app' const SITE_TITLE = 'kotatsu.app' @@ -117,7 +118,8 @@ export default defineConfigWithTheme({ 'VPNavScreenTranslations', 'VPNavBar', 'VPNavBarMenu', - 'VPNavScreenMenu' + 'VPNavScreenMenu', + 'VPFooter', ].map(componentName => ({ find: new RegExp(`^.*\/${componentName}\.vue$`), replacement: fileURLToPath( @@ -125,6 +127,9 @@ export default defineConfigWithTheme({ ) })), }, + plugins: [ + Unocss(), + ] }, sitemap: { diff --git a/.vitepress/theme/components/Feature.vue b/.vitepress/theme/components/Feature.vue index 52acce9..c9d81f1 100644 --- a/.vitepress/theme/components/Feature.vue +++ b/.vitepress/theme/components/Feature.vue @@ -18,7 +18,7 @@ defineProps<{ .Feature { color: inherit; display: block; - border: 1px solid var(--vp-c-bg-soft); + border: 4px solid var(--vp-c-brand-soft); border-radius: var(--vp-border-radius); height: 100%; overflow-x: hidden; diff --git a/.vitepress/theme/components/Footer.vue b/.vitepress/theme/components/Footer.vue new file mode 100644 index 0000000..fde4337 --- /dev/null +++ b/.vitepress/theme/components/Footer.vue @@ -0,0 +1,299 @@ + + + + + \ No newline at end of file diff --git a/.vitepress/theme/components/Link.vue b/.vitepress/theme/components/Link.vue new file mode 100644 index 0000000..1fa6f8b --- /dev/null +++ b/.vitepress/theme/components/Link.vue @@ -0,0 +1,41 @@ + + + + + \ No newline at end of file diff --git a/.vitepress/theme/composables/social.ts b/.vitepress/theme/composables/social.ts new file mode 100644 index 0000000..f294d42 --- /dev/null +++ b/.vitepress/theme/composables/social.ts @@ -0,0 +1,12 @@ +export const socialList = { + github: { + title: 'GitHub', + link: 'https://github.com/KotatsuApp', + icon: 'GitHub', + }, + telegram: { + title: 'Telegram', + link: 'https://t.me/kotatsuapp', + icon: '', + }, +} \ No newline at end of file diff --git a/.vitepress/theme/index.ts b/.vitepress/theme/index.ts index 5bf20d5..5a88542 100644 --- a/.vitepress/theme/index.ts +++ b/.vitepress/theme/index.ts @@ -7,6 +7,7 @@ import DefaultTheme from 'vitepress/theme-without-fonts' import Layout from './components/Layout.vue' import './styles/global.css' import './styles/glightbox.css' +import 'uno.css' export default { extends: DefaultTheme, diff --git a/.vitepress/theme/types/index.ts b/.vitepress/theme/types/index.ts index 6b6b036..1d06196 100644 --- a/.vitepress/theme/types/index.ts +++ b/.vitepress/theme/types/index.ts @@ -10,4 +10,19 @@ export namespace Theme { export interface TeamMember extends Omit { name: Record } +} + +export interface CustomConfig { + footer: { + qrcodeTitle: string + qrcodeMessage: string + qrcodeLink: string + navigation: { + title: string + items: { + text: string + link: string + }[] + }[] + } } \ No newline at end of file diff --git a/.vitepress/theme/utils.ts b/.vitepress/theme/utils.ts index 9edd9b9..e2165ea 100644 --- a/.vitepress/theme/utils.ts +++ b/.vitepress/theme/utils.ts @@ -5,6 +5,8 @@ import { normalize } from 'vitepress/dist/client/shared' import { type Translator, translators } from '../../website/translators' import { Theme } from './types' +const markdownLinkRegexp = /.md((\?|#).*)?$/ + export function findPath( pageData: DocsPageData, config: UserConfig, @@ -108,4 +110,81 @@ export function getTranslator(translator: string): Translator | undefined { } return translators[translator] +} + +export function isObject(value) { + const type = typeof value + return value != null && (type === 'object' || type === 'function') +} + +export const isRelativeLink = (link: string) => + /^(?!www\.|http[s]?:\/\/|[A-Za-z]:\\|\/\/).*/.test(link) + +/** + * Determine a link is http link or not + * + * - http://github.com + * - https://github.com + * - //github.com + */ +export const isLinkHttp = (link: string): boolean => + /^(https?:)?\/\//.test(link) + +/** + * Determine a link is ftp link or not + */ +export const isLinkFtp = (link: string): boolean => link.startsWith('ftp://') + +export const isLinkExternal = (link: string, base = '/'): boolean => { + // http link or ftp link + if (isLinkHttp(link) || isLinkFtp(link)) { + return true + } + + // absolute link that does not start with `base` and does not end with `.md` + if ( + link.startsWith('/') && + !link.startsWith(base) && + !markdownLinkRegexp.test(link) + ) { + return true + } + return false +} + +export function baseHelper(obj, base): any { + function modifyLink(obj) { + if (Array.isArray(obj)) { + return obj.map((item) => modifyLink(item)) + } else if (isObject(obj)) { + const newObj = {} + for (let key in obj) { + if (Array.isArray(obj[key]) || typeof obj[key] === 'object') { + newObj[key] = modifyLink(obj[key]) + } else if (key === 'link' && isRelativeLink(obj[key])) { + newObj[key] = base + obj[key] + if (isLinkExternal(obj[key])) newObj['target'] = '_blank' + } else { + newObj[key] = obj[key] + } + } + return newObj + } else { + return obj + } + } + + function modifyKey(obj) { + let newObj = {} + for (let key in obj) { + if (key.startsWith('/') && base !== '') { + newObj[base + key] = obj[key] + } else { + newObj[key] = obj[key] + } + } + return newObj + } + + return modifyKey(modifyLink(obj)) } \ No newline at end of file diff --git a/package.json b/package.json index 7228e2f..c780276 100644 --- a/package.json +++ b/package.json @@ -58,10 +58,14 @@ "dependencies": { "@octokit/rest": "20.0.2", "@octokit/types": "12.0.0", - "@vueuse/core": "^10.1.2", + "@vueuse/core": "^10.3.0", + "@vueuse/integrations": "^10.3.0", "@xobotyi/scrollbar-width": "^1.9.5", "glightbox": "^3.2.0", "moment": "2.29.4", + "qrcode": "^1.5.3", + "sass": "^1.64.2", + "unocss": "^0.54.2", "uuid": "^9.0.0" }, "engines": { diff --git a/website/account/index.md b/website/account/index.md index 3869483..6b32cd8 100644 --- a/website/account/index.md +++ b/website/account/index.md @@ -5,4 +5,5 @@ lastUpdated: false editLink: false prev: false next: false +footer: false --- \ No newline at end of file diff --git a/website/changelogs/index.md b/website/changelogs/index.md index a9f433b..ca8d11f 100644 --- a/website/changelogs/index.md +++ b/website/changelogs/index.md @@ -5,6 +5,7 @@ lastUpdated: false editLink: false prev: false next: false +footer: false ---