Refactoring: cleaning up main.ts file
This commit is contained in:
434
src/InterfaceLogic.ts
Normal file
434
src/InterfaceLogic.ts
Normal file
@ -0,0 +1,434 @@
|
||||
import { EditorView } from "codemirror";
|
||||
import { vim } from "@replit/codemirror-vim";
|
||||
import { type Editor } from "./main";
|
||||
import {
|
||||
documentation_factory,
|
||||
hideDocumentation,
|
||||
showDocumentation,
|
||||
updateDocumentationContent,
|
||||
} from "./Documentation";
|
||||
import {
|
||||
type Universe,
|
||||
template_universe,
|
||||
template_universes,
|
||||
loadUniverse,
|
||||
emptyUrl,
|
||||
share,
|
||||
closeUniverseModal,
|
||||
openUniverseModal,
|
||||
} from "./FileManagement";
|
||||
import { loadSamples } from "./API";
|
||||
import { tryEvaluate } from "./Evaluator";
|
||||
import { inlineHoveringTips } from "./documentation/inlineHelp";
|
||||
import { lineNumbers } from "@codemirror/view";
|
||||
|
||||
export const installInterfaceLogic = (app: Editor) => {
|
||||
(app.interface.line_numbers_checkbox as HTMLInputElement).checked =
|
||||
app.settings.line_numbers;
|
||||
(app.interface.time_position_checkbox as HTMLInputElement).checked =
|
||||
app.settings.time_position;
|
||||
(app.interface.tips_checkbox as HTMLInputElement).checked = app.settings.tips;
|
||||
(app.interface.midi_clock_checkbox as HTMLInputElement).checked =
|
||||
app.settings.send_clock;
|
||||
(app.interface.midi_channels_scripts as HTMLInputElement).checked =
|
||||
app.settings.midi_channels_scripts;
|
||||
(app.interface.midi_clock_ppqn as HTMLInputElement).value =
|
||||
app.settings.midi_clock_ppqn.toString();
|
||||
if (!app.settings.time_position) {
|
||||
(app.interface.timeviewer as HTMLElement).classList.add("hidden");
|
||||
}
|
||||
(app.interface.load_demo_songs as HTMLInputElement).checked =
|
||||
app.settings.load_demo_songs;
|
||||
|
||||
const tabs = document.querySelectorAll('[id^="tab-"]');
|
||||
// Iterate over the tabs with an index
|
||||
for (let i = 0; i < tabs.length; i++) {
|
||||
tabs[i].addEventListener("click", (event) => {
|
||||
// Updating the CSS accordingly
|
||||
tabs[i].classList.add("bg-orange-300");
|
||||
for (let j = 0; j < tabs.length; j++) {
|
||||
if (j != i) tabs[j].classList.remove("bg-orange-300");
|
||||
}
|
||||
app.currentFile().candidate = app.view.state.doc.toString();
|
||||
|
||||
let tab = event.target as HTMLElement;
|
||||
let tab_id = tab.id.split("-")[1];
|
||||
app.local_index = parseInt(tab_id);
|
||||
app.updateEditorView();
|
||||
});
|
||||
}
|
||||
|
||||
app.interface.topos_logo.addEventListener("click", () => {
|
||||
hideDocumentation();
|
||||
app.updateKnownUniversesView();
|
||||
openUniverseModal();
|
||||
});
|
||||
|
||||
app.buttonElements.play_buttons.forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
if (app.isPlaying) {
|
||||
app.setButtonHighlighting("pause", true);
|
||||
app.isPlaying = !app.isPlaying;
|
||||
app.clock.pause();
|
||||
app.api.MidiConnection.sendStopMessage();
|
||||
} else {
|
||||
app.setButtonHighlighting("play", true);
|
||||
app.isPlaying = !app.isPlaying;
|
||||
app.clock.start();
|
||||
app.api.MidiConnection.sendStartMessage();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.buttonElements.clear_buttons.forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
app.setButtonHighlighting("clear", true);
|
||||
if (confirm("Do you want to reset the current universe?")) {
|
||||
app.universes[app.selected_universe] =
|
||||
structuredClone(template_universe);
|
||||
app.updateEditorView();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.interface.documentation_button.addEventListener("click", () => {
|
||||
showDocumentation(app);
|
||||
});
|
||||
|
||||
app.interface.destroy_universes_button.addEventListener("click", () => {
|
||||
if (confirm("Do you want to destroy all universes?")) {
|
||||
app.universes = {
|
||||
...template_universes,
|
||||
};
|
||||
app.updateKnownUniversesView();
|
||||
}
|
||||
});
|
||||
|
||||
app.interface.audio_nudge_range.addEventListener("input", () => {
|
||||
app.clock.nudge = parseInt(
|
||||
(app.interface.audio_nudge_range as HTMLInputElement).value
|
||||
);
|
||||
});
|
||||
|
||||
app.interface.dough_nudge_range.addEventListener("input", () => {
|
||||
app.dough_nudge = parseInt(
|
||||
(app.interface.dough_nudge_range as HTMLInputElement).value
|
||||
);
|
||||
});
|
||||
|
||||
app.interface.upload_universe_button.addEventListener("click", () => {
|
||||
const fileInput = document.createElement("input");
|
||||
fileInput.type = "file";
|
||||
fileInput.accept = ".json";
|
||||
|
||||
fileInput.addEventListener("change", (event) => {
|
||||
const input = event.target as HTMLInputElement;
|
||||
const file = input.files?.[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.readAsText(file, "UTF-8");
|
||||
|
||||
reader.onload = (evt) => {
|
||||
const data = JSON.parse(evt.target!.result as string);
|
||||
for (const [key, value] of Object.entries(data)) {
|
||||
app.universes[key] = value as Universe;
|
||||
}
|
||||
};
|
||||
reader.onerror = (evt) => {
|
||||
console.error("An error occurred reading the file:", evt);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
document.body.appendChild(fileInput);
|
||||
fileInput.click();
|
||||
document.body.removeChild(fileInput);
|
||||
});
|
||||
|
||||
app.interface.download_universe_button.addEventListener("click", () => {
|
||||
// Trigger save of the universe before downloading
|
||||
app.settings.saveApplicationToLocalStorage(app.universes, app.settings);
|
||||
|
||||
// Generate a file name based on timestamp
|
||||
let fileName = `topos-universes-${Date.now()}.json`;
|
||||
|
||||
// Create Blob and Object URL
|
||||
const blob = new Blob([JSON.stringify(app.settings.universes)], {
|
||||
type: "application/json",
|
||||
});
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
// Create a temporary anchor and trigger download
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = fileName;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
|
||||
// Revoke the Object URL to free resources
|
||||
URL.revokeObjectURL(url);
|
||||
});
|
||||
|
||||
app.interface.load_universe_button.addEventListener("click", () => {
|
||||
let query = (app.interface.buffer_search as HTMLInputElement).value;
|
||||
if (query.length > 2 && query.length < 20 && !query.includes(" ")) {
|
||||
loadUniverse(app, query);
|
||||
app.settings.selected_universe = query;
|
||||
(app.interface.buffer_search as HTMLInputElement).value = "";
|
||||
closeUniverseModal();
|
||||
app.view.focus();
|
||||
emptyUrl();
|
||||
}
|
||||
});
|
||||
|
||||
app.interface.eval_button.addEventListener("click", () => {
|
||||
app.currentFile().candidate = app.view.state.doc.toString();
|
||||
app.flashBackground("#404040", 200);
|
||||
});
|
||||
|
||||
app.buttonElements.stop_buttons.forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
app.setButtonHighlighting("stop", true);
|
||||
app.isPlaying = false;
|
||||
app.clock.stop();
|
||||
});
|
||||
});
|
||||
|
||||
app.interface.local_button.addEventListener("click", () =>
|
||||
app.changeModeFromInterface("local")
|
||||
);
|
||||
app.interface.global_button.addEventListener("click", () =>
|
||||
app.changeModeFromInterface("global")
|
||||
);
|
||||
app.interface.init_button.addEventListener("click", () =>
|
||||
app.changeModeFromInterface("init")
|
||||
);
|
||||
app.interface.note_button.addEventListener("click", () =>
|
||||
app.changeModeFromInterface("notes")
|
||||
);
|
||||
|
||||
app.interface.font_family_selector.addEventListener("change", () => {
|
||||
//@ts-ignore
|
||||
let new_font = (app.interface.font_family_selector as HTMLSelectElement)
|
||||
.value;
|
||||
});
|
||||
|
||||
app.interface.font_size_input.addEventListener("input", () => {
|
||||
let new_value: string | number = (
|
||||
app.interface.font_size_input as HTMLInputElement
|
||||
).value;
|
||||
app.settings.font_size = parseInt(new_value);
|
||||
});
|
||||
|
||||
app.interface.settings_button.addEventListener("click", () => {
|
||||
// Populate the font family selector
|
||||
const doughNudgeRange = app.interface.dough_nudge_range as HTMLInputElement;
|
||||
doughNudgeRange.value = app.dough_nudge.toString();
|
||||
// @ts-ignore
|
||||
const doughNumber = document.getElementById(
|
||||
"doughnumber"
|
||||
) as HTMLInputElement;
|
||||
doughNumber.value = app.dough_nudge.toString();
|
||||
(app.interface.font_family_selector as HTMLSelectElement).value =
|
||||
app.settings.font;
|
||||
|
||||
if (app.settings.font_size === null) {
|
||||
app.settings.font_size = 12;
|
||||
}
|
||||
const fontSizeInput = app.interface.font_size_input as HTMLInputElement;
|
||||
fontSizeInput.value = app.settings.font_size.toString();
|
||||
|
||||
// Get the right value to update graphical widgets
|
||||
const lineNumbersCheckbox = app.interface
|
||||
.line_numbers_checkbox as HTMLInputElement;
|
||||
lineNumbersCheckbox.checked = app.settings.line_numbers;
|
||||
const timePositionCheckbox = app.interface
|
||||
.time_position_checkbox as HTMLInputElement;
|
||||
timePositionCheckbox.checked = app.settings.time_position;
|
||||
const tipsCheckbox = app.interface.tips_checkbox as HTMLInputElement;
|
||||
tipsCheckbox.checked = app.settings.tips;
|
||||
const midiClockCheckbox = app.interface
|
||||
.midi_clock_checkbox as HTMLInputElement;
|
||||
midiClockCheckbox.checked = app.settings.send_clock;
|
||||
const midiChannelsScripts = app.interface
|
||||
.midi_channels_scripts as HTMLInputElement;
|
||||
midiChannelsScripts.checked = app.settings.midi_channels_scripts;
|
||||
const midiClockPpqn = app.interface.midi_clock_ppqn as HTMLInputElement;
|
||||
midiClockPpqn.value = app.settings.midi_clock_ppqn.toString();
|
||||
const loadDemoSongs = app.interface.load_demo_songs as HTMLInputElement;
|
||||
loadDemoSongs.checked = app.settings.load_demo_songs;
|
||||
const vimModeCheckbox = app.interface.vim_mode_checkbox as HTMLInputElement;
|
||||
vimModeCheckbox.checked = app.settings.vimMode;
|
||||
|
||||
let modal_settings = document.getElementById("modal-settings");
|
||||
let editor = document.getElementById("editor");
|
||||
modal_settings?.classList.remove("invisible");
|
||||
|
||||
editor?.classList.add("invisible");
|
||||
});
|
||||
|
||||
app.interface.close_settings_button.addEventListener("click", () => {
|
||||
let modal_settings = document.getElementById("modal-settings");
|
||||
let editor = document.getElementById("editor");
|
||||
modal_settings?.classList.add("invisible");
|
||||
editor?.classList.remove("invisible");
|
||||
// Update the font size once again
|
||||
app.view.dispatch({
|
||||
effects: app.fontSize.reconfigure(
|
||||
EditorView.theme({
|
||||
"&": { fontSize: app.settings.font_size + "px" },
|
||||
"&content": {
|
||||
fontFamily: app.settings.font,
|
||||
fontSize: app.settings.font_size + "px",
|
||||
},
|
||||
".cm-gutters": { fontSize: app.settings.font_size + "px" },
|
||||
})
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
app.interface.close_universes_button.addEventListener("click", () => {
|
||||
openUniverseModal();
|
||||
});
|
||||
|
||||
app.interface.share_button.addEventListener("click", async () => {
|
||||
// trigger a manual save
|
||||
app.currentFile().candidate = app.view.state.doc.toString();
|
||||
app.currentFile().committed = app.view.state.doc.toString();
|
||||
app.settings.saveApplicationToLocalStorage(app.universes, app.settings);
|
||||
// encode as a blob!
|
||||
await share(app);
|
||||
});
|
||||
|
||||
app.interface.vim_mode_checkbox.addEventListener("change", () => {
|
||||
let checked = (app.interface.vim_mode_checkbox as HTMLInputElement).checked
|
||||
? true
|
||||
: false;
|
||||
app.settings.vimMode = checked;
|
||||
app.view.dispatch({
|
||||
effects: app.vimModeCompartment.reconfigure(checked ? vim() : []),
|
||||
});
|
||||
});
|
||||
|
||||
app.interface.line_numbers_checkbox.addEventListener("change", () => {
|
||||
let lineNumbersCheckbox = app.interface
|
||||
.line_numbers_checkbox as HTMLInputElement;
|
||||
let checked = lineNumbersCheckbox.checked ? true : false;
|
||||
app.settings.line_numbers = checked;
|
||||
app.view.dispatch({
|
||||
effects: app.withLineNumbers.reconfigure(checked ? [lineNumbers()] : []),
|
||||
});
|
||||
});
|
||||
|
||||
app.interface.time_position_checkbox.addEventListener("change", () => {
|
||||
let timeviewer = document.getElementById("timeviewer") as HTMLElement;
|
||||
let checked = (app.interface.time_position_checkbox as HTMLInputElement)
|
||||
.checked
|
||||
? true
|
||||
: false;
|
||||
app.settings.time_position = checked;
|
||||
checked
|
||||
? timeviewer.classList.remove("hidden")
|
||||
: timeviewer.classList.add("hidden");
|
||||
});
|
||||
|
||||
app.interface.tips_checkbox.addEventListener("change", () => {
|
||||
let checked = (app.interface.tips_checkbox as HTMLInputElement).checked
|
||||
? true
|
||||
: false;
|
||||
app.settings.tips = checked;
|
||||
app.view.dispatch({
|
||||
effects: app.hoveringCompartment.reconfigure(
|
||||
checked ? inlineHoveringTips : []
|
||||
),
|
||||
});
|
||||
});
|
||||
|
||||
app.interface.midi_clock_checkbox.addEventListener("change", () => {
|
||||
let checked = (app.interface.midi_clock_checkbox as HTMLInputElement)
|
||||
.checked
|
||||
? true
|
||||
: false;
|
||||
app.settings.send_clock = checked;
|
||||
});
|
||||
|
||||
app.interface.midi_channels_scripts.addEventListener("change", () => {
|
||||
let checked = (app.interface.midi_channels_scripts as HTMLInputElement)
|
||||
.checked
|
||||
? true
|
||||
: false;
|
||||
app.settings.midi_channels_scripts = checked;
|
||||
});
|
||||
|
||||
app.interface.midi_clock_ppqn.addEventListener("change", () => {
|
||||
let value = parseInt(
|
||||
(app.interface.midi_clock_ppqn as HTMLInputElement).value
|
||||
);
|
||||
app.settings.midi_clock_ppqn = value;
|
||||
});
|
||||
|
||||
app.interface.load_demo_songs.addEventListener("change", () => {
|
||||
let checked = (app.interface.load_demo_songs as HTMLInputElement).checked
|
||||
? true
|
||||
: false;
|
||||
app.settings.load_demo_songs = checked;
|
||||
});
|
||||
|
||||
app.interface.universe_creator.addEventListener("submit", (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
let data = new FormData(app.interface.universe_creator as HTMLFormElement);
|
||||
let universeName = data.get("universe") as string | null;
|
||||
|
||||
if (universeName) {
|
||||
if (universeName.length > 2 && universeName.length < 20) {
|
||||
loadUniverse(app, universeName);
|
||||
app.settings.selected_universe = universeName;
|
||||
(app.interface.buffer_search as HTMLInputElement).value = "";
|
||||
closeUniverseModal();
|
||||
app.view.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
tryEvaluate(app, app.universes[app.selected_universe.toString()].init);
|
||||
|
||||
[
|
||||
"introduction",
|
||||
"interface",
|
||||
"interaction",
|
||||
"code",
|
||||
"time",
|
||||
"sound",
|
||||
"samples",
|
||||
"synths",
|
||||
"chaining",
|
||||
"patterns",
|
||||
"ziffers",
|
||||
"midi",
|
||||
"functions",
|
||||
"lfos",
|
||||
"probabilities",
|
||||
"variables",
|
||||
// "reference",
|
||||
"shortcuts",
|
||||
"about",
|
||||
"bonus",
|
||||
].forEach((e) => {
|
||||
let name = `docs_` + e;
|
||||
document.getElementById(name)!.addEventListener("click", async () => {
|
||||
if (name !== "docs_samples") {
|
||||
app.currentDocumentationPane = e;
|
||||
updateDocumentationContent(app);
|
||||
} else {
|
||||
console.log("Loading samples!");
|
||||
await loadSamples().then(() => {
|
||||
app.docs = documentation_factory(app);
|
||||
app.currentDocumentationPane = e;
|
||||
updateDocumentationContent(app);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user