avatar uploading to storage bucket
This commit is contained in:
parent
4d86fa2256
commit
4a539e67a0
49
web/lib/firebase/storage.ts
Normal file
49
web/lib/firebase/storage.ts
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import {
|
||||||
|
getStorage,
|
||||||
|
ref,
|
||||||
|
uploadBytesResumable,
|
||||||
|
getDownloadURL,
|
||||||
|
} from 'firebase/storage'
|
||||||
|
|
||||||
|
const storage = getStorage()
|
||||||
|
|
||||||
|
export const uploadImage = async (
|
||||||
|
username: string,
|
||||||
|
file: File,
|
||||||
|
onProgress?: (progress: number, isRunning: boolean) => void
|
||||||
|
) => {
|
||||||
|
const storageRef = ref(storage, `user-images/${username}/${file.name}`)
|
||||||
|
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
|
||||||
|
}
|
|
@ -11,12 +11,14 @@ import {
|
||||||
cleanUsername,
|
cleanUsername,
|
||||||
} from '../../common/util/clean-username'
|
} from '../../common/util/clean-username'
|
||||||
import { changeUserInfo } from '../lib/firebase/api-call'
|
import { changeUserInfo } from '../lib/firebase/api-call'
|
||||||
|
import { uploadImage } from '../lib/firebase/storage'
|
||||||
|
|
||||||
export default function ProfilePage() {
|
export default function ProfilePage() {
|
||||||
const user = useUser()
|
const user = useUser()
|
||||||
const privateUser = usePrivateUser(user?.id)
|
const privateUser = usePrivateUser(user?.id)
|
||||||
|
|
||||||
const [avatarUrl, setAvatarUrl] = useState(user?.avatarUrl || '')
|
const [avatarUrl, setAvatarUrl] = useState(user?.avatarUrl || '')
|
||||||
|
const [avatarLoading, setAvatarLoading] = useState(false)
|
||||||
const [name, setName] = useState(user?.name || '')
|
const [name, setName] = useState(user?.name || '')
|
||||||
const [username, setUsername] = useState(user?.username || '')
|
const [username, setUsername] = useState(user?.username || '')
|
||||||
|
|
||||||
|
@ -59,32 +61,20 @@ export default function ProfilePage() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const [selectedFile, setSelectedFile] = useState<undefined | Blob>()
|
const fileHandler = async (event: any) => {
|
||||||
|
const file = event.target.files[0]
|
||||||
|
|
||||||
const changeHandler = (event: any) => {
|
setAvatarLoading(true)
|
||||||
setSelectedFile(event.target.files[0])
|
|
||||||
// handleSubmission()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const handleSubmission = () => {
|
await uploadImage(user?.username || 'default', file)
|
||||||
// if (!selectedFile) return
|
.then(async (url) => {
|
||||||
const formData = new FormData()
|
await changeUserInfo({ avatarUrl: url })
|
||||||
|
setAvatarUrl(url)
|
||||||
formData.append('File', event.target.files[0])
|
setAvatarLoading(false)
|
||||||
|
|
||||||
fetch(
|
|
||||||
'https://freeimage.host/api/1/upload?key=6d207e02198a847aa98d0a2a901485a5',
|
|
||||||
{
|
|
||||||
method: 'POST',
|
|
||||||
body: formData,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then((response) => response.json())
|
|
||||||
.then((result) => {
|
|
||||||
console.log('Success:', result)
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch(() => {
|
||||||
console.error('Error:', error)
|
setAvatarLoading(false)
|
||||||
|
setAvatarUrl(user?.avatarUrl || '')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,13 +84,19 @@ export default function ProfilePage() {
|
||||||
<Title text="Profile" />
|
<Title text="Profile" />
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<img
|
{avatarLoading ? (
|
||||||
src={avatarUrl}
|
<button className="btn btn-ghost btn-lg btn-circle loading"></button>
|
||||||
width={80}
|
) : (
|
||||||
height={80}
|
<>
|
||||||
className="rounded-full bg-gray-400 flex items-center justify-center"
|
<img
|
||||||
/>
|
src={avatarUrl}
|
||||||
<input type="file" name="file" onChange={changeHandler} />
|
width={80}
|
||||||
|
height={80}
|
||||||
|
className="rounded-full bg-gray-400 flex items-center justify-center"
|
||||||
|
/>
|
||||||
|
<input type="file" name="file" onChange={fileHandler} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<label className="label">
|
<label className="label">
|
||||||
|
|
Loading…
Reference in New Issue
Block a user