Skip to content

Commit

Permalink
MDL-79194 core_courseformat: optimize section reload
Browse files Browse the repository at this point in the history
  • Loading branch information
ferranrecio committed Sep 27, 2023
1 parent 05b377f commit d13749e
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 7 deletions.
2 changes: 1 addition & 1 deletion course/format/amd/build/local/content.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion course/format/amd/build/local/content.min.js.map

Large diffs are not rendered by default.

32 changes: 29 additions & 3 deletions course/format/amd/src/local/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -545,17 +545,37 @@ export default class Component extends BaseComponent {
}
);
promise.then((html, js) => {
// Other state change can reload the CM or the section before this one.
if (!document.contains(cmitem)) {
return;
}
Templates.replaceNode(cmitem, html, js);
this._indexContents();
pendingReload.resolve();
return;
}).catch();
}).catch(() => {
pendingReload.resolve();
});
};
debouncedReload = debounce(reload, 200);
debouncedReload = debounce(reload, 200, {cancel: true});
this.debouncedReloads.set(pendingKey, debouncedReload);
return debouncedReload;
}

/**
* Cancel the active reload CM debounced function, if any.
* @param {Number} cmId
*/
_cancelDebouncedReloadCm(cmId) {
const pendingKey = `courseformat/content:reloadCm_${cmId}`;
const debouncedReload = this.debouncedReloads.get(pendingKey);
if (!debouncedReload) {
return;
}
debouncedReload.cancel();
this.debouncedReloads.delete(pendingKey);
}

/**
* Reload a course section contents.
*
Expand All @@ -569,6 +589,10 @@ export default class Component extends BaseComponent {
const pendingReload = new Pending(`courseformat/content:reloadSection_${element.id}`);
const sectionitem = this.getElement(this.selectors.SECTION, element.id);
if (sectionitem) {
// Cancel any pending reload because the section will reload cms too.
for (const cmId of element.cmlist) {
this._cancelDebouncedReloadCm(cmId);
}
const promise = Fragment.loadFragment(
'core_courseformat',
'section',
Expand All @@ -584,7 +608,9 @@ export default class Component extends BaseComponent {
this._indexContents();
pendingReload.resolve();
return;
}).catch();
}).catch(() => {
pendingReload.resolve();
});
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/amd/build/utils.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/amd/build/utils.min.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions lib/amd/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,15 @@ const debounceMap = new Map();
* @param {Number} wait The number of milliseconds to wait after the final attempt to execute
* @param {Object} [options]
* @param {boolean} [options.pending=false] Whether to wrap the debounced method in a pending promise
* @param {boolean} [options.cancel=false] Whether to add a cancel method to the debounced function
* @return {Function}
*/
export const debounce = (
func,
wait,
{
pending = false,
cancel = false,
} = {},
) => {
let timeout = null;
Expand All @@ -119,6 +121,12 @@ export const debounce = (
}, wait);
};

if (cancel) {
returnedFunction.cancel = () => {
clearTimeout(timeout);
};
}

return returnedFunction;
};

Expand Down

0 comments on commit d13749e

Please sign in to comment.