Skip to content

Commit

Permalink
feat: add the ability to group projects
Browse files Browse the repository at this point in the history
Signed-off-by: The1111mp <[email protected]>
  • Loading branch information
1111mp committed May 2, 2024
1 parent d358218 commit f2612a0
Show file tree
Hide file tree
Showing 19 changed files with 1,472 additions and 80 deletions.
7 changes: 7 additions & 0 deletions @types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ declare global {
updateAt: string;
}

interface Group {
name: string;
desc?: string;
version: string;
projects: string[];
}

interface ConfigrationExport {
color?: string;
mirrors?: string | null;
Expand Down
24 changes: 24 additions & 0 deletions _locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -502,5 +502,29 @@
"Configration-import-success": {
"message": "The import has been completed. If you encounter data inconsistency, please restart the application.",
"description": "The text of the Configration-import-success"
},
"Groups": {
"message": "Groups",
"description": "The text of the Groups"
},
"Group-Name": {
"message": "Group Name",
"description": "The text of the Group-Name"
},
"Group-Desc": {
"message": "Group Description",
"description": "The text of the Group-Desc"
},
"Create-Group": {
"message": "Create Group",
"description": "The text of the Create-Group"
},
"Group-Delete": {
"message": "Are you sure to delete this group?",
"description": "The text of the Group-Delete"
},
"Input-To-Search": {
"message": "input to search",
"description": "The text of the Input-To-Search"
}
}
24 changes: 24 additions & 0 deletions _locales/zh_CN/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -502,5 +502,29 @@
"Configration-import-success": {
"message": "导入已完成。 如果遇到数据不一致,请重启应用。",
"description": "The text of the Configration-import-success"
},
"Groups": {
"message": "分组",
"description": "The text of the Groups"
},
"Group-Name": {
"message": "分组名称",
"description": "The text of the Group-Name"
},
"Group-Desc": {
"message": "分组描述",
"description": "The text of the Group-Desc"
},
"Create-Group": {
"message": "创建分组",
"description": "The text of the Create-Group"
},
"Group-Delete": {
"message": "确定要删除此分组吗?",
"description": "The text of the Group-Delete"
},
"Input-To-Search": {
"message": "输入以搜索",
"description": "The text of the Input-To-Search"
}
}
1 change: 1 addition & 0 deletions src/main/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ export const APPDIR = join(HOME, '.nvmd'),
VERSIONS_FILENAME = join(APPDIR, 'versions.json'),
SETTING_JSONFILE = join(APPDIR, 'setting.json'),
PROJECTS_JSONFILE = join(APPDIR, 'projects.json'),
GROUPS_JSONFILE = join(APPDIR, 'groups.json'),
MIRRATION_FILE = join(APPDIR, 'migration'),
NVMDRC_NAME = '.nvmdrc';
26 changes: 26 additions & 0 deletions src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ import {
getProjects,
getVersion,
syncProjectVersion,
updateProjectAndSyncVersion,
updateProjects,
updateProjectsAndSync
} from "./utils/projects";
import { createGroup, getGroups, updateGroupVersion, updateGroups } from "./utils/groups";
import { gt } from "semver";
import loadLocale from "./locale";
import { Closer, Themes } from "../types";
Expand Down Expand Up @@ -501,6 +503,7 @@ Promise.resolve().then(() => {
}
);

// * Projects
ipcMain.handle("get-projects", async (_event, load: boolean = false) => {
return getProjects(load);
});
Expand All @@ -516,6 +519,18 @@ Promise.resolve().then(() => {
return syncProjectVersion(path, version);
});

ipcMain.handle(
"update-project-remove-group",
(_event, projectsPath: string[], groupName: string, version: string) => {
return updateProjectAndSyncVersion({
projects: projectsPath,
groupName,
version
});
}
);

// * Configration
ipcMain.handle("configration-export", async (_event, args: Nvmd.ConfigrationExport) => {
const { color, setting: exportSetting, projects, path, mirrors } = args;
let output: Nvmd.Configration = {};
Expand Down Expand Up @@ -551,4 +566,15 @@ Promise.resolve().then(() => {
return { canceled, color, mirrors, setting: importSetting };
}
);

// * Groups
ipcMain.handle("group-get", (_event, load: boolean = false) => getGroups(load));

ipcMain.handle("group-create", (_event, group: Nvmd.Group) => createGroup(group));

ipcMain.handle("group-update", (_event, groups: Nvmd.Group[]) => updateGroups(groups));

ipcMain.handle("group-update-version", (_event, group: Nvmd.Group, version: string) =>
updateGroupVersion(group, version)
);
});
77 changes: 77 additions & 0 deletions src/main/utils/groups.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { join } from "node:path";
import { pathExists, readFile, readJson, writeJson, writeFile, remove } from "fs-extra";
import { GROUPS_JSONFILE, NVMDRC_NAME } from "../constants";
import { syncProjectVersion, updateProjectAndSyncVersion } from "./projects";

let cacheGroups: Nvmd.Group[];

export async function getGroups(load: boolean = false): Promise<Nvmd.Group[]> {
if (cacheGroups !== void 0 && !load) {
return cacheGroups;
}

if (!(await pathExists(GROUPS_JSONFILE))) {
cacheGroups = [];
return cacheGroups;
}

const groups = (await readJson(GROUPS_JSONFILE, { throws: false })) || [];

cacheGroups = groups;

return groups;
}

export async function createGroup(group: Nvmd.Group) {
const { projects, version } = group;

// * Need to update the version of the project
if (projects && projects.length && version) {
// * projects saves the path of the project
await updateProjectAndSyncVersion({
projects,
groupName: group.name,
version
});
}

if (projects && projects.length) {
// If the project is already in another group, you need to remove it from the group.
cacheGroups.forEach((cacheGroup) => {
const { projects } = cacheGroup;
cacheGroup.projects = projects.filter((project) => !projects.includes(project));
});
}

const newGroups = [group, ...cacheGroups];

await writeJson(GROUPS_JSONFILE, newGroups);
cacheGroups = newGroups;
return;
}

export async function updateGroups(groups: Nvmd.Group[], path?: string) {
if (path && (await pathExists(join(path, NVMDRC_NAME)))) {
await remove(join(path, NVMDRC_NAME));
}

await writeJson(GROUPS_JSONFILE, groups);
cacheGroups = groups;
return;
}

export async function updateGroupVersion(group: Nvmd.Group, version: string) {
const { projects, name } = group;
await Promise.all(projects.map((projectPath) => syncProjectVersion(projectPath, version)));

const newGroups = [...cacheGroups];
newGroups.forEach((group) => {
if (group.name === name) {
group.version = version;
}
});

cacheGroups = newGroups;
await writeJson(GROUPS_JSONFILE, newGroups);
return cacheGroups;
}
29 changes: 29 additions & 0 deletions src/main/utils/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,32 @@ export async function syncProjectVersion(path: string, version: string) {
await writeFile(join(path, NVMDRC_NAME), version);
return 200;
}

type UpdateByGroup = {
projects: string[];
groupName: string;
version: string;
};

export async function updateProjectAndSyncVersion({ projects, groupName, version }: UpdateByGroup) {
const asyncVerions: Promise<any>[] = [],
newProjects = [...cacheProjects];
projects.forEach((projectPath) => {
// update projectpath/.nvmdrc
asyncVerions.push(syncProjectVersion(projectPath, version));

// update $HOMEPATH/.nvmd/projects.json
// await updateProjectFromGroup({ groupName });
newProjects.forEach((project) => {
if (project.path === projectPath) {
project.version = groupName;
}
});
});

cacheProjects = newProjects;
asyncVerions.push(writeJson(PROJECTS_JSONFILE, newProjects));

await Promise.all(asyncVerions);
return cacheProjects;
}
19 changes: 18 additions & 1 deletion src/preload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ const electronHandler = {
onThemeChanged = callback;
},

// projects
openFolderSelecter: ({
title,
multiple = false,
Expand All @@ -135,6 +136,14 @@ const electronHandler = {
ipcRenderer.invoke("update-projects", projects, path) as Promise<void>,
syncProjectVersion: (path: string, version: string) =>
ipcRenderer.invoke("sync-project-version", path, version) as Promise<404 | 200>,
updateProjectsWhenRemoveGroup: (
projectsPath: string[],
groupName: string = "",
version: string = ""
) =>
ipcRenderer.invoke("update-project-remove-group", projectsPath, groupName, version) as Promise<
Nvmd.Project[]
>,
onRegistProjectUpdate: (callback: OnProjectUpdate | null) => {
onProjectUpdate = callback;
},
Expand All @@ -150,7 +159,15 @@ const electronHandler = {
onConfigrationImport: (args: { sync: boolean; title: string }) =>
ipcRenderer.invoke("configration-import", args) as Promise<
OpenDialogReturnValue & { color?: string; mirrors?: string; setting?: Nvmd.Setting }
>
>,

// * Groups
getGroups: (load: boolean = false) =>
ipcRenderer.invoke("group-get", load) as Promise<Nvmd.Group[]>,
onGroupCreate: (group: Nvmd.Group) => ipcRenderer.invoke("group-create", group),
onGroupUpdate: (groups: Nvmd.Group[]) => ipcRenderer.invoke("group-update", groups),
onGroupUpdateVersion: (group: Nvmd.Group, version: string) =>
ipcRenderer.invoke("group-update-version", group, version) as Promise<Nvmd.Group[]>
};

contextBridge.exposeInMainWorld("Context", electronHandler);
Expand Down
Loading

0 comments on commit f2612a0

Please sign in to comment.