mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Reduce use of type casting (#3723)
This commit is contained in:
parent
493320fb33
commit
b6afddd181
54 changed files with 85 additions and 84 deletions
|
@ -18,7 +18,7 @@ function getCSS(nightMode: boolean, fontSize: number): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStyle(css: string): HTMLStyleElement {
|
function getStyle(css: string): HTMLStyleElement {
|
||||||
const style = document.createElement("style") as HTMLStyleElement;
|
const style = document.createElement("style");
|
||||||
style.appendChild(document.createTextNode(css));
|
style.appendChild(document.createTextNode(css));
|
||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
|
|
|
@ -386,9 +386,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
* Enable/Disable add-on buttons that do not have the `perm` class
|
* Enable/Disable add-on buttons that do not have the `perm` class
|
||||||
*/
|
*/
|
||||||
function setAddonButtonsDisabled(disabled: boolean): void {
|
function setAddonButtonsDisabled(disabled: boolean): void {
|
||||||
document.querySelectorAll("button.linkb:not(.perm)").forEach((button) => {
|
document
|
||||||
(button as HTMLButtonElement).disabled = disabled;
|
.querySelectorAll<HTMLButtonElement>("button.linkb:not(.perm)")
|
||||||
});
|
.forEach((button) => {
|
||||||
|
button.disabled = disabled;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
import { ImageOcclusionFieldIndexes } from "@generated/anki/image_occlusion_pb";
|
import { ImageOcclusionFieldIndexes } from "@generated/anki/image_occlusion_pb";
|
||||||
|
|
|
@ -43,17 +43,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
$: setStyling("fontSize", fontSize + "px");
|
$: setStyling("fontSize", fontSize + "px");
|
||||||
$: setStyling("direction", direction);
|
$: setStyling("direction", direction);
|
||||||
|
|
||||||
const styles = [
|
const styles: StyleLinkType[] = [
|
||||||
{
|
{
|
||||||
id: "rootStyle",
|
id: "rootStyle",
|
||||||
type: "link" as "link",
|
type: "link",
|
||||||
href: "./_anki/css/editable.css",
|
href: "./_anki/css/editable.css",
|
||||||
} as StyleLinkType,
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function attachToShadow(element: Element) {
|
function attachToShadow(element: Element) {
|
||||||
const customStyles = mount(CustomStyles, {
|
const customStyles = mount(CustomStyles, {
|
||||||
target: element.shadowRoot as any,
|
target: element.shadowRoot!,
|
||||||
props: { styles },
|
props: { styles },
|
||||||
});
|
});
|
||||||
customStyles.addStyleTag("userBase").then((styleTag) => {
|
customStyles.addStyleTag("userBase").then((styleTag) => {
|
||||||
|
|
|
@ -16,7 +16,7 @@ function filterStyling(
|
||||||
): (element: HTMLElement) => void {
|
): (element: HTMLElement) => void {
|
||||||
return (element: HTMLElement): void => {
|
return (element: HTMLElement): void => {
|
||||||
// jsdom does not support @@iterator, so manually iterate
|
// jsdom does not support @@iterator, so manually iterate
|
||||||
const toRemove = [] as string[];
|
const toRemove: string[] = [];
|
||||||
for (let i = 0; i < element.style.length; i++) {
|
for (let i = 0; i < element.style.length; i++) {
|
||||||
const key = element.style.item(i);
|
const key = element.style.item(i);
|
||||||
const value = element.style.getPropertyValue(key);
|
const value = element.style.getPropertyValue(key);
|
||||||
|
|
|
@ -35,7 +35,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
export { placement as preferredPlacement };
|
export { placement as preferredPlacement };
|
||||||
|
|
||||||
/* Used by Popover to set animation direction depending on placement */
|
/* Used by Popover to set animation direction depending on placement */
|
||||||
const placementPromise = writable(undefined as Promise<Placement> | undefined);
|
const placementPromise = writable<Promise<Placement> | undefined>();
|
||||||
setContext(floatingKey, placementPromise);
|
setContext(floatingKey, placementPromise);
|
||||||
|
|
||||||
export let offset = 5;
|
export let offset = 5;
|
||||||
|
|
|
@ -27,7 +27,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
import { overlayKey } from "./context-keys";
|
import { overlayKey } from "./context-keys";
|
||||||
|
|
||||||
/* Used by Popover to set animation direction depending on placement */
|
/* Used by Popover to set animation direction depending on placement */
|
||||||
const placementPromise = writable(undefined as Promise<Placement> | undefined);
|
const placementPromise = writable<Promise<Placement> | undefined>();
|
||||||
setContext(overlayKey, placementPromise);
|
setContext(overlayKey, placementPromise);
|
||||||
|
|
||||||
export let padding = 0;
|
export let padding = 0;
|
||||||
|
|
|
@ -17,7 +17,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
callback: (key: KeyType) => Promise<boolean>,
|
callback: (key: KeyType) => Promise<boolean>,
|
||||||
): void {
|
): void {
|
||||||
stateStore.update((map: StateMap): StateMap => {
|
stateStore.update((map: StateMap): StateMap => {
|
||||||
const newMap = new Map() as StateMap;
|
const newMap: StateMap = new Map();
|
||||||
|
|
||||||
for (const key of map.keys()) {
|
for (const key of map.keys()) {
|
||||||
newMap.set(key, callback(key));
|
newMap.set(key, callback(key));
|
||||||
|
|
|
@ -50,7 +50,7 @@ export function restoreSelection(base: Node, location: SelectionLocation): void
|
||||||
base,
|
base,
|
||||||
selection,
|
selection,
|
||||||
range,
|
range,
|
||||||
location as SelectionLocationContent,
|
location,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -375,10 +375,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
function deleteSelectedTags() {
|
function deleteSelectedTags() {
|
||||||
tagTypes
|
tagTypes
|
||||||
.map((tag, index) => [tag.selected, index])
|
.map((tag, index): [boolean, number] => [tag.selected, index])
|
||||||
.filter(([selected]) => selected)
|
.filter(([selected]) => selected)
|
||||||
.reverse()
|
.reverse()
|
||||||
.forEach(([, index]) => deleteTagAt(index as number));
|
.forEach(([, index]) => deleteTagAt(index));
|
||||||
deselect();
|
deselect();
|
||||||
saveTags();
|
saveTags();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,8 @@ function imageLoaded(img: HTMLImageElement): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractImageSrcs(fragment: DocumentFragment): string[] {
|
function extractImageSrcs(fragment: DocumentFragment): string[] {
|
||||||
const srcs = [...fragment.querySelectorAll("img[src]")].map(
|
const srcs = [...fragment.querySelectorAll<HTMLImageElement>("img[src]")].map(
|
||||||
(img) => (img as HTMLImageElement).src,
|
(img) => img.src,
|
||||||
);
|
);
|
||||||
return srcs;
|
return srcs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ function exampleInput(): SchedulingStatesWithContext {
|
||||||
|
|
||||||
test("can change oneof", () => {
|
test("can change oneof", () => {
|
||||||
let states = exampleInput().states!;
|
let states = exampleInput().states!;
|
||||||
const jsonStates = states.toJson({ "emitDefaultValues": true }) as any;
|
const jsonStates = states.toJson({ "emitDefaultValues": true });
|
||||||
// again should be a relearning state
|
// again should be a relearning state
|
||||||
const inner = states.again?.kind?.value?.kind;
|
const inner = states.again?.kind?.value?.kind;
|
||||||
assert(inner?.case === "relearning");
|
assert(inner?.case === "relearning");
|
||||||
|
|
|
@ -34,7 +34,7 @@ function createPreloadLink(href: string, as: string): HTMLLinkElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractExternalStyleSheets(fragment: DocumentFragment): CSSElement[] {
|
function extractExternalStyleSheets(fragment: DocumentFragment): CSSElement[] {
|
||||||
return ([...fragment.querySelectorAll("style, link")] as CSSElement[])
|
return [...fragment.querySelectorAll<CSSElement>("style, link")]
|
||||||
.filter((css) =>
|
.filter((css) =>
|
||||||
(css instanceof HTMLStyleElement && css.innerHTML.includes("@import"))
|
(css instanceof HTMLStyleElement && css.innerHTML.includes("@import"))
|
||||||
|| (css instanceof HTMLLinkElement && css.rel === "stylesheet")
|
|| (css instanceof HTMLLinkElement && css.rel === "stylesheet")
|
||||||
|
|
|
@ -21,7 +21,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
export let revlog: RevlogEntry[];
|
export let revlog: RevlogEntry[];
|
||||||
export let desiredRetention: number;
|
export let desiredRetention: number;
|
||||||
let svg = null as HTMLElement | SVGElement | null;
|
let svg: HTMLElement | SVGElement | null = null;
|
||||||
const bounds = defaultGraphBounds();
|
const bounds = defaultGraphBounds();
|
||||||
const title = tr.cardStatsFsrsForgettingCurveTitle();
|
const title = tr.cardStatsFsrsForgettingCurveTitle();
|
||||||
|
|
||||||
|
|
|
@ -93,12 +93,12 @@ export class ChangeNotetypeInfoWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
input(): ChangeNotetypeRequest {
|
input(): ChangeNotetypeRequest {
|
||||||
return this.info.input as ChangeNotetypeRequest;
|
return this.info.input!;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Pack changes back into input message for saving. */
|
/** Pack changes back into input message for saving. */
|
||||||
intoInput(): ChangeNotetypeRequest {
|
intoInput(): ChangeNotetypeRequest {
|
||||||
const input = this.info.input as ChangeNotetypeRequest;
|
const input = this.info.input!;
|
||||||
input.newFields = nullToNegativeOne(this.fields);
|
input.newFields = nullToNegativeOne(this.fields);
|
||||||
if (this.templates) {
|
if (this.templates) {
|
||||||
input.newTemplates = nullToNegativeOne(this.templates);
|
input.newTemplates = nullToNegativeOne(this.templates);
|
||||||
|
@ -194,7 +194,7 @@ export class ChangeNotetypeState {
|
||||||
idx,
|
idx,
|
||||||
name: entry.name,
|
name: entry.name,
|
||||||
current: entry.id === currentId,
|
current: entry.id === currentId,
|
||||||
} as NotetypeListEntry),
|
} satisfies NotetypeListEntry),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
url: "https://faqs.ankiweb.net/the-2021-scheduler.html#add-ons-and-custom-scheduling",
|
url: "https://faqs.ankiweb.net/the-2021-scheduler.html#add-ons-and-custom-scheduling",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const helpSections = Object.values(settings) as HelpItem[];
|
const helpSections: HelpItem[] = Object.values(settings);
|
||||||
|
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let carousel: Carousel;
|
let carousel: Carousel;
|
||||||
|
|
|
@ -34,7 +34,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
help: tr.deckConfigAlwaysIncludeQuestionAudioTooltip(),
|
help: tr.deckConfigAlwaysIncludeQuestionAudioTooltip(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const helpSections = Object.values(settings) as HelpItem[];
|
const helpSections: HelpItem[] = Object.values(settings);
|
||||||
|
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let carousel: Carousel;
|
let carousel: Carousel;
|
||||||
|
|
|
@ -49,7 +49,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
help: tr.deckConfigAnswerActionTooltip2(),
|
help: tr.deckConfigAnswerActionTooltip2(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const helpSections = Object.values(settings) as HelpItem[];
|
const helpSections: HelpItem[] = Object.values(settings);
|
||||||
|
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let carousel: Carousel;
|
let carousel: Carousel;
|
||||||
|
|
|
@ -40,7 +40,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
help: tr.deckConfigBuryInterdayLearningTooltip() + priorityTooltip,
|
help: tr.deckConfigBuryInterdayLearningTooltip() + priorityTooltip,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const helpSections = Object.values(settings) as HelpItem[];
|
const helpSections: HelpItem[] = Object.values(settings);
|
||||||
|
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let carousel: Carousel;
|
let carousel: Carousel;
|
||||||
|
|
|
@ -143,7 +143,7 @@
|
||||||
url: HelpPage.DeckOptions.newCardsday,
|
url: HelpPage.DeckOptions.newCardsday,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const helpSections = Object.values(settings) as HelpItem[];
|
const helpSections: HelpItem[] = Object.values(settings);
|
||||||
|
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let carousel: Carousel;
|
let carousel: Carousel;
|
||||||
|
|
|
@ -97,7 +97,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
help: tr.deckConfigReviewSortOrderTooltip() + currentDeck,
|
help: tr.deckConfigReviewSortOrderTooltip() + currentDeck,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const helpSections = Object.values(settings) as HelpItem[];
|
const helpSections: HelpItem[] = Object.values(settings);
|
||||||
|
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let carousel: Carousel;
|
let carousel: Carousel;
|
||||||
|
|
|
@ -300,10 +300,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
return tr.deckConfigPredictedOptimalRetention({ num: retention.toFixed(2) });
|
return tr.deckConfigPredictedOptimalRetention({ num: retention.toFixed(2) });
|
||||||
}
|
}
|
||||||
|
|
||||||
let tableData: TableDatum[] = [] as any;
|
let tableData: TableDatum[] = [];
|
||||||
const bounds = defaultGraphBounds();
|
const bounds = defaultGraphBounds();
|
||||||
bounds.marginLeft += 8;
|
bounds.marginLeft += 8;
|
||||||
let svg = null as HTMLElement | SVGElement | null;
|
let svg: HTMLElement | SVGElement | null = null;
|
||||||
let simulationNumber = 0;
|
let simulationNumber = 0;
|
||||||
|
|
||||||
let points: Point[] = [];
|
let points: Point[] = [];
|
||||||
|
|
|
@ -55,7 +55,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
sched: HelpItemScheduler.FSRS,
|
sched: HelpItemScheduler.FSRS,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const helpSections = Object.values(settings) as HelpItem[];
|
const helpSections: HelpItem[] = Object.values(settings);
|
||||||
|
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let carousel: Carousel;
|
let carousel: Carousel;
|
||||||
|
|
|
@ -68,7 +68,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
url: HelpPage.Leeches.waiting,
|
url: HelpPage.Leeches.waiting,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const helpSections = Object.values(settings) as HelpItem[];
|
const helpSections: HelpItem[] = Object.values(settings);
|
||||||
|
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let carousel: Carousel;
|
let carousel: Carousel;
|
||||||
|
|
|
@ -80,7 +80,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
url: HelpPage.DeckOptions.insertionOrder,
|
url: HelpPage.DeckOptions.insertionOrder,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const helpSections = Object.values(settings) as HelpItem[];
|
const helpSections: HelpItem[] = Object.values(settings);
|
||||||
|
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let carousel: Carousel;
|
let carousel: Carousel;
|
||||||
|
|
|
@ -45,7 +45,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
help: tr.deckConfigStopTimerOnAnswerTooltip(),
|
help: tr.deckConfigStopTimerOnAnswerTooltip(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const helpSections = Object.values(settings) as HelpItem[];
|
const helpSections: HelpItem[] = Object.values(settings);
|
||||||
|
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let carousel: Carousel;
|
let carousel: Carousel;
|
||||||
|
|
|
@ -22,7 +22,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
export let sourceData: GraphsResponse | null = null;
|
export let sourceData: GraphsResponse | null = null;
|
||||||
export let prefs: GraphPrefs;
|
export let prefs: GraphPrefs;
|
||||||
|
|
||||||
let histogramData = null as HistogramData | null;
|
let histogramData: HistogramData | null = null;
|
||||||
let tableData: TableDatum[] = [];
|
let tableData: TableDatum[] = [];
|
||||||
let graphRange: GraphRange = GraphRange.Month;
|
let graphRange: GraphRange = GraphRange.Month;
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
const bounds = defaultGraphBounds();
|
const bounds = defaultGraphBounds();
|
||||||
|
|
||||||
let svg = null as HTMLElement | SVGElement | null;
|
let svg: HTMLElement | SVGElement | null = null;
|
||||||
|
|
||||||
$: if (sourceData) {
|
$: if (sourceData) {
|
||||||
renderButtons(svg as SVGElement, bounds, sourceData, graphRange);
|
renderButtons(svg as SVGElement, bounds, sourceData, graphRange);
|
||||||
|
|
|
@ -30,13 +30,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
bounds.marginLeft = 20;
|
bounds.marginLeft = 20;
|
||||||
bounds.marginRight = 20;
|
bounds.marginRight = 20;
|
||||||
|
|
||||||
let svg = null as HTMLElement | SVGElement | null;
|
let svg: HTMLElement | SVGElement | null = null;
|
||||||
const maxYear = new Date().getFullYear();
|
const maxYear = new Date().getFullYear();
|
||||||
let minYear = 0;
|
let minYear = 0;
|
||||||
let targetYear = maxYear;
|
let targetYear = maxYear;
|
||||||
|
|
||||||
$: if (sourceData) {
|
$: if (sourceData) {
|
||||||
graphData = gatherData(sourceData, $prefs.calendarFirstDayOfWeek as number);
|
graphData = gatherData(sourceData, $prefs.calendarFirstDayOfWeek);
|
||||||
renderCalendar(
|
renderCalendar(
|
||||||
svg as SVGElement,
|
svg as SVGElement,
|
||||||
bounds,
|
bounds,
|
||||||
|
@ -52,7 +52,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
$: {
|
$: {
|
||||||
if (revlogRange < RevlogRange.Year) {
|
if (revlogRange < RevlogRange.Year) {
|
||||||
minYear = maxYear;
|
minYear = maxYear;
|
||||||
} else if ((revlogRange as RevlogRange) === RevlogRange.Year) {
|
} else if (revlogRange === RevlogRange.Year) {
|
||||||
minYear = maxYear - 1;
|
minYear = maxYear - 1;
|
||||||
} else {
|
} else {
|
||||||
minYear = 2000;
|
minYear = 2000;
|
||||||
|
|
|
@ -20,14 +20,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<SearchEventMap>();
|
const dispatch = createEventDispatcher<SearchEventMap>();
|
||||||
|
|
||||||
let svg = null as HTMLElement | SVGElement | null;
|
let svg: HTMLElement | SVGElement | null = null;
|
||||||
|
|
||||||
const bounds = defaultGraphBounds();
|
const bounds = defaultGraphBounds();
|
||||||
bounds.width = 225;
|
bounds.width = 225;
|
||||||
bounds.marginBottom = 0;
|
bounds.marginBottom = 0;
|
||||||
|
|
||||||
let graphData = null as unknown as GraphData;
|
let graphData: GraphData = null!;
|
||||||
let tableData = null as unknown as TableDatum[];
|
let tableData: TableDatum[] = null!;
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
graphData = gatherData(sourceData, $prefs.cardCountsSeparateInactive);
|
graphData = gatherData(sourceData, $prefs.cardCountsSeparateInactive);
|
||||||
|
|
|
@ -20,7 +20,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<SearchEventMap>();
|
const dispatch = createEventDispatcher<SearchEventMap>();
|
||||||
|
|
||||||
let histogramData = null as HistogramData | null;
|
let histogramData: HistogramData | null = null;
|
||||||
let tableData: TableDatum[] = [];
|
let tableData: TableDatum[] = [];
|
||||||
|
|
||||||
$: if (sourceData) {
|
$: if (sourceData) {
|
||||||
|
|
|
@ -20,7 +20,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<SearchEventMap>();
|
const dispatch = createEventDispatcher<SearchEventMap>();
|
||||||
|
|
||||||
let histogramData = null as HistogramData | null;
|
let histogramData: HistogramData | null = null;
|
||||||
let tableData: TableDatum[] = [];
|
let tableData: TableDatum[] = [];
|
||||||
|
|
||||||
$: if (sourceData) {
|
$: if (sourceData) {
|
||||||
|
|
|
@ -24,9 +24,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<SearchEventMap>();
|
const dispatch = createEventDispatcher<SearchEventMap>();
|
||||||
|
|
||||||
let graphData = null as GraphData | null;
|
let graphData: GraphData | null = null;
|
||||||
let histogramData = null as HistogramData | null;
|
let histogramData: HistogramData | null = null;
|
||||||
let tableData: TableDatum[] = [] as any;
|
let tableData: TableDatum[] = [];
|
||||||
let graphRange: GraphRange = GraphRange.Month;
|
let graphRange: GraphRange = GraphRange.Month;
|
||||||
|
|
||||||
$: if (sourceData) {
|
$: if (sourceData) {
|
||||||
|
|
|
@ -14,7 +14,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
export let data: HistogramData | null = null;
|
export let data: HistogramData | null = null;
|
||||||
|
|
||||||
const bounds = defaultGraphBounds();
|
const bounds = defaultGraphBounds();
|
||||||
let svg = null as HTMLElement | SVGElement | null;
|
let svg: HTMLElement | SVGElement | null = null;
|
||||||
|
|
||||||
$: histogramGraph(svg as SVGElement, bounds, data);
|
$: histogramGraph(svg as SVGElement, bounds, data);
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -23,7 +23,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
const bounds = defaultGraphBounds();
|
const bounds = defaultGraphBounds();
|
||||||
|
|
||||||
let svg = null as HTMLElement | SVGElement | null;
|
let svg: HTMLElement | SVGElement | null = null;
|
||||||
|
|
||||||
$: if (sourceData) {
|
$: if (sourceData) {
|
||||||
renderHours(svg as SVGElement, bounds, sourceData, graphRange);
|
renderHours(svg as SVGElement, bounds, sourceData, graphRange);
|
||||||
|
|
|
@ -28,7 +28,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
const dispatch = createEventDispatcher<SearchEventMap>();
|
const dispatch = createEventDispatcher<SearchEventMap>();
|
||||||
|
|
||||||
let intervalData: IntervalGraphData | null = null;
|
let intervalData: IntervalGraphData | null = null;
|
||||||
let histogramData = null as HistogramData | null;
|
let histogramData: HistogramData | null = null;
|
||||||
let tableData: TableDatum[] = [];
|
let tableData: TableDatum[] = [];
|
||||||
let range = IntervalRange.Percentile95;
|
let range = IntervalRange.Percentile95;
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
let displayedSearch = $search;
|
let displayedSearch = $search;
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
switch (searchRange as SearchRange) {
|
switch (searchRange) {
|
||||||
case SearchRange.Deck:
|
case SearchRange.Deck:
|
||||||
$search = displayedSearch = "deck:current";
|
$search = displayedSearch = "deck:current";
|
||||||
break;
|
break;
|
||||||
|
@ -45,7 +45,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
}
|
}
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
switch (revlogRange as RevlogRange) {
|
switch (revlogRange) {
|
||||||
case RevlogRange.Year:
|
case RevlogRange.Year:
|
||||||
$days = 365;
|
$days = 365;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -20,7 +20,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<SearchEventMap>();
|
const dispatch = createEventDispatcher<SearchEventMap>();
|
||||||
|
|
||||||
let histogramData = null as HistogramData | null;
|
let histogramData: HistogramData | null = null;
|
||||||
let tableData: TableDatum[] = [];
|
let tableData: TableDatum[] = [];
|
||||||
|
|
||||||
$: if (sourceData) {
|
$: if (sourceData) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
let graphData: GraphData | null = null;
|
let graphData: GraphData | null = null;
|
||||||
|
|
||||||
const bounds = defaultGraphBounds();
|
const bounds = defaultGraphBounds();
|
||||||
let svg = null as HTMLElement | SVGElement | null;
|
let svg: HTMLElement | SVGElement | null = null;
|
||||||
let graphRange: GraphRange = GraphRange.Month;
|
let graphRange: GraphRange = GraphRange.Month;
|
||||||
let showTime = false;
|
let showTime = false;
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
graphData = gatherData(sourceData);
|
graphData = gatherData(sourceData);
|
||||||
}
|
}
|
||||||
|
|
||||||
let tableData: TableDatum[] = [] as any;
|
let tableData: TableDatum[] = [];
|
||||||
$: if (graphData) {
|
$: if (graphData) {
|
||||||
tableData = renderReviews(
|
tableData = renderReviews(
|
||||||
svg as SVGElement,
|
svg as SVGElement,
|
||||||
|
|
|
@ -28,7 +28,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
const dispatch = createEventDispatcher<SearchEventMap>();
|
const dispatch = createEventDispatcher<SearchEventMap>();
|
||||||
|
|
||||||
let intervalData: IntervalGraphData | null = null;
|
let intervalData: IntervalGraphData | null = null;
|
||||||
let histogramData = null as HistogramData | null;
|
let histogramData: HistogramData | null = null;
|
||||||
let tableData: TableDatum[] = [];
|
let tableData: TableDatum[] = [];
|
||||||
let range = IntervalRange.Percentile95;
|
let range = IntervalRange.Percentile95;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
export let y: number = 0;
|
export let y: number = 0;
|
||||||
export let show = true;
|
export let show = true;
|
||||||
|
|
||||||
let container = null as unknown as HTMLDivElement;
|
let container: HTMLDivElement | null = null;
|
||||||
|
|
||||||
let adjustedX: number, adjustedY: number;
|
let adjustedX: number, adjustedY: number;
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
setGraphPreferences,
|
setGraphPreferences,
|
||||||
);
|
);
|
||||||
|
|
||||||
let sourceData = null as null | GraphsResponse;
|
let sourceData: GraphsResponse | null = null;
|
||||||
let loading = true;
|
let loading = true;
|
||||||
$: updateSourceData($search, $days);
|
$: updateSourceData($search, $days);
|
||||||
|
|
||||||
|
|
|
@ -75,21 +75,21 @@ export function renderButtons(
|
||||||
buttonNum: idx + 1,
|
buttonNum: idx + 1,
|
||||||
group: "learning",
|
group: "learning",
|
||||||
count,
|
count,
|
||||||
} as Datum;
|
} satisfies Datum;
|
||||||
}),
|
}),
|
||||||
...sourceData.young.map((count: number, idx: number) => {
|
...sourceData.young.map((count: number, idx: number) => {
|
||||||
return {
|
return {
|
||||||
buttonNum: idx + 1,
|
buttonNum: idx + 1,
|
||||||
group: "young",
|
group: "young",
|
||||||
count,
|
count,
|
||||||
} as Datum;
|
} satisfies Datum;
|
||||||
}),
|
}),
|
||||||
...sourceData.mature.map((count: number, idx: number) => {
|
...sourceData.mature.map((count: number, idx: number) => {
|
||||||
return {
|
return {
|
||||||
buttonNum: idx + 1,
|
buttonNum: idx + 1,
|
||||||
group: "mature",
|
group: "mature",
|
||||||
count,
|
count,
|
||||||
} as Datum;
|
} satisfies Datum;
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ export function renderCalendar(
|
||||||
const weekNumber = sourceData.timeFunction.count(timeYear(date), date);
|
const weekNumber = sourceData.timeFunction.count(timeYear(date), date);
|
||||||
const weekDay = timeDay.count(sourceData.timeFunction(date), date);
|
const weekDay = timeDay.count(sourceData.timeFunction(date), date);
|
||||||
const yearDay = timeDay.count(timeYear(date), date);
|
const yearDay = timeDay.count(timeYear(date), date);
|
||||||
dayMap.set(yearDay, { day, count, weekNumber, weekDay, date } as DayDatum);
|
dayMap.set(yearDay, { day, count, weekNumber, weekDay, date });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!maxCount) {
|
if (!maxCount) {
|
||||||
|
@ -132,7 +132,7 @@ export function renderCalendar(
|
||||||
weekNumber,
|
weekNumber,
|
||||||
weekDay,
|
weekDay,
|
||||||
date,
|
date,
|
||||||
} as DayDatum);
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const data = Array.from(dayMap.values());
|
const data = Array.from(dayMap.values());
|
||||||
|
|
|
@ -130,9 +130,8 @@ export function renderCards(
|
||||||
count: count[1],
|
count: count[1],
|
||||||
show: count[2],
|
show: count[2],
|
||||||
query: count[3],
|
query: count[3],
|
||||||
idx,
|
|
||||||
total: n,
|
total: n,
|
||||||
} as SummedDatum;
|
} satisfies SummedDatum;
|
||||||
});
|
});
|
||||||
// ensuring a non-zero range makes the percentages not break
|
// ensuring a non-zero range makes the percentages not break
|
||||||
// in an empty collection
|
// in an empty collection
|
||||||
|
@ -181,7 +180,7 @@ export function renderCards(
|
||||||
percent: `${percent}%`,
|
percent: `${percent}%`,
|
||||||
colour: barColours[idx],
|
colour: barColours[idx],
|
||||||
query: d.query,
|
query: d.query,
|
||||||
} as TableDatum)
|
} satisfies TableDatum)
|
||||||
: [];
|
: [];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ export function histogramGraph(
|
||||||
setDataAvailable(svg, true);
|
setDataAvailable(svg, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const binValue = data.binValue ?? ((bin: any): number => bin.length as number);
|
const binValue = data.binValue ?? ((bin: Bin<any, any>) => bin.length);
|
||||||
|
|
||||||
const x = data.scale.range([bounds.marginLeft, bounds.width - bounds.marginRight]);
|
const x = data.scale.range([bounds.marginLeft, bounds.width - bounds.marginRight]);
|
||||||
svg.select<SVGGElement>(".x-ticks")
|
svg.select<SVGGElement>(".x-ticks")
|
||||||
|
|
|
@ -20,7 +20,7 @@ export async function setupGraphs(
|
||||||
{
|
{
|
||||||
search = "deck:current",
|
search = "deck:current",
|
||||||
days = 365,
|
days = 365,
|
||||||
controller = null as typeof SvelteComponent<any> | null,
|
controller = null satisfies typeof SvelteComponent<any> | null,
|
||||||
} = {},
|
} = {},
|
||||||
): Promise<GraphsPage> {
|
): Promise<GraphsPage> {
|
||||||
checkNightMode();
|
checkNightMode();
|
||||||
|
|
|
@ -291,7 +291,7 @@ export function renderReviews(
|
||||||
.attr("direction", "ltr");
|
.attr("direction", "ltr");
|
||||||
|
|
||||||
svg.select("path.cumulative-overlay")
|
svg.select("path.cumulative-overlay")
|
||||||
.datum(areaData as any)
|
.datum(areaData)
|
||||||
.attr(
|
.attr(
|
||||||
"d",
|
"d",
|
||||||
area()
|
area()
|
||||||
|
|
|
@ -53,9 +53,9 @@ async function setupImageOcclusion(setupOptions?: SetupImageOcclusionOptions): P
|
||||||
/** We must make sure the image has loaded before we can access its dimensions.
|
/** We must make sure the image has loaded before we can access its dimensions.
|
||||||
* This can happen if not preloading, or if preloading takes too long. */
|
* This can happen if not preloading, or if preloading takes too long. */
|
||||||
async function waitForImage(): Promise<void> {
|
async function waitForImage(): Promise<void> {
|
||||||
const image = document.querySelector(
|
const image = document.querySelector<HTMLImageElement>(
|
||||||
"#image-occlusion-container img",
|
"#image-occlusion-container img",
|
||||||
) as HTMLImageElement | null;
|
);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
// error will be handled later
|
// error will be handled later
|
||||||
return;
|
return;
|
||||||
|
@ -116,9 +116,9 @@ function calculateContainerSize(
|
||||||
let oneTimeSetupDone = false;
|
let oneTimeSetupDone = false;
|
||||||
|
|
||||||
async function setupImageOcclusionInner(setupOptions?: SetupImageOcclusionOptions): Promise<void> {
|
async function setupImageOcclusionInner(setupOptions?: SetupImageOcclusionOptions): Promise<void> {
|
||||||
const canvas = document.querySelector(
|
const canvas = document.querySelector<HTMLCanvasElement>(
|
||||||
"#image-occlusion-canvas",
|
"#image-occlusion-canvas",
|
||||||
) as HTMLCanvasElement | null;
|
);
|
||||||
if (canvas == null) {
|
if (canvas == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -126,9 +126,9 @@ async function setupImageOcclusionInner(setupOptions?: SetupImageOcclusionOption
|
||||||
const container = document.getElementById(
|
const container = document.getElementById(
|
||||||
"image-occlusion-container",
|
"image-occlusion-container",
|
||||||
) as HTMLDivElement;
|
) as HTMLDivElement;
|
||||||
const image = document.querySelector(
|
const image = document.querySelector<HTMLImageElement>(
|
||||||
"#image-occlusion-container img",
|
"#image-occlusion-container img",
|
||||||
) as HTMLImageElement;
|
);
|
||||||
if (image == null) {
|
if (image == null) {
|
||||||
await setupI18n({
|
await setupI18n({
|
||||||
modules: [
|
modules: [
|
||||||
|
|
|
@ -60,7 +60,7 @@ export function exportShapesToClozeDeletions(occludeInactive: boolean): {
|
||||||
if (shapeOrShapes instanceof Text) {
|
if (shapeOrShapes instanceof Text) {
|
||||||
ordinal = 0;
|
ordinal = 0;
|
||||||
} else if (missingOrdinals.length > 0) {
|
} else if (missingOrdinals.length > 0) {
|
||||||
ordinal = missingOrdinals.shift() as number;
|
ordinal = missingOrdinals.shift()!;
|
||||||
} else {
|
} else {
|
||||||
ordinal = nextOrdinal;
|
ordinal = nextOrdinal;
|
||||||
nextOrdinal++;
|
nextOrdinal++;
|
||||||
|
@ -96,7 +96,7 @@ export function baseShapesFromFabric(): ShapeOrShapes[] {
|
||||||
&& (activeObject.size() > 1)
|
&& (activeObject.size() > 1)
|
||||||
? activeObject
|
? activeObject
|
||||||
: null;
|
: null;
|
||||||
const objects = canvas.getObjects() as fabric.Object[];
|
const objects = canvas.getObjects();
|
||||||
const boundingBox = getBoundingBoxSize();
|
const boundingBox = getBoundingBoxSize();
|
||||||
// filter transparent rectangles
|
// filter transparent rectangles
|
||||||
return objects
|
return objects
|
||||||
|
|
|
@ -66,7 +66,7 @@ const zoomResetInner = (canvas: fabric.Canvas): void => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const enablePinchZoom = (canvas: fabric.Canvas) => {
|
export const enablePinchZoom = (canvas: fabric.Canvas) => {
|
||||||
const hammer = new Hammer(upperCanvasElement(canvas)) as any;
|
const hammer = new Hammer(upperCanvasElement(canvas));
|
||||||
hammer.get("pinch").set({ enable: true });
|
hammer.get("pinch").set({ enable: true });
|
||||||
hammer.on("pinchin pinchout", ev => {
|
hammer.on("pinchin pinchout", ev => {
|
||||||
currentScale = Math.min(Math.max(minScale, ev.scale * zoomScale), maxScale);
|
currentScale = Math.min(Math.max(minScale, ev.scale * zoomScale), maxScale);
|
||||||
|
|
|
@ -51,7 +51,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
url: HelpPage.PackageImporting.updating,
|
url: HelpPage.PackageImporting.updating,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const helpSections = Object.values(settings) as HelpItem[];
|
const helpSections: HelpItem[] = Object.values(settings);
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let carousel: Carousel;
|
let carousel: Carousel;
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
url: HelpPage.TextImporting.html,
|
url: HelpPage.TextImporting.html,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const helpSections = Object.values(settings) as HelpItem[];
|
const helpSections: HelpItem[] = Object.values(settings);
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let carousel: Carousel;
|
let carousel: Carousel;
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
url: HelpPage.TextImporting.root,
|
url: HelpPage.TextImporting.root,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const helpSections = Object.values(settings) as HelpItem[];
|
const helpSections: HelpItem[] = Object.values(settings);
|
||||||
let modal: Modal;
|
let modal: Modal;
|
||||||
let carousel: Carousel;
|
let carousel: Carousel;
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
|
|
||||||
const importer = {
|
const importer: Importer = {
|
||||||
doImport: () => importJsonFile({ val: data.path }, {}),
|
doImport: () => importJsonFile({ val: data.path }, {}),
|
||||||
} as Importer;
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ImportPage path={data.path} {importer} />
|
<ImportPage path={data.path} {importer} />
|
||||||
|
|
Loading…
Reference in a new issue