This commit is contained in:
2023-08-03 23:12:35 +02:00
parent 4c239c12f1
commit e9de465358
2 changed files with 51 additions and 114 deletions

View File

@ -5,18 +5,10 @@ import { MidiConnection } from "./IO/MidiConnection";
// @ts-ignore // @ts-ignore
import { webaudioOutput, samples } from '@strudel.cycles/webaudio'; import { webaudioOutput, samples } from '@strudel.cycles/webaudio';
interface TimePoint { // const sound = (value: any) => ({
bar: number, // value, context: {},
beat: number, // ensureObjectValue: () => {}
pulse: number // });
}
const sound = (value: any) => ({
value, context: {},
ensureObjectValue: () => { }
});
class DrunkWalk { class DrunkWalk {
public min: number; public min: number;
@ -70,11 +62,11 @@ export class UserAPI {
private _drunk: DrunkWalk = new DrunkWalk(-100, 100, false); private _drunk: DrunkWalk = new DrunkWalk(-100, 100, false);
MidiConnection: MidiConnection = new MidiConnection() MidiConnection: MidiConnection = new MidiConnection()
strudelSound = webaudioOutput() // strudelSound = webaudioOutput()
load: samples load: samples
constructor (public app: Editor) { constructor (public app: Editor) {
this.load = samples("github:tidalcycles/Dirt-Samples/master"); // this.load = samples("github:tidalcycles/Dirt-Samples/master");
} }
// ============================================================= // =============================================================
@ -424,7 +416,7 @@ export class UserAPI {
// Trivial functions // Trivial functions
// ============================================================= // =============================================================
sound = async (values: object) => { // sound = async (values: object) => {
webaudioOutput(sound(values), 0.00) // webaudioOutput(sound(values), 0.00)
} // }
} }

View File

@ -1,27 +1,27 @@
import "./style.css"; import "./style.css";
import { EditorView } from "codemirror";
import { editorSetup } from "./EditorSetup"; import { editorSetup } from "./EditorSetup";
import { EditorView } from "codemirror";
import { EditorState, Compartment } from "@codemirror/state"; import { EditorState, Compartment } from "@codemirror/state";
import { javascript } from "@codemirror/lang-javascript"; import { javascript } from "@codemirror/lang-javascript";
import { markdown } from "@codemirror/lang-markdown"; import { markdown } from "@codemirror/lang-markdown";
import { Clock } from "./Clock";
import { vim } from "@replit/codemirror-vim";
import { AppSettings } from "./AppSettings";
import { ViewUpdate } from "@codemirror/view";
import { UserAPI } from "./API";
import { Extension } from "@codemirror/state"; import { Extension } from "@codemirror/state";
import { ViewUpdate } from "@codemirror/view";
import { oneDark } from "@codemirror/theme-one-dark";
import { vim } from "@replit/codemirror-vim";
import { Clock } from "./Clock";
import { AppSettings } from "./AppSettings";
import { UserAPI } from "./API";
import { import {
Universes, Universes,
File, File,
template_universe, template_universe,
template_universes, template_universes,
} from "./AppSettings"; } from "./AppSettings";
import { oneDark } from "@codemirror/theme-one-dark";
import { tryEvaluate } from "./Evaluator"; import { tryEvaluate } from "./Evaluator";
export class Editor { export class Editor {
// Data structures for editor text management
universes: Universes = template_universes; universes: Universes = template_universes;
selected_universe: string; selected_universe: string;
local_index: number = 1; local_index: number = 1;
@ -155,7 +155,6 @@ export class Editor {
this.chosenLanguage.of(javascript()), this.chosenLanguage.of(javascript()),
EditorView.updateListener.of((v: ViewUpdate) => { EditorView.updateListener.of((v: ViewUpdate) => {
v; v;
// This is the event listener for the editor
}), }),
]; ];
@ -499,9 +498,8 @@ export class Editor {
// If the editor is in notes mode, we need to update the selectedLanguage // If the editor is in notes mode, we need to update the selectedLanguage
this.view.dispatch({ this.view.dispatch({
effects: this.chosenLanguage.reconfigure(this.editor_mode == "notes" ? markdown() : javascript()) effects: this.chosenLanguage.reconfigure(this.editor_mode == "notes" ? [markdown()] : [javascript()])
}) })
console.log(this.chosenLanguage.get(this.view.state))
this.updateEditorView(); this.updateEditorView();
} }
@ -556,24 +554,19 @@ export class Editor {
} }
updateEditorView(): void { updateEditorView(): void {
// Remove everything from the editor
this.view.dispatch({
changes: {
from: 0,
to: this.view.state.doc.toString().length,
insert: '',
},
});
// Insert something
this.view.dispatch({ this.view.dispatch({
changes: { changes: {
from: 0, from: 0,
to: this.view.state.doc.toString().length,
insert: this.currentFile().candidate, insert: this.currentFile().candidate,
}, },
}); });
} }
/**
* @returns The current file being edited
*/
currentFile(): File { currentFile(): File {
switch (this.editor_mode) { switch (this.editor_mode) {
case "global": case "global":
@ -587,83 +580,31 @@ export class Editor {
} }
} }
loadUniverse(universeName: string) { /**
* @param universeName: The name of the universe to load
*/
loadUniverse(universeName: string): void {
// Saving the current file before initiating the switch logic
this.currentFile().candidate = this.view.state.doc.toString(); this.currentFile().candidate = this.view.state.doc.toString();
// Getting the new universe name and moving on
let selectedUniverse = universeName.trim(); let selectedUniverse = universeName.trim();
if (this.universes[selectedUniverse] === undefined) { if (this.universes[selectedUniverse] === undefined) {
this.universes[selectedUniverse] = template_universe; this.universes[selectedUniverse] = template_universe;
} }
this.selected_universe = this.settings.selected_universe; this.selected_universe = selectedUniverse;
this.settings.selected_universe = this.selected_universe;
this.universe_viewer.innerHTML = `Topos: ${selectedUniverse}`; this.universe_viewer.innerHTML = `Topos: ${selectedUniverse}`;
// We should also update the editor accordingly
this.view.dispatch({ // Updating the editor View to reflect the selected universe
changes: { this.updateEditorView();
from: 0,
to: this.view.state.doc.toString().length, // Evaluating the initialisation script for the selected universe
insert: "",
},
});
this.view.dispatch({
changes: { from: 0, insert: this.currentFile().candidate },
});
tryEvaluate(this, this.universes[this.selected_universe.toString()].init) tryEvaluate(this, this.universes[this.selected_universe.toString()].init)
} }
getCodeBlock(): string { openSettingsModal(): void {
// Capture the position of the cursor
let cursor = this.view.state.selection.main.head;
const state = this.view.state;
const { head } = state.selection.main;
const currentLine = state.doc.lineAt(head);
let startLine = currentLine;
while (
startLine.number > 1 &&
!/^\s*$/.test(state.doc.line(startLine.number - 1).text)
) {
startLine = state.doc.line(startLine.number - 1);
}
let endLine = currentLine;
while (
endLine.number < state.doc.lines &&
!/^\s*$/.test(state.doc.line(endLine.number + 1).text)
) {
endLine = state.doc.line(endLine.number + 1);
}
let result_string = state.doc.sliceString(startLine.from, endLine.to);
result_string = result_string
.split("\n")
.map((line, index, lines) => {
const trimmedLine = line.trim();
if (
index === lines.length - 1 ||
/^\s/.test(lines[index + 1]) ||
trimmedLine.startsWith("@")
) {
return line;
} else {
return line + ";\\";
}
})
.join("\n");
return result_string;
}
getSelectedLines = (): string => {
const state = this.view.state;
const { from, to } = state.selection.main;
const fromLine = state.doc.lineAt(from);
const toLine = state.doc.lineAt(to);
this.view.dispatch({
selection: { anchor: 0 + fromLine.from, head: toLine.to },
});
// Release the selection and get the cursor back to its original position
return state.doc.sliceString(fromLine.from, toLine.to);
};
openSettingsModal() {
if ( if (
document.getElementById("modal-settings")!.classList.contains("invisible") document.getElementById("modal-settings")!.classList.contains("invisible")
) { ) {
@ -674,12 +615,12 @@ export class Editor {
} }
} }
closeSettingsModal() { closeSettingsModal(): void {
document.getElementById("editor")!.classList.remove("invisible"); document.getElementById("editor")!.classList.remove("invisible");
document.getElementById("modal-settings")!.classList.add("invisible"); document.getElementById("modal-settings")!.classList.add("invisible");
} }
openBuffersModal() { openBuffersModal():void {
// If the modal is hidden, unhide it and hide the editor // If the modal is hidden, unhide it and hide the editor
if ( if (
document.getElementById("modal-buffers")!.classList.contains("invisible") document.getElementById("modal-buffers")!.classList.contains("invisible")
@ -692,7 +633,7 @@ export class Editor {
} }
} }
closeBuffersModal() { closeBuffersModal():void {
// @ts-ignore // @ts-ignore
document.getElementById("buffer-search")!.value = ""; document.getElementById("buffer-search")!.value = "";
document.getElementById("editor")!.classList.remove("invisible"); document.getElementById("editor")!.classList.remove("invisible");
@ -700,7 +641,11 @@ export class Editor {
document.getElementById("modal-buffers")!.classList.add("invisible"); document.getElementById("modal-buffers")!.classList.add("invisible");
} }
flashBackground(color: string, duration: number) { /**
* @param color the color to flash the background
* @param duration the duration of the flash
*/
flashBackground(color: string, duration: number): void {
// Set the flashing color // Set the flashing color
this.view.dom.style.backgroundColor = color; this.view.dom.style.backgroundColor = color;
const gutters = this.view.dom.getElementsByClassName("cm-gutter"); const gutters = this.view.dom.getElementsByClassName("cm-gutter");
@ -712,13 +657,12 @@ export class Editor {
Array.from(gutters).forEach(gutter => gutter.style.backgroundColor = ""); Array.from(gutters).forEach(gutter => gutter.style.backgroundColor = "");
}, duration); }, duration);
} }
} }
// Creating the application
const app = new Editor(); const app = new Editor();
// Starting the clock after displaying a modal
function startClock() { function startClock() {
document.getElementById("editor")!.classList.remove("invisible"); document.getElementById("editor")!.classList.remove("invisible");
document.getElementById("modal")!.classList.add("hidden"); document.getElementById("modal")!.classList.add("hidden");
@ -741,6 +685,9 @@ function startOnEnter(e: KeyboardEvent) {
document.addEventListener("keydown", startOnEnter); document.addEventListener("keydown", startOnEnter);
document.getElementById("start-button")!.addEventListener("click", startClock); document.getElementById("start-button")!.addEventListener("click", startClock);
/**
* @param event The mouse event
*/
function reportMouseCoordinates(event: MouseEvent) { function reportMouseCoordinates(event: MouseEvent) {
app._mouseX = event.clientX; app._mouseX = event.clientX;
app._mouseY = event.clientY; app._mouseY = event.clientY;
@ -748,7 +695,6 @@ function reportMouseCoordinates(event: MouseEvent) {
window.addEventListener('mousemove', reportMouseCoordinates); window.addEventListener('mousemove', reportMouseCoordinates);
// When the user leaves the page, all the universes should be saved in the localStorage // When the user leaves the page, all the universes should be saved in the localStorage
window.addEventListener("beforeunload", () => { window.addEventListener("beforeunload", () => {
event.preventDefault(); event.preventDefault();
@ -758,5 +704,4 @@ window.addEventListener("beforeunload", () => {
app.settings.saveApplicationToLocalStorage(app.universes, app.settings); app.settings.saveApplicationToLocalStorage(app.universes, app.settings);
app.clock.stop() app.clock.stop()
return null; return null;
}); });