Contains the "frontend" of the extension. Consists of panels, each of which has an associated Panel
type. For example, the state of the "My Courses" webview is stored in a MyCoursesPanel
prop. The panel types are all in the shared
directory in the repository root, so they can be shared between the "frontend" and "backend".
Each panel requests the data it needs to display with a message fired in an onMount
hook, for example:
onMount(() => {
vscode.postMessage({
type: "requestMyCoursesData",
sourcePanel: panel,
});
});
they then receive this data (and other messages) using an addMessageListener
helper function:
addMessageListener(panel, (message) => {
switch (message.type) {
case "setMyCourses": {
panel.courses = message.courses;
savePanelState(panel);
break;
}
case "setTmcDataPath": {
panel.tmcDataPath = message.tmcDataPath;
savePanelState(panel);
break;
}
case "setTmcDataSize": {
panel.tmcDataSize = message.tmcDataSize;
savePanelState(panel);
break;
}
case "selectedOrganization": {
selectedOrganizationSlug.set(message.slug);
vscode.postMessage({
type: "selectCourse",
sourcePanel: panel,
slug: message.slug,
});
break;
}
case "selectedCourse": {
vscode.postMessage({
type: "addCourse",
organizationSlug: message.organizationSlug,
courseId: message.courseId,
requestingPanel: panel,
});
// todo: only close side panel on success
vscode.postMessage({
type: "closeSidePanel",
});
break;
}
default:
assertUnreachable(message);
}
});
When the panel state is changed, it can be saved with the savePanelState
function, so that the state can be loaded when reopening VSCode and such.