feat: undo groups

This commit is contained in:
cha0s 2022-04-11 20:14:54 -05:00
parent a6a676a2f1
commit 443fe7f2b3
2 changed files with 30 additions and 32 deletions

View File

@ -26,10 +26,10 @@ export default (Action, flecks) => class ProjectAction extends Action {
const buffer = await readFile(path); const buffer = await readFile(path);
const json = fromBuffer(buffer, flecks); const json = fromBuffer(buffer, flecks);
if (json.history?.redo?.length) { if (json.history?.redo?.length) {
const patch = json.history.redo[json.history.redo.length - 1]; const {group, patch} = json.history.redo.at(-1);
socket.send(['Action', patchJsonResource({patch, project, uri}, true)]); socket.send(['Action', patchJsonResource({patch, project, uri}, true)]);
applyPatch(json, patch); applyPatch(json, patch);
json.history.undo.push(compare(json, fromBuffer(buffer, flecks))); json.history.undo.push({group, patch: compare(json, fromBuffer(buffer, flecks))});
json.history.redo.pop(); json.history.redo.pop();
await writeFile(path, toBuffer(json, flecks)); await writeFile(path, toBuffer(json, flecks));
} }
@ -47,10 +47,10 @@ export default (Action, flecks) => class ProjectAction extends Action {
const buffer = await readFile(path); const buffer = await readFile(path);
const json = fromBuffer(buffer, flecks); const json = fromBuffer(buffer, flecks);
if (json.history?.undo?.length) { if (json.history?.undo?.length) {
const patch = json.history.undo[json.history.undo.length - 1]; const {group, patch} = json.history.undo.at(-1);
socket.send(['Action', patchJsonResource({patch, project, uri}, true)]); socket.send(['Action', patchJsonResource({patch, project, uri}, true)]);
applyPatch(json, patch); applyPatch(json, patch);
json.history.redo.push(compare(json, fromBuffer(buffer, flecks))); json.history.redo.push({group, patch: compare(json, fromBuffer(buffer, flecks))});
json.history.undo.pop(); json.history.undo.pop();
await writeFile(path, toBuffer(json, flecks)); await writeFile(path, toBuffer(json, flecks));
} }

View File

@ -7,39 +7,37 @@ const startFlush = (flecks) => {
const flushPatches = async () => { const flushPatches = async () => {
const patches = flecks.get('$persea/core.patches'); const patches = flecks.get('$persea/core.patches');
if (patches.length > 0) { if (patches.length > 0) {
const patching = {};
while (patches.length > 0) { while (patches.length > 0) {
const {patch, project, uri} = patches.shift(); const {
group,
patch,
project,
uri,
} = patches.shift();
const path = join(process.cwd(), 'projects', project, uri); const path = join(process.cwd(), 'projects', project, uri);
if (!patching[path]) { // Get controller.
const {toBuffer, fromBuffer} = flecks.get('$avocado/resource/persea.controllers') const {toBuffer, fromBuffer} = flecks.get('$avocado/resource/persea.controllers')
.find(({matcher}) => uri.match(matcher)); .find(({matcher}) => uri.match(matcher));
patching[path] = new Promise((resolve) => { // Load.
readFile(path).then((buffer) => {
resolve({
fromBuffer,
toBuffer,
json: fromBuffer(buffer, flecks),
});
});
});
}
// eslint-disable-next-line no-await-in-loop // eslint-disable-next-line no-await-in-loop
const {json} = await patching[path]; const buffer = await readFile(path);
const json = fromBuffer(buffer, flecks);
// Patch.
applyPatch(json, patch); applyPatch(json, patch);
// Manage history.
const undo = compare(json, fromBuffer(buffer, flecks));
json.history = json.history || {redo: [], undo: []};
json.history.redo = [];
if (
0 === json.history.undo.length
|| group !== json.history.undo.at(-1).group
) {
json.history.undo.push({group, patch: undo});
}
// Flush.
// eslint-disable-next-line no-await-in-loop
await writeFile(path, toBuffer(json, flecks));
} }
await Promise.all(
Object.entries(patching)
.map(async ([path, promise]) => {
const {fromBuffer, toBuffer, json} = await promise;
const buffer = await readFile(path);
const undo = compare(json, fromBuffer(buffer, flecks));
json.history = json.history || {redo: [], undo: []};
json.history.redo = [];
json.history.undo.push(undo);
return writeFile(path, toBuffer(json, flecks));
}),
);
} }
setTimeout(flushPatches, 0); setTimeout(flushPatches, 0);
}; };