2022-07-14 16:44:52 +00:00
|
|
|
import { ref, uploadBytesResumable, getDownloadURL } from 'firebase/storage'
|
2022-07-16 18:37:28 +00:00
|
|
|
import { nanoid } from 'nanoid'
|
2022-07-14 16:44:52 +00:00
|
|
|
import { storage } from './init'
|
2022-02-04 03:04:56 +00:00
|
|
|
|
Rich content (#620)
* Add TipTap editor and renderer components
* Change market description editor to rich text
* Type description as JSON, fix string-based logic
- Delete make-predictions.tsx
- Delete feed logic that showed descriptions
* wip Fix API validation
* fix type error
* fix extension import (backend)
In firebase, typescript compiles imports into common js imports
like `const StarterKit = require("@tiptap/starter-kit")`
Even though StarterKit is exported from the cjs file, it gets imported
as undefined. But it magically works if we import *
If you're reading this in the future, consider replacing StarterKit with
the entire list of extensions.
* Stop load on fail create market, improve warning
* Refactor editor as hook / fix infinite submit bug
Move state of editor back up to parent
We have to do this later anyways to allow parent to edit
* Add images - display, paste + uploading
* add uploading state of image
* Fix placeholder, misc styling
min height, quote
* Fix appending to description
* code review fixes: rename, refactor, chop carets
* Add hint & upload button on new lines
- bump to Tailwind 3.1 for arbitrary variants
* clean up, run prettier
* rename FileButton to FileUploadButton
* add image extension as functions dependency
2022-07-13 18:58:22 +00:00
|
|
|
// TODO: compress large images
|
2022-02-04 03:04:56 +00:00
|
|
|
export const uploadImage = async (
|
|
|
|
username: string,
|
|
|
|
file: File,
|
|
|
|
onProgress?: (progress: number, isRunning: boolean) => void
|
|
|
|
) => {
|
2022-07-16 18:37:28 +00:00
|
|
|
// Replace filename with a nanoid to avoid collisions
|
|
|
|
const [, ext] = file.name.split('.')
|
|
|
|
const filename = `${nanoid(10)}.${ext}`
|
|
|
|
const storageRef = ref(storage, `user-images/${username}/${filename}`)
|
2022-02-04 03:04:56 +00:00
|
|
|
const uploadTask = uploadBytesResumable(storageRef, file)
|
|
|
|
|
|
|
|
let resolvePromise: (url: string) => void
|
|
|
|
let rejectPromise: (reason?: any) => void
|
|
|
|
|
|
|
|
const promise = new Promise<string>((resolve, reject) => {
|
|
|
|
resolvePromise = resolve
|
|
|
|
rejectPromise = reject
|
|
|
|
})
|
|
|
|
|
|
|
|
const unsubscribe = uploadTask.on(
|
|
|
|
'state_changed',
|
|
|
|
(snapshot) => {
|
|
|
|
const progress = snapshot.bytesTransferred / snapshot.totalBytes
|
|
|
|
const isRunning = snapshot.state === 'running'
|
|
|
|
if (onProgress) onProgress(progress, isRunning)
|
|
|
|
},
|
|
|
|
(error) => {
|
|
|
|
// A full list of error codes is available at
|
|
|
|
// https://firebase.google.com/docs/storage/web/handle-errors
|
|
|
|
rejectPromise(error)
|
|
|
|
unsubscribe()
|
|
|
|
},
|
|
|
|
() => {
|
|
|
|
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
|
|
|
|
resolvePromise(downloadURL)
|
|
|
|
})
|
|
|
|
|
|
|
|
unsubscribe()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
return await promise
|
|
|
|
}
|