From 53e4c8f6dbbc9ff54a743626db7686c352903c35 Mon Sep 17 00:00:00 2001 From: Lucas Garron Date: Fri, 27 Aug 2021 21:32:50 -0700 Subject: [PATCH 1/5] [twizzle/edit] Update to v2 elems! This was the minimum to get things to pass the type system again. It almost certainly doesn't work. --- src/cubing/twisty/index.ts | 2 + src/sites/alpha.twizzle.net/edit/app.ts | 98 ++++++++----------- .../alpha.twizzle.net/edit/control-pane.css | 6 +- src/sites/alpha.twizzle.net/edit/index.css | 2 +- src/sites/alpha.twizzle.net/edit/index.html | 8 +- src/sites/alpha.twizzle.net/index.css | 43 ++++++++ 6 files changed, 95 insertions(+), 64 deletions(-) create mode 100644 src/sites/alpha.twizzle.net/index.css diff --git a/src/cubing/twisty/index.ts b/src/cubing/twisty/index.ts index f01e14fe2..67d848e89 100644 --- a/src/cubing/twisty/index.ts +++ b/src/cubing/twisty/index.ts @@ -1,6 +1,8 @@ export { TwistyPlayerV2 } from "./views/TwistyPlayerV2"; export type { TwistyPlayerV2Config } from "./views/TwistyPlayerV2"; +export { TwistyAlgEditorV2 } from "./views/TwistyAlgEditor/TwistyAlgEditorV2"; + // Old export type { Twisty3DPuzzle } from "./views/3D/puzzles/Twisty3DPuzzle"; export { diff --git a/src/sites/alpha.twizzle.net/edit/app.ts b/src/sites/alpha.twizzle.net/edit/app.ts index 9e3bd4b46..adec1ded1 100644 --- a/src/sites/alpha.twizzle.net/edit/app.ts +++ b/src/sites/alpha.twizzle.net/edit/app.ts @@ -1,18 +1,10 @@ -import { KPuzzle } from "../../../cubing/kpuzzle"; import { Alg, AlgBuilder, LineComment, Newline } from "../../../cubing/alg"; +import { experimentalEnsureAlg } from "../../../cubing/alg/Alg"; +import { KPuzzle } from "../../../cubing/kpuzzle"; import { puzzles } from "../../../cubing/puzzles"; -import "../../../cubing/twisty"; // For `` custom elem registration. -import type { Twisty3DCanvas, TwistyAlgEditor } from "../../../cubing/twisty"; -import { - ExperimentalStickering, - TwistyPlayer, - TwistyPlayerInitialConfig, -} from "../../../cubing/twisty"; -import { findOrCreateChild, findOrCreateChildWithClass } from "./dom"; -import { APP_TITLE } from "./strings"; -import { puzzleGroups, supportedPuzzles } from "./supported-puzzles"; -import { getURLParam, setURLParams } from "./url-params"; +import { cube2x2x2KPuzzle } from "../../../cubing/puzzles/implementations/2x2x2/2x2x2.kpuzzle.json_"; import { cube3x3x3KPuzzle } from "../../../cubing/puzzles/implementations/3x3x3/3x3x3.kpuzzle.json_"; +import { randomScrambleForEvent } from "../../../cubing/scramble"; import { experimentalSolve2x2x2, experimentalSolve3x3x3IgnoringCenters, @@ -20,15 +12,23 @@ import { solvePyraminx, solveSkewb, } from "../../../cubing/search"; -import { cube2x2x2KPuzzle } from "../../../cubing/puzzles/implementations/2x2x2/2x2x2.kpuzzle.json_"; -import { randomScrambleForEvent } from "../../../cubing/scramble"; +import type { PuzzleStreamMoveEventRegisterCompatible } from "../../../cubing/stream/process/ReorientedStream"; +import "../../../cubing/twisty"; // For `` custom elem registration. +import { + ExperimentalStickering, + TwistyPlayerV2, + TwistyPlayerV2Config, +} from "../../../cubing/twisty"; import { customElementsShim } from "../../../cubing/twisty/old/dom/element/node-custom-element-shims"; -import { examples } from "./examples"; -import { experimentalEnsureAlg } from "../../../cubing/alg/Alg"; import "../../../cubing/twisty/old/dom/stream/TwistyStreamSource"; import type { TwistyStreamSource } from "../../../cubing/twisty/old/dom/stream/TwistyStreamSource"; -import type { PuzzleStreamMoveEventRegisterCompatible } from "../../../cubing/stream/process/ReorientedStream"; import type { PuzzleID } from "../../../cubing/twisty/old/dom/TwistyPlayerConfig"; +import type { TwistyAlgEditorV2 } from "../../../cubing/twisty/views/TwistyAlgEditor/TwistyAlgEditorV2"; +import { findOrCreateChild, findOrCreateChildWithClass } from "./dom"; +import { examples } from "./examples"; +import { APP_TITLE } from "./strings"; +import { puzzleGroups, supportedPuzzles } from "./supported-puzzles"; +import { setURLParams } from "./url-params"; export interface AppData { puzzleName: string; @@ -68,7 +68,7 @@ const SCRAMBLE_EVENTS: Partial> = { }; export class App { - public twistyPlayer: TwistyPlayer; + public twistyPlayer: TwistyPlayerV2; private puzzlePane: HTMLElement; private cachedSetupAnchor: "start" | "end"; private controlPane: ControlPane; @@ -113,7 +113,7 @@ export class App { } private initializeTwisty(initialData: AppData): void { - const twistyConfig: TwistyPlayerInitialConfig = { + const twistyConfig: TwistyPlayerV2Config = { alg: new Alg(), viewerLink: "none", }; @@ -122,10 +122,7 @@ export class App { twistyConfig.visualization = displayablePuzzle.viz; twistyConfig.experimentalSetupAnchor = initialData.experimentalSetupAnchor; twistyConfig.experimentalStickering = initialData.experimentalStickering; - this.twistyPlayer = new TwistyPlayer(twistyConfig); - if (getURLParam("debug-simultaneous")) { - this.twistyPlayer.experimentalSetCursorIndexer("simultaneous"); - } + this.twistyPlayer = new TwistyPlayerV2(twistyConfig); this.setExperimentalSetupAlg(initialData.experimentalSetupAlg); this.setAlg(initialData.alg); this.puzzlePane.appendChild(this.twistyPlayer); @@ -135,7 +132,7 @@ export class App { private setExperimentalSetupAlg(experimentalSetupAlg: Alg): boolean { try { this.twistyPlayer.experimentalSetupAlg = experimentalSetupAlg; - this.twistyPlayer.timeline.jumpToStart(); + this.twistyPlayer.jumpToStart(); setURLParams({ "experimental-setup-alg": experimentalSetupAlg }); return true; } catch (e) { @@ -149,9 +146,9 @@ export class App { try { this.twistyPlayer.alg = alg; if (this.cachedSetupAnchor === "start") { - this.twistyPlayer.timeline.jumpToEnd(); + this.twistyPlayer.jumpToEnd(); } else { - this.twistyPlayer.timeline.jumpToStart(); + this.twistyPlayer.jumpToStart(); } setURLParams({ alg }); return true; @@ -279,8 +276,8 @@ class ButtonGrid extends HTMLElement { customElementsShim.define("button-grid", ButtonGrid); class ControlPane { - public experimentalSetupAlgInput: TwistyAlgEditor; - public algInput: TwistyAlgEditor; + public experimentalSetupAlgInput: TwistyAlgEditorV2; + public algInput: TwistyAlgEditorV2; public puzzleSelect: HTMLSelectElement; public setupAnchorSelect: HTMLSelectElement; public stickeringSelect: HTMLSelectElement; @@ -303,7 +300,7 @@ class ControlPane { ) => boolean, private solve: () => void, private scramble: () => void, - private twistyPlayer: TwistyPlayer, + private twistyPlayer: TwistyPlayerV2, ) { const appTitleElem = findOrCreateChildWithClass(this.element, "title"); appTitleElem.textContent = APP_TITLE; @@ -311,8 +308,8 @@ class ControlPane { this.experimentalSetupAlgInput = findOrCreateChildWithClass( this.element, "experimental-setup-alg", - "twisty-alg-editor", - ) as TwistyAlgEditor; + "twisty-alg-editor-v2", + ) as TwistyAlgEditorV2; this.experimentalSetupAlgInput.twistyPlayer = twistyPlayer; this.experimentalSetupAlgInput.algString = initialData.experimentalSetupAlg.toString(); @@ -321,8 +318,8 @@ class ControlPane { this.algInput = findOrCreateChildWithClass( this.element, "alg", - "twisty-alg-editor", - ) as TwistyAlgEditor; + "twisty-alg-editor-v2", + ) as TwistyAlgEditorV2; this.algInput, { twistyPlayer }; this.algInput.twistyPlayer = twistyPlayer; this.algInput.algString = initialData.alg.toString(); @@ -414,12 +411,12 @@ class ControlPane { const move = e.detail.move; let alg = this.twistyPlayer.alg; try { - this.twistyPlayer.experimentalAddMove(move, true); + this.twistyPlayer.experimentalAddMove(move); // TODO alg = this.twistyPlayer.alg; } catch (e) { console.info("Ignoring move:", move.toString()); } - this.algInput.algString = alg.toString(); + // this.algInput.algString = alg; setURLParams({ alg }); } @@ -489,7 +486,7 @@ class ControlPane { private onTempoInput(): void { const tempoScale = parseFloat(this.tempoInput.value); - this.twistyPlayer.timeline.tempoScale = tempoScale; + this.twistyPlayer.tempoScale = tempoScale; this.tempoDisplay.textContent = `${tempoScale}×`; } @@ -499,20 +496,24 @@ class ControlPane { : "none"; } - private onToolAction(e: CustomEvent<{ action: string }>): void { + private async onToolAction( + e: CustomEvent<{ action: string }>, + ): Promise { switch (e.detail.action) { case "expand": - this.setAlg(this.twistyPlayer.alg.expand()); + this.setAlg((await this.twistyPlayer.model.algProp.get()).alg.expand()); break; case "simplify": - this.setAlg(this.twistyPlayer.alg.simplify()); + this.setAlg( + (await this.twistyPlayer.model.algProp.get()).alg.simplify(), + ); break; case "clear": this.setAlg(new Alg()); this.setExperimentalSetupAlg(new Alg()); break; case "invert": - this.setAlg(this.twistyPlayer.alg.invert()); + this.setAlg((await this.twistyPlayer.model.algProp.get()).alg.invert()); break; case "solve": this.solve(); @@ -532,22 +533,7 @@ class ControlPane { } private screenshot(): void { - const elem = this.app.twistyPlayer.viewerElems[0] as - | Twisty3DCanvas - | undefined; - if (elem) { - const url = elem.renderToDataURL({ - squareCrop: true, - minWidth: 2048, - minHeight: 2048, - }); - const a = document.createElement("a"); - a.href = url; - a.download = `[${ - this.app.twistyPlayer.puzzle - }] ${this.app.twistyPlayer.alg.toString()}.png`; - a.click(); - } + this.app.twistyPlayer.experimentalDownloadScreenshot(); } private connectInput(): void { diff --git a/src/sites/alpha.twizzle.net/edit/control-pane.css b/src/sites/alpha.twizzle.net/edit/control-pane.css index 2683bcb26..cb04fb764 100644 --- a/src/sites/alpha.twizzle.net/edit/control-pane.css +++ b/src/sites/alpha.twizzle.net/edit/control-pane.css @@ -38,7 +38,7 @@ control-pane h2 { border-top: 1px solid rgba(0, 0, 0, 0.5); } -control-pane twisty-alg-editor { +control-pane twisty-alg-editor-v2 { width: 100%; --border-color: rgba(0, 0, 0, 0); --font-family: "Ubuntu", Verdana, Tahoma, sans-serif; @@ -46,11 +46,11 @@ control-pane twisty-alg-editor { --padding: 0.75em; } -control-pane twisty-alg-editor:focus-within { +control-pane twisty-alg-editor-v2:focus-within { --background: rgb(255, 253, 251); } -control-pane twisty-alg-editor:hover { +control-pane twisty-alg-editor-v2:hover { background: white; } diff --git a/src/sites/alpha.twizzle.net/edit/index.css b/src/sites/alpha.twizzle.net/edit/index.css index e9366025f..571f3c766 100644 --- a/src/sites/alpha.twizzle.net/edit/index.css +++ b/src/sites/alpha.twizzle.net/edit/index.css @@ -36,7 +36,7 @@ puzzle-pane.loading { place-content: center; } -puzzle-pane twisty-player { +puzzle-pane twisty-player-v2 { width: 100%; height: 100%; overflow: hidden; diff --git a/src/sites/alpha.twizzle.net/edit/index.html b/src/sites/alpha.twizzle.net/edit/index.html index e9ce65b6c..5f2a63678 100644 --- a/src/sites/alpha.twizzle.net/edit/index.html +++ b/src/sites/alpha.twizzle.net/edit/index.html @@ -34,11 +34,11 @@

- + >
@@ -50,10 +50,10 @@

- + >

diff --git a/src/sites/alpha.twizzle.net/index.css b/src/sites/alpha.twizzle.net/index.css new file mode 100644 index 000000000..e9366025f --- /dev/null +++ b/src/sites/alpha.twizzle.net/index.css @@ -0,0 +1,43 @@ +@font-face { + font-family: "Ubuntu"; + src: url("../vendor/fonts/ubuntu/Ubuntu-Regular.ttf"); +} + +* { + box-sizing: border-box; +} + +html, +body { + width: 100%; + height: 100%; + margin: 0; +} + +app { + display: grid; + width: 100%; + height: 100%; + background: rgb(255, 245, 235); +} + +puzzle-pane { + grid-area: "puzzle"; + + background-size: 32px 32px; + background-position: 0 0, 16px 16px; + + display: grid; + + overflow: hidden; +} + +puzzle-pane.loading { + place-content: center; +} + +puzzle-pane twisty-player { + width: 100%; + height: 100%; + overflow: hidden; +} From 8bfc28607fe4c18c671c7b74c302ca02ea61dc28 Mon Sep 17 00:00:00 2001 From: Lucas Garron Date: Fri, 27 Aug 2021 22:08:33 -0700 Subject: [PATCH 2/5] [twisty] Fix up the editor's connection to the setup prop. --- src/cubing/twisty/views/TwistyAlgEditor/TwistyAlgEditorV2.ts | 2 +- src/sites/alpha.twizzle.net/edit/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cubing/twisty/views/TwistyAlgEditor/TwistyAlgEditorV2.ts b/src/cubing/twisty/views/TwistyAlgEditor/TwistyAlgEditorV2.ts index f5a95d3df..fb73cc63a 100644 --- a/src/cubing/twisty/views/TwistyAlgEditor/TwistyAlgEditorV2.ts +++ b/src/cubing/twisty/views/TwistyAlgEditor/TwistyAlgEditorV2.ts @@ -271,7 +271,7 @@ export class TwistyAlgEditorV2 extends ManagedCustomElement { return; } (async () => { - this.algString = (await twistyPlayer.model.algProp.get()).alg.toString(); + this.algString = (await this.#algProp!.get()).alg.toString(); })(); if (this.#twistyPlayerProp === "algProp") { diff --git a/src/sites/alpha.twizzle.net/edit/index.html b/src/sites/alpha.twizzle.net/edit/index.html index 5f2a63678..ea4588840 100644 --- a/src/sites/alpha.twizzle.net/edit/index.html +++ b/src/sites/alpha.twizzle.net/edit/index.html @@ -37,7 +37,7 @@

From 334270c7d79b20258f47ef761fb01031b177e0b8 Mon Sep 17 00:00:00 2001 From: Lucas Garron Date: Sat, 28 Aug 2021 01:30:06 -0700 Subject: [PATCH 3/5] [twizzle/edit] Fix up scramble/solve! --- src/sites/alpha.twizzle.net/edit/app.ts | 29 +++++++++++++++---------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/sites/alpha.twizzle.net/edit/app.ts b/src/sites/alpha.twizzle.net/edit/app.ts index adec1ded1..cfb081f5a 100644 --- a/src/sites/alpha.twizzle.net/edit/app.ts +++ b/src/sites/alpha.twizzle.net/edit/app.ts @@ -190,52 +190,59 @@ export class App { } async solve(): Promise { + const [puzzleID, currentAlgWithIssues] = await Promise.all([ + this.twistyPlayer.model.puzzleProp.get(), + this.twistyPlayer.model.algProp.get(), + ]); + const currentAlg = currentAlgWithIssues.alg; let solution: Alg; - switch (this.twistyPlayer.puzzle) { + switch (puzzleID) { case "2x2x2": { const kpuzzle = new KPuzzle(cube2x2x2KPuzzle); - kpuzzle.applyAlg(this.twistyPlayer.alg); + kpuzzle.applyAlg(currentAlg); solution = await experimentalSolve2x2x2(kpuzzle.state); break; } case "3x3x3": { const kpuzzle = new KPuzzle(cube3x3x3KPuzzle); - kpuzzle.applyAlg(this.twistyPlayer.alg); + kpuzzle.applyAlg(currentAlg); solution = await experimentalSolve3x3x3IgnoringCenters(kpuzzle.state); break; } case "skewb": { const kpuzzle = new KPuzzle(await puzzles.skewb.def()); - kpuzzle.applyAlg(this.twistyPlayer.alg); + kpuzzle.applyAlg(currentAlg); solution = await solveSkewb(kpuzzle.state); break; } case "pyraminx": { const kpuzzle = new KPuzzle(await puzzles.pyraminx.def()); - kpuzzle.applyAlg(this.twistyPlayer.alg); + kpuzzle.applyAlg(currentAlg); solution = await solvePyraminx(kpuzzle.state); break; } case "megaminx": { const kpuzzle = new KPuzzle(await puzzles.megaminx.def()); - kpuzzle.applyAlg(this.twistyPlayer.alg); + kpuzzle.applyAlg(currentAlg); solution = await solveMegaminx(kpuzzle.state); break; } default: return; } - this.controlPane.setAlg( - algAppend(this.twistyPlayer.alg, " Solution", solution), - ); + this.controlPane.setAlg(algAppend(currentAlg, " Solution", solution)); } async scramble(): Promise { - const event = SCRAMBLE_EVENTS[this.twistyPlayer.puzzle]; + const [puzzleID, currentAlgWithIssues] = await Promise.all([ + this.twistyPlayer.model.puzzleProp.get(), + this.twistyPlayer.model.algProp.get(), + ]); + const event = SCRAMBLE_EVENTS[puzzleID]; if (event) { this.controlPane.setAlg( algAppend( - this.twistyPlayer.alg, + currentAlgWithIssues.alg, " Scramble", await randomScrambleForEvent(event), ), From 9bb601364dcf52888b459d8826685f12fadf894e Mon Sep 17 00:00:00 2001 From: Lucas Garron Date: Sat, 28 Aug 2021 01:33:14 -0700 Subject: [PATCH 4/5] [twizzle/edit] Handle puzzle changes without a refresh. --- src/sites/alpha.twizzle.net/edit/app.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sites/alpha.twizzle.net/edit/app.ts b/src/sites/alpha.twizzle.net/edit/app.ts index cfb081f5a..c7fe9f260 100644 --- a/src/sites/alpha.twizzle.net/edit/app.ts +++ b/src/sites/alpha.twizzle.net/edit/app.ts @@ -161,8 +161,7 @@ export class App { private setPuzzle(puzzleName: string): boolean { setURLParams({ puzzle: puzzleName }); // TODO: Handle 2D/3D transitions - // this.twistyPlayer.setPuzzle(puzzleName); - location.reload(); + this.twistyPlayer.puzzle = puzzleName as PuzzleID; this.controlPane.setPuzzle(puzzleName); return true; } From 7b5be8e38382942a91ac91b4007bd74f325f7782 Mon Sep 17 00:00:00 2001 From: Lucas Garron Date: Sat, 28 Aug 2021 01:35:06 -0700 Subject: [PATCH 5/5] [twizzle/edit] Handle stickering changes without a refresh. --- src/sites/alpha.twizzle.net/edit/app.ts | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/sites/alpha.twizzle.net/edit/app.ts b/src/sites/alpha.twizzle.net/edit/app.ts index c7fe9f260..1a5fbd317 100644 --- a/src/sites/alpha.twizzle.net/edit/app.ts +++ b/src/sites/alpha.twizzle.net/edit/app.ts @@ -166,26 +166,14 @@ export class App { return true; } - public setSetupAnchor( - setupAnchor: "start" | "end", - reload: boolean = true, - ): boolean { + public setSetupAnchor(setupAnchor: "start" | "end"): void { setURLParams({ "experimental-setup-anchor": setupAnchor }); - if (reload) { - location.reload(); - } - return true; + this.twistyPlayer.experimentalSetupAnchor = setupAnchor; } - public setStickering( - stickering: ExperimentalStickering, - reload: boolean = true, - ): boolean { + public setStickering(stickering: ExperimentalStickering): void { setURLParams({ "experimental-stickering": stickering }); - if (reload) { - location.reload(); - } - return true; + this.twistyPlayer.experimentalStickering = stickering; } async solve(): Promise {