Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pylib/anki/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,18 @@
class ConfigManager:
def __init__(self, col: anki.collection.Collection):
self.col = col.weakref()
# Saved when the collection is loaded to prevent changes before restart.
Comment thread
Luc-Mcgrady marked this conversation as resolved.
self._experiments: dict[str, bool] = self.get_immutable("experimentalFeatures")

def get_immutable(self, key: str) -> Any:
try:
return from_json_bytes(self.col._backend.get_config_json(key))
except NotFoundError as exc:
raise KeyError from exc

def experiment_enabled(self, key: str) -> bool:
return self._experiments.get(key, False)

def set(self, key: str, val: Any) -> None:
self.col._backend.set_config_json_no_undo(
key=key,
Expand Down
2 changes: 2 additions & 0 deletions qt/aqt/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,8 @@ def _onsuccess(synced: bool) -> None:
onsuccess()
if not self.safeMode:
self.maybe_check_for_addon_updates(self.setup_auto_update)
if self.col.conf.experiment_enabled("ping"):
showInfo("You have the \"ping\" experiment enabled")

last_day_cutoff = self.col.sched.day_cutoff

Expand Down
3 changes: 3 additions & 0 deletions qt/aqt/mediasrv.py
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,9 @@ def save_custom_colours() -> bytes:
# DeckConfigService
"get_ignored_before_count",
"get_retention_workload",
# ConfigService
"set_config_json",
"get_config_json",
]


Expand Down
1 change: 1 addition & 0 deletions qt/aqt/webview.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ def _profileForPage(self, kind: AnkiWebViewKind) -> QWebEngineProfile:
AnkiWebViewKind.IMPORT_ANKI_PACKAGE,
AnkiWebViewKind.IMPORT_CSV,
AnkiWebViewKind.IMPORT_LOG,
AnkiWebViewKind.PREFERENCES,
)

global _profile_with_api_access, _profile_without_api_access
Expand Down
10 changes: 8 additions & 2 deletions rslib/src/backend/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,14 @@ impl From<StringKeyProto> for StringKey {

impl crate::services::ConfigService for Collection {
fn get_config_json(&mut self, input: generic::String) -> Result<generic::Json> {
let val: Option<Value> = self.get_config_optional(input.val.as_str());
val.or_not_found(input.val)
let key = input.val.as_str();
let val: Option<Value> = self.get_config_optional(key);
let default = match key {
"experimentalFeatures" => Some(serde_json::from_str("{}").unwrap()),
_ => None,
};
val.or(default)
.or_not_found(key)
.and_then(|v| serde_json::to_vec(&v).map_err(Into::into))
.map(Into::into)
}
Expand Down
1 change: 1 addition & 0 deletions ts/lib/components/Switch.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
class:nightMode={$pageTheme.isDark}
bind:checked={value}
{disabled}
on:input
/>
</div>

Expand Down
16 changes: 11 additions & 5 deletions ts/routes/preferences/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script>
<script lang="ts">
import "../deck-options/deck-options-base.scss";
import Warning from "../deck-options/Warning.svelte";
import LabItem from "./LabItem.svelte";
import type { PreferenceStore } from "$lib/sveltelib/preferences";

export let data: { labPerfs: PreferenceStore<any> };
const labPerfs = data.labPerfs;
</script>

<div class="container">
Expand All @@ -17,13 +21,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<LabItem
title="Svelte note editor"
description="Replaces the legacy editor with a new Svelte-based implementation. May affect addon compatibility."
key="svelte-editor"
{labPerfs}
></LabItem>
<LabItem title="Example 2"></LabItem>
<LabItem
title="Example 3"
description="This is a long winded description to help demonstrate the tiling of these elements. They should remain in line because I have used the css grid rather than flex boxes for easy use."
title="Ping"
description="Enable this experiment and see an alert every time you load this profile. Used for testing the experiment interface."
key="ping"
{labPerfs}
></LabItem>
<LabItem title="Example 4"></LabItem>
</div>
</div>

Expand Down
16 changes: 16 additions & 0 deletions ts/routes/preferences/+page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { autoSavingPrefs } from "$lib/sveltelib/preferences";
import type { PageLoad } from "./$types";
import { getConfigJsonObject, setConfigJsonObject } from "./json";

const CONFIG_KEY = "experimentalFeatures";

export const load = (async () => {
const labPerfs = await autoSavingPrefs(
() => getConfigJsonObject(CONFIG_KEY),
($config) => setConfigJsonObject(CONFIG_KEY, $config),
);

return { labPerfs };
}) satisfies PageLoad;
11 changes: 10 additions & 1 deletion ts/routes/preferences/LabItem.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,25 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
import Switch from "$lib/components/Switch.svelte";
import type { PreferenceStore } from "$lib/sveltelib/preferences";

export let title: string;
export let description = "";
export let key: string;
export let labPerfs: PreferenceStore<any>;
let value = $labPerfs[key];

function onInput(e: Event) {
const target = e.target as HTMLInputElement;
$labPerfs = { ...$labPerfs, [key]: target.checked };
}
</script>

<label>
<div class="header">
<b>{title}</b>
<div class="switch">
<Switch id={title} value={false}></Switch>
<Switch id={title} bind:value on:input={onInput}></Switch>
</div>
</div>
{description}
Expand Down
21 changes: 21 additions & 0 deletions ts/routes/preferences/json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { getConfigJson, setConfigJson } from "@generated/backend";

const encoder = new TextEncoder();
const decoder = new TextDecoder();

export async function getConfigJsonObject(key: string) {
const resp = await getConfigJson({ val: key });
const json_string = decoder.decode(resp.json);
if (json_string.length > 0) {
return JSON.parse(json_string);
Comment thread
Luc-Mcgrady marked this conversation as resolved.
} else {
return {};
}
}

export async function setConfigJsonObject(key: string, value: any, undoable = false) {
value = JSON.stringify(value);
return await setConfigJson({ key, valueJson: encoder.encode(value), undoable });
}