mirror of
https://github.com/ankitects/anki.git
synced 2025-09-22 07:52:24 -04:00
Add PreferenceStore with gettable/settable preferences
* setting is not yet hooked up to rslib
This commit is contained in:
parent
665a13e378
commit
5fc8b1965a
5 changed files with 74 additions and 12 deletions
|
@ -5,7 +5,6 @@
|
||||||
import type pb from "anki/backend_proto";
|
import type pb from "anki/backend_proto";
|
||||||
import type { I18n } from "anki/i18n";
|
import type { I18n } from "anki/i18n";
|
||||||
import SeparateInactiveCheckbox from "./SeparateInactiveCheckbox.svelte";
|
import SeparateInactiveCheckbox from "./SeparateInactiveCheckbox.svelte";
|
||||||
import { cardCountsSeparateInactive } from "./preferences";
|
|
||||||
|
|
||||||
export let sourceData: pb.BackendProto.GraphsOut;
|
export let sourceData: pb.BackendProto.GraphsOut;
|
||||||
export let i18n: I18n;
|
export let i18n: I18n;
|
||||||
|
@ -18,9 +17,10 @@
|
||||||
|
|
||||||
let graphData = (null as unknown) as GraphData;
|
let graphData = (null as unknown) as GraphData;
|
||||||
let tableData = (null as unknown) as TableDatum[];
|
let tableData = (null as unknown) as TableDatum[];
|
||||||
|
let cardCountsSeparateInactive = false;
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
graphData = gatherData(sourceData, $cardCountsSeparateInactive, i18n);
|
graphData = gatherData(sourceData, cardCountsSeparateInactive, i18n);
|
||||||
tableData = renderCards(svg as any, bounds, graphData);
|
tableData = renderCards(svg as any, bounds, graphData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
<h1>{graphData.title}</h1>
|
<h1>{graphData.title}</h1>
|
||||||
|
|
||||||
<div class="range-box-inner">
|
<div class="range-box-inner">
|
||||||
<SeparateInactiveCheckbox {i18n} />
|
<SeparateInactiveCheckbox {i18n} bind:cardCountsSeparateInactive />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="counts-outer">
|
<div class="counts-outer">
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
<script lang="typescript">
|
<script lang="typescript">
|
||||||
import type { SvelteComponent } from "svelte/internal";
|
import type { SvelteComponent } from "svelte/internal";
|
||||||
import type { I18n } from "anki/i18n";
|
import type { I18n } from "anki/i18n";
|
||||||
|
import type { PreferenceStore } from "./preferences";
|
||||||
import type pb from "anki/backend_proto";
|
import type pb from "anki/backend_proto";
|
||||||
import { getGraphData, getGraphPreferences, RevlogRange } from "./graph-helpers";
|
import { getGraphData, RevlogRange } from "./graph-helpers";
|
||||||
|
import { getPreferences } from "./preferences";
|
||||||
|
|
||||||
export let i18n: I18n;
|
export let i18n: I18n;
|
||||||
export let nightMode: boolean;
|
export let nightMode: boolean;
|
||||||
|
@ -17,12 +19,18 @@
|
||||||
|
|
||||||
let active = false;
|
let active = false;
|
||||||
let sourceData: pb.BackendProto.GraphsOut | null = null;
|
let sourceData: pb.BackendProto.GraphsOut | null = null;
|
||||||
|
let preferences: PreferenceStore | null = null;
|
||||||
let revlogRange: RevlogRange;
|
let revlogRange: RevlogRange;
|
||||||
|
|
||||||
|
const preferencesPromise = getPreferences();
|
||||||
|
|
||||||
const refreshWith = async (search: string, days: number) => {
|
const refreshWith = async (search: string, days: number) => {
|
||||||
active = true;
|
active = true;
|
||||||
try {
|
try {
|
||||||
sourceData = await getGraphData(search, days);
|
[sourceData, preferences] = await Promise.all([
|
||||||
|
getGraphData(search, days),
|
||||||
|
preferencesPromise,
|
||||||
|
]);
|
||||||
revlogRange = days > 365 || days === 0 ? RevlogRange.All : RevlogRange.Year;
|
revlogRange = days > 365 || days === 0 ? RevlogRange.All : RevlogRange.Year;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
sourceData = null;
|
sourceData = null;
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<script lang="typescript">
|
<script lang="typescript">
|
||||||
import type { I18n } from "anki/i18n";
|
import type { I18n } from "anki/i18n";
|
||||||
import { cardCountsSeparateInactive } from "./preferences";
|
|
||||||
|
|
||||||
export let i18n: I18n;
|
export let i18n: I18n;
|
||||||
|
export let cardCountsSeparateInactive: boolean;
|
||||||
|
|
||||||
const label = i18n.tr(i18n.TR.STATISTICS_COUNTS_SEPARATE_SUSPENDED_BURIED_CARDS);
|
const label = i18n.tr(i18n.TR.STATISTICS_COUNTS_SEPARATE_SUSPENDED_BURIED_CARDS);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" bind:checked={$cardCountsSeparateInactive} />
|
<input type="checkbox" bind:checked={cardCountsSeparateInactive} />
|
||||||
{label}
|
{label}
|
||||||
</label>
|
</label>
|
||||||
|
|
|
@ -1,15 +1,69 @@
|
||||||
|
import { getGraphPreferences } from "./graph-helpers";
|
||||||
import { writable } from "svelte/store";
|
import { writable } from "svelte/store";
|
||||||
|
import type pb from "anki/backend_proto";
|
||||||
|
|
||||||
function createPreference(initialValue: unknown) {
|
interface CustomStore<T> {
|
||||||
|
subscribe: (getter: (value: T) => void) => () => void;
|
||||||
|
set: (value: T) => void;
|
||||||
|
get: () => T;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PreferenceStore = {
|
||||||
|
[K in keyof pb.BackendProto.GraphsPreferencesOut]: CustomStore<
|
||||||
|
pb.BackendProto.GraphsPreferencesOut[K]
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
|
function createPreference<T>(
|
||||||
|
initialValue: T,
|
||||||
|
savePreferences: () => void
|
||||||
|
): CustomStore<T> {
|
||||||
const { subscribe, set } = writable(initialValue);
|
const { subscribe, set } = writable(initialValue);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
subscribe,
|
subscribe,
|
||||||
set: (v: unknown) => {
|
set: (v: T): void => {
|
||||||
set(v);
|
set(v);
|
||||||
|
savePreferences();
|
||||||
|
},
|
||||||
|
get: (): T => {
|
||||||
|
let result: any /* T */;
|
||||||
|
subscribe((value: T) => (result = value))();
|
||||||
|
return result;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const calendarFirstDayOfWeek = createPreference(0);
|
function preparePreferences(
|
||||||
export const cardCountsSeparateInactive = createPreference(false);
|
graphsPreferences: pb.BackendProto.GraphsPreferencesOut,
|
||||||
|
save: (prefs: pb.BackendProto.GraphsPreferencesOut) => void
|
||||||
|
): PreferenceStore {
|
||||||
|
const preferences: Partial<PreferenceStore> = {};
|
||||||
|
|
||||||
|
function constructPreferences(): pb.BackendProto.GraphsPreferencesOut {
|
||||||
|
const payload: Partial<pb.BackendProto.GraphsPreferencesOut> = {};
|
||||||
|
for (const [key, pref] of Object.entries(preferences as PreferenceStore)) {
|
||||||
|
payload[key] = pref.get();
|
||||||
|
}
|
||||||
|
return payload as pb.BackendProto.GraphsPreferencesOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
function savePreferences(): void {
|
||||||
|
const preferences = constructPreferences();
|
||||||
|
save(preferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(graphsPreferences)) {
|
||||||
|
preferences[key] = createPreference(value, savePreferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
return preferences as PreferenceStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getPreferences() {
|
||||||
|
const initialPreferences = await getGraphPreferences();
|
||||||
|
|
||||||
|
return preparePreferences(initialPreferences, (prefs) => {
|
||||||
|
console.log("preferences to save", prefs);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"module": "es6",
|
"module": "es6",
|
||||||
"lib": ["es2016", "es2019.array", "dom", "dom.iterable"],
|
"lib": ["es2017", "es2019.array", "dom", "dom.iterable"],
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"anki/*": ["../bazel-bin/ts/lib/*"]
|
"anki/*": ["../bazel-bin/ts/lib/*"]
|
||||||
|
|
Loading…
Reference in a new issue