forked from coracle/flotilla
Upload profile pictures instead of doing base64
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
<script lang="ts">
|
||||
import {randomId, call} from "@welshman/lib"
|
||||
import {preventDefault, stopPropagation, compressFile} from "@lib/html"
|
||||
import CloseCircle from "@assets/icons/close-circle.svg?dataurl"
|
||||
import AddCircle from "@assets/icons/add-circle.svg?dataurl"
|
||||
import GallerySend from "@assets/icons/gallery-send.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import {uploadFile} from "@app/core/commands"
|
||||
|
||||
interface Props {
|
||||
file?: File | undefined
|
||||
url?: string | undefined
|
||||
}
|
||||
|
||||
let {file = $bindable(), url = $bindable()}: Props = $props()
|
||||
|
||||
const id = randomId()
|
||||
|
||||
const onDragEnter = () => {
|
||||
active = true
|
||||
}
|
||||
|
||||
const onDragOver = () => {
|
||||
active = true
|
||||
}
|
||||
|
||||
const onDragLeave = () => {
|
||||
active = false
|
||||
}
|
||||
|
||||
const onDrop = async (e: any) => {
|
||||
active = false
|
||||
|
||||
file = await compressFile(e.dataTransfer.files[0])
|
||||
}
|
||||
|
||||
const onChange = async (e: any) => {
|
||||
file = await compressFile(e.target.files[0])
|
||||
}
|
||||
|
||||
const onClear = () => {
|
||||
initialUrl = undefined
|
||||
file = undefined
|
||||
url = undefined
|
||||
}
|
||||
|
||||
let active = $state(false)
|
||||
let initialUrl = $state(url)
|
||||
|
||||
$effect(() => {
|
||||
call(async () => {
|
||||
if (file) {
|
||||
const {result} = await uploadFile(file)
|
||||
|
||||
if (result?.url) {
|
||||
url = result.url
|
||||
} else {
|
||||
const reader = new FileReader()
|
||||
|
||||
reader.addEventListener(
|
||||
"load",
|
||||
() => {
|
||||
url = reader.result as string
|
||||
},
|
||||
false,
|
||||
)
|
||||
|
||||
reader.readAsDataURL(file)
|
||||
}
|
||||
} else {
|
||||
url = initialUrl
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<form>
|
||||
<input {id} type="file" accept="image/*" onchange={onChange} class="hidden" />
|
||||
<label
|
||||
for={id}
|
||||
aria-label="Drag and drop files here."
|
||||
style="background-image: url({url});"
|
||||
class="relative flex h-24 w-24 shrink-0 cursor-pointer items-center justify-center rounded-full border-2 border-solid border-base-content bg-base-300 bg-cover bg-center transition-all"
|
||||
class:transparent={!url}
|
||||
class:border-primary={active}
|
||||
ondragenter={stopPropagation(preventDefault(onDragEnter))}
|
||||
ondragover={stopPropagation(preventDefault(onDragOver))}
|
||||
ondragleave={stopPropagation(preventDefault(onDragLeave))}
|
||||
ondrop={stopPropagation(preventDefault(onDrop))}>
|
||||
<div
|
||||
class="absolute right-0 top-0 h-5 w-5 overflow-hidden rounded-full bg-primary"
|
||||
class:bg-error={url}
|
||||
class:bg-primary={!url}>
|
||||
{#if url}
|
||||
<span
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
onmousedown={stopPropagation(onClear)}
|
||||
ontouchstart={stopPropagation(onClear)}>
|
||||
<Icon icon={CloseCircle} class="scale-150 !bg-base-300" />
|
||||
</span>
|
||||
{:else}
|
||||
<Icon icon={AddCircle} class="scale-150 !bg-base-300" />
|
||||
{/if}
|
||||
</div>
|
||||
{#if !url}
|
||||
<Icon icon={GallerySend} size={7} />
|
||||
{/if}
|
||||
</label>
|
||||
</form>
|
||||
@@ -8,7 +8,7 @@
|
||||
import Field from "@lib/components/Field.svelte"
|
||||
import FieldInline from "@lib/components/FieldInline.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import InputProfilePicture from "@lib/components/InputProfilePicture.svelte"
|
||||
import InputProfilePicture from "@app/components/InputProfilePicture.svelte"
|
||||
import InfoHandle from "@app/components/InfoHandle.svelte"
|
||||
import {pushModal} from "@app/util/modal"
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import {preventDefault} from "@lib/html"
|
||||
import InputProfilePicture from "@lib/components/InputProfilePicture.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Field from "@lib/components/Field.svelte"
|
||||
import FireMinimalistic from "@assets/icons/fire-minimalistic.svg?dataurl"
|
||||
@@ -11,6 +10,7 @@
|
||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import InfoRelay from "@app/components/InfoRelay.svelte"
|
||||
import InputProfilePicture from "@app/components/InputProfilePicture.svelte"
|
||||
import SpaceCreateFinish from "@app/components/SpaceCreateFinish.svelte"
|
||||
import {pushModal} from "@app/util/modal"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user