From f1288e6039765fc7943d10128d1eca0302902d39 Mon Sep 17 00:00:00 2001
From: hwr <763230412@qq.com>
Date: Tue, 15 Aug 2023 13:39:28 +0800
Subject: [PATCH] feat: implement
LocalStorage,SetDefault,DeleteCollection,AddCurRepo feature
---
.../features/repo-collection/view.tsx | 242 +++++++++++++++---
1 file changed, 208 insertions(+), 34 deletions(-)
diff --git a/src/pages/ContentScripts/features/repo-collection/view.tsx b/src/pages/ContentScripts/features/repo-collection/view.tsx
index 28d40c07..300e27d3 100644
--- a/src/pages/ContentScripts/features/repo-collection/view.tsx
+++ b/src/pages/ContentScripts/features/repo-collection/view.tsx
@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React, { useEffect, useState } from 'react';
import { DownOutlined } from '@ant-design/icons';
import { Dropdown, Space, Divider, Button, Input, theme } from 'antd';
import type { MenuProps } from 'antd';
@@ -7,7 +7,17 @@ import {
GithubOutlined,
SettingOutlined,
DeleteOutlined,
+ FolderAddOutlined,
} from '@ant-design/icons';
+import { getRepoName } from '../../../../helpers/get-repo-info';
+
+const iconMap: any = {
+ AppstoreOutlined: AppstoreOutlined,
+ GithubOutlined: GithubOutlined,
+ SettingOutlined: SettingOutlined,
+ DeleteOutlined: DeleteOutlined,
+ FolderAddOutlined: FolderAddOutlined,
+};
const { useToken } = theme;
@@ -33,50 +43,152 @@ function getItem(
const View = () => {
const { token } = useToken();
-
const contentStyle: React.CSSProperties = {
backgroundColor: token.colorBgElevated,
borderRadius: token.borderRadiusLG,
boxShadow: token.boxShadowSecondary,
};
-
const menuStyle: React.CSSProperties = {
boxShadow: 'none',
};
-
- const [items, setitems] = useState([
+ const DefaultItems = [
getItem('X-Lab', 'collection1', , [
getItem('delete collection', 'delete1', ),
+ getItem('add current Repo', 'add1', ),
{ type: 'divider' },
- getItem('open-digger', '1'),
- getItem('open-perf', '2'),
- getItem('open-leaderboard', '3'),
- getItem('open-wonderland', '4'),
+ getItem('open-digger', '1.1'),
+ getItem('open-perf', '1.2'),
+ getItem('open-leaderboard', '1.3'),
+ getItem('open-wonderland', '1.4'),
]),
- getItem('Collection Two', 'collection2', , [
+ getItem('Hypertrons', 'collection2', , [
getItem('delete collection', 'delete2', ),
+ getItem('add current Repo', 'add2', ),
{ type: 'divider' },
- getItem('Option 5', '5'),
- getItem('Option 6', '6'),
+ getItem('hypertrons-crx', '2.1'),
+ getItem('hypertrons-crx-website', '2.2'),
]),
getItem('Collection Three', 'collection3', , [
getItem('delete collection', 'delete3', ),
+ getItem('add current Repo', 'add3', ),
{ type: 'divider' },
- getItem('Option 9', '9'),
- getItem('Option 10', '10'),
- getItem('Option 11', '11'),
- getItem('Option 12', '12'),
+ getItem('Option 9', '3.1'),
+ getItem('Option 10', '3.2'),
+ getItem('Option 11', '3.3'),
+ getItem('Option 12', '3.4'),
]),
- ]);
-
+ ];
+ const [items, setitems] = useState(DefaultItems);
+ const [refresh, setRefresh] = useState(0);
const [newCollectionName, setNewCollectionName] = useState('');
+ const [open, setOpen] = useState(false);
+
+ //将 Repo Collection 信息转化为 `JSON` 用于存至 Chrome 本地
+ const StorageCollection = (Storage: any) => {
+ const jsonArray = Storage.map((item: any) => {
+ const childrenArray = item.children
+ ? item.children.map((child: any) => {
+ if (child.type === 'divider') {
+ return { type: 'divider' };
+ }
+ return {
+ label: child.label,
+ key: child.key,
+ icon: child.icon && child.icon.type.render.displayName,
+ };
+ })
+ : undefined;
+
+ return {
+ label: item.label,
+ key: item.key,
+ icon: item.icon && item.icon.type.render.displayName,
+ children: childrenArray,
+ };
+ });
+
+ chrome.storage.local.set({ UserCollection: jsonArray }).then(() => {
+ console.log('UserCollection is set');
+ });
+ };
+
+ //每次对 Repo Collection 列表更新后,执行 UpdateCollection 更新 Key值
+ const UpdateCollection = (updatedItems: any) => {
+ const renumberedItems = updatedItems.map((collection: any, index: any) => {
+ return {
+ ...collection,
+ key: `collection${index + 1}`,
+ children: collection.children.map((child: any) => {
+ if (/^delete/.test(child.key)) {
+ return {
+ ...child,
+ key: `delete${index + 1}`,
+ };
+ } else if (/^add/.test(child.key)) {
+ return {
+ ...child,
+ key: `add${index + 1}`,
+ };
+ } else if (child.type === 'divider') {
+ return { ...child };
+ } else {
+ const childIndex = parseInt(child.key.split('.')[1]);
+ return {
+ ...child,
+ key: `${index + 1}.${childIndex}`,
+ };
+ }
+ }),
+ };
+ });
+
+ console.log(renumberedItems);
+
+ setitems(renumberedItems);
+
+ // 更新本地存储
+ StorageCollection(renumberedItems);
+ };
+
+ // 将 JSON 转化为 Item 初始化的数据结构
+ const ConvertJSONToItem = (jsonArray: any) => {
+ return jsonArray.map((item: any) => {
+ const children = item.children.map((child: any) => {
+ if (child.type === 'divider') {
+ return { type: 'divider' };
+ }
+
+ const childIconComponent = child.icon
+ ? React.createElement(iconMap[child.icon])
+ : undefined;
+
+ return getItem(child.label, child.key, childIconComponent);
+ });
+
+ const iconComponent = item.icon
+ ? React.createElement(iconMap[item.icon])
+ : undefined;
+
+ return getItem(item.label, item.key, iconComponent, children);
+ });
+ };
+
+ // 读取用户自定义的 Repo Collection
+ useEffect(() => {
+ chrome.storage.local.get(['UserCollection']).then((result) => {
+ if (result.UserCollection) {
+ const CollectionArray: any = ConvertJSONToItem(result.UserCollection);
+ setitems(CollectionArray);
+ }
+ });
+ }, [refresh]);
const AddRepoCollection = () => {
if (newCollectionName.trim() === '') {
alert('请输入集合名称');
return;
}
- alert(newCollectionName);
+
// 找到所有 collection 编号的最大值
const collectionNumbers = items.map((item: any) => {
const match = item.key.match(/collection(\d+)/);
@@ -99,44 +211,105 @@ const View = () => {
`delete${newCollectionNumber}`,
),
+ getItem(
+ 'add current Repo',
+ `add${newCollectionNumber}`,
+
+ ),
{ type: 'divider' },
]
);
// 更新 items 数组
setitems([...items, newMenuItem]);
+
+ // 更新本地存储,需要转化为JSON格式
+ StorageCollection([...items, newMenuItem]);
+ };
+
+ const SetAsDefault = () => {
+ setitems(DefaultItems);
+ StorageCollection(DefaultItems);
};
- const DeleteRepoCollection = (info: any) => {
- const clickedItemKey = info.keyPath;
+ const handleMenuClick: MenuProps['onClick'] = (info) => {
+ const clickedItemKey: any = info.keyPath;
+
// Check if the clicked item is the "delete collection" label
if (/^delete/.test(clickedItemKey[0])) {
- const updatedItems = items.filter(
+ const updatedItems: any = items.filter(
(item: any) => item.key !== clickedItemKey[1]
);
- setitems(updatedItems);
// 重新分配集合的键值
- const renumberedItems = updatedItems.map((item: any, index) => {
- const match = item.key.match(/collection(\d+)/);
- const newCollectionNumber = index + 1;
- return {
- ...item,
- key: match ? `collection${newCollectionNumber}` : item.key,
- };
- });
+ UpdateCollection(updatedItems);
+ }
+
+ // Check if the clicked item is the "add current Repo" label
+ if (/^add/.test(clickedItemKey[0])) {
+ const RepoFullName = getRepoName();
+ const RepoName = RepoFullName.match(/\/([^/]+)$/);
+
+ if (RepoName) {
+ const CollectionNumber = clickedItemKey[1].match(/\d+/)[0];
+ const targetCollection: any = items.find(
+ (item: any) => item.key === clickedItemKey[1]
+ );
+
+ if (
+ targetCollection.children.some(
+ (item: any) => item.label === RepoName[1]
+ )
+ ) {
+ alert('该仓库已存在~');
+ return;
+ }
+ const pattern = new RegExp(`^${CollectionNumber}\.(\\d+)`);
+ const matchingNumbers = targetCollection.children
+ .filter((item: any) => pattern.test(item.key))
+ .map((item: any) => parseInt(item.key.match(pattern)[1]));
+ const maxNumber = Math.max(...matchingNumbers);
+
+ // 创建新的 Repo 编号
+ const newRepoKey = maxNumber + 1;
+
+ const newRepoLabel = RepoName[1];
- setitems(renumberedItems);
+ // 创建新的 Repo项
+ const newRepoItem = getItem(
+ newRepoLabel,
+ `${CollectionNumber}.${newRepoKey}`
+ );
+ targetCollection.children.push(newRepoItem);
+ }
+
+ // 更新 items 数组
+ setitems(items);
+
+ UpdateCollection(items);
+
+ setRefresh(refresh + 1);
}
};
+ const handleOpenChange = (newOpen: boolean) => {
+ setOpen(newOpen);
+ };
+
return (