cryptgeon/frontend/src/lib/views/Create.svelte

187 lines
4.0 KiB
Svelte
Raw Normal View History

2021-05-02 03:08:30 +02:00
<script lang="ts">
2021-12-22 13:10:08 +01:00
import { create, Note, PayloadToLargeError } from '$lib/api'
import { encrypt, getKeyFromString, getRandomBytes, Hex } from '$lib/crypto'
2021-05-02 12:31:32 +02:00
import Button from '$lib/ui/Button.svelte'
2021-12-21 00:15:04 +01:00
import FileUpload from '$lib/ui/FileUpload.svelte'
2021-12-22 13:10:08 +01:00
import MaxSize from '$lib/ui/MaxSize.svelte'
2021-05-02 12:31:32 +02:00
import Switch from '$lib/ui/Switch.svelte'
import TextArea from '$lib/ui/TextArea.svelte'
import TextInput from '$lib/ui/TextInput.svelte'
2021-12-22 13:10:08 +01:00
import { blur } from 'svelte/transition'
2022-01-16 14:02:53 +01:00
import { t } from 'svelte-intl-precompile'
2021-05-02 03:08:30 +02:00
let note: Note = {
2021-05-02 14:02:40 +02:00
contents: '',
2021-12-21 00:15:04 +01:00
meta: { type: 'text' },
2021-05-02 03:08:30 +02:00
views: 1,
expiration: 60,
}
let result: { password: string; id: string } | null = null
let advanced = false
2021-12-21 00:15:04 +01:00
let file = false
2022-01-16 14:02:53 +01:00
let timeExpiration = false
2021-05-02 03:08:30 +02:00
let message = ''
2021-05-02 14:41:08 +02:00
let loading = false
let error: string | null = null
2021-05-02 03:08:30 +02:00
$: if (!advanced) {
note.views = 1
2022-01-16 14:02:53 +01:00
timeExpiration = false
2021-05-02 03:08:30 +02:00
}
$: {
2022-01-16 14:02:53 +01:00
message = $t('home.explanation', {
values: {
type: $t(timeExpiration ? 'common.minutes' : 'common.views', {
values: { n: timeExpiration ? note.expiration : note.views },
}),
},
})
2021-05-02 03:08:30 +02:00
}
2021-12-21 00:15:04 +01:00
$: note.meta.type = file ? 'file' : 'text'
2021-12-22 13:10:08 +01:00
$: if (!file) {
note.contents = ''
}
2021-05-02 03:08:30 +02:00
async function submit() {
try {
2021-05-02 14:41:08 +02:00
error = null
2021-05-02 03:08:30 +02:00
loading = true
2021-05-03 12:21:51 +02:00
const password = Hex.encode(getRandomBytes(32))
const key = await getKeyFromString(password)
2021-05-02 03:08:30 +02:00
const data: Note = {
2021-05-03 12:21:51 +02:00
contents: await encrypt(note.contents, key),
2021-12-21 00:15:04 +01:00
meta: note.meta,
2021-05-02 03:08:30 +02:00
}
2022-01-16 14:02:53 +01:00
if (timeExpiration) data.expiration = parseInt(note.expiration as any)
else data.views = parseInt(note.views as any)
2021-05-02 03:08:30 +02:00
const response = await create(data)
result = {
password: password,
id: response.id,
}
2021-05-10 09:58:13 +02:00
} catch (e) {
2021-12-20 18:22:10 +01:00
if (e instanceof PayloadToLargeError) {
2022-01-16 14:02:53 +01:00
error = $t('home.errors.note_to_big')
2021-12-20 18:22:10 +01:00
} else {
2022-01-16 14:02:53 +01:00
error = $t('home.errors.note_error')
2021-12-20 18:22:10 +01:00
}
2021-05-02 03:08:30 +02:00
} finally {
loading = false
}
}
function reset() {
window.location.reload()
}
</script>
{#if result}
2021-05-03 12:21:51 +02:00
<TextInput
type="text"
readonly
2022-01-16 14:02:53 +01:00
label={$t('common.share_link')}
2021-05-16 11:16:25 +02:00
value="{window.location.origin}/note/{result.id}#{result.password}"
2021-05-03 12:21:51 +02:00
copy
/>
2021-05-02 03:08:30 +02:00
<br />
2021-05-08 21:46:33 +02:00
<p>
2022-01-16 14:02:53 +01:00
{@html $t('home.new_note_notice')}
2021-05-08 21:46:33 +02:00
</p>
<br />
2022-01-16 14:02:53 +01:00
<Button on:click={reset}>{$t('home.new_note')}</Button>
2021-05-02 03:08:30 +02:00
{:else}
2021-12-30 22:36:28 +01:00
<p>
2022-01-16 14:02:53 +01:00
{@html $t('home.intro')}
2021-12-30 22:36:28 +01:00
</p>
2021-05-02 03:08:30 +02:00
<form on:submit|preventDefault={submit}>
<fieldset disabled={loading}>
2021-12-21 00:15:04 +01:00
{#if file}
2022-01-16 14:02:53 +01:00
<FileUpload label={$t('common.file')} on:file={(f) => (note.contents = f.detail)} />
2021-12-21 00:15:04 +01:00
{:else}
2022-01-16 14:02:53 +01:00
<TextArea label={$t('common.note')} bind:value={note.contents} placeholder="..." />
2021-12-21 00:15:04 +01:00
{/if}
2021-05-02 03:08:30 +02:00
<div class="bottom">
2022-01-16 14:02:53 +01:00
<Switch class="file" label={$t('common.file')} bind:value={file} />
<Switch label={$t('common.advanced')} bind:value={advanced} />
2021-12-21 00:15:04 +01:00
<div class="grow" />
2021-12-22 13:10:08 +01:00
<div class="tr">
2022-01-16 14:02:53 +01:00
<small>{$t('common.max')}: <MaxSize /> </small>
2021-12-22 13:10:08 +01:00
<br />
2022-01-16 14:02:53 +01:00
<Button type="submit">{$t('common.create')}</Button>
2021-12-22 13:10:08 +01:00
</div>
2021-05-02 03:08:30 +02:00
</div>
2021-05-02 14:41:08 +02:00
{#if error}
<div class="error-text">{error}</div>
{/if}
2021-05-08 21:46:33 +02:00
<p>
<br />
{#if loading}
2022-01-16 14:02:53 +01:00
{$t('common.loading')}
2021-05-08 21:46:33 +02:00
{:else}
{message}
{/if}
</p>
2021-05-02 03:08:30 +02:00
2021-12-22 13:10:08 +01:00
{#if advanced}
<div transition:blur={{ duration: 250 }}>
<br />
<div class="fields">
<TextInput
type="number"
2022-01-16 14:02:53 +01:00
label={$t('common.views', { values: { n: 0 } })}
2021-12-22 13:10:08 +01:00
bind:value={note.views}
2022-01-16 14:02:53 +01:00
disabled={timeExpiration}
2021-12-22 13:10:08 +01:00
max={100}
/>
<div class="middle-switch">
2022-01-16 14:02:53 +01:00
<Switch label={$t('common.mode')} bind:value={timeExpiration} color={false} />
2021-12-22 13:10:08 +01:00
</div>
<TextInput
type="number"
2022-01-16 14:02:53 +01:00
label={$t('common.minutes', { values: { n: 0 } })}
2021-12-22 13:10:08 +01:00
bind:value={note.expiration}
2022-01-16 14:02:53 +01:00
disabled={!timeExpiration}
2021-12-22 13:10:08 +01:00
max={360}
/>
2021-05-02 03:08:30 +02:00
</div>
</div>
2021-12-22 13:10:08 +01:00
{/if}
2021-05-02 03:08:30 +02:00
</fieldset>
</form>
{/if}
<style>
.bottom {
display: flex;
align-items: flex-end;
margin-top: 0.5rem;
}
2021-12-21 00:15:04 +01:00
.bottom :global(.file) {
margin-right: 0.5rem;
}
.grow {
flex: 1;
}
2021-05-02 03:08:30 +02:00
.middle-switch {
margin: 0 1rem;
}
2021-12-20 18:22:10 +01:00
.error-text {
margin-top: 0.5rem;
}
2021-12-22 13:10:08 +01:00
.fields {
display: flex;
}
2021-05-02 03:08:30 +02:00
</style>