feat(ui): add 'ask' type toast

This commit is contained in:
max_richter 2021-03-13 01:32:28 +01:00
parent ab894e9709
commit dd2e476065
4 changed files with 91 additions and 28 deletions

View File

@ -0,0 +1,36 @@
import Toast from "components/Toast";
import { commitStore, route } from "stores";
(async () => {
const commits = (await fetch("build/git.json").then(res => res.json())).map(c => {
c.date = Date.parse(c.date);
return c;
})
commitStore.set(commits);
let currentCommit = localStorage.getItem("currentCommit");
if (!currentCommit) currentCommit = commits[0].id;
localStorage.setItem("currentCommit", currentCommit);
let reachedCurrentCommit = false;
const newCommits = commits.filter(c => {
if (reachedCurrentCommit) return true;
if (c.id === currentCommit) {
reachedCurrentCommit = true;
}
});
if (newCommits.length > 2) {
if (window.location.hash !== "#changelog") {
if ((await Toast.ask(`There are <b>${newCommits.length}</b> updates. Do you want to see them?`, ["yes", "no"])) === "yes") {
route.set("changelog")
}
}
}
})();
export default {};

View File

@ -1,8 +1,10 @@
interface Toast { interface Toast {
type: string; type: string;
msg: string; msg: string;
time: number; duration: number;
res?: () => void; options?: string[];
rej?: () => void;
resolve?: () => void;
reject?: () => void;
} }

View File

@ -1,10 +1,13 @@
<script lang="ts"> <script lang="ts">
import { fly } from "svelte/transition"; import { fly } from "svelte/transition";
export let msg; export let msg;
//export let time; //export let duration;
export let type; export let type;
export let res; export let resolve;
export let rej;
export let options = ["okay", "nope"];
const gridCols = options.map((v) => "auto").join(" ");
</script> </script>
<div transition:fly={{ duration: 500, x: -50 }} class={`wrapper type-${type}`}> <div transition:fly={{ duration: 500, x: -50 }} class={`wrapper type-${type}`}>
@ -12,8 +15,16 @@
{#if type === "confirm"} {#if type === "confirm"}
<div class="button-wrapper"> <div class="button-wrapper">
<button on:click={res}>okay</button> <button on:click={() => resolve(true)} class="accept">okay</button>
<button on:click={rej}>nope</button> <button on:click={() => resolve(false)} class="reject">nope</button>
</div>
{/if}
{#if type === "ask"}
<div class="button-wrapper" style={`grid-template-columns: ${gridCols};`}>
{#each options as opt}
<button on:click={() => resolve(opt)}>{opt}</button>
{/each}
</div> </div>
{/if} {/if}
</div> </div>
@ -24,7 +35,8 @@
padding-top: 2.5px; padding-top: 2.5px;
margin: 5px; margin: 5px;
background-color: white; background-color: white;
z-index: 999; font-size: 1.2em;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);
} }
.wrapper.type-warn { .wrapper.type-warn {
@ -40,7 +52,7 @@
.button-wrapper { .button-wrapper {
width: 100%; width: 100%;
display: grid; display: grid;
grid-template-columns: 1fr 1fr; border-top: solid thin black;
} }
.button-wrapper > button { .button-wrapper > button {
@ -48,15 +60,20 @@
background: none; background: none;
height: 100%; height: 100%;
padding: 0px; padding: 0px;
padding: 2px 5px;
border: none; border: none;
color: black; color: black;
outline: solid thin black; border-right: solid thin black;
} }
.button-wrapper > button:first-child { .button-wrapper > button:last-child {
border: none;
}
.accept {
background-color: rgb(131, 255, 131); background-color: rgb(131, 255, 131);
} }
.button-wrapper > button:last-child { .reject {
background-color: rgb(255, 126, 126); background-color: rgb(255, 126, 126);
} }

View File

@ -1,24 +1,31 @@
import store from "./store"; import store from "./store";
function add(type, msg, duration) { interface addOptions {
type?: string,
msg?: string,
duration?: number,
options?: string[]
}
function add({ type = "info", msg = "Hey :)", duration = 3000, options = [] }: addOptions) {
let prom: Promise<boolean>; let prom: Promise<boolean | string>;
const toast: Toast = { const toast: Toast = {
type, type,
msg, msg,
time: duration options,
duration
} }
if (type === "confirm") { if (type === "confirm" || type === "ask") {
prom = new Promise((res, rej) => { prom = new Promise((resolve, rej) => {
toast.res = () => { toast.resolve = (result = true) => {
store.update(toasts => toasts.filter(t => t !== toast)); store.update(toasts => toasts.filter(t => t !== toast));
res(true); resolve(result);
}; };
toast.rej = () => { toast.reject = (result = false) => {
store.update(toasts => toasts.filter(t => t !== toast)); store.update(toasts => toasts.filter(t => t !== toast));
res(false); resolve(result);
}; };
}) })
} }
@ -27,8 +34,8 @@ function add(type, msg, duration) {
setTimeout(() => { setTimeout(() => {
store.update(toasts => toasts.filter(t => t !== toast)); store.update(toasts => toasts.filter(t => t !== toast));
if (type === "confirm") { if (type === "confirm" || type === "ask") {
toast.rej(); toast.reject();
} }
}, duration); }, duration);
@ -37,8 +44,9 @@ function add(type, msg, duration) {
} }
export default { export default {
info: msg => add("info", msg, 3000), info: msg => add({ msg }),
warn: msg => add("warn", msg, 3000), warn: msg => add({ type: "warn", msg }),
error: msg => add("error", msg, 3000), error: msg => add({ type: "error", msg }),
confirm: msg => add("confirm", msg, 10000), confirm: msg => add({ type: "confirm", msg, duration: 10000 }),
ask: (msg, options) => add({ type: "ask", msg, options, duration: 10000 })
} }