Skip to content

Commit 300adb5

Browse files
committed
Configure new theme when changing theme.
1 parent 59257e2 commit 300adb5

File tree

3 files changed

+60
-14
lines changed

3 files changed

+60
-14
lines changed

admin/index.html

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,13 @@
101101
themes.sort((a, b) => a.name.localeCompare(b.name));
102102
}
103103

104-
async function saveConfig(themes, desiredThemeId) {
104+
async function getExtraConfig(themeId) {
105+
let endpoint = `${getApiBaseUrl()}/api/themes/${themeId}`;
106+
let res = await fetch(new URL(endpoint));
107+
return (await res.json())['extra_config'];
108+
}
109+
110+
async function saveConfig(themes, desiredThemeId, themeExtraConfig) {
105111
let endpoint = `${getApiBaseUrl()}/api/config`;
106112
let headers = {
107113
...{
@@ -114,7 +120,7 @@
114120
let response = await fetch(endpoint, {
115121
method: 'PUT',
116122
headers: headers,
117-
body: JSON.stringify({ theme: desiredThemeId }),
123+
body: JSON.stringify({ theme: desiredThemeId, extra_config: themeExtraConfig }),
118124
});
119125
if (response.ok) {
120126
for (let theme of themes) {
@@ -174,21 +180,36 @@ <h2 class="card-title" x-text="site.domain"></h2>
174180
</div>
175181
</template>
176182
<template x-if="host">
177-
<div class="w-full mx-auto" x-data="{themes: []}" x-init="await getConfig(themes);">
183+
<div class="w-full mx-auto" x-data="{themes: [], theme: null, themeExtraConfig: ''}"
184+
x-init="await getConfig(themes);">
178185
<div>
186+
<dialog id="themeExtraConfigModal" class="modal">
187+
<div class="modal-box">
188+
<form method="dialog">
189+
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"></button>
190+
<h3 class="text-lg font-bold">Configure theme</h3>
191+
<p class="py-4">
192+
<textarea class="textarea textarea-bordered w-full h-80" x-model="themeExtraConfig">
193+
</textarea>
194+
</p>
195+
<button class="btn btn-primary"
196+
x-on:click="await saveConfig(themes, theme.id, themeExtraConfig);">Ok</button>
197+
</form>
198+
</div>
199+
</dialog>
179200
<div class="mt-12">
180201
<div class="w-full mt-24">
181202
<div class="flex flex-wrap gap-4">
182-
<template x-for="theme in themes">
183-
<div :class="theme.selected ? 'bg-primary text-primary-content' : 'bg-neutral text-neutral-content'"
203+
<template x-for="t in themes">
204+
<div :class="t.selected ? 'bg-primary text-primary-content' : 'bg-neutral text-neutral-content'"
184205
class="card w-96 card-xs shadow-sm">
185206
<div class="card-body">
186-
<h2 class="card-title" x-text="theme.name"></h2>
187-
<p x-text="theme.description"></p>
188-
<p>License: <span x-text="theme.license"></span></p>
207+
<h2 class="card-title" x-text="t.name"></h2>
208+
<p x-text="t.description"></p>
209+
<p>License: <span x-text="t.license"></span></p>
189210
<div class="justify-end card-actions">
190-
<button :class="{'btn-primary': !theme.selected}" class="btn"
191-
x-on:click="await saveConfig(themes, theme.id);">Select</button>
211+
<button :class="{'btn-primary': !t.selected}" class="btn"
212+
x-on:click="theme = t; themeExtraConfig = await getExtraConfig(t.id); themeExtraConfigModal.showModal();">Select</button>
192213
</div>
193214
</div>
194215
</div>

src/main.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ struct PostSiteRequestBody {
9393
#[derive(Deserialize, Serialize)]
9494
struct PutSiteConfigRequestBody {
9595
theme: String,
96+
extra_config: Option<String>,
9697
}
9798

9899
#[derive(Deserialize, Serialize)]
@@ -685,10 +686,27 @@ async fn handle_put_site_config(mut request: Request<State>) -> tide::Result<Res
685686

686687
let old_theme = config.theme;
687688

689+
let body: PutSiteConfigRequestBody = request.body_json().await?;
690+
691+
config.theme = body.theme;
692+
693+
if let Some(extra_config) = body.extra_config {
694+
match toml::from_str(&extra_config) {
695+
Ok(extra_config) => {
696+
config = config.with_extra(extra_config, true);
697+
}
698+
Err(_) => {
699+
return Err(tide::Error::from_str(
700+
StatusCode::BadRequest,
701+
"Cannot parse theme config",
702+
));
703+
}
704+
};
705+
}
706+
688707
// NB: we need to load config from the file rather than using the one already loaded,
689708
// which is already merged with the theme's config! That means... we need to save it first!
690709
// TODO: How can this be improved?
691-
config.theme = request.body_json::<PutSiteConfigRequestBody>().await?.theme;
692710
site::save_config(&config_path, &config)?;
693711

694712
let Ok(themes) = request.state().themes.read() else {
@@ -1087,7 +1105,7 @@ fn validate_themes(
10871105
let mut empty_site = Site::empty(&theme_id);
10881106
match toml::from_str(&theme.extra_config) {
10891107
Ok(extra_config) => {
1090-
empty_site.config = empty_site.config.with_extra(extra_config);
1108+
empty_site.config = empty_site.config.with_extra(extra_config, false);
10911109
}
10921110
Err(e) => {
10931111
log::warn!("Failed to load theme extra config {}: {}", theme_id, e);

src/site.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,15 @@ impl SiteConfig {
9090
Self { pubkey, ..self }
9191
}
9292

93-
pub fn with_extra(mut self, extra_config: HashMap<String, toml::Value>) -> Self {
93+
pub fn with_extra(
94+
mut self,
95+
extra_config: HashMap<String, toml::Value>,
96+
overwrite: bool,
97+
) -> Self {
9498
for (k, v) in &extra_config {
99+
if overwrite && self.extra.contains_key(k) {
100+
self.extra.remove(k);
101+
}
95102
if !self.extra.contains_key(k) {
96103
self.extra.insert(k.to_string(), v.clone());
97104
}
@@ -539,7 +546,7 @@ pub fn load_site(
539546

540547
if let Some(theme) = themes.get(&config.theme) {
541548
let extra_config: HashMap<String, toml::Value> = toml::from_str(&theme.extra_config)?;
542-
config = config.with_extra(extra_config);
549+
config = config.with_extra(extra_config, false);
543550
}
544551

545552
let mut site = Site {

0 commit comments

Comments
 (0)