Merge pull request #331 from toeverything/refactor/cascade-event

Refactor/cascade event
This commit is contained in:
DarkSky
2022-08-25 18:56:32 +08:00
committed by GitHub
3 changed files with 48 additions and 29 deletions
@@ -180,9 +180,49 @@ export class AsyncBlock {
return this.event_emitter.emit(eventName, eventData);
}
onUpdate(callback: (event: EventData) => void) {
this.on('update', callback);
/**
* @param deep observe deep
*
* NOTICE: the observe of children is async,
* so there maybe have some delay before observe done.
*/
onUpdate(callback: (event: EventData) => void, deep = 0) {
let expired = false;
const unobserveMap: Record<string, () => void> = {};
const observeChildren = () => {
if (deep <= 0) {
return;
}
this.children().then(children => {
// Check current event listeners is not expired
if (expired) {
return;
}
children.forEach(child => {
if (unobserveMap[child.id]) return;
const unobserve = child.onUpdate(callback, deep - 1);
unobserveMap[child.id] = unobserve;
});
});
};
const unobserveChildren = () => {
Object.values(unobserveMap).forEach(unobserve => {
unobserve();
});
};
this.on('update', e => {
callback(e);
// Update children observe
observeChildren();
});
observeChildren();
return () => {
expired = true;
unobserveChildren();
this.off('update', callback);
};
}
@@ -40,6 +40,8 @@ export const KanbanParentBlockRender = ({
};
const useBlockProgress = (block?: AsyncBlock) => {
// Progress of the progress bar. The range is between 0 and 1.
// Default progress is 1, that is 100%.
const [progress, setProgress] = useState(1);
useEffect(() => {
@@ -57,36 +59,13 @@ const useBlockProgress = (block?: AsyncBlock) => {
setProgress(checkedTodoChildren.length / todoChildren.length);
};
let childrenQueue: (() => void)[] = [];
const childrenUnobserve = () => {
childrenQueue.forEach(fn => fn());
childrenQueue = [];
};
const observeChildren = async () => {
const children = await block.children();
childrenUnobserve();
children.forEach(child => {
const unobserve = child.onUpdate(() => {
updateProgress();
});
childrenQueue.push(unobserve);
});
};
observeChildren();
updateProgress();
const unobserve = block.onUpdate(() => {
observeChildren();
updateProgress();
});
}, 1);
return () => {
unobserve();
childrenUnobserve();
};
return unobserve;
}, [block]);
return progress;
@@ -168,7 +168,7 @@ export class Database {
block.on('children', observer_name, listener);
block.on('content', observer_name, listener);
block.on('parent', observer_name, listener);
block.on('cascade', observer_name, listener);
// block.on('cascade', observer_name, listener);
}
this.#observers.setStatus(observer_name, 'observing');
@@ -189,7 +189,7 @@ export class Database {
block.off('children', observer_name);
block.off('content', observer_name);
block.off('parent', observer_name);
block.off('cascade', observer_name);
// block.off('cascade', observer_name);
}
}
}