Merge pull request #331 from toeverything/refactor/cascade-event
Refactor/cascade event
This commit is contained in:
@@ -180,9 +180,49 @@ export class AsyncBlock {
|
|||||||
return this.event_emitter.emit(eventName, eventData);
|
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 () => {
|
return () => {
|
||||||
|
expired = true;
|
||||||
|
unobserveChildren();
|
||||||
this.off('update', callback);
|
this.off('update', callback);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ export const KanbanParentBlockRender = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const useBlockProgress = (block?: AsyncBlock) => {
|
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);
|
const [progress, setProgress] = useState(1);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -57,36 +59,13 @@ const useBlockProgress = (block?: AsyncBlock) => {
|
|||||||
setProgress(checkedTodoChildren.length / todoChildren.length);
|
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();
|
updateProgress();
|
||||||
|
|
||||||
const unobserve = block.onUpdate(() => {
|
const unobserve = block.onUpdate(() => {
|
||||||
observeChildren();
|
|
||||||
updateProgress();
|
updateProgress();
|
||||||
});
|
}, 1);
|
||||||
|
|
||||||
return () => {
|
return unobserve;
|
||||||
unobserve();
|
|
||||||
childrenUnobserve();
|
|
||||||
};
|
|
||||||
}, [block]);
|
}, [block]);
|
||||||
|
|
||||||
return progress;
|
return progress;
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ export class Database {
|
|||||||
block.on('children', observer_name, listener);
|
block.on('children', observer_name, listener);
|
||||||
block.on('content', observer_name, listener);
|
block.on('content', observer_name, listener);
|
||||||
block.on('parent', 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');
|
this.#observers.setStatus(observer_name, 'observing');
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ export class Database {
|
|||||||
block.off('children', observer_name);
|
block.off('children', observer_name);
|
||||||
block.off('content', observer_name);
|
block.off('content', observer_name);
|
||||||
block.off('parent', observer_name);
|
block.off('parent', observer_name);
|
||||||
block.off('cascade', observer_name);
|
// block.off('cascade', observer_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user