mirror of
https://github.com/Horizontal42/summarum.git
synced 2026-11-10 19:11:58 +03:00
wire cross-sheet references into the editor and document lifecycle
This commit is contained in:
parent
8fb9ee3a31
commit
9d8f977c46
2 changed files with 20 additions and 4 deletions
21
src/main.ts
21
src/main.ts
|
|
@ -14,6 +14,7 @@ import type { LineResult } from "./engine";
|
||||||
import { setLang, detectLang, t } from "./i18n";
|
import { setLang, detectLang, t } from "./i18n";
|
||||||
import { runExtensions } from "./extensions";
|
import { runExtensions } from "./extensions";
|
||||||
import { checkForUpdate } from "./updater";
|
import { checkForUpdate } from "./updater";
|
||||||
|
import { Workspace } from "./workspace";
|
||||||
import { EN, RU } from "./engine/vocab-data";
|
import { EN, RU } from "./engine/vocab-data";
|
||||||
|
|
||||||
function welcomeText(lang: string): string {
|
function welcomeText(lang: string): string {
|
||||||
|
|
@ -25,6 +26,7 @@ const $ = <T extends HTMLElement>(sel: string): T => document.querySelector(sel)
|
||||||
|
|
||||||
let engine: SumEngine;
|
let engine: SumEngine;
|
||||||
let editor: SumEditor;
|
let editor: SumEditor;
|
||||||
|
let workspace: Workspace;
|
||||||
let settings: SettingsData;
|
let settings: SettingsData;
|
||||||
let data: AppData;
|
let data: AppData;
|
||||||
let lastResults: LineResult[] = [];
|
let lastResults: LineResult[] = [];
|
||||||
|
|
@ -204,7 +206,7 @@ function searchAllSheets(query: string): SearchHit[] {
|
||||||
const hits: SearchHit[] = [];
|
const hits: SearchHit[] = [];
|
||||||
for (const doc of data.docs) {
|
for (const doc of data.docs) {
|
||||||
const contents = data.contents[doc.id] ?? "";
|
const contents = data.contents[doc.id] ?? "";
|
||||||
const results = engine.evaluateDocument(contents);
|
const results = workspace.evaluateSheet(doc.id, contents);
|
||||||
const lines = contents.split("\n");
|
const lines = contents.split("\n");
|
||||||
for (let i = 0; i < results.length; i++) {
|
for (let i = 0; i < results.length; i++) {
|
||||||
const r = results[i];
|
const r = results[i];
|
||||||
|
|
@ -536,6 +538,7 @@ async function refreshRates(force = false): Promise<void> {
|
||||||
Object.entries(payload.rates).map(([k, v]) => [k, Number(v)])
|
Object.entries(payload.rates).map(([k, v]) => [k, Number(v)])
|
||||||
);
|
);
|
||||||
applyAllRates();
|
applyAllRates();
|
||||||
|
workspace.invalidateAll();
|
||||||
editor.refresh();
|
editor.refresh();
|
||||||
ratesFetchedAt = payload.fetchedAt;
|
ratesFetchedAt = payload.fetchedAt;
|
||||||
if (force) toast(t("ratesUpdated"));
|
if (force) toast(t("ratesUpdated"));
|
||||||
|
|
@ -568,6 +571,7 @@ async function refreshMarket(force = false): Promise<void> {
|
||||||
marketPrices = prices;
|
marketPrices = prices;
|
||||||
marketFetchedAt = Math.floor(Date.now() / 1000);
|
marketFetchedAt = Math.floor(Date.now() / 1000);
|
||||||
applyAllRates();
|
applyAllRates();
|
||||||
|
workspace.invalidateAll();
|
||||||
editor.refresh();
|
editor.refresh();
|
||||||
if (force) toast(t("marketUpdated"));
|
if (force) toast(t("marketUpdated"));
|
||||||
}
|
}
|
||||||
|
|
@ -588,7 +592,7 @@ async function fetchNeededHistoricalRates(text: string): Promise<void> {
|
||||||
if (rates) { engine.setHistoricalRates(date, rates); fetched = true; }
|
if (rates) { engine.setHistoricalRates(date, rates); fetched = true; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fetched) editor.refresh();
|
if (fetched) { workspace.invalidateAll(); editor.refresh(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderMarketInfo(): void {
|
function renderMarketInfo(): void {
|
||||||
|
|
@ -657,7 +661,7 @@ async function renderSheetImage(): Promise<void> {
|
||||||
const lineH = Math.round(fontSize * 1.7);
|
const lineH = Math.round(fontSize * 1.7);
|
||||||
const padX = 20, padTop = 16, padBot = 16;
|
const padX = 20, padTop = 16, padBot = 16;
|
||||||
|
|
||||||
const doc = engine.evaluateDocument(editor.getText());
|
const doc = workspace.evaluateSheet(activeDoc().id, editor.getText());
|
||||||
const rawLines = editor.getText().split("\n");
|
const rawLines = editor.getText().split("\n");
|
||||||
|
|
||||||
const canvas = document.createElement("canvas");
|
const canvas = document.createElement("canvas");
|
||||||
|
|
@ -775,6 +779,10 @@ async function boot(): Promise<void> {
|
||||||
const scripts = await loadExtensionScripts();
|
const scripts = await loadExtensionScripts();
|
||||||
runExtensions(engine, scripts);
|
runExtensions(engine, scripts);
|
||||||
|
|
||||||
|
workspace = new Workspace(engine, () =>
|
||||||
|
data.docs.map((d) => ({ id: d.id, title: d.title, text: data.contents[d.id] ?? "" })),
|
||||||
|
);
|
||||||
|
|
||||||
editor = new SumEditor(
|
editor = new SumEditor(
|
||||||
$("#editor"),
|
$("#editor"),
|
||||||
$("#results"),
|
$("#results"),
|
||||||
|
|
@ -783,6 +791,7 @@ async function boot(): Promise<void> {
|
||||||
onChange(text) {
|
onChange(text) {
|
||||||
const doc = activeDoc();
|
const doc = activeDoc();
|
||||||
data.contents[doc.id] = text;
|
data.contents[doc.id] = text;
|
||||||
|
workspace.invalidate(doc.id);
|
||||||
if (!doc.customTitle) {
|
if (!doc.customTitle) {
|
||||||
doc.title = titleFromContent(text);
|
doc.title = titleFromContent(text);
|
||||||
syncTitleField();
|
syncTitleField();
|
||||||
|
|
@ -804,6 +813,7 @@ async function boot(): Promise<void> {
|
||||||
renderTotal();
|
renderTotal();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
(text) => workspace.evaluateSheet(activeDoc().id, text),
|
||||||
data.contents[data.activeId] ?? "",
|
data.contents[data.activeId] ?? "",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -815,13 +825,18 @@ async function boot(): Promise<void> {
|
||||||
const titleField = $<HTMLInputElement>("#doc-title");
|
const titleField = $<HTMLInputElement>("#doc-title");
|
||||||
titleField.addEventListener("change", () => {
|
titleField.addEventListener("change", () => {
|
||||||
const doc = activeDoc();
|
const doc = activeDoc();
|
||||||
|
const oldTitle = doc.title;
|
||||||
const v = titleField.value.trim();
|
const v = titleField.value.trim();
|
||||||
if (v) {
|
if (v) {
|
||||||
doc.title = v.slice(0, 60);
|
doc.title = v.slice(0, 60);
|
||||||
doc.customTitle = true;
|
doc.customTitle = true;
|
||||||
|
const rewrites = workspace.renameSheet(doc.id, oldTitle, doc.title);
|
||||||
|
for (const r of rewrites) data.contents[r.id] = r.text;
|
||||||
|
workspace.invalidateAll();
|
||||||
} else {
|
} else {
|
||||||
doc.customTitle = false;
|
doc.customTitle = false;
|
||||||
doc.title = titleFromContent(data.contents[doc.id] ?? "");
|
doc.title = titleFromContent(data.contents[doc.id] ?? "");
|
||||||
|
workspace.invalidateAll();
|
||||||
}
|
}
|
||||||
syncTitleField();
|
syncTitleField();
|
||||||
renderDocList();
|
renderDocList();
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,7 @@ export class SumEditor {
|
||||||
resultsEl: HTMLElement,
|
resultsEl: HTMLElement,
|
||||||
private engine: SumEngine,
|
private engine: SumEngine,
|
||||||
private cb: EditorCallbacks,
|
private cb: EditorCallbacks,
|
||||||
|
private evaluateDoc: (text: string) => LineResult[],
|
||||||
initialText: string,
|
initialText: string,
|
||||||
) {
|
) {
|
||||||
this.resultsEl = resultsEl;
|
this.resultsEl = resultsEl;
|
||||||
|
|
@ -310,7 +311,7 @@ export class SumEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private evaluate(text: string): void {
|
private evaluate(text: string): void {
|
||||||
this.results = this.engine.evaluateDocument(text);
|
this.results = this.evaluateDoc(text);
|
||||||
this.view.dispatch({ effects: setResults.of(this.results) });
|
this.view.dispatch({ effects: setResults.of(this.results) });
|
||||||
this.cb.onResults(this.results);
|
this.cb.onResults(this.results);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue