mirror of
https://github.com/fantasticit/think.git
synced 2026-10-30 22:56:06 +08:00
feat: 部分配置动态化
This commit is contained in:
+27
-17
@@ -1,18 +1,28 @@
|
||||
# 以下为前台动态渲染的配置,修改后,无需打包,重启服务即可
|
||||
dynamic:
|
||||
# 输入 logo 的图片地址
|
||||
logo: ''
|
||||
appName: '云策文档'
|
||||
appDescription: '云策文档是一款开源知识管理工具。通过独立的知识库空间,结构化地组织在线协作文档,实现知识的积累与沉淀,促进知识的复用与流通。'
|
||||
appKeywords: '云策文档,协作,文档,fantasticit,https://github.com/fantasticit/think'
|
||||
# 版权信息,可以是 HTML
|
||||
copyrightInformation: '<p>Develop by fantasticit</p>'
|
||||
# 外部跳转按钮配置
|
||||
externalButtonText: 'Github'
|
||||
externalButtonURL: 'https://github.com/fantasticit/think'
|
||||
|
||||
# 开发环境配置
|
||||
client:
|
||||
port: 5001
|
||||
assetPrefix: '/'
|
||||
apiUrl: 'http://localhost:5002/api'
|
||||
collaborationUrl: 'ws://localhost:5003'
|
||||
# 以下为页面 meta 配置
|
||||
seoAppName: '云策文档'
|
||||
seoDescription: '云策文档是一款开源知识管理工具。通过独立的知识库空间,结构化地组织在线协作文档,实现知识的积累与沉淀,促进知识的复用与流通。'
|
||||
seoKeywords: '云策文档,协作,文档,fantasticit,https://github.com/fantasticit/think'
|
||||
# 预先连接的来源,空格分割(比如图片存储服务器)
|
||||
dnsPrefetch: '//wipi.oss-cn-shanghai.aliyuncs.com'
|
||||
# 站点地址(如:https://think.codingit.cn/),一定要设置,否则会出现 cookie、跨域等问题
|
||||
siteUrl: 'http://localhost:5001'
|
||||
# 一定要设置,否则会出现 cookie、跨域等问题,注意如果网页部署在 https://think.codingit.cn,那这里的值应当为 .codingit.cn(没有 think)
|
||||
siteUrl:
|
||||
'http://localhost:5001'
|
||||
# 一定要设置,否则会出现 cookie、跨域等问题,注意如果网页部署在 https://think.codingit.cn,那这里的值应当为 .codingit.cn(没有 think)
|
||||
siteDomain: ''
|
||||
|
||||
server:
|
||||
@@ -58,18 +68,18 @@ oss:
|
||||
# 线上更改为服务端地址(如:https://api.codingit.cn)
|
||||
server: 'http://localhost:5002'
|
||||
s3:
|
||||
enable: true
|
||||
enable: false
|
||||
config:
|
||||
# isp 提供商,可选 minio,s3,aliyun,tencent
|
||||
cloudisp: 'minio'
|
||||
accessKeyId: ''
|
||||
secretAccessKey: ''
|
||||
bucket: ''
|
||||
region: ''
|
||||
# 仅cloudisp 的值为 minio/s3 时配置,其它提供商为空
|
||||
forcePathStyle: false
|
||||
# 仅cloudisp 的值为 minio 时配置,其它提供商为空
|
||||
endpoint: ''
|
||||
# isp 提供商,可选 minio,s3,aliyun,tencent
|
||||
cloudisp: 'minio'
|
||||
accessKeyId: ''
|
||||
secretAccessKey: ''
|
||||
bucket: ''
|
||||
region: ''
|
||||
# 仅cloudisp 的值为 minio/s3 时配置,其它提供商为空
|
||||
forcePathStyle: false
|
||||
# 仅cloudisp 的值为 minio 时配置,其它提供商为空
|
||||
endpoint: ''
|
||||
|
||||
# jwt 配置
|
||||
jwt:
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
# 以下为前台动态渲染的配置,修改后,无需打包,重启服务即可
|
||||
dynamic:
|
||||
# 输入 logo 的图片地址
|
||||
logo: ''
|
||||
appName: '云策文档'
|
||||
appDescription: '云策文档是一款开源知识管理工具。通过独立的知识库空间,结构化地组织在线协作文档,实现知识的积累与沉淀,促进知识的复用与流通。'
|
||||
appKeywords: '云策文档,协作,文档,fantasticit,https://github.com/fantasticit/think'
|
||||
# 版权信息,可以是 HTML
|
||||
copyrightInformation: '<p>Develop by fantasticit</p>'
|
||||
# 外部跳转按钮配置
|
||||
externalButtonText: 'Github'
|
||||
externalButtonURL: 'https://github.com/fantasticit/think'
|
||||
|
||||
# 开发环境配置
|
||||
client:
|
||||
port: 5001
|
||||
|
||||
@@ -25,9 +25,7 @@ const nextConfig = semi({
|
||||
COLLABORATION_API_URL: config.client.collaborationUrl,
|
||||
ENABLE_OSS_S3: config.oss.s3.enable,
|
||||
DNS_PREFETCH: (config.client.dnsPrefetch || '').split(' '),
|
||||
SEO_APPNAME: config.client.seoAppName,
|
||||
SEO_DESCRIPTION: config.client.seoDescription,
|
||||
SEO_KEYWORDS: config.client.seoKeywords,
|
||||
SITE_URL: config.client.siteUrl,
|
||||
},
|
||||
webpack: (config, { dev, isServer }) => {
|
||||
config.resolve.plugins.push(new TsconfigPathsPlugin());
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
import { IconLikeHeart } from '@douyinfe/semi-icons';
|
||||
import { Space, Typography } from '@douyinfe/semi-ui';
|
||||
|
||||
import { RuntimeConfig } from 'hooks/use-runtime-config';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
export const Author = () => {
|
||||
const config = RuntimeConfig.useHook();
|
||||
|
||||
return (
|
||||
<div style={{ padding: '16px 0', textAlign: 'center' }}>
|
||||
<Text>
|
||||
<Space>
|
||||
Develop by
|
||||
<Text link={{ href: 'https://github.com/fantasticit/think' }}>fantasticit</Text>
|
||||
with <IconLikeHeart style={{ color: 'red' }} />
|
||||
</Space>
|
||||
</Text>
|
||||
{config.copyrightInformation ? (
|
||||
<div dangerouslySetInnerHTML={{ __html: config.copyrightInformation }}></div>
|
||||
) : (
|
||||
<Text>
|
||||
<Space>
|
||||
Develop by
|
||||
<Text link={{ href: 'https://github.com/fantasticit/think' }}>fantasticit</Text>
|
||||
with <IconLikeHeart style={{ color: 'red' }} />
|
||||
</Space>
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,43 +1,50 @@
|
||||
import { Typography } from '@douyinfe/semi-ui';
|
||||
|
||||
import { RuntimeConfig } from 'hooks/use-runtime-config';
|
||||
import Link from 'next/link';
|
||||
|
||||
import styles from './index.module.scss';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
export const LogoName = process.env.SEO_APPNAME;
|
||||
|
||||
export const LogoImage = () => {
|
||||
const config = RuntimeConfig.useHook();
|
||||
|
||||
return (
|
||||
<Link href={'/'} as={'/'}>
|
||||
<a style={{ width: 36, height: 36 }}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.0"
|
||||
width="36"
|
||||
height="36"
|
||||
viewBox="0 0 512 512"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
>
|
||||
<g
|
||||
transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
||||
fill="var(--semi-color-primary)"
|
||||
stroke="none"
|
||||
{config.logo ? (
|
||||
<img src={config.logo} />
|
||||
) : (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.0"
|
||||
width="36"
|
||||
height="36"
|
||||
viewBox="0 0 512 512"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
>
|
||||
<path d="M880 4799 c-85 -8 -208 -39 -235 -59 -5 -4 -28 -13 -49 -20 -54 -17 -179 -142 -196 -196 -7 -21 -16 -43 -20 -49 -25 -36 -51 -144 -60 -250 -14 -169 -13 -3182 1 -3335 9 -100 37 -215 59 -245 4 -5 13 -28 20 -49 17 -54 142 -179 196 -196 21 -7 44 -16 49 -20 36 -25 144 -51 250 -60 164 -13 3180 -13 3335 0 101 9 211 36 245 60 6 4 28 13 49 20 54 17 179 142 196 196 7 21 16 44 20 49 22 30 50 145 59 245 14 153 15 3166 1 3335 -9 106 -35 214 -60 250 -4 6 -13 28 -20 49 -17 54 -142 179 -196 196 -21 7 -43 16 -49 20 -30 22 -145 50 -245 59 -139 13 -3205 13 -3350 0z m2418 -1532 c281 -282 512 -516 512 -521 0 -9 -27 -39 -174 -196 -39 -42 -109 -118 -156 -170 -47 -52 -87 -97 -90 -100 -3 -3 -43 -45 -90 -95 -46 -49 -116 -124 -154 -165 -39 -42 -105 -113 -146 -159 -41 -46 -91 -100 -110 -120 -45 -48 -248 -266 -286 -309 -29 -31 -35 -33 -156 -47 -69 -8 -220 -19 -334 -25 -115 -6 -238 -15 -274 -20 -82 -12 -520 -34 -527 -27 -6 7 16 328 27 389 5 26 14 116 20 200 6 84 15 178 20 208 5 30 14 120 20 200 15 211 18 226 54 263 35 36 281 267 366 343 30 27 68 63 85 79 17 17 87 82 155 145 68 63 140 131 160 150 20 19 81 76 136 125 54 50 135 124 179 166 200 188 209 196 240 198 6 1 241 -230 523 -512z" />
|
||||
</g>
|
||||
</svg>
|
||||
<g
|
||||
transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
||||
fill="var(--semi-color-primary)"
|
||||
stroke="none"
|
||||
>
|
||||
<path d="M880 4799 c-85 -8 -208 -39 -235 -59 -5 -4 -28 -13 -49 -20 -54 -17 -179 -142 -196 -196 -7 -21 -16 -43 -20 -49 -25 -36 -51 -144 -60 -250 -14 -169 -13 -3182 1 -3335 9 -100 37 -215 59 -245 4 -5 13 -28 20 -49 17 -54 142 -179 196 -196 21 -7 44 -16 49 -20 36 -25 144 -51 250 -60 164 -13 3180 -13 3335 0 101 9 211 36 245 60 6 4 28 13 49 20 54 17 179 142 196 196 7 21 16 44 20 49 22 30 50 145 59 245 14 153 15 3166 1 3335 -9 106 -35 214 -60 250 -4 6 -13 28 -20 49 -17 54 -142 179 -196 196 -21 7 -43 16 -49 20 -30 22 -145 50 -245 59 -139 13 -3205 13 -3350 0z m2418 -1532 c281 -282 512 -516 512 -521 0 -9 -27 -39 -174 -196 -39 -42 -109 -118 -156 -170 -47 -52 -87 -97 -90 -100 -3 -3 -43 -45 -90 -95 -46 -49 -116 -124 -154 -165 -39 -42 -105 -113 -146 -159 -41 -46 -91 -100 -110 -120 -45 -48 -248 -266 -286 -309 -29 -31 -35 -33 -156 -47 -69 -8 -220 -19 -334 -25 -115 -6 -238 -15 -274 -20 -82 -12 -520 -34 -527 -27 -6 7 16 328 27 389 5 26 14 116 20 200 6 84 15 178 20 208 5 30 14 120 20 200 15 211 18 226 54 263 35 36 281 267 366 343 30 27 68 63 85 79 17 17 87 82 155 145 68 63 140 131 160 150 20 19 81 76 136 125 54 50 135 124 179 166 200 188 209 196 240 198 6 1 241 -230 523 -512z" />
|
||||
</g>
|
||||
</svg>
|
||||
)}
|
||||
</a>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export const LogoText = () => {
|
||||
const config = RuntimeConfig.useHook();
|
||||
|
||||
return (
|
||||
<Link href={'/'} as={'/'}>
|
||||
<a className={styles.wrap}>
|
||||
<Text>{LogoName}</Text>
|
||||
<Text>{config?.appName}</Text>
|
||||
</a>
|
||||
</Link>
|
||||
);
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import { Helmet } from 'react-helmet';
|
||||
|
||||
import { RuntimeConfig } from 'hooks/use-runtime-config';
|
||||
|
||||
interface IProps {
|
||||
title: string;
|
||||
needTitleSuffix?: boolean;
|
||||
}
|
||||
|
||||
const buildTitle = (title) => `${title} - 云策文档`;
|
||||
|
||||
export const Seo: React.FC<IProps> = ({ title, needTitleSuffix = true }) => {
|
||||
const config = RuntimeConfig.useHook();
|
||||
|
||||
const buildTitle = useCallback(() => {
|
||||
return `${title} - ${config?.appName}`;
|
||||
}, [title, config?.appName]);
|
||||
|
||||
useEffect(() => {
|
||||
window.document.title = needTitleSuffix ? buildTitle(title) : title;
|
||||
}, [title, needTitleSuffix]);
|
||||
window.document.title = needTitleSuffix ? buildTitle() : title;
|
||||
}, [title, needTitleSuffix, buildTitle]);
|
||||
|
||||
return (
|
||||
<Helmet>
|
||||
<title>{needTitleSuffix ? buildTitle(title) : title}</title>
|
||||
<title>{needTitleSuffix ? buildTitle() : title}</title>
|
||||
</Helmet>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import { createGlobalHook } from './create-global-hook';
|
||||
|
||||
export type IRuntimeConfig = {
|
||||
logo?: string;
|
||||
appName?: string;
|
||||
appDescription?: string;
|
||||
appKeywords?: string;
|
||||
copyrightInformation?: string;
|
||||
externalButtonText?: string;
|
||||
externalButtonURL?: string;
|
||||
};
|
||||
|
||||
const useRuntimeConfig = (defaultConfig: IRuntimeConfig = {}) => {
|
||||
const [config, setConfig] = useState(defaultConfig);
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
export const RuntimeConfig = createGlobalHook<IRuntimeConfig, IRuntimeConfig>(useRuntimeConfig);
|
||||
@@ -11,6 +11,7 @@ import { preloadTiptapResources } from 'tiptap/preload';
|
||||
import { isMobile } from 'helpers/env';
|
||||
import { DocumentVersionControl } from 'hooks/use-document-version';
|
||||
import { IsOnMobile } from 'hooks/use-on-mobile';
|
||||
import { IRuntimeConfig, RuntimeConfig } from 'hooks/use-runtime-config';
|
||||
import { Theme } from 'hooks/use-theme';
|
||||
import App from 'next/app';
|
||||
import Head from 'next/head';
|
||||
@@ -19,7 +20,7 @@ import 'viewerjs/dist/viewer.css';
|
||||
import 'styles/globals.scss';
|
||||
import 'thirtypart/array-prototype-at';
|
||||
|
||||
class MyApp extends App<{ isMobile: boolean }> {
|
||||
class MyApp extends App<{ isMobile: boolean; runtimeConfig: IRuntimeConfig }> {
|
||||
state = {
|
||||
queryClient: new QueryClient({
|
||||
defaultOptions: {
|
||||
@@ -36,13 +37,19 @@ class MyApp extends App<{ isMobile: boolean }> {
|
||||
static getInitialProps = async ({ Component, ctx }) => {
|
||||
const request = ctx?.req;
|
||||
const getPagePropsPromise = Component.getInitialProps ? Component.getInitialProps(ctx) : Promise.resolve({});
|
||||
const [pageProps] = await Promise.all([getPagePropsPromise]).catch((err) => {
|
||||
return [{}];
|
||||
const [pageProps, runtimeConfig] = await Promise.all([
|
||||
getPagePropsPromise,
|
||||
fetch(`${process.env.SITE_URL}/api/config`).then((res) => {
|
||||
return res.json();
|
||||
}),
|
||||
]).catch((err) => {
|
||||
return [{}, {}];
|
||||
});
|
||||
|
||||
return {
|
||||
pageProps,
|
||||
isMobile: isMobile(request?.headers['user-agent']),
|
||||
runtimeConfig,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -57,7 +64,7 @@ class MyApp extends App<{ isMobile: boolean }> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { Component, pageProps, isMobile } = this.props;
|
||||
const { Component, pageProps, isMobile, runtimeConfig } = this.props;
|
||||
const { queryClient } = this.state;
|
||||
|
||||
return (
|
||||
@@ -68,24 +75,23 @@ class MyApp extends App<{ isMobile: boolean }> {
|
||||
content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, user-scalable=no, viewport-fit=cover"
|
||||
/>
|
||||
<meta charSet="utf-8" />
|
||||
<meta name="description" content={process.env.SEO_DESCRIPTION} />
|
||||
<meta name="keywords" content={process.env.SEO_KEYWORDS}></meta>
|
||||
<meta name="application-name" content={process.env.SEO_APPNAME} />
|
||||
<meta name="description" content={runtimeConfig.appDescription} />
|
||||
<meta name="keywords" content={runtimeConfig.appKeywords}></meta>
|
||||
<meta name="application-name" content={runtimeConfig.appName} />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
||||
<meta name="apple-mobile-web-app-title" content={process.env.SEO_APPNAME} />
|
||||
<meta name="description" content={process.env.SEO_DESCRIPTION} />
|
||||
<meta name="apple-mobile-web-app-title" content={runtimeConfig.appName} />
|
||||
<meta name="description" content={runtimeConfig.appDescription} />
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<meta name="msapplication-TileColor" content="#ffffff" />
|
||||
<meta name="msapplication-tap-highlight" content="no" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content={process.env.SEO_APPNAME} />
|
||||
<meta property="og:description" content={process.env.SEO_DESCRIPTION} />
|
||||
<meta property="og:site_name" content={process.env.SEO_APPNAME} />
|
||||
<meta property="og:title" content={runtimeConfig.appName} />
|
||||
<meta property="og:description" content={runtimeConfig.appDescription} />
|
||||
<meta property="og:site_name" content={runtimeConfig.appName} />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<link rel="apple-touch-icon" href="/icon192.png" />
|
||||
{((process.env.DNS_PREFETCH || []) as string[]).map((url) => (
|
||||
<link key={url} rel="dns-prefetch" href={url} />
|
||||
))}
|
||||
@@ -94,11 +100,13 @@ class MyApp extends App<{ isMobile: boolean }> {
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Hydrate state={pageProps.dehydratedState}>
|
||||
<Theme.Provider>
|
||||
<IsOnMobile.Provider initialState={isMobile}>
|
||||
<DocumentVersionControl.Provider initialState={false}>
|
||||
<Component {...pageProps} />
|
||||
</DocumentVersionControl.Provider>
|
||||
</IsOnMobile.Provider>
|
||||
<RuntimeConfig.Provider initialState={runtimeConfig}>
|
||||
<IsOnMobile.Provider initialState={isMobile}>
|
||||
<DocumentVersionControl.Provider initialState={false}>
|
||||
<Component {...pageProps} />
|
||||
</DocumentVersionControl.Provider>
|
||||
</IsOnMobile.Provider>
|
||||
</RuntimeConfig.Provider>
|
||||
</Theme.Provider>
|
||||
</Hydrate>
|
||||
</QueryClientProvider>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { getRuntimeConfig } from '@think/config';
|
||||
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
export default function handler(req: NextApiRequest, res: NextApiResponse<Record<string, unknown>>) {
|
||||
res.status(200).json(getRuntimeConfig() as Record<string, unknown>);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import { Button, Typography } from '@douyinfe/semi-ui';
|
||||
|
||||
import { Seo } from 'components/seo';
|
||||
import { toLogin, useUser } from 'data/user';
|
||||
import { RuntimeConfig } from 'hooks/use-runtime-config';
|
||||
import { TeamWorkIllustration } from 'illustrations/team-work';
|
||||
import { SingleColumnLayout } from 'layouts/single-column';
|
||||
import type { NextPage } from 'next';
|
||||
@@ -14,6 +15,8 @@ import styles from './index.module.scss';
|
||||
const { Title, Paragraph } = Typography;
|
||||
|
||||
const Page: NextPage = () => {
|
||||
const config = RuntimeConfig.useHook();
|
||||
|
||||
const { user } = useUser();
|
||||
|
||||
const start = useCallback(() => {
|
||||
@@ -24,9 +27,9 @@ const Page: NextPage = () => {
|
||||
}
|
||||
}, [user]);
|
||||
|
||||
const toGithub = useCallback(() => {
|
||||
window.open('https://github.com/fantasticit/think');
|
||||
}, []);
|
||||
const toExternal = useCallback(() => {
|
||||
window.open(config.externalButtonURL);
|
||||
}, [config.externalButtonURL]);
|
||||
|
||||
return (
|
||||
<SingleColumnLayout>
|
||||
@@ -36,18 +39,18 @@ const Page: NextPage = () => {
|
||||
<div className={styles.content}>
|
||||
<div>
|
||||
<div>
|
||||
<Title style={{ marginBottom: 12 }}>云策文档</Title>
|
||||
<Paragraph type="tertiary">
|
||||
云策文档是一款开源知识管理工具。通过独立的知识库空间,结构化地组织在线协作文档,实现知识的积累与沉淀,促进知识的复用与流通。
|
||||
</Paragraph>
|
||||
<Title style={{ marginBottom: 12 }}>{config?.appName}</Title>
|
||||
<Paragraph type="tertiary">{config?.appDescription}</Paragraph>
|
||||
</div>
|
||||
<div style={{ margin: '32px 0' }}>
|
||||
<Button theme="solid" onClick={start}>
|
||||
开始使用
|
||||
</Button>
|
||||
<Button style={{ marginLeft: 12 }} onClick={toGithub}>
|
||||
Github
|
||||
</Button>
|
||||
{config.externalButtonText && (
|
||||
<Button style={{ marginLeft: 12 }} onClick={toExternal}>
|
||||
{config.externalButtonText}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,12 +12,12 @@ import cls from 'classnames';
|
||||
import { Banner } from 'components/banner';
|
||||
import { CommentEditor } from 'components/document/comments';
|
||||
import { ImageViewer } from 'components/image-viewer';
|
||||
import { LogoName } from 'components/logo';
|
||||
import { getRandomColor } from 'helpers/color';
|
||||
import { isAndroid, isIOS } from 'helpers/env';
|
||||
import { useDocumentStyle } from 'hooks/use-document-style';
|
||||
import { useNetwork } from 'hooks/use-network';
|
||||
import { IsOnMobile } from 'hooks/use-on-mobile';
|
||||
import { RuntimeConfig } from 'hooks/use-runtime-config';
|
||||
import { useToggle } from 'hooks/use-toggle';
|
||||
|
||||
import { CollaborationKit } from '../kit';
|
||||
@@ -47,6 +47,7 @@ export const EditorInstance = forwardRef((props: IProps, ref) => {
|
||||
renderInEditorPortal,
|
||||
onTitleUpdate,
|
||||
} = props;
|
||||
const config = RuntimeConfig.useHook();
|
||||
const $headerContainer = useRef<HTMLDivElement>();
|
||||
const $mainContainer = useRef<HTMLDivElement>();
|
||||
const { isMobile } = IsOnMobile.useHook();
|
||||
@@ -110,7 +111,7 @@ export const EditorInstance = forwardRef((props: IProps, ref) => {
|
||||
const listener = (event: KeyboardEvent) => {
|
||||
if ((event.ctrlKey || event.metaKey) && event.keyCode == 83) {
|
||||
event.preventDefault();
|
||||
Toast.info(`${LogoName}会实时保存你的数据,无需手动保存。`);
|
||||
Toast.info(`${config.appName}会实时保存你的数据,无需手动保存。`);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -120,7 +121,7 @@ export const EditorInstance = forwardRef((props: IProps, ref) => {
|
||||
return () => {
|
||||
window.document.removeEventListener('keydown', listener);
|
||||
};
|
||||
}, []);
|
||||
}, [config.appName]);
|
||||
|
||||
// 监听键盘收起、打开
|
||||
useEffect(() => {
|
||||
|
||||
Vendored
+1
@@ -1 +1,2 @@
|
||||
export declare function getConfig(): Record<string, unknown>;
|
||||
export declare function getRuntimeConfig(): Record<string, unknown>;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.getConfig = void 0;
|
||||
exports.getRuntimeConfig = exports.getConfig = void 0;
|
||||
var fs = require("fs-extra");
|
||||
var yaml = require("js-yaml");
|
||||
var path = require("path");
|
||||
@@ -9,8 +9,8 @@ var FILE_ENV_NAME = {
|
||||
test: 'test',
|
||||
production: 'prod'
|
||||
};
|
||||
var env = process.env.NODE_ENV || 'development';
|
||||
function getConfig() {
|
||||
var env = process.env.NODE_ENV || 'development';
|
||||
var filePath = path.join(__dirname, '../../../config', "".concat(FILE_ENV_NAME[env], ".yaml"));
|
||||
if (!fs.existsSync(filePath)) {
|
||||
throw new Error("Can not find config file: ".concat(filePath));
|
||||
@@ -18,3 +18,15 @@ function getConfig() {
|
||||
return yaml.load(fs.readFileSync(filePath, 'utf8'));
|
||||
}
|
||||
exports.getConfig = getConfig;
|
||||
function getRuntimeConfig() {
|
||||
var env = process.env.NODE_ENV || 'development';
|
||||
var filePath = path.join(__dirname, '../../../../../../config', "".concat(FILE_ENV_NAME[env], ".yaml"));
|
||||
if (!fs.existsSync(filePath)) {
|
||||
filePath = path.join(__dirname, '../../../config', "".concat(FILE_ENV_NAME[env], ".yaml"));
|
||||
}
|
||||
if (!fs.existsSync(filePath)) {
|
||||
throw new Error("Can not find config file: ".concat(filePath));
|
||||
}
|
||||
return (yaml.load(fs.readFileSync(filePath, 'utf8')).dynamic || {});
|
||||
}
|
||||
exports.getRuntimeConfig = getRuntimeConfig;
|
||||
|
||||
@@ -8,9 +8,9 @@ const FILE_ENV_NAME = {
|
||||
production: 'prod',
|
||||
};
|
||||
|
||||
const env = process.env.NODE_ENV || 'development';
|
||||
|
||||
export function getConfig() {
|
||||
const env = process.env.NODE_ENV || 'development';
|
||||
|
||||
const filePath = path.join(__dirname, '../../../config', `${FILE_ENV_NAME[env]}.yaml`);
|
||||
|
||||
if (!fs.existsSync(filePath)) {
|
||||
@@ -19,3 +19,19 @@ export function getConfig() {
|
||||
|
||||
return yaml.load(fs.readFileSync(filePath, 'utf8')) as Record<string, unknown>;
|
||||
}
|
||||
|
||||
export function getRuntimeConfig() {
|
||||
const env = process.env.NODE_ENV || 'development';
|
||||
|
||||
let filePath = path.join(__dirname, '../../../../../../config', `${FILE_ENV_NAME[env]}.yaml`);
|
||||
|
||||
if (!fs.existsSync(filePath)) {
|
||||
filePath = path.join(__dirname, '../../../config', `${FILE_ENV_NAME[env]}.yaml`);
|
||||
}
|
||||
|
||||
if (!fs.existsSync(filePath)) {
|
||||
throw new Error(`Can not find config file: ${filePath}`);
|
||||
}
|
||||
|
||||
return (yaml.load(fs.readFileSync(filePath, 'utf8')).dynamic || {}) as Record<string, unknown>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user