Skip to content

Commit

Permalink
✨ feat(config): add giscus and discord
Browse files Browse the repository at this point in the history
  • Loading branch information
倏昱 committed Jul 10, 2023
1 parent 735bc99 commit d17d5b8
Show file tree
Hide file tree
Showing 20 changed files with 135 additions and 173 deletions.
Empty file modified .husky/commit-msg
100644 → 100755
Empty file.
Empty file modified .husky/pre-commit
100644 → 100755
Empty file.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,35 @@ $ pnpm install
$ pnpm start
```

Theme Config:

```ts
interface SiteThemeConfig {
actions: HeroProps['actions'];
apiHeader?: ApiHeaderConfig | false;
description?: string;
features: FeaturesProps['items'];
footer?: string | false;
footerConfig?: FooterConfig;
giscus?: {
category: string;
categoryId: string;
repo: `${string}/${string}`;
repoId: string;
};
hero?: HeroConfig | Record<string, HeroConfig>;
hideHomeNav?: boolean;
logo?: string;
name?: string;
siteToken?: SiteConfigToken;
socialLinks?: {
discord?: `https://discord.gg/${string}`;
github?: string;
};
title?: string;
}
```

<div align="right">

[![][back-to-top]](#readme-top)
Expand Down
10 changes: 8 additions & 2 deletions example/.dumirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ const themeConfig = {
sourceUrl: `{github}/tree/master/src/{atomId}/index.tsx`,
},
description: 'Lobe UI is an open-source UI component library for building chatbot web apps',

features: [
{
description:
Expand All @@ -49,16 +48,23 @@ const themeConfig = {
},
],
footer: 'Made with 🤯 by LobeHub',
giscus: {
category: 'Q&A',
categoryId: 'DIC_kwDOJloKoM4CXsCu',
repo: 'lobehub/lobe-ui',
repoId: 'R_kgDOJloKoA',
},
name: 'DUMI',
socialLinks: {
discord: 'https://discord.gg/AYFPHvv2jT',
github: homepage,
},
title: 'Dumi Theme LobeHub',
};

export default defineConfig({
alias: {
'@': resolve(__dirname, 'src'),
'@': resolve(__dirname, '../src'),
'dumi-theme-lobehub': resolve(__dirname, '../src'),
},
codeSplitting: {
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"prepublishOnly": "npm run build",
"prettier": "prettier -c --write --no-error-on-unmatched-pattern \"**/**\"",
"release": "semantic-release",
"start": "concurrently \"npm run dev\" \"npm run dev:docs\"",
"start": "npm run dev",
"test": "vitest --passWithNoTests",
"test:coverage": "vitest run --coverage --passWithNoTests",
"test:update": "vitest -u",
Expand Down Expand Up @@ -92,7 +92,6 @@
"@vitest/coverage-v8": "latest",
"clean-pkg-json": "^1",
"commitlint": "^17",
"concurrently": "^8",
"dumi": "^2",
"dumi-assets-types": "^1",
"eslint": "^8",
Expand Down
2 changes: 1 addition & 1 deletion src/components/StoreUpdater/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const homeNav = {
};

export const StoreUpdater = () => {
const siteData = useSiteData();
const siteData: any = useSiteData();
const sidebar = useSidebarData();
const routeMeta = useRouteMeta();
const tabMeta = useTabMeta();
Expand Down
32 changes: 18 additions & 14 deletions src/pages/Docs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,32 @@ import { shallow } from 'zustand/shallow';

import ApiHeader from '@/slots/ApiHeader';
import Content from '@/slots/Content';
import { isApiPageSel, useSiteStore } from '@/store';
import { giscusSel, isApiPageSel, useSiteStore } from '@/store';

import { useStyles } from './styles';

const Documents = memo(() => {
const outlet = useOutlet();
const { mobile } = useResponsive();
const isApiPage = useSiteStore(isApiPageSel, shallow);
const { isApiPage, giscus } = useSiteStore(
(st) => ({ giscus: giscusSel(st), isApiPage: isApiPageSel(st) }),
shallow,
);
const { styles } = useStyles();

const Comment = useCallback(
() => (
<Giscus
category="Q&A"
categoryId="DIC_kwDOJloKoM4CXsCu"
id="lobehub"
mapping="title"
repo="lobehub/lobe-ui"
repoId="R_kgDOJloKoA"
/>
),
[location.pathname],
() =>
giscus && (
<Giscus
category={giscus.category}
categoryId={giscus.categoryId}
id="lobehub"
mapping="title"
repo={giscus.repo}
repoId={giscus.repoId}
/>
),
[giscus, location.pathname],
);
return (
<>
Expand All @@ -41,7 +45,7 @@ const Documents = memo(() => {
) : undefined}
<Content>
{outlet}
<Comment />
{giscus && <Comment />}
</Content>
</Center>
</>
Expand Down
5 changes: 0 additions & 5 deletions src/plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,11 @@ import { join } from 'node:path';

import { getHash } from './utils';

/*
* SSR 抽取样式
*/
const SSRPlugin = (api: IApi) => {
api.describe({
key: '@',
});

// 如果没有开启 SSR,则啥也不做
if (!api.userConfig.ssr) return;

api.logger.info('detect ssr config, when building html will extract css.');
Expand Down Expand Up @@ -46,7 +42,6 @@ const SSRPlugin = (api: IApi) => {
.map((file) => {
const antdCache = (global as any).__ANTD_CACHE__;

// 提取 antd-style 样式到独立 css 文件
const styles = extractStaticStyle(file.content, { antdCache });

for (const result of styles) {
Expand Down
13 changes: 6 additions & 7 deletions src/slots/Footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Center, Flexbox } from 'react-layout-kit';
import { shallow } from 'zustand/shallow';

import { githubSel, useSiteStore } from '@/store';
import { IFooter } from '@/types';
import { FooterConfig } from '@/types';

import { getColumns } from './columns';
import { useStyles } from './style';
Expand All @@ -20,12 +20,11 @@ const Footer = memo(() => {

if (!themeConfig.footer) return;

const footer = themeConfig.footerConfig as IFooter;
const footer = themeConfig.footerConfig as FooterConfig;

const columns =
footer?.columns === false
? undefined
: getColumns({ github: githubUrl || (pkg as any).homepage });
const columns = footer?.columns
? undefined
: getColumns({ github: githubUrl || (pkg as any).homepage });

const bottomFooter = footer?.bottom || themeConfig.footer;

Expand All @@ -50,7 +49,7 @@ const Footer = memo(() => {
}
columns={columns}
contentMaxWidth={theme.contentMaxWidth}
theme={footer?.theme || (theme.appearance as FooterProps['theme'])}
theme={theme.appearance as FooterProps['theme']}
/>
);
});
Expand Down
37 changes: 37 additions & 0 deletions src/slots/Header/DiscordButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ActionIcon } from '@lobehub/ui';
import { createStyles } from 'antd-style';
import { type LucideIcon, createLucideIcon } from 'lucide-react';
import { memo } from 'react';

import { discordSel, useSiteStore } from '@/store';

const Discord: LucideIcon = createLucideIcon('Discord', [
[
'path',
{
d: 'M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z',
key: '18tl5t',
},
],
]);

const useStyles = createStyles(
({ css }) => css`
svg {
overflow: visible !important;
}
`,
);

const DiscordButton = memo(() => {
const inviteUrl = useSiteStore(discordSel);
const { styles } = useStyles();

return inviteUrl ? (
<a href={inviteUrl} rel="noreferrer" target={'_blank'}>
<ActionIcon className={styles} icon={Discord} size="site" />
</a>
) : undefined;
});

export default DiscordButton;
6 changes: 3 additions & 3 deletions src/slots/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import SearchBar from '@/slots/SearchBar';
import { useSiteStore } from '@/store/useSiteStore';

import Burger from './Burger';
import DiscordButton from './DiscordButton';
import GithubButton from './GithubButton';
import LangSwitch from './LangSwitch';
import ThemeSwitch from './ThemeSwitch';
Expand All @@ -25,10 +26,9 @@ const Header = memo(() => {
<ThemeSwitch />
) : (
<>
{' '}
<SearchBar />
<LangSwitch />
<SearchBar /> <LangSwitch />
<GithubButton />
<DiscordButton />
<ThemeSwitch />
</>
)
Expand Down
4 changes: 2 additions & 2 deletions src/slots/PreviewerActions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useStyles } from './style';

const SIZE = { blockSize: 24, fontSize: 16, strokeWidth: 2 };

export interface IPreviewerActionsProps extends IPreviewerProps {
export interface PreviewerActionsProps extends IPreviewerProps {
demoContainer: HTMLDivElement | HTMLIFrameElement;
/**
* disabled actions
Expand All @@ -18,7 +18,7 @@ export interface IPreviewerActionsProps extends IPreviewerProps {
forceShowCode?: boolean;
}

const PreviewerActions: FC<IPreviewerActionsProps> = (props) => {
const PreviewerActions: FC<PreviewerActionsProps> = (props) => {
const intl = useIntl();
const files = Object.entries(props.asset.dependencies).filter(([, { type }]) => type === 'FILE');
const [activeKey, setActiveKey] = useState(0);
Expand Down
9 changes: 0 additions & 9 deletions src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,8 @@ export * from './selectors';
export * from './useSiteStore';
export * from './useThemeStore';

/**
* @title 数据选择器
*/
export const siteSelectors = {
/**
* @title API 头部选择器
*/
apiHeader: apiHeaderSel,
/**
* @title 扁平化侧边栏选择器
*/
flattenSidebar: flattenSidebarSel,
token: tokenSel,
};
8 changes: 0 additions & 8 deletions src/store/selectors/apiHeader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export const apiHeaderSel = (s: SiteStore): ApiHeaderProps => {
const fm = s.routeMeta.frontmatter;
const localeId = s.locale.id;

// 统一的路径匹配替换方法
const replaceUrl = (rawString: string) => {
return rawString
.replace('{github}', REPO_BASE)
Expand All @@ -43,17 +42,10 @@ export const apiHeaderSel = (s: SiteStore): ApiHeaderProps => {
docUrl: documentUrlMatch,
} = (s.siteData.themeConfig.apiHeader || {}) as ApiHeaderConfig;

// 1. 兜底默认使用文档的 apiHeader.pkg
// 2. 如果 themeConfig 里配置了 pkg, 则使用配置的 pkg
// 3. 兜底使用 package.json 中的 name
const displayPackage = fm.apiHeader?.pkg || package_;

// 1. 默认使用文档的 fm.atomId
// 2. 兜底到文档 title
const componentName = fm.atomId || fm.title;

// 1. 优先选择使用文档 apiHeader.defaultImport
// 2. 默认使用 false
const defaultImport = fm.apiHeader?.defaultImport || false;

const sourceUrl =
Expand Down
25 changes: 0 additions & 25 deletions src/store/selectors/hero.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,53 +12,28 @@ const localeValueSel = (s: SiteStore, value: any) => {
return value;
};

/**
* Hero Title 选择器
* 选择逻辑:优先使用 hero 配置的 title, 再兜底到 themeConfig 中的 name
*/
export const heroTitleSel = (s: SiteStore) =>
s.routeMeta.frontmatter.hero?.title ||
// 从 hero 的 title 中选择
localeValueSel(s, s.siteData.themeConfig.hero)?.title ||
// @deprecated 1.0 正式版本移除
// 从 hero 的 title 中选择
localeValueSel(s, s.siteData.themeConfig.title) ||
s.siteData.themeConfig.name;

/**
* Hero description 选择器
* 选择逻辑:优先使用 hero 配置的 description, 再兜底到 themeConfig 中的 name
*/
export const heroDescSel = (s: SiteStore) =>
s.routeMeta.frontmatter.hero?.description ||
// 从 hero 的 description 中选择
localeValueSel(s, s.siteData.themeConfig.hero)?.description ||
// @deprecated 1.0 正式版本移除
// 从 hero 的 description 中选择
localeValueSel(s, s.siteData.themeConfig.description);

/**
* Hero Action 选择器
* 选择逻辑:优先使用 hero 配置的 actions, 再兜底到 themeConfig 中的 actions
*/
export const heroActionsSel = (s: SiteStore) =>
s.routeMeta.frontmatter.hero?.actions ||
// 从 hero 的 actions 中选择
localeValueSel(s, s.siteData.themeConfig.hero)?.actions ||
// @deprecated 1.0 正式版本移除
localeValueSel(s, s.siteData.themeConfig.actions);

/**
* Features 选择器
*/
export const featuresSel = (s: SiteStore): FeatureItem[] => {
if (!isHeroPageSel(s)) return [];

return (
localeValueSel(s, s.siteData.themeConfig.hero)?.features ||
// @deprecated 1.0 正式版本移除
localeValueSel(s, s.siteData.themeConfig.features) ||
// 在themeConfig 没有配置的话,尝试兜底到 frontmatter 中的配置
s.routeMeta.frontmatter.features ||
[]
);
Expand Down
11 changes: 4 additions & 7 deletions src/store/selectors/siteBasicInfo.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { SiteStore } from '../useSiteStore';

/**
* 站点标题选择器
*/
export const siteTitleSel = (s: SiteStore) => s.siteData.themeConfig.title;

export const githubSel = (s: SiteStore) =>
// 优先取 socialLinks 里的 github
// TODO: 后面的 github 在 1.0 里废弃
s.siteData.themeConfig.socialLinks?.github || s.siteData.themeConfig.github;
export const githubSel = (s: SiteStore) => s.siteData.themeConfig.socialLinks?.github || '';
export const discordSel = (s: SiteStore) => s.siteData.themeConfig.socialLinks?.discord || '';

export const giscusSel = (s: SiteStore) => s.siteData.themeConfig.giscus;
Loading

0 comments on commit d17d5b8

Please sign in to comment.