Compare commits
79 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
335628a673 | |
|
|
a8487e872c | |
|
|
6933bd2522 | |
|
|
8334ed8f1f | |
|
|
cb118912cd | |
|
|
787adfb9df | |
|
|
18d3563f93 | |
|
|
5ae87e2c9e | |
|
|
01bd6cbeca | |
|
|
e69145b044 | |
|
|
13470cff23 | |
|
|
301d935e25 | |
|
|
c5612f3820 | |
|
|
f1e56aa094 | |
|
|
f40c214714 | |
|
|
30342321a1 | |
|
|
a9c3418906 | |
|
|
58f05b94b5 | |
|
|
dee3ac6f7f | |
|
|
a3d7f28276 | |
|
|
755bc9b39e | |
|
|
44deb88bf6 | |
|
|
49a1b0ac80 | |
|
|
052359a869 | |
|
|
9e7cd38a9b | |
|
|
0496d06611 | |
|
|
0bfc41a107 | |
|
|
b00f9410b7 | |
|
|
6f86993cd2 | |
|
|
755d5a1458 | |
|
|
85d565673d | |
|
|
1a35531779 | |
|
|
d935beb32b | |
|
|
db79a292fe | |
|
|
9c3a8045f2 | |
|
|
72ba937cc7 | |
|
|
27ad030d00 | |
|
|
6fe15976cd | |
|
|
b078aad980 | |
|
|
67b595e993 | |
|
|
03205514d7 | |
|
|
b90807ec78 | |
|
|
9a9af98f32 | |
|
|
2a51850239 | |
|
|
78fb5b937c | |
|
|
4a45635f9f | |
|
|
9f749b95bd | |
|
|
0dfd1e85af | |
|
|
414015cb78 | |
|
|
051f8c46d0 | |
|
|
fd847677f6 | |
|
|
8459ce10a6 | |
|
|
40773778fe | |
|
|
3e83e1eb97 | |
|
|
a1dd4a80cd | |
|
|
2bf929b766 | |
|
|
d9b183f990 | |
|
|
d42f2507f9 | |
|
|
438f25ecc0 | |
|
|
49139b0c91 | |
|
|
fd6700d469 | |
|
|
029c632a6a | |
|
|
454539e304 | |
|
|
a1ba9b6290 | |
|
|
0853469518 | |
|
|
bff4c21c12 | |
|
|
119203d9b6 | |
|
|
a33b20b44d | |
|
|
52694207fa | |
|
|
93e9b8b19c | |
|
|
145a3e95b0 | |
|
|
831905fa06 | |
|
|
decde18f46 | |
|
|
553500298f | |
|
|
bdd14fbfda | |
|
|
bd1f30fe00 | |
|
|
a3329cbd60 | |
|
|
1fcd9e0873 | |
|
|
202d7e55e2 |
|
|
@ -0,0 +1,63 @@
|
|||
version: 2
|
||||
name: 任务三
|
||||
description: ""
|
||||
global:
|
||||
concurrent: 1
|
||||
trigger:
|
||||
webhook: gitlink@1.0.0
|
||||
event:
|
||||
- ref: pr
|
||||
ruleset-operator: AND
|
||||
workflow:
|
||||
- ref: start
|
||||
name: 开始
|
||||
task: start
|
||||
- ref: git_clone_0
|
||||
name: git clone
|
||||
task: git_clone@1.2.9
|
||||
input:
|
||||
username: ((basefile.user1))
|
||||
password: ((basefile.user1_password))
|
||||
remote_url: '"https://gitlink.org.cn/gonggong123zzz/gitlink_help_center.git"'
|
||||
ref: '"refs/heads/master"'
|
||||
commit_id: '""'
|
||||
depth: 1
|
||||
needs:
|
||||
- start
|
||||
- ref: docker_image_build_0
|
||||
name: docker镜像构建
|
||||
task: docker_image_build@1.6.0
|
||||
input:
|
||||
docker_username: ((basefile.docker_user))
|
||||
docker_password: ((basefile.docker_pass))
|
||||
image_name: '"crpi-nmcmhgtru1ytuxul.cn-hangzhou.personal.cr.aliyuncs.com/gitlink_gonggong123zzz/baseali"'
|
||||
image_tag: '"latest"'
|
||||
registry_address: '"crpi-nmcmhgtru1ytuxul.cn-hangzhou.personal.cr.aliyuncs.com"'
|
||||
docker_file: '"Dockerfile"'
|
||||
docker_build_path: '"."'
|
||||
workspace: git_clone_0.git_path
|
||||
image_push: true
|
||||
build_args: '""'
|
||||
needs:
|
||||
- git_clone_0
|
||||
- ref: ssh_cmd_0
|
||||
name: ssh执行命令
|
||||
task: ssh_cmd@1.1.1
|
||||
input:
|
||||
ssh_pass: ((basefile.ssh_password))
|
||||
ssh_ip: '"118.31.168.130"'
|
||||
ssh_port: '"22"'
|
||||
ssh_user: '"root"'
|
||||
ssh_cmd: '"docker stop ghc_group1 || true && docker rm ghc_group1 || true &&
|
||||
docker pull
|
||||
crpi-nmcmhgtru1ytuxul.cn-hangzhou.personal.cr.aliyuncs.com/gitlink_gonggong123zzz/baseali:latest
|
||||
&& docker run -d -p 3000:3000 --name ghc_group1
|
||||
crpi-nmcmhgtru1ytuxul.cn-hangzhou.personal.cr.aliyuncs.com/gitlink_gonggong123zzz/baseali:latest"'
|
||||
needs:
|
||||
- docker_image_build_0
|
||||
- ref: end
|
||||
name: 结束
|
||||
task: end
|
||||
needs:
|
||||
- ssh_cmd_0
|
||||
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
version: 2
|
||||
name: 未命名项目
|
||||
description: ""
|
||||
global:
|
||||
concurrent: 1
|
||||
trigger:
|
||||
webhook: gitlink@1.0.0
|
||||
event:
|
||||
- ref: push
|
||||
ruleset-operator: AND
|
||||
workflow:
|
||||
- ref: start
|
||||
name: 开始
|
||||
task: start
|
||||
- ref: git_clone_0
|
||||
name: git clone
|
||||
task: git_clone@1.2.9
|
||||
input:
|
||||
username: ((ganshihao21.ganshihao21_user))
|
||||
password: ((ganshihao21.ganshihao21))
|
||||
remote_url: '"https://gitlink.org.cn/ganshihao21/reposync.git"'
|
||||
ref: '"refs/heads/master"'
|
||||
commit_id: '""'
|
||||
depth: 1
|
||||
needs:
|
||||
- start
|
||||
- ref: docker_image_build_0
|
||||
name: docker镜像构建
|
||||
task: docker_image_build@1.6.0
|
||||
input:
|
||||
docker_username: ((nudt_devops.nudt_devops))
|
||||
docker_password: ((nudt_devops.nudt_devops))
|
||||
image_name: '"registry.cn-guangzhou.aliyuncs.com/nudt_devops/reposync_group5"'
|
||||
image_tag: '"latest"'
|
||||
registry_address: '"registry.cn-guangzhou.aliyuncs.com"'
|
||||
docker_file: '"Dockerfile"'
|
||||
docker_build_path: '"."'
|
||||
workspace: git_clone_0.git_path
|
||||
image_push: true
|
||||
build_args: '""'
|
||||
needs:
|
||||
- git_clone_0
|
||||
- ref: ssh_cmd_0
|
||||
name: ssh执行命令
|
||||
task: ssh_cmd@1.1.1
|
||||
input:
|
||||
ssh_pass: ((ssh_key.ssh_key))
|
||||
ssh_ip: '"47.96.164.145"'
|
||||
ssh_port: '"22"'
|
||||
ssh_user: '"root"'
|
||||
ssh_cmd: '"docker stop abc_group5 && docker rm abc_group5 && docker pull
|
||||
registry.cn-guangzhou.aliyuncs.com/nudt_devops/reposync_group5:latest &&
|
||||
docker run -d -p 3000:3000 --name abc_group5
|
||||
registry.cn-guangzhou.aliyuncs.com/nudt_devops/reposync_group5:latest"'
|
||||
needs:
|
||||
- docker_image_build_0
|
||||
- ref: end
|
||||
name: 结束
|
||||
task: end
|
||||
needs:
|
||||
- ssh_cmd_0
|
||||
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
---
|
||||
sidebar_label: 'bot市场首页'
|
||||
sidebar_position: 4
|
||||
---
|
||||
import LangSwitch from './LangSwitch';
|
||||
import MyButton from './mybutton';
|
||||
|
||||
<LangSwitch
|
||||
zhContent={[
|
||||
'Bot市场是进行Bot分享与复用的重要模块,主要包括bot的搜索发现,详情查看等功能。',
|
||||
'Bot市场主页中展示了目前所有已经上架市场的bot简要信息,包括bot的头像,名称,开发者,简介和安装次数等信息,用户可根据这些基本信息初步判断该bot是否符合自己的项目需求。',
|
||||
'在bot市场主页中,用户可以选择指定的bot种类,筛选出特定分类的bot,在这个种类范围内进行搜索与选择。',
|
||||
'此外,用户通过在搜索栏中输入关键字进行搜索,可检索出内容包含指定关键字的相关bot。',
|
||||
'用户可结合种类筛选和关键字搜索缩小范围,在市场中快速找到符合项目相关需求的bot。',
|
||||
'',
|
||||
'在bot市场页中,用户点击指定的bot卡片即可进入该bot的详情页。Bot的详情页包含bot的头像,名称,开发者,种类和详细介绍等信息,用户可在此掌握该bot的各项介绍,进一步判断是否将其安装到指定仓库中。',
|
||||
'',
|
||||
'在bot详情页中,若用户认为该bot满足自己的项目需求,可点击"安装此Bot"按钮,了解该bot的权限信息,将其安装到指定的仓库中,关于安装的更多介绍可见"Bot安装"部分。',
|
||||
'去市场看看吧!'
|
||||
]}
|
||||
enContent={[
|
||||
'The bot market is an important module for sharing and reusing bots, mainly including functions such as searching, discovering, and viewing details of bots.',
|
||||
'The Bot Market homepage displays brief information about all bots that have been put on the market, including their avatars, names, developers, introductions, and installation times. Users can use this basic information to preliminarily determine whether the bot meets their project requirements.',
|
||||
'On the bot market homepage, users can select a specific type of bot, filter out specific categories of bots, and search and select within this category range.',
|
||||
'In addition, users can search for relevant bots containing specified keywords by entering keywords in the search bar.',
|
||||
'Users can combine category filtering and keyword search to narrow down the scope and quickly find bots that meet project related needs in the market.',
|
||||
'',
|
||||
'In the bot market page, users can click on the specified bot card to enter the details page of the bot. The details page of the bot includes information such as the bot avatar, name, developer, type, and detailed introduction. Users can grasp the various introductions of the bot here and further determine whether to install it in the designated warehouse.',
|
||||
'',
|
||||
'In the bot details page, if users believe that the bot meets their project requirements, they can click the "Install this bot" button to learn about the bots permission information and install it in the designated warehouse. For more information on installation, please refer to the "Bot Installation" section',
|
||||
'Go take a look at the market!'
|
||||
]}
|
||||
>
|
||||
|
||||
<MyButton onClick={() => {location.href = "https://www.gitlink.org.cn/softbot";}}>Bot市场</MyButton>
|
||||
</LangSwitch>
|
||||
|
||||
# Bot市场
|
||||
|
||||
Bot市场是进行Bot分享与复用的重要模块,主要包括bot的搜索发现,详情查看等功能。
|
||||
|
||||
Bot市场主页中展示了目前所有已经上架市场的bot简要信息,包括bot的头像,名称,开发者,简介和安装次数等信息,用户可根据这些基本信息初步判断该bot是否符合自己的项目需求。
|
||||
|
||||
在bot市场主页中,用户可以选择指定的bot种类,筛选出特定分类的bot,在这个种类范围内进行搜索与选择。
|
||||
|
||||
此外,用户通过在搜索栏中输入关键字进行搜索,可检索出内容包含指定关键字的相关bot。
|
||||
|
||||
用户可结合种类筛选和关键字搜索缩小范围,在市场中快速找到符合项目相关需求的bot。
|
||||
|
||||

|
||||
|
||||
在bot市场页中,用户点击指定的bot卡片即可进入该bot的详情页。Bot的详情页包含bot的头像,名称,开发者,种类和详细介绍等信息,用户可在此掌握该bot的各项介绍,进一步判断是否将其安装到指定仓库中。
|
||||
|
||||

|
||||
|
||||
在bot详情页中,若用户认为该bot满足自己的项目需求,可点击"安装此Bot"按钮,了解该bot的权限信息,将其安装到指定的仓库中,关于安装的更多介绍可见"Bot安装"部分。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
去市场看看吧!
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import React, { useState } from 'react';
|
||||
import MyButton from './mybutton';
|
||||
|
||||
const LangSwitch = ({ zhContent, enContent, children }) => {
|
||||
const [lang, setLang] = useState('zh');
|
||||
const content = lang === 'zh' ? zhContent : enContent;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<MyButton onClick={() => setLang(lang === 'zh' ? 'en' : 'zh')}>
|
||||
{lang === 'zh' ? '中/英' : 'EN/中'}
|
||||
</MyButton>
|
||||
{content.map((item, idx) => (
|
||||
item ? <p key={idx}>{item}</p> : null
|
||||
))}
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LangSwitch;
|
||||
|
|
@ -1,88 +1,44 @@
|
|||
---
|
||||
sidebar_label: 'bot安装'
|
||||
sidebar_position: 1
|
||||
---
|
||||
import MyButton from './mybutton';
|
||||
---
|
||||
sidebar_label: 'bot安装'
|
||||
sidebar_position: 1
|
||||
---
|
||||
import LangSwitch from './LangSwitch';
|
||||
|
||||
<MyButton onClick={() => {
|
||||
var pElements = document.getElementsByTagName('p');
|
||||
var hElements = document.getElementsByTagName('h1');
|
||||
var aElements = document.getElementsByTagName('a');
|
||||
var hzh = ['bot安装','bot安装'];
|
||||
var hen = ['Bot Installation','Bot Installation'];
|
||||
var azh = ['跳到主要内容','','帮助中心','','','','','','','','','','','','','','','','','','','','','机器人(Bot)','编辑此页','上一页 bot市场','下一页bot 配置','网站首页','关于我们','教学实践','合作伙伴','API文档','Git常用命令','引擎使用手册','服务协议','官网邮箱:gitlink@ccf.org.cn','QQ群','公众号'];
|
||||
var aen = ['Jump to main content','','Help Center','','','','','','','','','','','','','','','','','','','','','Robot (Bot)','Edit this page','last page Bot market','next page Bot configuration','Website homepage','About Us','Teaching practice','Partners','API documentation','Common Git commands','Engine User Manual','Service Agreement','Official website email: gitlink@ccf.org.cn','QQ group','Official Account'];
|
||||
var zhtranalate = ['Bot安装是进行bot安装和管理控制的重要模块,主要包括bot安装、安装查询、安装管理等功能。','在bot详情页,用户点击“安装此Bot”按钮后,可以看到该bot工作所需的各项权限信息。若用户同意授予bot所需的相关权限即可进行安装。用户可选择将bot安装到所有仓库(用户拥有的所有仓库)中,也可以选择指定的仓库进行安装。','','在个人“设置”或者“仓库设置”中,用户可以看到目前已经安装的Bot情况,点击“配置”按钮可以对bot安装情况进行配置,点击“卸载”按钮可以进行卸载。','','在bot安装配置页中,用户可以掌握该bot的安装位置和工作状态。若用户需要更改bot的工作仓库时,可以进行更改安装位置。bot的工作状态包括激活和挂起,用户可根据需要对bot的状态进行调整,将其挂起或者激活,会影响到bot对仓库数据的访问权限。','','©Copyright 2024 CCF 开源发展委员会','Powered by Trustie& IntelliDE 京ICP备13000930号'];
|
||||
var entranslate = ['Bot installation is an important module for bot installation and management control, which mainly includes functions such as bot installation, installation queries, and installation management.','On the bot details page, after clicking the "Install this bot" button, users can see the necessary permission information for the bot to work. If the user agrees to grant the necessary permissions to the bot, installation can proceed. Users can choose to install the bot in all warehouses (all warehouses owned by the user) or select a specified warehouse for installation.','','In personal "settings" or "warehouse settings", users can see the current installation status of bots. Click the "configure" button to configure the bot installation status, and click the "uninstall" button to uninstall.','','In the bot installation configuration page, users can grasp the installation location and working status of the bot. If the user needs to change the workspace of the bot, they can change the installation location. The working status of bots includes activation and suspension. Users can adjust the status of bots as needed. Suspending or activating bots can affect their access to warehouse data.','','© Copyright 2024 CCF Open Source Development Committee','Powered by Trust&IntelliDE Beijing ICP Preparation No. 13000930'];
|
||||
if (pElements[0].innerText == zhtranalate[0]){
|
||||
for (var i = 0; i < pElements.length; i++) {
|
||||
if (pElements[i].innerText != ''){
|
||||
if (i < pElements.length){
|
||||
pElements[i].innerText = entranslate[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < pElements.length; i++) {
|
||||
if (pElements[i].innerText != ''){
|
||||
if (i < pElements.length){
|
||||
pElements[i].innerText = zhtranalate[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hElements[0].innerText == hzh[0]){
|
||||
for (var i = 0; i < hElements.length; i++) {
|
||||
if (hElements[i].innerText != ''){
|
||||
if (i < hElements.length){
|
||||
hElements[i].innerText = hen[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < hElements.length; i++) {
|
||||
if (hElements[i].innerText != ''){
|
||||
if (i < hElements.length){
|
||||
hElements[i].innerText = hzh[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aElements[0].innerText == azh[0]){
|
||||
for (var i = 0; i < aElements.length; i++) {
|
||||
if (aElements[i].innerText != ''){
|
||||
if (i < aElements.length){
|
||||
aElements[i].innerText = aen[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < aElements.length; i++) {
|
||||
if (aElements[i].innerText != ''){
|
||||
if (i < aElements.length){
|
||||
aElements[i].innerText = azh[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}>中/英</MyButton>
|
||||
<LangSwitch
|
||||
zhContent={[
|
||||
'Bot安装是进行bot安装和管理控制的重要模块,主要包括bot安装、安装查询、安装管理等功能。',
|
||||
'在bot详情页,用户点击"安装此Bot"按钮后,可以看到该bot工作所需的各项权限信息。若用户同意授予bot所需的相关权限即可进行安装。用户可选择将bot安装到所有仓库(用户拥有的所有仓库)中,也可以选择指定的仓库进行安装。',
|
||||
'',
|
||||
'在个人"设置"或者"仓库设置"中,用户可以看到目前已经安装的Bot情况,点击"配置"按钮可以对bot安装情况进行配置,点击"卸载"按钮可以进行卸载。',
|
||||
'',
|
||||
'在bot安装配置页中,用户可以掌握该bot的安装位置和工作状态。若用户需要更改bot的工作仓库时,可以进行更改安装位置。bot的工作状态包括激活和挂起,用户可根据需要对bot的状态进行调整,将其挂起或者激活,会影响到bot对仓库数据的访问权限。'
|
||||
]}
|
||||
enContent={[
|
||||
'Bot installation is an important module for bot installation and management control, which mainly includes functions such as bot installation, installation queries, and installation management.',
|
||||
'On the bot details page, after clicking the "Install this bot" button, users can see the necessary permission information for the bot to work. If the user agrees to grant the necessary permissions to the bot, installation can proceed. Users can choose to install the bot in all warehouses (all warehouses owned by the user) or select a specified warehouse for installation.',
|
||||
'',
|
||||
'In personal "settings" or "warehouse settings", users can see the current installation status of bots. Click the "configure" button to configure the bot installation status, and click the "uninstall" button to uninstall.',
|
||||
'',
|
||||
'In the bot installation configuration page, users can grasp the installation location and working status of the bot. If the user needs to change the workspace of the bot, they can change the installation location. The working status of bots includes activation and suspension. Users can adjust the status of bots as needed. Suspending or activating bots can affect their access to warehouse data.'
|
||||
]}
|
||||
>
|
||||
<img src="../../static/img/bot/botinstall1.png" alt="botinstall1" />
|
||||
<img src="../../static/img/bot/botinstall2.png" alt="botinstall2" />
|
||||
<img src="../../static/img/bot/botinstall3.png" alt="botinstall3" />
|
||||
</LangSwitch>
|
||||
|
||||
# bot安装
|
||||
|
||||
# bot安装
|
||||
Bot安装是进行bot安装和管理控制的重要模块,主要包括bot安装、安装查询、安装管理等功能。
|
||||
|
||||
Bot安装是进行bot安装和管理控制的重要模块,主要包括bot安装、安装查询、安装管理等功能。
|
||||
在bot详情页,用户点击"安装此Bot"按钮后,可以看到该bot工作所需的各项权限信息。若用户同意授予bot所需的相关权限即可进行安装。用户可选择将bot安装到所有仓库(用户拥有的所有仓库)中,也可以选择指定的仓库进行安装。
|
||||
|
||||
在bot详情页,用户点击“安装此Bot”按钮后,可以看到该bot工作所需的各项权限信息。若用户同意授予bot所需的相关权限即可进行安装。用户可选择将bot安装到所有仓库(用户拥有的所有仓库)中,也可以选择指定的仓库进行安装。
|
||||

|
||||
|
||||

|
||||
在个人"设置"或者"仓库设置"中,用户可以看到目前已经安装的Bot情况,点击"配置"按钮可以对bot安装情况进行配置,点击"卸载"按钮可以进行卸载。
|
||||
|
||||
在个人“设置”或者“仓库设置”中,用户可以看到目前已经安装的Bot情况,点击“配置”按钮可以对bot安装情况进行配置,点击“卸载”按钮可以进行卸载。
|
||||

|
||||
|
||||

|
||||
在bot安装配置页中,用户可以掌握该bot的安装位置和工作状态。若用户需要更改bot的工作仓库时,可以进行更改安装位置。bot的工作状态包括激活和挂起,用户可根据需要对bot的状态进行调整,将其挂起或者激活,会影响到bot对仓库数据的访问权限。
|
||||
|
||||
在bot安装配置页中,用户可以掌握该bot的安装位置和工作状态。若用户需要更改bot的工作仓库时,可以进行更改安装位置。bot的工作状态包括激活和挂起,用户可根据需要对bot的状态进行调整,将其挂起或者激活,会影响到bot对仓库数据的访问权限。
|
||||
|
||||

|
||||

|
||||
|
|
@ -1,53 +1,40 @@
|
|||
---
|
||||
sidebar_label: 'bot市场'
|
||||
sidebar_label: 'bot市场首页'
|
||||
sidebar_position: 4
|
||||
---
|
||||
import LangSwitch from './LangSwitch';
|
||||
import MyButton from './mybutton';
|
||||
|
||||
<MyButton onClick={() => {
|
||||
var pElements = document.getElementsByTagName('p');
|
||||
var hElements = document.getElementsByTagName('h1');
|
||||
var hzh = ['bot市场','bot市场'];
|
||||
var hen = ['Bot Market','Bot Market'];
|
||||
var zhtranalate = ['Bot市场是进行Bot分享与复用的重要模块,主要包括bot的搜索发现,详情查看等功能。','Bot市场主页中展示了目前所有已经上架市场的bot简要信息,包括bot的头像,名称,开发者,简介和安装次数等信息,用户可根据这些基本信息初步判断该bot是否符合自己的项目需求。','在bot市场主页中,用户可以选择指定的bot种类,筛选出特定分类的bot,在这个种类范围内进行搜索与选择。','此外,用户通过在搜索栏中输入关键字进行搜索,可检索出内容包含指定关键字的相关bot。','用户可结合种类筛选和关键字搜索缩小范围,在市场中快速找到符合项目相关需求的bot。','','在bot市场页中,用户点击指定的bot卡片即可进入该bot的详情页。Bot的详情页包含bot的头像,名称,开发者,种类和详细介绍等信息,用户可在此掌握该bot的各项介绍,进一步判断是否将其安装到指定仓库中。','','在bot详情页中,若用户认为该bot满足自己的项目需求,可点击“安装此Bot”按钮,了解该bot的权限信息,将其安装到指定的仓库中,关于安装的更多介绍可见“Bot安装”部分。','去市场看看吧!','©Copyright 2024 CCF 开源发展委员会','Powered by Trustie& IntelliDE 京ICP备13000930号'];
|
||||
var entranslate = ['The bot market is an important module for sharing and reusing bots, mainly including functions such as searching, discovering, and viewing details of bots.' , 'The Bot Market homepage displays brief information about all bots that have been put on the market, including their avatars, names, developers, introductions, and installation times. Users can use this basic information to preliminarily determine whether the bot meets their project requirements.' , 'On the bot market homepage, users can select a specific type of bot, filter out specific categories of bots, and search and select within this category range.' , 'In addition, users can search for relevant bots containing specified keywords by entering keywords in the search bar.' , 'Users can combine category filtering and keyword search to narrow down the scope and quickly find bots that meet project related needs in the market.' , '' , 'In the bot market page, users can click on the specified bot card to enter the details page of the bot. The details page of the bot includes information such as the bot avatar, name, developer, type, and detailed introduction. Users can grasp the various introductions of the bot here and further determine whether to install it in the designated warehouse.' , '' , 'In the bot details page, if users believe that the bot meets their project requirements, they can click the "Install this bot" button to learn about the bots permission information and install it in the designated warehouse. For more information on installation, please refer to the "Bot Installation" section' , 'Go take a look at the market!' , '©Copyright 2024 CCF Open Source Development Committee' , 'Powered by Trustie& IntelliDE 京ICP备13000930号'];
|
||||
if (pElements[0].innerText == zhtranalate[0]){
|
||||
for (var i = 0; i < pElements.length; i++) {
|
||||
if (pElements[i].innerText != ''){
|
||||
if (i < pElements.length){
|
||||
pElements[i].innerText = entranslate[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < pElements.length; i++) {
|
||||
if (pElements[i].innerText != ''){
|
||||
if (i < pElements.length){
|
||||
pElements[i].innerText = zhtranalate[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hElements[0].innerText == hzh[0]){
|
||||
for (var i = 0; i < hElements.length; i++) {
|
||||
if (hElements[i].innerText != ''){
|
||||
if (i < hElements.length){
|
||||
hElements[i].innerText = hen[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < hElements.length; i++) {
|
||||
if (hElements[i].innerText != ''){
|
||||
if (i < hElements.length){
|
||||
hElements[i].innerText = hzh[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}>中/英</MyButton>
|
||||
<LangSwitch
|
||||
zhContent={[
|
||||
'Bot市场是进行Bot分享与复用的重要模块,主要包括bot的搜索发现,详情查看等功能。',
|
||||
'Bot市场主页中展示了目前所有已经上架市场的bot简要信息,包括bot的头像,名称,开发者,简介和安装次数等信息,用户可根据这些基本信息初步判断该bot是否符合自己的项目需求。',
|
||||
'在bot市场主页中,用户可以选择指定的bot种类,筛选出特定分类的bot,在这个种类范围内进行搜索与选择。',
|
||||
'此外,用户通过在搜索栏中输入关键字进行搜索,可检索出内容包含指定关键字的相关bot。',
|
||||
'用户可结合种类筛选和关键字搜索缩小范围,在市场中快速找到符合项目相关需求的bot。',
|
||||
'',
|
||||
'在bot市场页中,用户点击指定的bot卡片即可进入该bot的详情页。Bot的详情页包含bot的头像,名称,开发者,种类和详细介绍等信息,用户可在此掌握该bot的各项介绍,进一步判断是否将其安装到指定仓库中。',
|
||||
'',
|
||||
'在bot详情页中,若用户认为该bot满足自己的项目需求,可点击"安装此Bot"按钮,了解该bot的权限信息,将其安装到指定的仓库中,关于安装的更多介绍可见"Bot安装"部分。',
|
||||
'去市场看看吧!'
|
||||
]}
|
||||
enContent={[
|
||||
'The bot market is an important module for sharing and reusing bots, mainly including functions such as searching, discovering, and viewing details of bots.',
|
||||
'The Bot Market homepage displays brief information about all bots that have been put on the market, including their avatars, names, developers, introductions, and installation times. Users can use this basic information to preliminarily determine whether the bot meets their project requirements.',
|
||||
'On the bot market homepage, users can select a specific type of bot, filter out specific categories of bots, and search and select within this category range.',
|
||||
'In addition, users can search for relevant bots containing specified keywords by entering keywords in the search bar.',
|
||||
'Users can combine category filtering and keyword search to narrow down the scope and quickly find bots that meet project related needs in the market.',
|
||||
'',
|
||||
'In the bot market page, users can click on the specified bot card to enter the details page of the bot. The details page of the bot includes information such as the bot avatar, name, developer, type, and detailed introduction. Users can grasp the various introductions of the bot here and further determine whether to install it in the designated warehouse.',
|
||||
'',
|
||||
'In the bot details page, if users believe that the bot meets their project requirements, they can click the "Install this bot" button to learn about the bots permission information and install it in the designated warehouse. For more information on installation, please refer to the "Bot Installation" section',
|
||||
'Go take a look at the market!'
|
||||
]}
|
||||
>
|
||||
<img src="../../static/img/bot/botmarket1.png" alt="botmarket1" />
|
||||
<img src="../../static/img/bot/botmarket2.png" alt="botmarket2" />
|
||||
<MyButton onClick={() => {location.href = "https://www.gitlink.org.cn/softbot";}}>Bot市场</MyButton>
|
||||
</LangSwitch>
|
||||
|
||||
# Bot市场
|
||||
|
||||
|
|
@ -67,7 +54,7 @@ Bot市场主页中展示了目前所有已经上架市场的bot简要信息,
|
|||
|
||||

|
||||
|
||||
在bot详情页中,若用户认为该bot满足自己的项目需求,可点击“安装此Bot”按钮,了解该bot的权限信息,将其安装到指定的仓库中,关于安装的更多介绍可见“Bot安装”部分。
|
||||
在bot详情页中,若用户认为该bot满足自己的项目需求,可点击"安装此Bot"按钮,了解该bot的权限信息,将其安装到指定的仓库中,关于安装的更多介绍可见"Bot安装"部分。
|
||||
|
||||
|
||||
|
||||
|
|
@ -75,8 +62,4 @@ Bot市场主页中展示了目前所有已经上架市场的bot简要信息,
|
|||
|
||||
去市场看看吧!
|
||||
|
||||
<MyButton onClick={() => {
|
||||
location.href = "https://www.gitlink.org.cn/softbot";
|
||||
}}>Bot市场</MyButton>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,68 +1,49 @@
|
|||
---
|
||||
sidebar_label: 'bot开发'
|
||||
sidebar_position: 3
|
||||
sidebar_label: 'bot配置'
|
||||
sidebar_position: 2
|
||||
---
|
||||
import MyButton from './mybutton';
|
||||
import LangSwitch from './LangSwitch';
|
||||
|
||||
<MyButton onClick={() => {
|
||||
var pElements = document.getElementsByTagName('p');
|
||||
var hElements = document.getElementsByTagName('h1');
|
||||
var hzh = ['bot开发','bot开发'];
|
||||
var hen = ['Bot Development','Bot Development'];
|
||||
var zhtranalate = ['Bot开发是开发者进行bot注册的重要模块。' , '在个人“设置”中,用户可以看到目前已经注册的bot列表,点击对应bot的“编辑”按钮可以对已注册的bot进行配置;点击“Bot注册”按钮开始注册新的bot。' , '' , '在注册页中,开发者需要填写bot注册的相关信息,包括bot的名称、Webhook 地址,详细介绍等,系统将对开发者输入的信息进行合法性校验,确保bot各项信息的完整性和有效性。此外,系统将自动生成bot的唯一标识,同时调用 GitLink 平台的相关接口生成bot的身份凭证信息,包括客户端密钥和私钥等。' , '开发者需通过这些身份信息结合平台接口进行bot身份认证后,调用相关接口完成bot的相关功能。' , '平台开发API链接(待完善):https://www.gitlink.org.cn/docs/api#introduction' , '' , '' , '©Copyright 2024 CCF 开源发展委员会' , 'Powered by Trustie& IntelliDE 京ICP备13000930号'];
|
||||
var entranslate = ['Bot development is an important module for developers to register their bots.' , 'In personal settings, users can see a list of registered bots and click the "Edit" button on the corresponding bot to configure the registered bots; Click the "Bot Registration" button to start registering a new bot.' , '' , 'In the registration page, developers need to fill in the relevant information for bot registration, including the name of the bot, Webhook address, detailed introduction, etc. The system will verify the legality of the information entered by the developer to ensure the completeness and validity of all bot information. In addition, the system will automatically generate a unique identifier for the bot, and call the relevant interfaces of the GitLink platform to generate the identity credential information of the bot, including the client key and private key.' , 'Developers need to use these identity information in combination with the platform interface for bot identity authentication, and then call the relevant interface to complete the relevant functions of the bot.' , 'Platform development API link (to be improved): https://www.gitlink.org.cn/docs/api#introduction' , '' , '' , '© Copyright 2024 CCF Open Source Development Committee' , 'Powered by Trust&IntelliDE Beijing ICP Preparation No. 13000930'];
|
||||
if (pElements[0].innerText == zhtranalate[0]){
|
||||
for (var i = 0; i < pElements.length; i++) {
|
||||
if (pElements[i].innerText != ''){
|
||||
if (i < pElements.length){
|
||||
pElements[i].innerText = entranslate[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < pElements.length; i++) {
|
||||
if (pElements[i].innerText != ''){
|
||||
if (i < pElements.length){
|
||||
pElements[i].innerText = zhtranalate[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hElements[0].innerText == hzh[0]){
|
||||
for (var i = 0; i < hElements.length; i++) {
|
||||
if (hElements[i].innerText != ''){
|
||||
if (i < hElements.length){
|
||||
hElements[i].innerText = hen[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (var i = 0; i < hElements.length; i++) {
|
||||
if (hElements[i].innerText != ''){
|
||||
if (i < hElements.length){
|
||||
hElements[i].innerText = hzh[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}}>中/英</MyButton>
|
||||
<LangSwitch
|
||||
zhContent={[
|
||||
'Bot配置是开发者进行bot维护和配置的重要模块,主要包括bot基本信息维护、权限&订阅事件管理、高级选项配置等功能。',
|
||||
'Bot的基本信息维护中,开发者可以看到bot的各项基本信息,并可以根据需要对bot的头像,名称,Webhook地址等进行修改。',
|
||||
'',
|
||||
'Bot的权限&订阅事件管理中,开发者可根据对仓库资源的访问需要为bot分配不同的权限和等级,比如增加代码库权限,将拉取请求的写权限变为读权限等。开发者还能更改当前bot订阅的事件列表,比如订阅代码库推送,取消拉取请求分配订阅等,以实现bot功能的更新与升级。',
|
||||
'',
|
||||
'Bot高级选项配置中,开发者可以改变bot的公私有状态,从而影响到bot的使用范围。需要注意的是,公开状态下的bot在已有其他仓库安装的情况下不能变成私有。开发者可选择将bot上架到市场,需要填写上架信息,包括市场简介,主要功能,次要功能等各项信息。',
|
||||
'开发者还能进行bot的删除和转让操作,发起转让意味着更改bot的所有权,需要输入接受者的用户名。在接受者确定接受后,即可完成bot的所有权变更,拒绝则会取消本次的转让操作。'
|
||||
]}
|
||||
enContent={[
|
||||
'Bot configuration is an important module for developers to maintain and configure bots, mainly including basic bot information maintenance, permission&subscription event management, advanced option configuration, and other functions.',
|
||||
'In the basic information maintenance of bots, developers can see various basic information of bots and modify their avatars, names, Webhook addresses, etc. as needed.',
|
||||
'',
|
||||
'In the permission and subscription event management of bots, developers can assign different permissions and levels to bots based on their access needs to warehouse resources, such as adding code library permissions, changing write permissions for pull requests to read permissions, etc. Developers can also modify the event list of the current bot subscription, such as subscribing to code library push notifications, canceling pull request allocation subscriptions, etc., to achieve updates and upgrades of bot functionality.',
|
||||
'',
|
||||
'In the advanced options configuration of bots, developers can change the public and private status of bots, thereby affecting their usage scope. It should be noted that bots in public status cannot become private when installed in other warehouses. Developers can choose to put their bots on the market and need to fill in the listing information, including market introduction, main functions, secondary functions, and other related information.',
|
||||
'Developers can also perform bot deletion and transfer operations, initiating transfer means changing the ownership of the bot, and the recipients username needs to be entered. After the recipient confirms acceptance, the ownership change of the bot can be completed. Refusal will cancel the transfer operation.'
|
||||
]}
|
||||
>
|
||||
<img src="../../static/img/bot/botconfig1.png" alt="botconfig1" />
|
||||
<img src="../../static/img/bot/botconfig2.png" alt="botconfig2" />
|
||||
<img src="../../static/img/bot/botconfig3.png" alt="botconfig3" />
|
||||
</LangSwitch>
|
||||
|
||||
# Bot开发
|
||||
# Bot配置
|
||||
|
||||
Bot开发是开发者进行bot注册的重要模块。
|
||||
Bot配置是开发者进行bot维护和配置的重要模块,主要包括bot基本信息维护、权限&订阅事件管理、高级选项配置等功能。
|
||||
|
||||
在个人“设置”中,用户可以看到目前已经注册的bot列表,点击对应bot的“编辑”按钮可以对已注册的bot进行配置;点击“Bot注册”按钮开始注册新的bot。
|
||||
Bot的基本信息维护中,开发者可以看到bot的各项基本信息,并可以根据需要对bot的头像,名称,Webhook地址等进行修改。
|
||||
|
||||

|
||||

|
||||
|
||||
在注册页中,开发者需要填写bot注册的相关信息,包括bot的名称、Webhook 地址,详细介绍等,系统将对开发者输入的信息进行合法性校验,确保bot各项信息的完整性和有效性。此外,系统将自动生成bot的唯一标识,同时调用 GitLink 平台的相关接口生成bot的身份凭证信息,包括客户端密钥和私钥等。
|
||||
Bot的权限&订阅事件管理中,开发者可根据对仓库资源的访问需要为bot分配不同的权限和等级,比如增加代码库权限,将拉取请求的写权限变为读权限等。开发者还能更改当前bot订阅的事件列表,比如订阅代码库推送,取消拉取请求分配订阅等,以实现bot功能的更新与升级。
|
||||
|
||||
开发者需通过这些身份信息结合平台接口进行bot身份认证后,调用相关接口完成bot的相关功能。
|
||||

|
||||
|
||||
平台开发API链接(待完善):https://www.gitlink.org.cn/docs/api#introduction
|
||||
|
||||

|
||||
Bot高级选项配置中,开发者可以改变bot的公私有状态,从而影响到bot的使用范围。需要注意的是,公开状态下的bot在已有其他仓库安装的情况下不能变成私有。开发者可选择将bot上架到市场,需要填写上架信息,包括市场简介,主要功能,次要功能等各项信息。
|
||||
|
||||

|
||||
开发者还能进行bot的删除和转让操作,发起转让意味着更改bot的所有权,需要输入接受者的用户名。在接受者确定接受后,即可完成bot的所有权变更,拒绝则会取消本次的转让操作。
|
||||
|
||||

|
||||
|
|
|
|||
|
|
@ -16,16 +16,16 @@ sidebar_position: 2
|
|||
|
||||

|
||||
|
||||
**注**:只能使用以字母、数字开头,包含字母、数字、下划线、横杠等,长度4到20个字符
|
||||
**注**:只能使用以字母、数字开头,包含字母、数字、下划线、横杠等,长度4到20个字符
|
||||
|
||||
## 组织名称与组织描述
|
||||
|
||||

|
||||
|
||||
**注**:此处为必填项,不得为空
|
||||
**注**:此处为必填项,不得为空
|
||||
|
||||
## 可见性
|
||||
|
||||

|
||||
|
||||
**注**:可见性预设三类组织:公开、受限(仅对登录用户可见)、私有(仅对组织成员可见)。
|
||||
**注**:可见性预设三类组织:公开、受限(仅对登录用户可见)、私有(仅对组织成员可见)。
|
||||
|
|
|
|||
|
|
@ -18,4 +18,4 @@ sidebar_position: 4
|
|||

|
||||
此外,也可以复制邀请链接的方式来更方便地邀请成员加入到项目当中来
|
||||
|
||||
**注**:此项功能仅对管理员可见
|
||||
**注**:此项功能仅对管理员可见
|
||||
|
|
@ -8,5 +8,5 @@ sidebar_position: 5
|
|||
|
||||

|
||||
|
||||
**注**:在“拥有者”一栏的下拉选项中,可以选择:个人、组织、团队
|
||||
**注**:在“拥有者”一栏的下拉选项中,可以选择:个人、组织、团队
|
||||
|
||||
|
|
|
|||
|
|
@ -154,6 +154,17 @@ module.exports = {
|
|||
// sidebarPath: require.resolve('./sidebars.js'),
|
||||
editUrl:'https://www.gitlink.org.cn/Gitlink/gitlink_help_center/tree/master/',
|
||||
routeBasePath: "/",
|
||||
lastVersion: 'current',
|
||||
versions: {
|
||||
current: {
|
||||
label: '最新版本',
|
||||
path: '',
|
||||
},
|
||||
'1.1.0': {
|
||||
label: '1.1.0',
|
||||
path: 'version-1.1.0',
|
||||
},
|
||||
},
|
||||
},
|
||||
theme: {
|
||||
customCss: require.resolve('./src/css/custom.css'),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import './styles.css';
|
||||
|
||||
export default function BackToTopButton() {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const toggleVisibility = () => {
|
||||
if (window.pageYOffset > 300) {
|
||||
setIsVisible(true);
|
||||
} else {
|
||||
setIsVisible(false);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', toggleVisibility);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('scroll', toggleVisibility);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const scrollToTop = () => {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
className={`back-to-top-button ${isVisible ? 'visible' : ''}`}
|
||||
onClick={scrollToTop}
|
||||
aria-label="返回顶部"
|
||||
title="返回顶部"
|
||||
>
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M12 19V5M5 12l7-7 7 7" />
|
||||
</svg>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
.back-to-top-button {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
right: 20px;
|
||||
transform: translateY(-50%);
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--ifm-color-primary);
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: all 0.3s ease;
|
||||
z-index: 9999;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.back-to-top-button:hover {
|
||||
background-color: var(--ifm-color-primary-darker);
|
||||
transform: translateY(-50%) scale(1.1);
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.back-to-top-button.visible {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { useLocation } from '@docusaurus/router';
|
||||
import './styles.css';
|
||||
|
||||
export default function FavoriteButton() {
|
||||
const location = useLocation();
|
||||
const [isFavorited, setIsFavorited] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// 检查当前页面是否已收藏
|
||||
const favorites = JSON.parse(localStorage.getItem('favorites') || '[]');
|
||||
setIsFavorited(favorites.includes(location.pathname));
|
||||
}, [location.pathname]);
|
||||
|
||||
const toggleFavorite = () => {
|
||||
const favorites = JSON.parse(localStorage.getItem('favorites') || '[]');
|
||||
const currentPath = location.pathname;
|
||||
|
||||
if (favorites.includes(currentPath)) {
|
||||
// 取消收藏
|
||||
const newFavorites = favorites.filter(path => path !== currentPath);
|
||||
localStorage.setItem('favorites', JSON.stringify(newFavorites));
|
||||
setIsFavorited(false);
|
||||
} else {
|
||||
// 添加收藏
|
||||
favorites.push(currentPath);
|
||||
localStorage.setItem('favorites', JSON.stringify(favorites));
|
||||
setIsFavorited(true);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
className={`favorite-button ${isFavorited ? 'favorited' : ''}`}
|
||||
onClick={toggleFavorite}
|
||||
aria-label={isFavorited ? '取消收藏' : '收藏页面'}
|
||||
title={isFavorited ? '取消收藏' : '收藏页面'}
|
||||
>
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill={isFavorited ? '#ffd700' : 'none'}
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
.favorite-button {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
color: var(--ifm-navbar-link-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s ease;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.favorite-button:hover {
|
||||
background-color: var(--ifm-color-emphasis-200);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.favorite-button.favorited {
|
||||
color: #ffd700;
|
||||
}
|
||||
|
||||
.favorite-button.favorited:hover {
|
||||
color: #ffed4a;
|
||||
}
|
||||
|
||||
.favorite-button svg {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
import React, { useState } from 'react';
|
||||
import './styles.css';
|
||||
|
||||
export default function ScreenshotButton() {
|
||||
const [isCapturing, setIsCapturing] = useState(false);
|
||||
|
||||
const captureScreenshot = async () => {
|
||||
if (isCapturing) return;
|
||||
|
||||
setIsCapturing(true);
|
||||
|
||||
try {
|
||||
// 检查浏览器是否支持 Screen Capture API
|
||||
if (navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) {
|
||||
// 使用浏览器原生截图API
|
||||
const stream = await navigator.mediaDevices.getDisplayMedia({
|
||||
video: { mediaSource: 'screen' }
|
||||
});
|
||||
|
||||
const video = document.createElement('video');
|
||||
video.srcObject = stream;
|
||||
video.play();
|
||||
|
||||
// 等待视频加载完成
|
||||
await new Promise((resolve) => {
|
||||
video.addEventListener('loadedmetadata', resolve);
|
||||
});
|
||||
|
||||
// 延迟2秒,让选择窗口完全消失
|
||||
setTimeout(() => {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = video.videoWidth;
|
||||
canvas.height = video.videoHeight;
|
||||
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(video, 0, 0);
|
||||
|
||||
// 停止录制
|
||||
stream.getTracks().forEach(track => track.stop());
|
||||
|
||||
// 创建下载链接
|
||||
const link = document.createElement('a');
|
||||
link.download = `page-screenshot-${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.png`;
|
||||
link.href = canvas.toDataURL('image/png');
|
||||
|
||||
// 触发下载
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
|
||||
setIsCapturing(false);
|
||||
}, 2000); // 延迟2秒
|
||||
|
||||
} else {
|
||||
// 备用方案:提示用户手动截图
|
||||
alert('您的浏览器不支持自动截图,请使用 Ctrl+Shift+S 或 Cmd+Shift+4 手动截图');
|
||||
setIsCapturing(false);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
if (error.name === 'NotAllowedError') {
|
||||
alert('截图被用户取消');
|
||||
} else {
|
||||
console.error('截图失败:', error);
|
||||
alert('截图失败,请使用浏览器的截图功能(Ctrl+Shift+S 或 Cmd+Shift+4)');
|
||||
}
|
||||
setIsCapturing(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
className={`screenshot-button ${isCapturing ? 'capturing' : ''}`}
|
||||
onClick={captureScreenshot}
|
||||
disabled={isCapturing}
|
||||
aria-label={isCapturing ? '正在截图...' : '截图页面'}
|
||||
title={isCapturing ? '正在截图...' : '截图页面'}
|
||||
>
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/>
|
||||
<circle cx="12" cy="13" r="4"/>
|
||||
</svg>
|
||||
{isCapturing && (
|
||||
<div className="screenshot-loading">
|
||||
<div className="screenshot-spinner"></div>
|
||||
<span className="screenshot-countdown">等待2秒后截图...</span>
|
||||
</div>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
.screenshot-button {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
color: var(--ifm-navbar-link-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s ease;
|
||||
margin-right: 8px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.screenshot-button:hover {
|
||||
background-color: var(--ifm-color-emphasis-200);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.screenshot-button.capturing {
|
||||
color: var(--ifm-color-primary);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.screenshot-button.capturing:hover {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.screenshot-button svg {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.screenshot-loading {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background-color: var(--ifm-background-color);
|
||||
border: 1px solid var(--ifm-color-emphasis-300);
|
||||
border-radius: 8px;
|
||||
padding: 8px 12px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
z-index: 1000;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.screenshot-spinner {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border: 2px solid var(--ifm-color-emphasis-300);
|
||||
border-top: 2px solid var(--ifm-color-primary);
|
||||
border-radius: 50%;
|
||||
animation: screenshot-spin 1s linear infinite;
|
||||
}
|
||||
|
||||
.screenshot-countdown {
|
||||
font-size: 12px;
|
||||
color: var(--ifm-color-emphasis-700);
|
||||
}
|
||||
|
||||
@keyframes screenshot-spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
|
@ -16,9 +16,27 @@
|
|||
--ifm-color-primary-lightest: rgb(146, 224, 208);
|
||||
--ifm-code-font-size: 95%;
|
||||
--search-local-modal-background:#1b2440;
|
||||
--transition-duration: 0.3s;
|
||||
}
|
||||
|
||||
[data-theme] {
|
||||
transition: background-color var(--transition-duration) ease,
|
||||
color var(--transition-duration) ease,
|
||||
border-color var(--transition-duration) ease,
|
||||
box-shadow var(--transition-duration) ease;
|
||||
}
|
||||
|
||||
[data-theme] * {
|
||||
transition: background-color var(--transition-duration) ease,
|
||||
color var(--transition-duration) ease,
|
||||
border-color var(--transition-duration) ease,
|
||||
box-shadow var(--transition-duration) ease;
|
||||
}
|
||||
|
||||
.navbar{
|
||||
background-color: rgba(27, 36, 64, 1);
|
||||
transition: background-color var(--transition-duration) ease,
|
||||
box-shadow var(--transition-duration) ease !important;
|
||||
}
|
||||
.navbar__link--active,a:hover,.menu__link--active{
|
||||
color: rgba(70, 106, 255, 1)!important;
|
||||
|
|
@ -149,4 +167,208 @@ html[data-theme='dark'] .docusaurus-highlight-code-line {
|
|||
.widget{
|
||||
display: none!important;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* 打印样式 */
|
||||
@media print {
|
||||
.navbar,
|
||||
.footer,
|
||||
.theme-doc-toc-desktop,
|
||||
.theme-edit-this-page {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.main-wrapper {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.markdown {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
max-width: 100% !important;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
.markdown pre {
|
||||
white-space: pre-wrap !important;
|
||||
word-wrap: break-word !important;
|
||||
}
|
||||
|
||||
.markdown h1,
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
|
||||
/* 添加打印按钮样式 */
|
||||
.print-button {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
z-index: 100;
|
||||
background: var(--ifm-color-primary);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.print-button:hover {
|
||||
transform: scale(1.1);
|
||||
background: var(--ifm-color-primary-darker);
|
||||
}
|
||||
|
||||
/* 目录悬浮样式 */
|
||||
.theme-doc-toc-desktop {
|
||||
position: sticky !important;
|
||||
top: 80px !important;
|
||||
max-height: calc(100vh - 80px) !important;
|
||||
overflow-y: auto !important;
|
||||
padding: 1rem !important;
|
||||
background: var(--ifm-background-color) !important;
|
||||
border-radius: 8px !important;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1) !important;
|
||||
transition: all 0.3s ease !important;
|
||||
}
|
||||
|
||||
.theme-doc-toc-desktop:hover {
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15) !important;
|
||||
}
|
||||
|
||||
.theme-doc-toc-desktop .table-of-contents__link {
|
||||
font-size: 0.9rem !important;
|
||||
padding: 0.3rem 0 !important;
|
||||
transition: all 0.2s ease !important;
|
||||
}
|
||||
|
||||
.theme-doc-toc-desktop .table-of-contents__link:hover {
|
||||
color: var(--ifm-color-primary) !important;
|
||||
transform: translateX(5px) !important;
|
||||
}
|
||||
|
||||
.theme-doc-toc-desktop .table-of-contents__link--active {
|
||||
font-weight: bold !important;
|
||||
color: var(--ifm-color-primary) !important;
|
||||
}
|
||||
|
||||
/* 代码块复制按钮样式 */
|
||||
.code-block-copy-button {
|
||||
position: absolute !important;
|
||||
right: 0.5rem !important;
|
||||
top: 0.5rem !important;
|
||||
padding: 0.3rem 0.6rem !important;
|
||||
background: var(--ifm-background-color) !important;
|
||||
border: 1px solid var(--ifm-color-emphasis-300) !important;
|
||||
border-radius: 4px !important;
|
||||
font-size: 0.8rem !important;
|
||||
color: var(--ifm-color-emphasis-700) !important;
|
||||
cursor: pointer !important;
|
||||
transition: all 0.2s ease !important;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
||||
.code-block-wrapper:hover .code-block-copy-button {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.code-block-copy-button:hover {
|
||||
background: var(--ifm-color-primary) !important;
|
||||
color: white !important;
|
||||
border-color: var(--ifm-color-primary) !important;
|
||||
}
|
||||
|
||||
.code-block-copy-button.copied {
|
||||
background: var(--ifm-color-success) !important;
|
||||
color: white !important;
|
||||
border-color: var(--ifm-color-success) !important;
|
||||
}
|
||||
|
||||
/* 主题切换按钮动画 */
|
||||
.theme-toggle {
|
||||
transition: transform 0.3s ease !important;
|
||||
}
|
||||
|
||||
.theme-toggle:hover {
|
||||
transform: rotate(30deg) !important;
|
||||
}
|
||||
|
||||
/* 导航栏主题切换动画 */
|
||||
.navbar {
|
||||
transition: background-color var(--transition-duration) ease,
|
||||
box-shadow var(--transition-duration) ease !important;
|
||||
}
|
||||
|
||||
/* 侧边栏主题切换动画 */
|
||||
.menu {
|
||||
transition: background-color var(--transition-duration) ease,
|
||||
border-color var(--transition-duration) ease !important;
|
||||
}
|
||||
|
||||
/* 分享按钮样式 */
|
||||
.share-button {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 80px;
|
||||
z-index: 100;
|
||||
background: var(--ifm-color-primary);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.share-button:hover {
|
||||
transform: scale(1.1);
|
||||
background: var(--ifm-color-primary-darker);
|
||||
}
|
||||
|
||||
.share-menu {
|
||||
position: fixed;
|
||||
bottom: 70px;
|
||||
right: 80px;
|
||||
background: var(--ifm-background-color);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
padding: 10px;
|
||||
display: none;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.share-menu.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.share-menu a {
|
||||
display: block;
|
||||
padding: 8px 16px;
|
||||
color: var(--ifm-color-emphasis-700);
|
||||
text-decoration: none;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.share-menu a:hover {
|
||||
background: var(--ifm-color-primary);
|
||||
color: white;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
|
@ -1,149 +1,99 @@
|
|||
import React from 'react';
|
||||
import Layout from '@theme/Layout';
|
||||
import Link from '@docusaurus/Link';
|
||||
import clsx from 'clsx';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useLocation } from '@docusaurus/router';
|
||||
|
||||
import NewsSection from '../components/NewsSection';
|
||||
import HeroSection from '../components/HeroSection';
|
||||
import ProductsSection from '../components/ProductsSection';
|
||||
import InvestorsSection from '../components/InvestorsSection';
|
||||
import CustomersSection from '../components/CustomersSection';
|
||||
import DeveloperCommunitySection from '../components/DeveloperCommunitySection';
|
||||
import FeatureSection from '../components/FeatureSection';
|
||||
export default function EnhancedFeatures() {
|
||||
const location = useLocation();
|
||||
|
||||
const Icon3 = require('../../static/img/home-buildingblocks.svg').default;
|
||||
useEffect(() => {
|
||||
// 添加打印按钮
|
||||
const addPrintButton = () => {
|
||||
const printButton = document.createElement('button');
|
||||
printButton.className = 'print-button';
|
||||
printButton.innerHTML = '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9V2h12v7M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><path d="M6 14h12v8H6z"/></svg>';
|
||||
printButton.onclick = () => window.print();
|
||||
document.body.appendChild(printButton);
|
||||
};
|
||||
|
||||
const title = 'BoxyHQ';
|
||||
const description = 'Security Building Blocks for Developers';
|
||||
// 添加代码块复制按钮
|
||||
const addCodeCopyButtons = () => {
|
||||
const codeBlocks = document.querySelectorAll('pre');
|
||||
codeBlocks.forEach((block) => {
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = 'code-block-wrapper';
|
||||
block.parentNode.insertBefore(wrapper, block);
|
||||
wrapper.appendChild(block);
|
||||
|
||||
const IndexPage = () => {
|
||||
return (
|
||||
<Layout title={title} description={description}>
|
||||
<HeroSection
|
||||
title="Security Building Blocks for Developers"
|
||||
description="Reduce Time to Market without sacrificing your security posture! BoxyHQ’s suite of APIs for security and privacy helps engineering teams build and ship compliant cloud applications faster."
|
||||
image="/img/home-hero.svg"
|
||||
buttons={[
|
||||
{
|
||||
title: 'Get Started',
|
||||
href: 'https://boxyhq.com/docs',
|
||||
className: 'button--primary',
|
||||
},
|
||||
{
|
||||
title: 'Book a demo',
|
||||
href: 'https://meetings.hubspot.com/deepakprab/demo?__hstc=213510283.9a563789bb583fca1e9fb20a629c5c94.1651597904536.1664893584285.1664895920328.169&__hssc=213510283.1.1664895920328&__hsfp=498882655',
|
||||
className: 'button--primary button--outline',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
const copyButton = document.createElement('button');
|
||||
copyButton.className = 'code-block-copy-button';
|
||||
copyButton.textContent = '复制';
|
||||
copyButton.onclick = async () => {
|
||||
const code = block.querySelector('code').textContent;
|
||||
await navigator.clipboard.writeText(code);
|
||||
copyButton.textContent = '已复制';
|
||||
copyButton.classList.add('copied');
|
||||
setTimeout(() => {
|
||||
copyButton.textContent = '复制';
|
||||
copyButton.classList.remove('copied');
|
||||
}, 2000);
|
||||
};
|
||||
wrapper.appendChild(copyButton);
|
||||
});
|
||||
};
|
||||
|
||||
{/* <CustomersSection />
|
||||
<ProductsSection /> */}
|
||||
// 添加分享按钮
|
||||
const addShareButton = () => {
|
||||
const shareButton = document.createElement('button');
|
||||
shareButton.className = 'share-button';
|
||||
shareButton.innerHTML = '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"/><polyline points="16 6 12 2 8 6"/><line x1="12" y1="2" x2="12" y2="15"/></svg>';
|
||||
|
||||
const shareMenu = document.createElement('div');
|
||||
shareMenu.className = 'share-menu';
|
||||
shareMenu.innerHTML = `
|
||||
<a href="https://service.weibo.com/share/share.php?url=${encodeURIComponent(window.location.href)}&title=${encodeURIComponent(document.title)}" target="_blank">微博</a>
|
||||
<a href="https://connect.qq.com/widget/shareqq/index.html?url=${encodeURIComponent(window.location.href)}&title=${encodeURIComponent(document.title)}" target="_blank">QQ</a>
|
||||
<a href="https://www.linkedin.com/shareArticle?mini=true&url=${encodeURIComponent(window.location.href)}&title=${encodeURIComponent(document.title)}" target="_blank">LinkedIn</a>
|
||||
`;
|
||||
|
||||
<section className="page__section">
|
||||
<div className="container">
|
||||
<div className="row" style={{ gap: '10px', marginTop: '20px' }}>
|
||||
<div className="col col--5 col--offset-1">
|
||||
<div className="col-demo">
|
||||
<div className="card-demo" style={{}}>
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h3
|
||||
className="text--center"
|
||||
style={{ whiteSpace: 'pre-line' }}
|
||||
>
|
||||
The Importance of Developer Security
|
||||
</h3>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<p className="text--center">
|
||||
Cyber crimes are predicted to cost $10.5 trillion
|
||||
annually by 2025, but time pressures often cause 70% of
|
||||
development teams to skip crucial security steps.
|
||||
</p>
|
||||
<p>
|
||||
In today's world, it is no longer sufficient to
|
||||
prioritize productivity alone. The faster a developer
|
||||
moves, the more potential security holes will be left
|
||||
unaddressed.{' '}
|
||||
</p>
|
||||
</div>
|
||||
<div className="card__footer">
|
||||
<Link
|
||||
className={clsx('button button--primary button--block')}
|
||||
href="https://meetings.hubspot.com/deepakprab/demo?__hstc=213510283.9a563789bb583fca1e9fb20a629c5c94.1651597904536.1664893584285.1664895920328.169&__hssc=213510283.1.1664895920328&__hsfp=498882655"
|
||||
>
|
||||
Book a free developer-security session
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col col--5">
|
||||
<div className="col-demo">
|
||||
<div className="card-demo">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h3
|
||||
className="text--center"
|
||||
style={{ whiteSpace: 'pre-line' }}
|
||||
>
|
||||
Build or buy?
|
||||
</h3>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<p className="text--center">
|
||||
Save time and money with BoxyHQ's free open-source
|
||||
solution. Available under an Apache 2.0 license, our
|
||||
solutions make it easy for developers to collaborate and
|
||||
innovate, without the need for custom building or
|
||||
expensive fees.
|
||||
</p>
|
||||
<p className="text--center">
|
||||
Our solutions run in your environment, giving you full
|
||||
control. We simply provide the building blocks to help
|
||||
you succeed.
|
||||
</p>
|
||||
</div>
|
||||
<div className="card__footer">
|
||||
<Link
|
||||
className={clsx('button button--primary button--block')}
|
||||
href="mailto:hello@boxyhq.com"
|
||||
>
|
||||
Contact Us
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
shareButton.onclick = () => {
|
||||
shareMenu.classList.toggle('show');
|
||||
};
|
||||
|
||||
<FeatureSection
|
||||
title="Developer Security Tools"
|
||||
btnLink="https://awesome-oss-devsec.boxyhq.com/"
|
||||
btnText="Read More"
|
||||
image={Icon3}
|
||||
direction="right"
|
||||
>
|
||||
<p>
|
||||
We have curated a list of awesome open-source developer security
|
||||
tools.
|
||||
</p>
|
||||
<p>
|
||||
It includes security principles and controls relevant to popular
|
||||
compliance certifications (like ISO27001, SOC2, MVSP, etc.)
|
||||
</p>
|
||||
</FeatureSection>
|
||||
document.body.appendChild(shareButton);
|
||||
document.body.appendChild(shareMenu);
|
||||
};
|
||||
|
||||
{/* <NewsSection />
|
||||
<InvestorsSection />
|
||||
<DeveloperCommunitySection /> */}
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
// 添加主题切换按钮
|
||||
const addThemeToggleButton = () => {
|
||||
const themeToggleButton = document.createElement('button');
|
||||
themeToggleButton.className = 'theme-toggle';
|
||||
themeToggleButton.innerHTML = '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg>';
|
||||
themeToggleButton.onclick = () => {
|
||||
document.body.classList.toggle('data-theme');
|
||||
document.body.classList.toggle('green');
|
||||
};
|
||||
document.body.appendChild(themeToggleButton);
|
||||
};
|
||||
|
||||
export default IndexPage;
|
||||
// 添加主题选择器事件监听
|
||||
const themeSelector = document.getElementById('theme-selector');
|
||||
if (themeSelector) {
|
||||
themeSelector.addEventListener('change', function() {
|
||||
const selectedTheme = this.value;
|
||||
document.body.classList.remove('data-theme', 'green'); // 移除所有主题类
|
||||
if (selectedTheme === 'green') {
|
||||
document.body.classList.add('data-theme', 'green');
|
||||
} else {
|
||||
document.body.setAttribute('data-theme', selectedTheme);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化功能
|
||||
addPrintButton();
|
||||
addCodeCopyButtons();
|
||||
addShareButton();
|
||||
addThemeToggleButton();
|
||||
}, [location]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
import React from 'react';
|
||||
import {useThemeConfig} from '@docusaurus/theme-common';
|
||||
import {
|
||||
splitNavbarItems,
|
||||
useNavbarMobileSidebar,
|
||||
} from '@docusaurus/theme-common/internal';
|
||||
import NavbarItem from '@theme/NavbarItem';
|
||||
import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle';
|
||||
import SearchBar from '@theme/SearchBar';
|
||||
import NavbarMobileSidebarToggle from '@theme/Navbar/MobileSidebar/Toggle';
|
||||
import NavbarLogo from '@theme/Navbar/Logo';
|
||||
import NavbarSearch from '@theme/Navbar/Search';
|
||||
import ScreenshotButton from '@site/src/components/ScreenshotButton';
|
||||
import FavoriteButton from '@site/src/components/FavoriteButton';
|
||||
|
||||
import styles from './styles.module.css';
|
||||
|
||||
function useNavbarItems() {
|
||||
return useThemeConfig().navbar.items;
|
||||
}
|
||||
|
||||
function NavbarItems({items}) {
|
||||
return (
|
||||
<>
|
||||
{items.map((item, i) => (
|
||||
<NavbarItem {...item} key={i} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function NavbarContentLayout({left, right}) {
|
||||
return (
|
||||
<div className="navbar__inner">
|
||||
<div className="navbar__items">{left}</div>
|
||||
<div className="navbar__items navbar__items--right">{right}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function NavbarContent() {
|
||||
const mobileSidebar = useNavbarMobileSidebar();
|
||||
const items = useNavbarItems();
|
||||
const [leftItems, rightItems] = splitNavbarItems(items);
|
||||
|
||||
const searchBarItem = items.find((item) => item.type === 'search');
|
||||
|
||||
return (
|
||||
<NavbarContentLayout
|
||||
left={
|
||||
<>
|
||||
{!mobileSidebar.disabled && <NavbarMobileSidebarToggle />}
|
||||
<NavbarLogo />
|
||||
<NavbarItems items={leftItems} />
|
||||
</>
|
||||
}
|
||||
right={
|
||||
<>
|
||||
<NavbarItems items={rightItems} />
|
||||
<ScreenshotButton />
|
||||
<FavoriteButton />
|
||||
<NavbarColorModeToggle className={styles.colorModeToggle} />
|
||||
{!searchBarItem && (
|
||||
<NavbarSearch>
|
||||
<SearchBar />
|
||||
</NavbarSearch>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
.colorModeToggle {
|
||||
margin: 0 calc(var(--ifm-navbar-item-padding-horizontal) / 2);
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import React from 'react';
|
||||
import FavoriteButton from '@site/src/components/FavoriteButton';
|
||||
import BackToTopButton from '@site/src/components/BackToTopButton';
|
||||
|
||||
export default function Root({children}) {
|
||||
return (
|
||||
<>
|
||||
{children}
|
||||
<FavoriteButton />
|
||||
<BackToTopButton />
|
||||
</>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue