Skip to content

Commit

Permalink
allow packages to filter the toolbox
Browse files Browse the repository at this point in the history
  • Loading branch information
riknoll committed Nov 26, 2024
1 parent 3185d49 commit 261f446
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 3 deletions.
4 changes: 4 additions & 0 deletions localtypings/pxtpackage.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ declare namespace pxt {
theme?: string | pxt.Map<string>;
assetPack?: boolean; // if set to true, only the assets of this project will be imported when added as an extension (no code)
assetPacks?: Map<boolean>; // a map of dependency id to boolean that indicates which dependencies should be imported as asset packs
toolboxFilter?: {
namespaces: {[index: string]: "visible" | "hidden" | "disabled"},
blocks: {[index: string]: "visible" | "hidden" | "disabled"},
}
}

interface PackageExtension {
Expand Down
49 changes: 49 additions & 0 deletions webapp/src/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1000,4 +1000,53 @@ export function getExtensionOfFileName(filename: string) {

async function getHostCacheAsync(): Promise<pxt.BrowserUtils.IDBObjectStoreWrapper<{id: string, val: string}>> {
return getObjectStoreAsync(HOSTCACHE_TABLE)
}

export function getProjectToolboxFilters() {
const filters: pxt.editor.ProjectFilters = {};

const deps = mainPkg.sortedDeps();
// sort the dependencies by level and then id. lower level overrides
// higher level
deps.sort((a, b) => {
if (a.level === b.level) {
return pxt.U.strcmp(a.id, b.id);
}
return b.level - a.level;
});

const applyProjectFilter = (projectFilter: pxt.PackageConfig["toolboxFilter"], key: keyof pxt.PackageConfig["toolboxFilter"]) => {
if (!projectFilter[key]) {
return
}

if (!filters[key]) {
filters[key] = {};
}

for (const entry of Object.keys(projectFilter[key])) {
const value = String(projectFilter[key][entry]).toLowerCase();
if (value === "hidden") {
filters[key][entry] = pxt.editor.FilterState.Hidden;
}
else if (value === "visible") {
filters[key][entry] = pxt.editor.FilterState.Visible;
}
else if (value === "disabled") {
filters[key][entry] = pxt.editor.FilterState.Disabled;
}
}
}

for (const dep of deps) {
const projectFilter = dep.config?.toolboxFilter;
if (!projectFilter) {
continue;
}

applyProjectFilter(projectFilter, "blocks");
applyProjectFilter(projectFilter, "namespaces");
}

return filters;
}
28 changes: 25 additions & 3 deletions webapp/src/toolboxeditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import * as srceditor from "./srceditor";
import * as toolbox from "./toolbox";
import * as compiler from "./compiler";
import { getProjectToolboxFilters } from "./package";

export abstract class ToolboxEditor extends srceditor.Editor {

Expand All @@ -17,11 +18,32 @@ export abstract class ToolboxEditor extends srceditor.Editor {
abstract getBlocksForCategory(ns: string, subns?: string): toolbox.BlockDefinition[];

protected shouldShowBlock(blockId: string, ns: string, shadow?: boolean) {
const filters = this.parent.state.editorState && this.parent.state.editorState.filters;
let filters = this.parent.state.editorState && this.parent.state.editorState.filters;

const projectFilter = getProjectToolboxFilters();

if (projectFilter) {
if (filters) {
// tutorial filters override project filters
pxt.U.jsonMergeFrom(projectFilter, filters);
}

filters = projectFilter;
}


if (filters) {
// block-level filters should not apply to shadow blocks (nested)
const blockFilter = filters.blocks && (filters.blocks[blockId] || (this.blockIdMap && this.blockIdMap[blockId]?.some(id => filters.blocks[id])));
let blockFilter: pxt.editor.FilterState | boolean;
if (filters.blocks) {
if (filters.blocks[blockId] !== undefined) {
blockFilter = filters.blocks[blockId];
}
else {
blockFilter = this.blockIdMap && this.blockIdMap[blockId]?.some(id => filters.blocks[id]);
}
}
const categoryFilter = filters.namespaces && filters.namespaces[ns];
// block-level filters should not apply to shadow blocks (nested)
// First try block filters
if (blockFilter != undefined && blockFilter == pxt.editor.FilterState.Hidden && !shadow) return false;
if (blockFilter != undefined) return true;
Expand Down

0 comments on commit 261f446

Please sign in to comment.