mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-01-03 03:18:07 -05:00
76 lines
2.0 KiB
TypeScript
76 lines
2.0 KiB
TypeScript
import { ref, uploadBytesResumable, getDownloadURL } from 'firebase/storage'
|
|
import { nanoid } from 'nanoid'
|
|
import { storage } from './init'
|
|
import Compressor from 'compressorjs'
|
|
|
|
const ONE_YEAR_SECS = 60 * 60 * 24 * 365
|
|
|
|
export const uploadImage = async (
|
|
username: string,
|
|
file: File,
|
|
prefix?: string,
|
|
onProgress?: (progress: number, isRunning: boolean) => void
|
|
) => {
|
|
// 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}${prefix ? '/' + prefix : ''}/${filename}`
|
|
)
|
|
|
|
if (file.size > 20 * 1024 ** 2) {
|
|
return Promise.reject('File is over 20 MB')
|
|
}
|
|
|
|
// if >1MB compress
|
|
if (file.size > 1024 ** 2) {
|
|
file = await new Promise((resolve, reject) => {
|
|
new Compressor(file, {
|
|
quality: 0.6,
|
|
maxHeight: 1920,
|
|
maxWidth: 1920,
|
|
convertSize: 1000000, // if result >1MB turn to jpeg
|
|
success: (file: File) => resolve(file),
|
|
error: (error) => reject(error.message),
|
|
})
|
|
})
|
|
}
|
|
|
|
const uploadTask = uploadBytesResumable(storageRef, file, {
|
|
cacheControl: `public, max-age=${ONE_YEAR_SECS}`,
|
|
})
|
|
|
|
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
|
|
}
|