Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
bentwnghk committed Jan 16, 2024
2 parents 015de33 + 7bcb2e1 commit 9f25b1d
Show file tree
Hide file tree
Showing 12 changed files with 550 additions and 77 deletions.
72 changes: 72 additions & 0 deletions docs/Development/Contributing-Guidelines.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# 代码风格与贡献指南

欢迎来到 LobeChat 的代码风格与贡献指南。本指南将帮助您理解我们的代码规范和贡献流程,确保代码的一致性和项目的顺利进行。

## 代码风格

在 LobeChat 中,我们使用 `@lobehub/lint` 程序包来统一代码风格。该程序包内置了 `ESLint``Prettier``remarklint``stylelint` 的配置,以确保我们的 JavaScript、Markdown 和 CSS 文件遵循相同的编码标准。

### ESLint

我们的项目使用 ESLint 来检查 JavaScript 代码中的问题。您可以在项目根目录下找到 `.eslintrc.js` 文件,其中包含了我们对 `@lobehub/lint` 的 ESLint 配置的扩展和自定义规则。

为了与 Next.js 框架兼容,我们在配置中添加了 `plugin:@next/next/recommended`。此外,我们禁用了一些规则,以适应我们项目的特定需求。

请在提交代码前运行 ESLint,以确保您的代码符合项目规范。

### Prettier

Prettier 负责代码格式化,以保证代码的一致性。您可以在 `.prettierrc.js` 中找到我们的 Prettier 配置,它是从 `@lobehub/lint` 导入的。

在保存文件时,建议您配置您的编辑器以自动运行 Prettier,或者在提交前手动运行它。

### remarklint

对于 Markdown 文件,我们使用 remarklint 来确保文档格式的统一。您可以在项目中找到相应的配置文件。

### stylelint

我们使用 stylelint 来规范 CSS 代码的风格。在 `stylelint` 的配置文件中,我们基于 `@lobehub/lint` 的配置进行了一些自定义规则的调整。

确保您的样式代码在提交前通过了 stylelint 的检查。

## 贡献流程

LobeChat 采用 gitmoji 和 semantic release 作为我们的代码提交和发布流程。

### Gitmoji

在提交代码时,请使用 gitmoji 来标注您的提交信息。这有助于其他贡献者快速理解您提交的内容和目的。

Gitmoji commit messages 使用特定的 emoji 来表示提交的类型或意图。以下是一个示例:

```
📝 Update README with contribution guidelines
- Added section about code style preferences
- Included instructions for running tests
- Corrected typos and improved formatting
```

在这个示例中,📝 emoji 代表了文档的更新。提交信息清晰地描述了更改的内容,提供了具体的细节。

### Semantic Release

我们使用 semantic release 来自动化版本控制和发布流程。请确保您的提交信息遵循 semantic release 的规范,这样当代码合并到主分支后,系统就可以自动创建新的版本并发布。

### Commitlint

为了确保提交信息的一致性,我们使用 `commitlint` 来检查提交信息格式。您可以在 `.commitlintrc.js` 配置文件中找到相关规则。

在您提交代码之前,请确保您的提交信息遵循我们的规范。

### 如何贡献

1. Fork 项目到您的账户。
2. 创建一个新的分支进行开发。
3. 开发完成后,确保您的代码通过了上述的代码风格检查。
4. 提交您的更改,并使用合适的 gitmoji 标注您的提交信息。
5. 创建一个 Pull Request 到原项目的主分支。
6. 等待代码审查,并根据反馈进行必要的修改。

感谢您遵循这些指导原则,它们有助于我们维护项目的质量和一致性。我们期待您的贡献!
68 changes: 0 additions & 68 deletions docs/Development/Data-Store-Selectors.zh-CN.md

This file was deleted.

117 changes: 117 additions & 0 deletions docs/Development/Internationalization-Implementation.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# LobeChat 国际化实现指南

欢迎阅读 LobeChat 国际化实现指南。本文档将指导你了解 LobeChat 的国际化机制,包括文件结构、如何添加新语种。LobeChat 采用 `i18next``lobe-i18n` 作为国际化解决方案,旨在为用户提供流畅的多语言支持。

## 国际化概述

国际化(Internationalization,简称为 i18n)是一个让应用能够适应不同语言和地区的过程。在 LobeChat 中,我们支持多种语言,并通过 `i18next` 库来实现语言的动态切换和内容的本地化。我们的目标是让 LobeChat 能够为全球用户提供本地化的体验。

## 文件结构

在 LobeChat 的项目中,国际化相关的文件被组织如下:

- `src/locales/default`: 包含默认开发语言(中文)的翻译文件,我们作为中文。
- `locales`: 包含所有支持的语言文件夹,每个语言文件夹中包含相应语言的翻译文件,这些翻译文件通过 lobe-i18n 自动生成。

`src/locales` 这个目录结构中,`default` 文件夹包含了原始的翻译文件(中文),其他每个语言文件夹则包含了相应语言的 JSON 翻译文件。每个语言文件夹中的文件对应 `default` 文件夹中的 TypeScript 文件,确保了各语种之间的翻译文件结构一致性。

```
src/locales
├── create.ts
├── default
│ ├── chat.ts
│ ├── common.ts
│ ├── error.ts
│ ├── index.ts
│ ├── market.ts
│ ├── migration.ts
│ ├── plugin.ts
│ ├── setting.ts
│ ├── tool.ts
│ └── welcome.ts
└── resources.ts
```

通过 lobe-i18n 自动生成的文件结构如下:

```
locales
├── ar
│ ├── chat.json
│ ├── common.json
│ ├── error.json
│ └── ... (其他翻译文件)
├── de-DE
│ ├── chat.json
│ ├── common.json
│ ├── error.json
│ └── ... (其他翻译文件)
├── en-US
├── ... (其他语种目录)
├── zh-CN
└── zh-TW
```

## 核心实现逻辑

LobeChat 的国际化核心实现逻辑如下:

- 使用 `i18next` 库进行初始化和配置。
- 使用 `i18next-browser-languagedetector` 自动检测用户的语言偏好。
- 使用 `i18next-resources-to-backend` 动态加载翻译资源。
- 根据用户的语言偏好,设置 HTML 文档的方向(LTR 或 RTL)。

以下是一个简化的伪代码示例,用以说明 LobeChat 国际化的核心实现逻辑:

```ts
import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import resourcesToBackend from 'i18next-resources-to-backend';
import { isRtlLang } from 'rtl-detect';

// 创建 i18n 实例并配置
const createI18nInstance = (lang) => {
const i18nInstance = i18n
.use(LanguageDetector) // 使用语言检测
.use(
resourcesToBackend((language, namespace) => {
// 动态加载对应语言的翻译资源
return import(`path/to/locales/${language}/${namespace}.json`);
}),
);

// 监听语言变化事件,动态设置文档方向
i18nInstance.on('languageChanged', (language) => {
const direction = isRtlLang(language) ? 'rtl' : 'ltr';
document.documentElement.dir = direction; // 设置 HTML 文档方向
});

// 初始化 i18n 实例
i18nInstance.init({
// 相关配置
});

return i18nInstance;
};
```

在这个示例中,我们展示了如何使用 `i18next` 和相关插件来初始化国际化设置。我们动态导入了翻译资源,并响应语言变化事件来调整页面的文本方向。这个过程为 LobeChat 提供了灵活的多语言支持能力。

## 添加新的语言支持

我们通过以下工作,已经支持了全球多种语言:

- [✨ feat: adding Arabic Language Support #1049](https://github.com/lobehub/lobe-chat/pull/1049)
- [🌐 style: Add Vietnamese files and add the vi-VN option in the General Settings #860](https://github.com/lobehub/lobe-chat/pull/860)
- [🌐 style: support it-IT nl-NL and pl-PL locales #759](https://github.com/lobehub/lobe-chat/pull/759)
- [🌐 feat(locale): Add fr-FR (#637) #645](https://github.com/lobehub/lobe-chat/pull/645)
- [🌐 Add russian localy #137](https://github.com/lobehub/lobe-chat/pull/137)

要添加新的语种支持, 详细步骤请参考:[新语种添加指南](Add-New-Locale.zh-CN)

## 资源和进一步阅读

- [i18next 官方文档](https://www.i18next.com/)
- [lobe-i18n 工具说明](https://github.com/lobehub/lobe-cli-toolbox/tree/master/packages/lobe-i18n)

通过遵循本指南,你可以更好地理解和参与到 LobeChat 的国际化工作中,为全球用户提供无缝的多语言体验。
File renamed without changes.
49 changes: 49 additions & 0 deletions docs/Development/State-Management/Selectors.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 数据存储取数模块

selectors 是 LobeChat 数据流研发框架下的取数模块,它的作用是从 store 中以特定特务逻辑取出数据,供组件消费使用。

`src/store/tool/slices/plugin/selectors.ts` 为例:

这个 TypeScript 代码段定义了一个名为 `pluginSelectors` 的对象,该对象包含一系列用于从插件存储状态中检索数据的选择器函数。选择器是一种从 zustand 中提取和派生数据的函数。这个特定的例子是为了管理与前端应用程序的插件系统相关的状态。

下面是一些关键点的说明:

- `getCustomPluginById`: 根据插件 ID 返回自定义插件信息。
- `getInstalledPluginById`: 根据插件 ID 返回已安装插件的信息。
- `getPluginManifestById`: 根据插件 ID 返回插件清单。
- `getPluginMetaById`: 根据插件 ID 返回插件元数据。
- `getPluginSettingsById`: 根据插件 ID 返回插件设置。
- `installedCustomPluginMetaList`: 返回所有已安装的自定义插件的元数据列表。
- `installedPluginManifestList`: 返回所有已安装插件的清单列表。
- `installedPluginMetaList`: 返回所有已安装插件的元数据列表。
- `installedPlugins`: 返回所有已安装插件的列表。
- `isPluginHasUI`: 根据插件 ID 确定插件是否有 UI 组件。
- `isPluginInstalled`: 根据插件 ID 检查插件是否已安装。
- `storeAndInstallPluginsIdList`: 返回 store 中和已安装插件的所有 ID 列表。

选择器通过将复杂的状态选择逻辑封装在单独的函数中,使得在应用程序的其他部分调用状态数据时,代码更加简洁和直观。此外,由于使用了 TypeScript,每个函数都可以具有明确的输入和输出类型,这有助于提高代码的可靠性和开发效率。

在组件中,只需引入相应的选择器即可直接获取最终消费的数据:

```tsx | pure
import { useToolStore } from '@/store/tool';
import { pluginSelectors } from '@/store/tool/selectors';

const Render = () => {
const list = useToolStore(pluginSelectors.installedPluginMetaList);

return <> ... </>;
};
```

这样实现的好处在于:

1. **解耦和重用**:通过将选择器独立于组件,我们可以在多个组件之间复用这些选择器而不需要重写取数逻辑。这减少了重复代码,提高了开发效率,并且使得代码库更加干净和易于维护。
2. **性能优化**:选择器可以用来计算派生数据,这样可以避免在每个组件中重复计算相同的数据。当状态发生变化时,只有依赖于这部分状态的选择器才会重新计算,从而减少不必要的渲染和计算。
3. **易于测试**:选择器是纯函数,它们仅依赖于传入的参数。这意味着它们可以在隔离的环境中进行测试,无需模拟整个 store 或组件树。
4. **类型安全**:由于 LobeChat 使用 TypeScript,每个选择器都有明确的输入和输出类型定义。这为开发者提供了自动完成和编译时检查的优势,减少了运行时错误。
5. **可维护性**:选择器集中了状态的读取逻辑,使得跟踪状态的变化和管理更加直观。如果状态结构发生变化,我们只需要更新相应的选择器,而不是搜索和替换整个代码库中的多个位置。
6. **可组合性**:选择器可以组合其他选择器,以创建更复杂的选择逻辑。这种模式允许开发者构建一个选择器层次结构,使得状态选择更加灵活和强大。
7. **简化组件逻辑**:组件不需要知道状态的结构或如何获取和计算需要的数据。组件只需调用选择器即可获取渲染所需的数据,这使得组件逻辑变得更简单和清晰。

通过这样的设计,LobeChat 的开发者可以更专注于构建用户界面和业务逻辑,而不必担心数据的获取和处理细节。这种模式也为未来可能的状态结构变更提供了更好的适应性和扩展性。
Loading

0 comments on commit 9f25b1d

Please sign in to comment.