refarcor create & add loading animation

This commit is contained in:
cupcakearmy 2022-07-19 10:26:51 +02:00
parent 00ea3e37da
commit 38fb64f7a1
No known key found for this signature in database
GPG Key ID: 3235314B4D31232F
4 changed files with 111 additions and 45 deletions

View File

@ -0,0 +1,47 @@
<script lang="ts">
import { t } from 'svelte-intl-precompile'
import type { Note } from '$lib/api'
import { status } from '$lib/stores/status'
import Switch from '$lib/ui/Switch.svelte'
import TextInput from '$lib/ui/TextInput.svelte'
export let note: Note
export let timeExpiration = false
</script>
<div class="fields">
<TextInput
type="number"
label={$t('common.views', { values: { n: 0 } })}
bind:value={note.views}
disabled={timeExpiration}
max={$status?.max_views}
validate={(v) =>
($status && v < $status?.max_views) ||
$t('home.errors.max', { values: { n: $status?.max_views ?? 0 } })}
/>
<div class="middle-switch">
<Switch label={$t('common.mode')} bind:value={timeExpiration} color={false} />
</div>
<TextInput
type="number"
label={$t('common.minutes', { values: { n: 0 } })}
bind:value={note.expiration}
disabled={!timeExpiration}
max={$status?.max_expiration}
validate={(v) =>
($status && v < $status?.max_expiration) ||
$t('home.errors.max', { values: { n: $status?.max_expiration ?? 0 } })}
/>
</div>
<style>
.middle-switch {
margin: 0 1rem;
}
.fields {
display: flex;
}
</style>

View File

@ -0,0 +1,41 @@
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 100 100"
xml:space="preserve"
>
<rect fill="none" stroke="currentColor" stroke-width="4" x="25" y="25" width="50" height="50">
<animateTransform
attributeName="transform"
dur="0.5s"
from="0 50 50"
to="180 50 50"
type="rotate"
id="strokeBox"
attributeType="XML"
begin="rectBox.end"
/>
</rect>
<rect x="27" y="27" fill="currentColor" width="46" height="50">
<animate
attributeName="height"
dur="1.3s"
attributeType="XML"
from="50"
to="0"
id="rectBox"
fill="freeze"
begin="0s;strokeBox.end"
/>
</rect>
</svg>
<style>
svg {
height: 2em;
position: relative;
top: 0.6em;
pointer-events: none;
}
</style>

After

Width:  |  Height:  |  Size: 784 B

View File

@ -7,13 +7,14 @@
import { create, PayloadToLargeError } from '$lib/api'
import { Crypto, Hex } from '$lib/crypto'
import { status } from '$lib/stores/status'
import AdvancedParameters from '$lib/ui/AdvancedParameters.svelte'
import Button from '$lib/ui/Button.svelte'
import FileUpload from '$lib/ui/FileUpload.svelte'
import Loader from '$lib/ui/Loader.svelte'
import MaxSize from '$lib/ui/MaxSize.svelte'
import Result, { type NoteResult } from '$lib/ui/NoteResult.svelte'
import Switch from '$lib/ui/Switch.svelte'
import TextArea from '$lib/ui/TextArea.svelte'
import TextInput from '$lib/ui/TextInput.svelte'
let note: Note = {
contents: '',
@ -27,7 +28,7 @@
let isFile = false
let timeExpiration = false
let description = ''
let loading = false
let loading: string | null = null
let error: string | null = null
$: if (!advanced) {
@ -56,7 +57,7 @@
async function submit() {
try {
error = null
loading = true
loading = $t('common.encrypting')
const password = Hex.encode(Crypto.getRandomBytes(32))
const key = await Crypto.getKeyFromString(password)
@ -75,6 +76,7 @@
if (timeExpiration) data.expiration = parseInt(note.expiration as any)
else data.views = parseInt(note.views as any)
loading = $t('common.uploading')
const response = await create(data)
result = {
password: password,
@ -90,7 +92,7 @@
error = $t('home.errors.note_error')
}
} finally {
loading = false
loading = null
}
}
</script>
@ -102,7 +104,7 @@
{@html $status?.theme_text || $t('home.intro')}
</p>
<form on:submit|preventDefault={submit}>
<fieldset disabled={loading}>
<fieldset disabled={loading !== null}>
{#if isFile}
<FileUpload label={$t('common.file')} bind:files />
{:else}
@ -129,7 +131,7 @@
<p>
<br />
{#if loading}
{$t('common.loading')}
{loading} <Loader />
{:else}
{description}
{/if}
@ -138,31 +140,7 @@
{#if advanced}
<div transition:blur={{ duration: 250 }}>
<br />
<div class="fields">
<TextInput
type="number"
label={$t('common.views', { values: { n: 0 } })}
bind:value={note.views}
disabled={timeExpiration}
max={$status?.max_views}
validate={(v) =>
($status && v < $status?.max_views) ||
$t('home.errors.max', { values: { n: $status?.max_views ?? 0 } })}
/>
<div class="middle-switch">
<Switch label={$t('common.mode')} bind:value={timeExpiration} color={false} />
</div>
<TextInput
type="number"
label={$t('common.minutes', { values: { n: 0 } })}
bind:value={note.expiration}
disabled={!timeExpiration}
max={$status?.max_expiration}
validate={(v) =>
($status && v < $status?.max_expiration) ||
$t('home.errors.max', { values: { n: $status?.max_expiration ?? 0 } })}
/>
</div>
<AdvancedParameters bind:note bind:timeExpiration />
</div>
{/if}
</fieldset>
@ -184,15 +162,7 @@
flex: 1;
}
.middle-switch {
margin: 0 1rem;
}
.error-text {
margin-top: 0.5rem;
}
.fields {
display: flex;
}
</style>

View File

@ -16,6 +16,7 @@
import { get, info } from '$lib/api'
import { Crypto } from '$lib/crypto'
import Button from '$lib/ui/Button.svelte'
import Loader from '$lib/ui/Loader.svelte'
import ShowNote, { type DecryptedNote } from '$lib/ui/ShowNote.svelte'
export let id: string
@ -24,20 +25,20 @@
let note: DecryptedNote | null = null
let exists = false
let loading = true
let loading: string | null = null
let error: string | null = null
onMount(async () => {
// Check if note exists
try {
loading = true
loading = $t('common.loading')
password = window.location.hash.slice(1)
await info(id)
exists = true
} catch {
exists = false
} finally {
loading = false
loading = null
}
})
@ -47,8 +48,9 @@
async function show() {
try {
error = null
loading = true
loading = $t('common.downloading')
const data = await get(id)
loading = $t('common.decrypting')
const key = await Crypto.getKeyFromString(password)
switch (data.meta.type) {
case 'text':
@ -70,7 +72,7 @@
} catch {
error = $t('show.errors.decryption_failed')
} finally {
loading = false
loading = null
}
}
</script>
@ -97,5 +99,11 @@
{/if}
{/if}
{#if loading}
<p>{$t('common.loading')}</p>
<p class="loader">{loading} <Loader /></p>
{/if}
<style>
.loader {
text-align: center;
}
</style>