docs: update contributing guidelines and project README.

This commit is contained in:
kuekhaoyang
2025-11-24 21:43:44 +08:00
parent c85e4b5f8d
commit 3ee8bd24ec
2 changed files with 1384 additions and 110 deletions
+898 -61
View File
@@ -1,97 +1,934 @@
# 贡献指南 (Contributing Guide)
感谢你对 **KVideo** 项目感兴趣!我们非常欢迎并感谢社区的任何贡献无论是修复 Bug、改进文档,还是提出新功能建议。
欢迎来到 **KVideo** 项目!我们非常感谢你愿意为这个项目做出贡献无论是修复 Bug、添加新功能、改进文档,还是提出建议,你的每一份贡献都将让这个项目变得更好
为了确保协作顺畅,请在提交贡献前花几分钟阅读以下指南。
为了确保协作顺畅、代码质量一致,请在提交贡献前仔细阅读本指南。
## 📋 目录
- [行为准则](#行为准则)
- [快速开始](#快速开始)
- [开发环境设置](#开发环境设置)
- [代码规范](#代码规范)
- [Git 工作流程](#git-工作流程)
- [提交规范](#提交规范)
- [Pull Request 指南](#pull-request-指南)
- [设计系统规范](#设计系统规范)
- [测试要求](#测试要求)
- [常见问题](#常见问题)
## 🤝 行为准则
我们致力于构建一个开放、友好、包容的社区。请在参与项目时保持尊重和礼貌。
我们致力于构建一个开放、友好、包容的社区环境。请在参与项目时
## 🛠 开发流程
- ✅ 保持尊重和礼貌
- ✅ 欢迎不同的观点和经验
- ✅ 接受建设性的批评
- ✅ 专注于对社区最有利的事情
- ❌ 不要使用性别化的语言或图像
- ❌ 不要进行人身攻击或政治攻击
- ❌ 不要骚扰或歧视他人
### 1. Fork 项目
详细的行为准则请参阅 [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)。
首先,将本仓库 Fork 到你自己的 GitHub 账号下。
## 🚀 快速开始
### 2. 克隆到本地
### 我能贡献什么?
以下是一些你可以做出贡献的方式:
1. **🐛 报告 Bug**:发现了问题?请提交 Issue
2. **💡 提出新功能**:有好想法?在 Discussions 或 Issues 中分享
3. **📝 改进文档**:发现文档不清晰或有错误?帮助我们改进
4. **🎨 优化 UI/UX**:让界面更美观、更易用
5. **⚡ 性能优化**:让应用运行得更快
6. **🔧 修复 Bug**:解决现有的问题
7. **✨ 添加功能**:实现新的特性
### 第一次贡献?
如果这是你第一次为开源项目做贡献,我们推荐:
1. 浏览 [GitHub Issues](https://github.com/KuekHaoYang/KVideo/issues)
2. 寻找标记为 `good first issue` 的问题
3. 在 Issue 中评论,表明你想要解决这个问题
4. 按照本指南进行开发和提交
## 🛠 开发环境设置
### 系统要求
确保你的开发环境满足以下要求:
| 工具 | 最低版本 | 推荐版本 | 检查命令 |
|------|----------|----------|----------|
| **Node.js** | 20.0.0 | 20.x LTS | `node --version` |
| **npm** | 9.0.0 | 10.x | `npm --version` |
| **Git** | 2.30.0 | 最新版本 | `git --version` |
### 详细设置步骤
#### 1. Fork 仓库
点击 GitHub 页面右上角的 "Fork" 按钮,将项目 Fork 到你的账号下。
#### 2. 克隆仓库
```bash
git clone https://github.com/KuekHaoYang/KVideo.git
# 克隆你 Fork 的仓库
git clone https://github.com/YOUR_USERNAME/KVideo.git
cd KVideo
# 添加上游仓库
git remote add upstream https://github.com/KuekHaoYang/KVideo.git
```
### 3. 创建分支
请基于 `main` 分支创建新的功能分支。分支命名建议遵循以下规范:
* `feat/功能名称`: 新功能 (例如: `feat/add-subtitle-support`)
* `fix/问题描述`: 修复 Bug (例如: `fix/search-bar-layout`)
* `docs/文档修改`: 文档更新 (例如: `docs/update-readme`)
* `refactor/重构`: 代码重构 (例如: `refactor/api-client`)
#### 3. 安装依赖
```bash
git checkout -b feat/your-feature-name
npm install
```
### 4. 开发与调试
请确保你的代码符合项目的技术栈和风格:
* **TypeScript**: 请尽量使用强类型,避免使用 `any`
* **Tailwind CSS**: 使用 Tailwind 类名进行样式开发,保持 "Liquid Glass" 的设计风格。
* **组件化**: 保持组件的单一职责,复用 `components/ui` 下的基础组件。
启动本地开发服务器:
#### 4. 启动开发服务器
```bash
npm run dev
```
### 5. 提交代码 (Commit)
访问 `http://localhost:3000` 查看应用。
我们推荐使用 [Conventional Commits](https://www.conventionalcommits.org/) 规范来编写提交信息:
#### 5. 验证环境
* `feat`: 新功能
* `fix`: 修复 Bug
* `docs`: 文档变更
* `style`: 代码格式 (不影响代码运行的变动)
* `refactor`: 重构 (既不是新增功能,也不是修改 bug 的代码变动)
* `perf`: 性能优化
* `test`: 增加测试
* `chore`: 构建过程或辅助工具的变动
示例:
```bash
git commit -m "feat: 增加视频倍速播放功能"
```
### 6. 提交 Pull Request (PR)
1. 将代码推送到你的远程仓库:`git push origin feat/your-feature-name`
2. 在 GitHub 上发起 Pull Request 到 `KVideo:main` 分支。
3. 请在 PR 描述中详细说明你的修改内容、解决的问题以及测试截图(如果是 UI 变更)。
## 📐 代码风格
本项目使用 ESLint 和 Prettier 进行代码检查和格式化。在提交代码前,请确保通过了代码检查:
确保以下命令都能正常运行:
```bash
# 代码检查
npm run lint
# 构建测试
npm run build
```
## 🐛 发现 Bug
## 📏 代码规范
如果你发现了 Bug,请在 GitHub Issues 中提交报告。提交时请包含以下信息:
### 核心规范
* Bug 的详细描述
* 复现步骤
* 预期的行为
* 截图或报错日志 (如果有)
* 你的运行环境 (浏览器版本, OS 等)
#### 1. 文件长度限制 ⚠️
## 💡 提出新功能?
> [!CAUTION]
> **这是项目的硬性规则!所有项目文件必须保持在 150 行以内(除系统文件外)。**
如果你有新的想法,欢迎在 Issues 中提出 Feature Request。请详细描述该功能的用途和你的实现思路。
**检查命令:**
再次感谢你的贡献!让我们一起把 KVideo 变得更好!
```bash
find . -type f -not -path "*/node_modules/*" -not -path "*/.next/*" -not -path "*/.git/*" -not -name "package-lock.json" -not -name "*.png" -not -name "*.md" | xargs wc -l | awk '$1 > 150 && $2 != "total" {print $2 " - " $1 "行"}'
```
**如果命令有输出,说明有文件超过 150 行,必须重构!**
**重构策略:**
如果文件超过 150 行,请使用以下方法重构:
##### A. 提取组件
**问题:** 一个组件太长,包含太多 JSX
**解决方案:** 将大组件拆分为多个小组件
```typescript
// ❌ 不好:一个 200 行的大组件
export function VideoPlayer() {
// 150+ 行代码
return (
<div>
{/* 大量 JSX */}
</div>
);
}
// ✅ 好:拆分为多个小组件
export function VideoPlayer() {
return (
<div>
<PlayerControls />
<ProgressBar />
<VolumeControl />
</div>
);
}
// PlayerControls.tsx (单独文件)
export function PlayerControls() { /* ... */ }
// ProgressBar.tsx (单独文件)
export function ProgressBar() { /* ... */ }
// VolumeControl.tsx (单独文件)
export function VolumeControl() { /* ... */ }
```
##### B. 提取自定义 Hook
**问题:** 组件包含大量状态逻辑
**解决方案:** 将逻辑提取到自定义 Hook
```typescript
// ❌ 不好:组件内有大量状态逻辑
export function SearchPage() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const [loading, setLoading] = useState(false);
// ... 大量逻辑
const handleSearch = async () => {
// ... 50+ 行逻辑
};
return <div>{/* JSX */}</div>;
}
// ✅ 好:提取到自定义 Hook
export function SearchPage() {
const { query, results, loading, handleSearch } = useSearch();
return <div>{/* JSX */}</div>;
}
// useSearch.ts (单独文件)
export function useSearch() {
// ... 所有状态逻辑
return { query, results, loading, handleSearch };
}
```
##### C. 提取工具函数
**问题:** 文件包含大量辅助函数
**解决方案:** 将工具函数移到 `lib/utils/`
```typescript
// ❌ 不好:组件文件包含工具函数
export function VideoCard() {
const formatDuration = (seconds: number) => {
// ... 格式化逻辑
};
const formatDate = (date: Date) => {
// ... 格式化逻辑
};
// ... 更多工具函数
return <div>{/* JSX */}</div>;
}
// ✅ 好:提取到工具文件
import { formatDuration, formatDate } from '@/lib/utils/format-utils';
export function VideoCard() {
return <div>{/* JSX */}</div>;
}
// lib/utils/format-utils.ts
export function formatDuration(seconds: number) { /* ... */ }
export function formatDate(date: Date) { /* ... */ }
```
##### D. 模块化
**问题:** 单个文件处理多个相关功能
**解决方案:** 按功能拆分文件并使用桶文件(barrel exports
```typescript
// ❌ 不好:player-utils.ts 包含 200 行
export function parseHLS() { /* ... */ }
export function handlePlayback() { /* ... */ }
export function manageQuality() { /* ... */ }
// ... 更多函数
// ✅ 好:拆分为多个文件
// lib/utils/player/index.ts
export * from './hls-parser';
export * from './playback-manager';
export * from './quality-manager';
// lib/utils/player/hls-parser.ts
export function parseHLS() { /* ... */ }
// lib/utils/player/playback-manager.ts
export function handlePlayback() { /* ... */ }
// lib/utils/player/quality-manager.ts
export function manageQuality() { /* ... */ }
```
#### 2. TypeScript 规范
**类型安全**
```typescript
// ❌ 避免使用 any
function processData(data: any) {
return data.value;
}
// ✅ 使用具体类型
interface VideoData {
id: string;
title: string;
url: string;
}
function processData(data: VideoData) {
return data.title;
}
// ✅ 或使用 unknown(需要类型检查)
function processData(data: unknown) {
if (typeof data === 'object' && data !== null && 'value' in data) {
return (data as { value: string }).value;
}
throw new Error('Invalid data');
}
```
**函数返回类型**
```typescript
// ❌ 缺少返回类型
function calculateTotal(items) {
return items.reduce((sum, item) => sum + item.price, 0);
}
// ✅ 明确返回类型
function calculateTotal(items: Item[]): number {
return items.reduce((sum, item) => sum + item.price, 0);
}
```
**接口定义**
```typescript
// ✅ 使用 interface 定义对象类型
interface VideoCardProps {
video: Video;
onPlay: (id: string) => void;
className?: string;
}
// ✅ 使用 type 定义联合类型
type ThemeMode = 'light' | 'dark' | 'system';
```
#### 3. React 组件规范
**函数组件**
```typescript
// ✅ 标准函数组件结构
interface ButtonProps {
variant?: 'primary' | 'secondary';
children: React.ReactNode;
onClick?: () => void;
}
export function Button({ variant = 'primary', children, onClick }: ButtonProps) {
return (
<button
className={`btn btn-${variant}`}
onClick={onClick}
>
{children}
</button>
);
}
```
**组件文件组织**
```typescript
// 1. 导入
import React from 'react';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
// 2. 类型定义
interface ComponentProps {
// ...
}
// 3. 组件定义
export function Component({ prop1, prop2 }: ComponentProps) {
// 4. Hooks
const [state, setState] = useState();
const router = useRouter();
// 5. 事件处理函数
const handleClick = () => {
// ...
};
// 6. 渲染
return (
<div>{/* JSX */}</div>
);
}
```
**单一职责原则**
```typescript
// ❌ 组件做太多事情
export function VideoSection() {
// 获取数据
// 处理搜索
// 渲染列表
// 处理分页
// 处理过滤
}
// ✅ 拆分为专注的组件
export function VideoSection() {
const videos = useVideos();
return (
<div>
<SearchBar />
<FilterPanel />
<VideoList videos={videos} />
<Pagination />
</div>
);
}
```
#### 4. 样式规范
**Tailwind CSS 优先**
```typescript
// ✅ 使用 Tailwind 类名
export function Card({ children }: { children: React.ReactNode }) {
return (
<div className="rounded-2xl glass p-6 hover:shadow-lg transition-shadow">
{children}
</div>
);
}
```
**遵循 Liquid Glass 设计系统**
```typescript
// ✅ 正确使用圆角
<div className="rounded-2xl"> {/* 容器:大圆角 */}
<div className="rounded-full"> {/* 小元素:完全圆形 */}
// ❌ 不要使用其他圆角值
<div className="rounded-lg"> {/* 错误! */}
<div className="rounded-xl"> {/* 错误! */}
```
**响应式设计**
```typescript
// ✅ 移动优先的响应式设计
<div className="
flex flex-col {/* 移动端:垂直布局 */}
md:flex-row {/* 平板及以上:水平布局 */}
gap-4 md:gap-6 {/* 响应式间距 */}
">
```
#### 5. 命名规范
**文件命名**
- 组件文件:`PascalCase.tsx`(例如:`VideoCard.tsx`
- Hook 文件:`camelCase.ts`(例如:`useVideoPlayer.ts`
- 工具文件:`kebab-case.ts`(例如:`format-utils.ts`
- 类型文件:`kebab-case.ts`(例如:`video-types.ts`
**变量命名**
```typescript
// ✅ 清晰的命名
const videoList = [...];
const isLoading = false;
const handleSubmit = () => {};
// ❌ 模糊的命名
const data = [...];
const flag = false;
const fn = () => {};
```
**常量命名**
```typescript
// ✅ 全大写 + 下划线
const MAX_VIDEO_DURATION = 7200;
const API_BASE_URL = 'https://api.example.com';
```
#### 6. 导入顺序
```typescript
// 1. React 和 Next.js
import React from 'react';
import { useState } from 'react';
import Link from 'next/link';
// 2. 第三方库
import { create } from 'zustand';
// 3. 项目别名导入
import { Button } from '@/components/ui/Button';
import { formatDate } from '@/lib/utils/date-utils';
// 4. 相对路径导入
import { LocalComponent } from './LocalComponent';
// 5. 类型导入
import type { Video } from '@/lib/types/video';
```
## 🔄 Git 工作流程
### 分支策略
**主分支**
- `main`:稳定的生产分支,只接受 PR 合并
**功能分支命名**
遵循以下命名规范:
- `feat/功能名称`:新功能(例如:`feat/add-playlist`
- `fix/问题描述`:错误修复(例如:`fix/search-crash`
- `docs/文档修改`:文档更新(例如:`docs/update-readme`
- `refactor/重构名称`:代码重构(例如:`refactor/player-controls`
- `perf/优化内容`:性能优化(例如:`perf/image-loading`
- `style/样式修改`:样式调整(例如:`style/button-spacing`
- `test/测试内容`:测试相关(例如:`test/add-unit-tests`
- `chore/其他修改`:构建或工具变动(例如:`chore/update-deps`
### 开发流程
#### 1. 同步上游仓库
在开始新工作前,先同步最新的代码:
```bash
# 获取上游更新
git fetch upstream
# 切换到主分支
git checkout main
# 合并上游更新
git merge upstream/main
# 推送到你的 Fork
git push origin main
```
#### 2. 创建功能分支
```bash
# 从 main 创建新分支
git checkout -b feat/your-feature-name
# 确认当前分支
git branch
```
#### 3. 进行开发
在开发过程中:
- 频繁提交小的、原子性的改动
- 编写清晰的提交信息
- 定期运行 `npm run lint` 检查代码
#### 4. 提交前检查
**必须通过的检查:**
```bash
# 1. 代码规范检查
npm run lint
# 2. 文件长度检查
find . -type f -not -path "*/node_modules/*" -not -path "*/.next/*" -not -path "*/.git/*" -not -name "package-lock.json" -not -name "*.png" -not -name "*.md" | xargs wc -l | awk '$1 > 150 && $2 != "total" {print $2 " - " $1 "行"}'
# 3. 构建测试
npm run build
```
**如果任何检查失败,必须先修复!**
#### 5. 推送分支
```bash
# 推送到你的 Fork
git push origin feat/your-feature-name
```
## 📝 提交规范
### Conventional Commits
我们使用 [Conventional Commits](https://www.conventionalcommits.org/) 规范:
```
<type>(<scope>): <subject>
<body>
<footer>
```
**Type 类型:**
- `feat`:新功能
- `fix`:错误修复
- `docs`:文档变更
- `style`:代码格式(不影响代码运行)
- `refactor`:重构
- `perf`:性能优化
- `test`:测试相关
- `chore`:构建过程或辅助工具的变动
**示例:**
```bash
# 简单提交
git commit -m "feat: 添加视频播放列表功能"
# 详细提交
git commit -m "feat(player): 添加倍速播放功能
- 支持 0.5x 到 2x 的播放速度
- 添加速度选择器 UI
- 保存用户的速度偏好
Closes #123"
```
**提交信息最佳实践:**
- ✅ 使用中文或英文(保持一致)
- ✅ 使用祈使句("添加功能" 而不是 "添加了功能"
- ✅ 第一行不超过 50 个字符
- ✅ 正文每行不超过 72 个字符
- ✅ 说明 "做了什么" 和 "为什么",而不仅是 "怎么做"
## 🔍 Pull Request 指南
### 创建 PR
1. **推送分支到你的 Fork**
```bash
git push origin feat/your-feature-name
```
2. **在 GitHub 上创建 PR**
- 访问你的 Fork 页面
- 点击 "Compare & pull request"
- 选择目标分支:`KuekHaoYang/KVideo:main`
### PR 描述模板
```markdown
## 📝 变更说明
简要描述这个 PR 做了什么。
## 🎯 相关 Issue
Closes #123
Fixes #456
## 📸 截图(如果是 UI 变更)
[如果有 UI 变更,添加截图或 GIF]
## ✅ 检查清单
- [ ] 代码已通过 `npm run lint`
- [ ] 所有文件都在 150 行以内
- [ ] 构建成功(`npm run build`
- [ ] 已在本地测试所有变更
- [ ] 遵循 Liquid Glass 设计系统
- [ ] 提交信息符合规范
- [ ] 已更新相关文档
## 🧪 测试步骤
1. 第一步
2. 第二步
3. 预期结果
## 📌 额外说明
[任何其他需要 reviewer 知道的信息]
```
### PR 审查流程
1. **自动检查**GitHub Actions 会自动运行检查
2. **代码审查**:维护者会审查你的代码
3. **修改请求**:如果需要修改,会留下评论
4. **批准和合并**:审查通过后会被合并
### 回应审查意见
```bash
# 进行修改后
git add .
git commit -m "refactor: 根据审查意见调整代码"
git push origin feat/your-feature-name
```
PR 会自动更新。
## 🎨 设计系统规范
### Liquid Glass 原则
在编写 UI 代码时,必须遵循 Liquid Glass 设计系统:
#### 1. 圆角规范
> [!IMPORTANT]
> **只使用两种圆角:`rounded-2xl` 和 `rounded-full`**
```typescript
// ✅ 正确
<div className="rounded-2xl"> {/* 容器、卡片、按钮、输入框 */}
<div className="rounded-full"> {/* 头像、徽章、药丸形状 */}
// ❌ 错误
<div className="rounded-lg">
<div className="rounded-xl">
<div className="rounded-md">
```
#### 2. 玻璃效果
```typescript
// ✅ 使用 glass 类或 backdrop-filter
<div className="glass">
{/* 内容 */}
</div>
// 或自定义玻璃效果
<div className="
backdrop-blur-xl
backdrop-saturate-180
backdrop-brightness-110
bg-white/10
border border-white/20
">
```
#### 3. 动画过渡
```typescript
// ✅ 使用标准过渡曲线
<button className="
transition-all
duration-300
ease-out
hover:scale-105
">
```
#### 4. 颜色系统
```typescript
// ✅ 使用 CSS 变量
<div className="bg-glass text-glass-text border-glass-border">
// 或 Tailwind 的语义化颜色
<div className="bg-primary text-primary-foreground">
```
### 组件复用
优先复用 `components/ui/` 下的基础组件:
```typescript
// ✅ 好:复用基础组件
import { Button } from '@/components/ui/Button';
import { Modal } from '@/components/ui/Modal';
export function Feature() {
return (
<Modal>
<Button variant="primary"></Button>
</Modal>
);
}
// ❌ 不好:重新实现基础组件
export function Feature() {
return (
<div className="modal">
<button className="btn"></button>
</div>
);
}
```
## 🧪 测试要求
### 手动测试
在提交 PR 前,请手动测试以下内容:
#### 功能测试
- [ ] 新功能按预期工作
- [ ] 没有破坏现有功能
- [ ] 边界情况处理正确
#### 浏览器测试
在以下浏览器中测试:
- [ ] Chrome/Edge(最新版)
- [ ] Firefox(最新版)
- [ ] Safari(最新版)
#### 响应式测试
在以下设备尺寸测试:
- [ ] 移动端(375px - 428px
- [ ] 平板端(768px - 1024px
- [ ] 桌面端(1280px+
#### 无障碍测试
- [ ] 键盘导航正常工作
- [ ] 焦点状态清晰可见
- [ ] 屏幕阅读器友好
### 代码检查
```bash
# 运行 ESLint
npm run lint
# 检查文件长度
find . -type f -not -path "*/node_modules/*" -not -path "*/.next/*" -not -path "*/.git/*" -not -name "package-lock.json" -not -name "*.png" -not -name "*.md" | xargs wc -l | awk '$1 > 150 && $2 != "total" {print $2 " - " $1 "行"}'
```
## ❓ 常见问题
### Q1: 我应该从哪里开始?
**A:** 查看标记为 `good first issue` 的 Issues,这些通常比较简单,适合新手。
### Q2: 如何让文件保持在 150 行以内?
**A:** 参考 [文件长度限制](#1-文件长度限制-) 部分的重构策略。关键是:
- 提取组件
- 提取 Hook
- 提取工具函数
- 模块化
注:系统文件(如 README.md、CONTRIBUTING.md 等文档)不受此限制。
- 提取组件
- 提取 Hook
- 提取工具函数
- 模块化
### Q3: 我的 PR 多久会被审查?
**A:** 通常在 1-3 个工作日内。如果超过一周没有回应,可以在 PR 中添加评论提醒。
### Q4: 可以同时提交多个 PR 吗?
**A:** 可以,但建议每个 PR 专注于一个功能或修复。避免在一个 PR 中做太多不相关的改动。
### Q5: 如何解决合并冲突?
```bash
# 1. 同步上游
git fetch upstream
git checkout main
git merge upstream/main
# 2. 切换到功能分支并 rebase
git checkout feat/your-feature
git rebase main
# 3. 解决冲突后
git add .
git rebase --continue
# 4. 强制推送(因为 rebase 改变了历史)
git push origin feat/your-feature --force
```
### Q6: 我的提交信息写错了怎么办?
```bash
# 修改最后一次提交
git commit --amend -m "新的提交信息"
# 如果已经推送了
git push origin feat/your-feature --force
```
### Q7: 如何测试我的改动?
1. 启动开发服务器:`npm run dev`
2. 在浏览器中手动测试功能
3. 测试不同的设备尺寸
4. 运行 `npm run build` 确保生产构建成功
### Q8: Liquid Glass 设计系统在哪里定义?
`app/styles/glass.css` 文件中。所有组件都应该基于这个设计系统。
### Q9: 我需要更新文档吗?
如果你的 PR 包含以下内容,请更新相应文档:
- 新功能:更新 README.md
- API 变化:更新相关注释和文档
- 配置变化:更新配置说明
### Q10: 如何报告安全漏洞?
请查看 [SECURITY.md](SECURITY.md) 了解安全漏洞报告流程。不要在公开 Issue 中讨论安全问题。
## 📞 需要帮助?
如果你有任何问题:
1. **查看文档**README.md 和本指南
2. **搜索 Issues**:可能已经有人问过相同的问题
3. **提出问题**:在 Discussions 或 Issues 中提问
4. **联系维护者**[@KuekHaoYang](https://github.com/KuekHaoYang)
## 🎉 感谢你的贡献!
感谢你花时间阅读本指南,并为 KVideo 做出贡献。每一个贡献,无论大小,都让这个项目变得更好。
我们期待看到你的 Pull Request
---
<div align="center">
<strong>让我们一起打造更好的 KVideo</strong>
</div>
+486 -49
View File
@@ -5,112 +5,549 @@
> 一个基于 Next.js 16 构建的现代化视频聚合播放平台。采用独特的 "Liquid Glass" 设计语言,提供流畅的视觉体验和强大的视频搜索功能。
[![Next.js](https://img.shields.io/badge/Next.js-16.0-black?style=for-the-badge&logo=next.js)](https://nextjs.org/)
[![React](https://img.shields.io/badge/React-19.0-blue?style=for-the-badge&logo=react)](https://react.dev/)
[![React](https://img.shields.io/badge/React-19.2-blue?style=for-the-badge&logo=react)](https://react.dev/)
[![Tailwind CSS](https://img.shields.io/badge/Tailwind-4.0-38B2AC?style=for-the-badge&logo=tailwind-css)](https://tailwindcss.com/)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue?style=for-the-badge&logo=typescript)](https://www.typescriptlang.org/)
[![License](https://img.shields.io/badge/License-MIT-green?style=for-the-badge)](LICENSE)
## 📖 项目简介
**KVideo** 是一个高性能的视频聚合与播放应用。它利用 Next.js 16 的最新特性,结合 React 19 和 Tailwind CSS v4,打造了一个既美观又强大的视频浏览体验
**KVideo** 是一个高性能、现代化的视频聚合与播放应用,专注于提供极致的用户体验和视觉设计。本项目利用 Next.js 16 的最新特性,结合 React 19 和 Tailwind CSS v4,打造了一个既美观又强大的视频浏览平台
项目的核心设计理念**"Liquid Glass" (液态玻璃)** —— 一种强调透明感、模糊效果和流畅交互的视觉风格。
### 核心设计理念Liquid Glass液态玻璃
## ✨ 主要功能
项目的视觉设计基于 **"Liquid Glass"** 设计系统,这是一套融合了以下特性的现代化 UI 设计语言:
* **🎥 智能播放器**: 内置功能强大的视频播放器,支持多种流媒体格式,提供流畅的观看体验。
* **🔍 聚合并行搜索**: 能够同时在多个视频源中进行并行搜索 (`lib/api/search-api.ts`),快速定位目标内容。
* **🎬 豆瓣深度集成**: 自动对接豆瓣 API (`app/api/douban`),获取详尽的影视资料、评分和推荐。
* **🎨 Liquid Glass UI**: 独特的玻璃拟态设计系统,配合精细的动画效果,带来沉浸式的视觉享受。
* **💾 观看历史**: 本地化存储用户的观看进度和历史记录,随时继续观看。
* **📱 全端响应式**: 精心设计的响应式布局,在桌面、平板和手机上都能完美运行。
* **🌙 主题切换**: 内置深色模式与浅色模式,适应不同环境下的观看需求。
- **玻璃拟态效果**:通过 `backdrop-filter` 实现的磨砂半透明效果,让 UI 元素如同真实的玻璃材质
- **通用柔和度**:统一使用 `rounded-2xl``rounded-full` 两种圆角半径,创造和谐的视觉体验
- **光影交互**:悬停和聚焦状态下的内发光效果,模拟光线被"捕获"的物理现象
- **流畅动画**:基于物理的 `cubic-bezier` 曲线,实现自然的加速和减速过渡
- **深度层级**:清晰的 z-axis 层次结构,增强空间感和交互反馈
## ✨ 核心功能
### 🎥 智能视频播放
- **HLS 流媒体支持**:原生支持 HLS (.m3u8) 格式,提供流畅的视频播放体验
- **智能缓存机制**Service Worker 驱动的智能缓存系统,自动预加载和缓存视频片段
- **后台下载**:利用观看历史,在后台自动下载历史视频,确保离线也能观看
- **播放控制**:完整的播放控制功能,包括进度条、音量控制、播放速度调节、全屏模式等
- **移动端优化**:专门为移动设备优化的播放器界面和手势控制
### 🔍 多源并行搜索
- **聚合搜索引擎**:同时在多个视频源中并行搜索(`lib/api/search-api.ts`),大幅提升搜索速度
- **自定义视频源**:支持添加、编辑和管理自定义视频源(`lib/store/settings-store.ts`
- **智能解析**:统一的解析器系统(`lib/api/parsers.ts`),自动处理不同源的数据格式
- **搜索历史**:自动保存搜索历史,支持快速重新搜索(`lib/store/search-history-store.ts`
- **结果排序**:支持按评分、时间、相关性等多种方式排序搜索结果
### 🎬 豆瓣集成
- **详细影视信息**:自动获取豆瓣评分、演员阵容、剧情简介等详细信息
- **推荐系统**:基于豆瓣数据的相关推荐
- **专业评价**:展示豆瓣用户评价和专业影评
### 💾 观看历史管理
- **自动记录**:自动记录观看进度和历史(`lib/store/history-store.ts`
- **断点续播**:从上次观看位置继续播放
- **历史管理**:支持删除单条历史或清空全部历史
- **隐私保护**:所有数据存储在本地,不上传到服务器
### 📱 响应式设计
- **全端适配**:完美支持桌面、平板和移动设备
- **移动优先**:专门的移动端组件和交互设计
- **触摸优化**:针对触摸屏优化的手势和交互
### 🌙 主题系统
- **深色/浅色模式**:支持系统级主题切换
- **动态主题**:基于 CSS Variables 的动态主题系统
- **无缝过渡**:主题切换时的平滑过渡动画
### ⌨️ 无障碍设计
- **键盘导航**:完整的键盘快捷键支持
- **ARIA 标签**:符合 WCAG 2.2 标准的无障碍实现
- **语义化 HTML**:使用语义化标签提升可访问性
- **高对比度**:确保 4.5:1 的文字对比度
## 🛠 技术栈
本项目采用最前沿的前端技术栈构建:
### 前端核心
* **核心框架**: [Next.js 16](https://nextjs.org/) (App Router)
* **UI 库**: [React 19](https://react.dev/)
* **样式方案**: [Tailwind CSS v4](https://tailwindcss.com/) (配合 CSS Variables 实现动态主题)
* **状态管理**: [Zustand](https://github.com/pmndrs/zustand)
* **编程语言**: [TypeScript](https://www.typescriptlang.org/)
* **代码规范**: ESLint + Prettier
| 技术 | 版本 | 用途 |
|------|------|------|
| **[Next.js](https://nextjs.org/)** | 16.0.3 | React 框架,使用 App Router |
| **[React](https://react.dev/)** | 19.2.0 | UI 组件库 |
| **[TypeScript](https://www.typescriptlang.org/)** | 5.x | 类型安全的 JavaScript |
| **[Tailwind CSS](https://tailwindcss.com/)** | 4.x | 实用优先的 CSS 框架 |
| **[Zustand](https://github.com/pmndrs/zustand)** | 5.0.2 | 轻量级状态管理 |
### 开发工具
- **ESLint 9**:代码质量检查
- **PostCSS 8**CSS 处理器
- **Vercel Analytics**:性能监控和分析
### 架构特点
- **App Router**Next.js 13+ 的新路由系统,支持服务端组件和流式渲染
- **API Routes**:内置 API 端点,处理豆瓣数据和视频源代理
- **Service Worker**:离线缓存和智能预加载
- **Server Components**:优化首屏加载性能
- **Client Components**:复杂交互和状态管理
## 🚀 快速开始
按照以下步骤在本地启动项目:
### 环境要求
### 1. 环境准备
在开始之前,请确保你的开发环境满足以下要求:
确保你的开发环境满足以下要求:
* **Node.js**: v20.0.0 或更高版本
* **npm** 或 **yarn** / **pnpm**
| 工具 | 最低版本 | 推荐版本 |
|------|----------|----------|
| **Node.js** | 20.0.0 | 20.x LTS |
| **npm** | 9.0.0 | 10.x |
| **Git** | 2.30.0 | 最新版本 |
### 2. 获取代码
### 安装步骤
#### 1. 克隆仓库
```bash
git clone https://github.com/KuekHaoYang/KVideo.git
cd KVideo
```
### 3. 安装依赖
#### 2. 安装依赖
```bash
npm install
# 或者
```
如果你使用其他包管理器:
```bash
# 使用 yarn
yarn install
# 或者
# 使用 pnpm
pnpm install
```
### 4. 启动开发服务器
#### 3. 启动开发服务器
```bash
npm run dev
```
访问 [http://localhost:3000](http://localhost:3000) 即可看到应用
开发服务器将在 `http://localhost:3000` 启动
### 5. 构建生产版本
#### 4. 构建生产版本
```bash
# 构建
npm run build
# 启动生产服务器
npm start
```
## 📂 项目结构
```
KVideo/
├── app/ # Next.js App Router 路由与页面
│ ├── api/ # 后端 API 路由 (Douban, Search, etc.)
│ ├── player/ # 播放器页面
├── settings/ # 设置页面
└── globals.css # 全局样式 (包含 Liquid Glass 样式引入)
├── components/ # React UI 组件
├── player/ # 播放器相关组件
│ ├── search/ # 搜索相关组件
├── ui/ # 通用基础组件
── ...
├── lib/ # 工具函数与核心逻辑
│ ├── api/ # API 客户端与数据源定义
│ ├── store/ # Zustand 状态管理
└── utils/ # 通用工具函数
├── public/ # 静态资源
└── ...
├── app/ # Next.js App Router
│ ├── api/ # API 路由
│ ├── douban/ # 豆瓣 API 代理
│ │ └── route.ts # 豆瓣数据获取端点
│ ├── play/ # 视频播放代理
│ │ │ └── [...segments]/ # HLS 片段代理
│ └── proxy/ # 通用代理端点
│ ├── player/ # 播放器页面
│ └── page.tsx # 视频播放页面
── settings/ # 设置页面
└── page.tsx # 应用设置界面
│ ├── styles/ # 全局样式
│ ├── accordion.css # 手风琴组件样式
│ ├── badge.css # 徽章组件样式
│ │ ├── button.css # 按钮组件样式
│ │ ├── glass.css # Liquid Glass 核心样式
│ │ ├── input.css # 输入框组件样式
│ │ ├── modal.css # 模态框组件样式
│ │ └── tabs.css # 标签页组件样式
│ ├── globals.css # 全局 CSS 入口
│ ├── layout.tsx # 根布局组件
│ ├── page.tsx # 首页(搜索页面)
│ └── scroll-optimization.css # 滚动优化样式
├── components/ # React 组件
│ ├── history/ # 观看历史相关组件
│ │ ├── ClearHistoryButton.tsx
│ │ ├── HistoryDownloadManager.tsx
│ │ ├── HistoryItem.tsx
│ │ ├── HistoryModal.tsx
│ │ ├── HistoryScrollArea.tsx
│ │ ├── HistorySectionHeader.tsx
│ │ └── WatchHistorySidebar.tsx
│ ├── home/ # 首页相关组件
│ │ ├── HomeEpisodeList.tsx
│ │ ├── HomeHeader.tsx
│ │ ├── HomeLayout.tsx
│ │ ├── HomeSearchResults.tsx
│ │ ├── HomeVideoActions.tsx
│ │ ├── HomeVideoCard.tsx
│ │ └── HomeVideoGrid.tsx
│ ├── layout/ # 布局组件
│ │ └── SidebarLayout.tsx
│ ├── player/ # 播放器组件(53 个子组件)
│ │ ├── DesktopPlayer.tsx # 桌面播放器
│ │ ├── MobilePlayer.tsx # 移动端播放器
│ │ ├── PlaybackControls.tsx # 播放控制
│ │ ├── ProgressBar.tsx # 进度条
│ │ ├── VolumeControl.tsx # 音量控制
│ │ └── ... # 其他播放器组件
│ ├── search/ # 搜索相关组件
│ │ ├── SearchBar.tsx # 搜索栏
│ │ ├── SearchFilters.tsx # 搜索过滤器
│ │ ├── SearchHistory.tsx # 搜索历史
│ │ ├── SearchResults.tsx # 搜索结果
│ │ └── ... # 其他搜索组件
│ ├── settings/ # 设置相关组件
│ │ ├── SettingsLayout.tsx # 设置页面布局
│ │ ├── SourceManagement.tsx # 视频源管理
│ │ ├── ThemeSettings.tsx # 主题设置
│ │ └── ... # 其他设置组件
│ ├── ui/ # 通用 UI 组件
│ │ ├── Accordion.tsx # 手风琴组件
│ │ ├── Badge.tsx # 徽章组件
│ │ ├── Button.tsx # 按钮组件
│ │ ├── Input.tsx # 输入框组件
│ │ ├── Modal.tsx # 模态框组件
│ │ ├── ModalHeader.tsx # 模态框头部
│ │ ├── ScrollArea.tsx # 滚动区域
│ │ ├── Tabs.tsx # 标签页组件
│ │ └── ... # 其他基础组件
│ ├── SearchLoadingAnimation.tsx
│ ├── ServiceWorkerRegister.tsx # Service Worker 注册
│ ├── ThemeProvider.tsx # 主题提供者
│ └── ThemeSwitcher.tsx # 主题切换器
├── lib/ # 核心逻辑和工具函数
│ ├── accessibility/ # 无障碍功能
│ │ └── keyboard-shortcuts.ts # 键盘快捷键
│ ├── api/ # API 客户端
│ │ ├── client.ts # HTTP 客户端
│ │ ├── default-sources.ts # 默认视频源配置
│ │ ├── detail-api.ts # 视频详情 API
│ │ ├── http-utils.ts # HTTP 工具函数
│ │ ├── parsers.ts # 数据解析器
│ │ ├── search-api.ts # 搜索 API(并行搜索)
│ │ └── video-sources.ts # 视频源类型定义
│ ├── hooks/ # React Hooks
│ │ ├── mobile/ # 移动端专用 hooks
│ │ │ ├── useMobileGestures.ts
│ │ │ ├── useMobilePlaybackControls.ts
│ │ │ └── useMobileTouchControls.ts
│ │ ├── useHistoryDownloader.ts # 历史视频下载
│ │ ├── useHomePage.ts # 首页逻辑
│ │ ├── useInfiniteScroll.ts # 无限滚动
│ │ ├── useKeyboardNavigation.ts # 键盘导航
│ │ ├── useMobilePlayer.ts # 移动端播放器
│ │ ├── useParallelSearch.ts # 并行搜索
│ │ ├── useSearchAction.ts # 搜索操作
│ │ ├── useSearchCache.ts # 搜索缓存
│ │ ├── useSearchHistory.ts # 搜索历史
│ │ ├── useSearchState.ts # 搜索状态
│ │ ├── useSourceBadges.ts # 来源徽章
│ │ ├── useTypeBadges.ts # 类型徽章
│ │ └── useVideoPlayer.ts # 视频播放器
│ ├── store/ # Zustand 状态管理
│ │ ├── history-store.ts # 观看历史状态
│ │ ├── search-history-store.ts # 搜索历史状态
│ │ ├── settings-helpers.ts # 设置辅助函数
│ │ └── settings-store.ts # 应用设置状态
│ ├── types/ # TypeScript 类型定义
│ │ └── video.ts # 视频相关类型
│ └── utils/ # 工具函数
│ ├── cache-utils.ts # 缓存工具
│ ├── date-utils.ts # 日期工具
│ ├── dom-utils.ts # DOM 工具
│ ├── image-utils.ts # 图片工具
│ ├── player-utils.ts # 播放器工具
│ ├── scroll-utils.ts # 滚动工具
│ ├── storage-utils.ts # 存储工具
│ ├── theme-utils.ts # 主题工具
│ ├── url-utils.ts # URL 工具
│ └── video-utils.ts # 视频工具
├── public/ # 静态资源
│ ├── icon.png # 应用图标
│ └── service-worker.js # Service Worker(缓存和离线支持)
├── .github/ # GitHub 配置
│ └── workflows/ # GitHub Actions
├── .gitignore # Git 忽略文件
├── CODE_OF_CONDUCT.md # 行为准则
├── CONTRIBUTING.md # 贡献指南
├── LICENSE # MIT 许可证
├── README.md # 项目说明(本文件)
├── SECURITY.md # 安全政策
├── eslint.config.mjs # ESLint 配置
├── next-env.d.ts # Next.js 类型定义
├── next.config.ts # Next.js 配置
├── package.json # 项目依赖
├── postcss.config.mjs # PostCSS 配置
└── tsconfig.json # TypeScript 配置
```
## 🤝 贡献指南
## 🎨 Liquid Glass 设计系统
欢迎提交 Issue 和 Pull Request!详细的贡献规范请参考 [CONTRIBUTING.md](CONTRIBUTING.md)。
### 设计原则
Liquid Glass 设计系统是本项目的视觉核心,遵循以下原则:
#### 1. 玻璃效果(数字元材质)
```css
/* 核心玻璃效果实现 */
.glass {
backdrop-filter: blur(20px) saturate(180%) brightness(110%);
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
}
```
#### 2. 统一圆角
- **容器类组件**:使用 `rounded-2xl`(较大的圆角)
- 按钮、输入框、卡片、模态框等
- **小型元素**:使用 `rounded-full`(完全圆形/药丸形)
- 头像、徽章、滑块拇指等
#### 3. 光影交互
- 悬停状态:内发光效果
- 焦点状态:增强的边框高亮
- 动态阴影:根据交互状态调整
#### 4. 流畅动画
```css
/* 标准过渡曲线 */
transition: all 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
```
### 组件库
项目包含完整的 Liquid Glass 组件库:
- **Accordion**:手风琴折叠面板
- **Badge**:状态徽章和标签
- **Button**:多种样式的按钮
- **Input**:输入框和文本区域
- **Modal**:模态对话框
- **Tabs**:标签页切换
- **ScrollArea**:自定义滚动区域
- 更多组件位于 `components/ui/`
## 🏗 架构设计
### 状态管理
使用 Zustand 进行状态管理,主要的 store 包括:
1. **Settings Store**`lib/store/settings-store.ts`
- 主题设置
- 视频源管理
- 搜索排序偏好
- 播放器设置
2. **History Store**`lib/store/history-store.ts`
- 观看历史记录
- 播放进度
- 历史管理操作
3. **Search History Store**`lib/store/search-history-store.ts`
- 搜索历史
- 快速搜索建议
### API 架构
#### 并行搜索引擎
```typescript
// lib/api/search-api.ts
// 同时在多个视频源中搜索,返回聚合结果
export async function parallelSearch(query: string): Promise<SearchResult[]>
```
#### 豆瓣集成
```typescript
// app/api/douban/route.ts
// 代理豆瓣 API,避免 CORS 问题
```
#### 视频代理
```typescript
// app/api/play/[...segments]/route.ts
// 代理视频请求,处理跨域和防盗链
```
### 缓存策略
#### Service Worker 缓存
- **HLS 清单文件**:缓存 m3u8 播放列表
- **视频片段**:智能缓存 .ts 视频片段
- **静态资源**:缓存图片、CSS、JS 文件
#### 历史视频预加载
- 后台自动下载历史视频
- 优先级队列管理
- 存储空间管理
### 性能优化
1. **服务端组件**:首屏快速加载
2. **代码分割**:按路由自动分割
3. **图片优化**:渐进式加载
4. **虚拟滚动**:大列表性能优化
5. **缓存策略**:多层缓存机制
## 🧑‍💻 开发指南
### 代码规范
#### 文件长度限制
> [!IMPORTANT]
> **所有项目文件必须保持在 150 行以内(除系统文件外)**
这是项目的硬性规则。在提交代码前,请运行以下命令检查:
```bash
find . -type f -not -path "*/node_modules/*" -not -path "*/.next/*" -not -path "*/.git/*" -not -name "package-lock.json" -not -name "*.png" -not -name "*.md" | xargs wc -l | awk '$1 > 150 && $2 != "total" {print $2 " - " $1 "行"}'
```
如果有文件超过 150 行,请重构代码:
1. **提取组件**:将大组件拆分为多个小组件
2. **提取 Hook**:将复杂逻辑提取到自定义 Hook
3. **提取工具函数**:将通用函数移至 `lib/utils/`
4. **模块化**:按功能拆分文件
#### TypeScript 规范
- 避免使用 `any`,使用具体类型或 `unknown`
- 为所有函数添加返回类型
- 使用接口(`interface`)定义对象类型
- 合理使用泛型提高代码复用性
#### 组件规范
- 使用函数组件和 Hooks
- 遵循单一职责原则
- Props 类型必须明确定义
- 复用 `components/ui/` 下的基础组件
#### 样式规范
- 优先使用 Tailwind 类名
- 复杂样式使用 CSS Modules 或专用 CSS 文件
- 遵循 Liquid Glass 设计系统
- 确保响应式设计
### Git 工作流
1.`main` 分支创建功能分支
2. 使用语义化的分支名(`feat/``fix/``docs/` 等)
3. 编写清晰的提交信息
4. 提交 PR 前确保通过所有检查
### 测试
运行代码检查:
```bash
npm run lint
```
### 调试技巧
1. **React DevTools**:检查组件状态和 props
2. **Console 日志**:使用分组和样式化日志
3. **Network 面板**:监控 API 请求和缓存
4. **Performance 面板**:分析性能瓶颈
## 🚢 部署
### Vercel 部署(推荐)
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/KuekHaoYang/KVideo)
1. 连接 GitHub 仓库
2. Vercel 会自动检测 Next.js 项目
3. 点击 "Deploy" 即可
### 静态导出
```bash
# next.config.ts 中添加
export default {
output: 'export'
}
# 构建
npm run build
# 输出到 out/ 目录
```
## 🤝 贡献
我们非常欢迎各种形式的贡献!请查看 [CONTRIBUTING.md](CONTRIBUTING.md) 了解详细的贡献指南。
### 快速贡献
1. **报告 Bug**:使用 GitHub Issues
2. **功能建议**:在 Issues 中提出
3. **代码贡献**Fork → Branch → PR
4. **文档改进**:直接提交 PR
## 📄 许可证
本项目基于 MIT 许可证开源。详情请参阅 [LICENSE](LICENSE) 文件
本项目基于 [MIT 许可证](LICENSE) 开源
## 🙏 致谢
感谢以下开源项目:
- [Next.js](https://nextjs.org/) - React 框架
- [Tailwind CSS](https://tailwindcss.com/) - CSS 框架
- [Zustand](https://github.com/pmndrs/zustand) - 状态管理
- [React](https://react.dev/) - UI 库
## 📞 联系方式
- **作者**[KuekHaoYang](https://github.com/KuekHaoYang)
- **项目主页**[https://github.com/KuekHaoYang/KVideo](https://github.com/KuekHaoYang/KVideo)
- **问题反馈**[GitHub Issues](https://github.com/KuekHaoYang/KVideo/issues)
---
<div align="center">
Made with ❤️ by <a href="https://github.com/KuekHaoYang">KuekHaoYang</a>
<br>
如果这个项目对你有帮助,请考虑给一个 ⭐️
</div>