项目简介
- OrbitDB Control Center提供了一个用于管理 OrbitDB 数据库的 UI界面
- github地址: 在浏览器中运行 Control Center
启动:npm start
- npm start会运行如下json中的start命令,其通过react-scripts启动运行,
react-scripts
is a set of scripts from the create-react-app starter pack. create-react-app helps you kick off projects without configuring, so you do not have to setup your project by yourself.
"scripts": {
"start": "react-scripts --openssl-legacy-provider start",
"build": "react-scripts --openssl-legacy-provider build",
"test": "react-scripts test --env=./jestEnv.js",
"eject": "react-scripts eject"
},
index.js
src\index.js
通过ReactDOM.render
代码渲染组件的 DOM 节点root
,将React Router
包裹的APP组件渲染到root
节点:
import React from 'react'
import ReactDOM from 'react-dom'
import { HashRouter as Router } from 'react-router-dom'
import './index.css'
import App from './App'
import * as serviceWorker from './serviceWorker'
ReactDOM.render(
<Router> // Router为React Router 提供的组件,用于处理应用中的路由。它包裹着 App 组件,确保在 App 内部的组件能够访问路由功能
<App />
</Router>,
document.getElementById('root') // root页面可通过 npm i create-react-app ,npm create-react-app react-basic 创建
)
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
//serviceWorker.unregister()
App.js
- App.js 进行全局状态管理、路由管理、并根据路由进行总体界面结构渲染
function App () {
const initialState = {
user: null,
loginDialogOpen: false,
createDBDialogOpen: false,
addDBDialogOpen: false,
programs: [],
program: false,
db: null,
entries: [],
orbitdbStatus: 'Starting',
ipfsStatus: 'Starting',
loading: {
programs: false
}
}
// 用于状态管理部分的状态更新
// 接收当前的 state 和一个 action,并根据 action 的类型返回新的状态
const reducer = (state, action) => {
switch (action.type) {
case actions.SYSTEMS.SET_ORBITDB:
return {
...state,
orbitdbStatus: action.orbitdbStatus
}
…………
return state
}
}
return (
<StateProvider initialState={initialState} reducer={reducer}>
…………
</StateProvider>
)
}
export default App
界面部分
<StateProvider initialState={initialState} reducer={reducer}>
<Pane background='tint1' height='100%'> // 创建一个背景为'tint1'且高度为100%的容器
<Header /> // 渲染页面的头部组件
<Systems /> // 渲染系统相关的组件
<Switch> // 用于在不同的路由之间进行切换
<Route path='/search'> // 定义'/search'路径的路由
<SearchResultsView /> // 渲染搜索结果视图组件
</Route>
<Route path='/orbitdb/:programName/:dbName'> // 定义包含参数的路径
<DatabaseView /> // 渲染数据库视图组件
</Route>
<Route path='/'> // 定义根路径的路由
<DatabasesView /> // 渲染数据库列表视图组件
</Route>
</Switch>
</Pane>
</StateProvider>
Header
<Header />
主要用于渲染页面的头部组件和处理搜索输入。
Systems
-
Systems组件用于管理和显示 IPFS 和 OrbitDB 的状态,包含useEffect部分和渲染部分部分。
-
useEffect 部分:
- 在组件挂载时,设置加载状态为
true
。 - 调用
initIPFS
初始化 IPFS,成功后更新状态为IPFS
启动。 - 接着调用
initOrbitDB
初始化 OrbitDB,成功后更新状态为OrbitDB
启动。 - 使用
getAllDatabases
获取所有数据库,反转其顺序后更新状态,并设置加载状态为false
。 - React.useEffect 是一个副作用钩子,异步函数,用于在组件渲染后执行特定的代码。它接受两个参数:第一个是一个函数,该函数包含需要执行的副作用(如数据获取、订阅或手动更改 DOM);第二个是一个依赖数组,指定哪些变量变化时需要重新运行该副作用。下边为一个例子,当加载Welcome组件时,如果props.name发生变换,则进行document.title的修改:
- 在组件挂载时,设置加载状态为
import React, { useEffect } from 'react';
function Welcome(props) {
useEffect(() => {
document.title = `Hello, ${props.name}`;
}, [props.name]);
return <h1>Hello, {props.name}</h1>;
}
- 渲染部分 部分:
- 如果
IPFS
启动,则显示绿色的状态指示器,否则显示黄色的状态指示器。 - 对于
OrbitDB
,根据状态显示不同的指示器。 - 渲染一个连接钱包的按钮
ConnectToWalletButton
标签。
- 如果
import React from 'react' // 导入 React 库
import {
majorScale, // 导入用于定义大尺寸的函数
minorScale, // 导入用于定义小尺寸的函数
Pane, // 导入用于创建容器的组件
Text, // 导入用于显示文本的组件
StatusIndicator // 导入状态指示器组件
} from 'evergreen-ui' // 从 evergreen-ui 库中导入以上组件
import { initIPFS, initOrbitDB, getAllDatabases } from '../database' // 导入数据库初始化和数据获取的函数
import { actions, useStateValue } from '../state' // 导入状态管理的 actions 和状态钩子
import ConnectToWalletButton from './ConnectToWalletButton' // 导入连接钱包按钮组件
function Systems () { // 定义 Systems 组件
const [appState, dispatch] = useStateValue() // 使用状态钩子获取应用状态和 dispatch 函数
React.useEffect(() => { // 使用副作用钩子
dispatch({ type: actions.PROGRAMS.SET_PROGRAMS_LOADING, loading: true }) // 设置程序加载状态为 true
initIPFS().then(async (ipfs) => { // 初始化 IPFS
dispatch({ type: actions.SYSTEMS.SET_IPFS, ipfsStatus: 'Started' }) // 设置 IPFS 状态为 "Started"
initOrbitDB(ipfs).then(async (databases) => { // 初始化 OrbitDB
dispatch({ type: actions.SYSTEMS.SET_ORBITDB, orbitdbStatus: 'Started' }) // 设置 OrbitDB 状态为 "Started"
const programs = await getAllDatabases() // 获取所有数据库
dispatch({ type: actions.PROGRAMS.SET_PROGRAMS, programs: programs.reverse() }) // 设置程序列表,并反转顺序
dispatch({ type: actions.PROGRAMS.SET_PROGRAMS_LOADING, loading: false }) // 设置程序加载状态为 false
})
})
}, [dispatch]) // 依赖项为 dispatch,确保在其改变时重新运行副作用
return ( // 渲染组件
<Pane background='white' elevation={1}> {/* 白色背景的面板 */}
<Pane
display='flex' // 使用 flexbox 布局
flexDirection='row' // 主轴方向为行
alignItems='left' // 子项左对齐
paddingX={majorScale(6)} // 左右内边距
paddingY={majorScale(1)} // 上下内边距
>
<Pane display='flex' flexDirection='row' width='100%'> {/* 包含状态指示器和按钮的面板 */}
<Text
display='flex' // 使用 flexbox 布局
alignItems='center' // 子项垂直居中对齐
fontWeight='600' // 字体加粗
marginRight={minorScale(1)} // 右外边距
>
Systems:
</Text>
{
appState.ipfsStatus === 'Started' // 根据 IPFS 状态渲染相应的状态指示器
? <StatusIndicator color='success'>IPFS</StatusIndicator> // IPFS 状态为 "Started" 时显示成功状态
: <StatusIndicator color='warning'>IPFS</StatusIndicator> // 否则显示警告状态
}
{
appState.orbitdbStatus === 'Started' // 根据 OrbitDB 状态渲染相应的状态指示器
? <StatusIndicator color='success'>OrbitDB</StatusIndicator> // OrbitDB 状态为 "Started" 时显示成功状态
: <StatusIndicator color='warning'>OrbitDB</StatusIndicator> // 否则显示警告状态
}
<ConnectToWalletButton style={{ marginLeft: 'auto' }} /> {/* 渲染连接钱包按钮,自动左侧外边距 */}
</Pane>
</Pane>
</Pane>
)
}
export default Systems // 导出 Systems 组件