web: settings reset confirmation, icons for small dialog

- cleaned up dialog i18n
- better red color
- made :active state visible for dialog buttons on mobile
- better body padding in small dialog
- better small dialog typing with optional values
This commit is contained in:
wukko 2024-07-20 21:48:17 +06:00
parent def6e26b9f
commit d7bf98a80b
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2
10 changed files with 117 additions and 32 deletions

8
web/i18n/en/dialog.json Normal file
View file

@ -0,0 +1,8 @@
{
"button.gotit": "got it",
"button.cancel": "cancel",
"button.erase": "erase",
"erase.title": "erase all settings?",
"erase.body": "are you sure you want to reset all settings? this action is immediate and irreversible."
}

View file

@ -1,4 +1,3 @@
{
"cobalt": "cobalt",
"gotit": "got it"
"cobalt": "cobalt"
}

View file

@ -93,5 +93,7 @@
"advanced.debug": "debug",
"advanced.debug.title": "enable debug features",
"advanced.debug.description": "gives you access to a page with app & device info useful for debugging.",
"advanced.data": "settings data",
"advanced.reset": "erase all settings"
}

View file

@ -1,22 +1,55 @@
<script lang="ts">
import { t } from '$lib/i18n/translations';
import IconTrash from '@tabler/icons-svelte/IconTrash.svelte';
import { resetSettings } from '$lib/state/settings';
import { t } from "$lib/i18n/translations";
import { resetSettings } from "$lib/state/settings";
import IconTrash from "@tabler/icons-svelte/IconTrash.svelte";
import { createDialog } from "$lib/dialogs";
const resetDialog = () => {
createDialog({
id: "wipe-confirm",
type: "small",
icon: "warn-red",
title: $t("dialog.erase.title"),
bodyText: $t("dialog.erase.body"),
buttons: [
{
text: $t("dialog.button.cancel"),
main: false,
action: () => {},
},
{
text: $t("dialog.button.erase"),
color: "red",
main: true,
action: () => resetSettings(),
},
],
});
};
</script>
<button id="setting-button-reset" class="button" on:click={resetSettings}>
<IconTrash /> { $t('settings.advanced.reset') }
<button id="setting-button-reset" class="button" on:click={resetDialog}>
<IconTrash />
{$t("settings.advanced.reset")}
</button>
<style>
button {
#setting-button-reset {
background-color: var(--red);
color: var(--white);
width: max-content;
text-align: left;
}
button:hover {
#setting-button-reset:hover {
background-color: var(--dark-red);
}
#setting-button-reset :global(svg) {
stroke-width: 2px;
height: 24px;
width: 24px;
}
</style>

View file

@ -12,6 +12,7 @@
id={dialog.id}
title={dialog.title}
meowbalt={dialog.meowbalt}
icon={dialog.icon}
bodyText={dialog.bodyText}
bodySubText={dialog.bodySubText}
buttons={dialog.buttons}

View file

@ -2,13 +2,16 @@
import { tick } from "svelte";
import { killDialog } from "$lib/dialogs";
import type { DialogButton } from "$lib/types/dialog";
import type { DialogButton, SmallDialogIcons } from "$lib/types/dialog";
import Meowbalt from "$components/misc/Meowbalt.svelte";
import type { MeowbaltEmotions } from "$lib/types/meowbalt";
import IconAlertTriangle from "@tabler/icons-svelte/IconAlertTriangle.svelte";
export let id: string;
export let meowbalt: MeowbaltEmotions;
export let meowbalt: MeowbaltEmotions | undefined;
export let icon: SmallDialogIcons | undefined;
export let title: string = "";
export let bodyText: string = "";
export let bodySubText: string = "";
@ -45,12 +48,19 @@
<Meowbalt emotion={meowbalt} />
</div>
{/if}
{#if title}
<div class="popup-header">
<h2>{title}</h2>
</div>
{/if}
<div class="popup-body">
{#if title || icon}
<div class="popup-header">
{#if icon === "warn-red"}
<div class="popup-icon {icon}">
<IconAlertTriangle />
</div>
{/if}
{#if title}
<h2>{title}</h2>
{/if}
</div>
{/if}
{#if bodyText}
<div class="body-text" tabindex="-1">{bodyText}</div>
{/if}
@ -61,7 +71,7 @@
<div class="popup-buttons">
{#each buttons as button}
<button
class="button elevated popup-button"
class="button popup-button {button.color}"
class:active={button.main}
on:click={async () => {
await button.action();
@ -116,8 +126,15 @@
gap: var(--padding);
}
.popup-body {
gap: 8px;
}
.small-dialog {
--small-dialog-padding: 18px;
align-items: center;
text-align: center;
max-width: 340px;
width: calc(
100% - var(--padding) * 2 - var(--small-dialog-padding) * 2
@ -144,8 +161,6 @@
.small-dialog.meowbalt-visible {
padding-top: calc(var(--padding) * 4);
align-items: center;
text-align: center;
}
.meowbalt-container {
@ -153,8 +168,16 @@
top: -120px;
}
.popup-header {
.popup-header h2 {
color: var(--secondary);
font-size: 19px;
}
.popup-header .popup-icon.warn-red :global(svg) {
stroke-width: 1.5px;
height: 50px;
width: 50px;
stroke: var(--red);
}
.body-text {
@ -175,6 +198,8 @@
flex-direction: row;
width: 100%;
gap: calc(var(--padding) / 2);
overflow: scroll;
border-radius: var(--border-radius);
}
.popup-button {
@ -182,10 +207,18 @@
height: 40px;
}
.popup-button.red {
background-color: var(--red);
}
.popup-button:not(.active) {
background-color: var(--button-elevated);
}
.popup-button:not(.active):active {
background-color: var(--button-elevated-hover);
}
.popup-button:not(:focus-visible) {
box-shadow: none;
}

View file

@ -16,16 +16,16 @@
$: buttonAltText = $t('a11y.save.download');
$: isDisabled = false;
let defaultErrorPopup = {
let defaultErrorPopup: DialogInfo = {
id: "save-error",
type: "small",
meowbalt: "error",
buttons: [{
text: $t("general.gotit"),
text: $t("dialog.button.gotit"),
main: true,
action: () => {},
}]
} as DialogInfo
}
const changeDownloadButton = (state: string) => {
isDisabled = true;

View file

@ -2,17 +2,20 @@ import type { MeowbaltEmotions } from "$lib/types/meowbalt";
export type DialogButton = {
text: string,
color: "blue" | "red" | "default",
color?: "red",
main: boolean,
action: () => unknown | Promise<unknown>
}
export type SmallDialogIcons = "warn-red";
export type DialogInfo = {
id: string,
type: "small",
meowbalt: MeowbaltEmotions | "",
title: string,
bodyText: string,
bodySubText: string,
meowbalt?: MeowbaltEmotions,
icon?: SmallDialogIcons,
title?: string,
bodyText?: string,
bodySubText?: string,
buttons: DialogButton[],
}

View file

@ -60,8 +60,9 @@
--white: #ffffff;
--gray: #75757e;
--red: #f92f2f;
--dark-red: #df0707;
--red: #ed2236;
--dark-red: #d61c2e;
--green: #51cf5e;
--blue: #2f8af9;
@ -127,6 +128,7 @@
--secondary: #e1e1e1;
--gray: #818181;
--blue: #2a7ce1;
--green: #37aa42;
@ -288,6 +290,10 @@
background-color: var(--secondary);
}
:global(.button.active:active) {
background-color: var(--button-active-hover);
}
/* important is used because active class is toggled by state */
/* and added to the end of the list, taking priority */
:global(.active:focus-visible) {

View file

@ -15,6 +15,6 @@
/>
</SettingsCategory>
<SettingsCategory sectionId="settings" title={$t("tabs.settings")}>
<SettingsCategory sectionId="data" title={$t("settings.advanced.data")}>
<ResetSettingsButton />
</SettingsCategory>
</SettingsCategory>