Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | 1x 51x 51x 111x 111x 22x 22x 22x 109x 22x 22x 109x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 2x 2x 1x 1x 2x 2x 51x | import { atom } from "nanostores";
import { createNanoEvents } from "nanoevents";
import { Slice } from "../slice";
import { ProjectSlice } from "./project-slice";
import { CHART_REF, LEVEL } from "../components";
import { EntityBuilder } from "../../entity-manager";
import type { Entity } from "../../entity-manager";
import type { LevelInfo } from "../types";
export class LevelSlice extends Slice {
static readonly sliceKey = "level";
$hiddenLevelIds = atom<Set<string>>(new Set());
private events = createNanoEvents<{ levelsChanged: () => void }>();
getLevelEntitiesForChart(chartId: string): Entity[] {
const em = this.ctx.get(ProjectSlice).entityManager;
return em
.entitiesWithComponent(LEVEL)
.filter((entity) => {
const ref = em.getComponent(entity, CHART_REF);
return ref?.chartId === chartId;
})
.sort((a, b) => {
const levelA = em.getComponent(a, LEVEL);
const levelB = em.getComponent(b, LEVEL);
return (levelA?.sortOrder ?? 0) - (levelB?.sortOrder ?? 0);
});
}
isLevelHidden(levelId: string): boolean {
return this.$hiddenLevelIds.get().has(levelId);
}
getLevelsForChart(chartId: string): LevelInfo[] {
return this.getLevelEntitiesForChart(chartId).map((entity) => {
const level = this.ctx.get(ProjectSlice).entityManager.getComponent(entity, LEVEL);
return {
id: entity.id,
name: level?.name ?? "Untitled",
mode: level?.mode ?? "beat-7k",
sortOrder: level?.sortOrder ?? 0,
visible: !this.isLevelHidden(entity.id),
};
});
}
getVisibleLevels(chartId: string): LevelInfo[] {
return this.getLevelsForChart(chartId).filter((l) => l.visible);
}
addLevel(chartId: string, name: string, mode: string): string {
const em = this.ctx.get(ProjectSlice).entityManager;
const existing = this.getLevelEntitiesForChart(chartId);
const maxOrder =
existing.length > 0
? Math.max(...existing.map((e) => em.getComponent(e, LEVEL)?.sortOrder ?? 0))
: -1;
const level = new EntityBuilder()
.with(LEVEL, { name, mode, sortOrder: maxOrder + 1 })
.with(CHART_REF, { chartId })
.build();
em.insert(level);
this.events.emit("levelsChanged");
return level.id;
}
removeLevel(levelId: string): void {
this.ctx.get(ProjectSlice).entityManager.remove(levelId);
const hidden = new Set(this.$hiddenLevelIds.get());
hidden.delete(levelId);
this.$hiddenLevelIds.set(hidden);
this.events.emit("levelsChanged");
}
toggleLevelVisibility(levelId: string): void {
const hidden = new Set(this.$hiddenLevelIds.get());
if (hidden.has(levelId)) {
hidden.delete(levelId);
} else {
hidden.add(levelId);
}
this.$hiddenLevelIds.set(hidden);
this.events.emit("levelsChanged");
}
onLevelsChanged(cb: () => void): () => void {
return this.events.on("levelsChanged", cb);
}
}
|