add: theme settings import/export ui

This commit is contained in:
trisua 2025-04-13 01:24:16 -04:00
parent 30b23660b6
commit 85bf844e2d
3 changed files with 263 additions and 173 deletions

View file

@ -114,6 +114,8 @@ version = "1.0.0"
"settings:label.theme_hue" = "Theme hue" "settings:label.theme_hue" = "Theme hue"
"settings:label.theme_sat" = "Theme sat" "settings:label.theme_sat" = "Theme sat"
"settings:label.theme_lit" = "Theme lit" "settings:label.theme_lit" = "Theme lit"
"settings:label.import" = "Import"
"settings:label.export" = "Export"
"mod_panel:label.open_reported_content" = "Open reported content" "mod_panel:label.open_reported_content" = "Open reported content"
"mod_panel:label.manage_profile" = "Manage profile" "mod_panel:label.manage_profile" = "Manage profile"

View file

@ -34,11 +34,13 @@ profile.settings.enable_questions and user %}
<div class="card flex flex-col gap-4"> <div class="card flex flex-col gap-4">
<!-- prettier-ignore --> <!-- prettier-ignore -->
{% for post in posts %} {% for post in posts %}
{% if post[2].read_access == "Everybody" %}
{% if post[0].context.repost and post[0].context.repost.reposting %} {% if post[0].context.repost and post[0].context.repost.reposting %}
{{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true, can_manage_post=is_self) }} {{ components::repost(repost=post[3], post=post[0], owner=post[1], secondary=true, community=post[2], show_community=true, can_manage_post=is_self) }}
{% else %} {% else %}
{{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2], can_manage_post=is_self) }} {{ components::post(post=post[0], owner=post[1], question=post[4], secondary=true, community=post[2], can_manage_post=is_self) }}
{% endif %} {% endif %}
{% endif %}
{% endfor %} {% endfor %}
{{ components::pagination(page=page, items=posts|length) }} {{ components::pagination(page=page, items=posts|length) }}

View file

@ -313,6 +313,21 @@
<div class="w-full hidden flex flex-col gap-2" data-tab="theme"> <div class="w-full hidden flex flex-col gap-2" data-tab="theme">
<div class="card tertiary flex flex-col gap-2" id="theme_settings"> <div class="card tertiary flex flex-col gap-2" id="theme_settings">
<div
class="card w-full flex flex-wrap gap-2"
ui_ident="import_export"
>
<button class="primary" onclick="import_theme_settings()">
{{ icon "upload" }}
<span>{{ text "settings:label.import" }}</span>
</button>
<button class="secondary" onclick="export_theme_settings()">
{{ icon "download" }}
<span>{{ text "settings:label.export" }}</span>
</button>
</div>
<div class="card-nest" ui_ident="theme_preference"> <div class="card-nest" ui_ident="theme_preference">
<div class="card small"> <div class="card small">
<b>Theme preference</b> <b>Theme preference</b>
@ -710,6 +725,7 @@
"change_banner", "change_banner",
]); ]);
ui.refresh_container(theme_settings, [ ui.refresh_container(theme_settings, [
"import_export",
"theme_preference", "theme_preference",
"profile_theme", "profile_theme",
]); ]);
@ -773,9 +789,10 @@
settings, settings,
); );
ui.generate_settings_ui( const can_use_custom_css =
theme_settings, "{{ user.permissions|has_supporter }}" === "true";
[
const theme_settings_ui_json = [
[ [
[ [
"disable_other_themes", "disable_other_themes",
@ -945,9 +962,78 @@
description: "Hover state for secondary buttons.", description: "Hover state for secondary buttons.",
}, },
], ],
], ];
if (can_use_custom_css) {
theme_settings_ui_json.push([[], "Advanced", "title"]);
theme_settings_ui_json.push([
["theme_custom_css", "Custom CSS"],
settings.theme_custom_css,
"textarea",
{
description:
"Custom CSS input embedded into your theme.",
},
]);
}
ui.generate_settings_ui(
theme_settings,
theme_settings_ui_json,
settings, settings,
); );
globalThis.import_theme_settings = () => {
const input = document.createElement("input");
input.type = "file";
input.accept = "application/json";
document.body.appendChild(input);
input.addEventListener("change", async (e) => {
const json = JSON.parse(await e.target.files[0].text());
for (const setting of Object.entries(json)) {
settings[setting[0]] = setting[1];
}
input.remove();
save_settings();
setTimeout(() => {
window.location.reload();
}, 150);
});
input.click();
};
globalThis.export_theme_settings = () => {
const theme_settings = {
profile_theme: settings.profile_theme,
};
for (const setting of Object.entries(settings)) {
if (setting[0].startsWith("theme_")) {
theme_settings[setting[0]] = setting[1];
}
}
const blob = new Blob(
[JSON.stringify(theme_settings, null, 4)],
{
type: "appliction/json",
},
);
const url = URL.createObjectURL(blob);
const anchor = document.createElement("a");
anchor.href = url;
anchor.setAttribute("download", "theme.json");
document.body.appendChild(anchor);
anchor.click();
anchor.remove();
};
}); });
</script> </script>
</main> </main>