Improved file upload
This commit is contained in:
parent
42c72b6174
commit
1ecc3e3fa4
@ -43,10 +43,10 @@ component InputSelection(id string, value string, label string, placeholder stri
|
||||
each option in options
|
||||
option(value=option.Value)= option.Label
|
||||
|
||||
component InputImage(id string, label string, endpoint string)
|
||||
component InputFileUpload(id string, label string, uploadType string, endpoint string)
|
||||
.widget-section
|
||||
label(for=id)= label + ":"
|
||||
button.action(data-action="selectFile", data-trigger="click", data-preview-image-id=id + "-preview", data-endpoint=endpoint)
|
||||
button.action(id=id, data-action="selectFile", data-trigger="click", data-endpoint=endpoint, data-type=uploadType)
|
||||
Icon("upload")
|
||||
span Select file
|
||||
|
||||
|
@ -9,7 +9,7 @@ component EditAnimeImages(anime *arn.Anime)
|
||||
Icon("picture-o")
|
||||
span Image
|
||||
|
||||
InputImage("anime-image-input", "File", "/api/upload/anime/" + anime.ID + "/image")
|
||||
InputFileUpload("anime-image-input", "File", "image", "/api/upload/anime/" + anime.ID + "/image")
|
||||
|
||||
.anime-image-container
|
||||
img#anime-image-input-preview.anime-cover-image.lazy(data-src=anime.ImageLink("large"), data-webp="true", data-color=anime.AverageColor(), alt="Anime image")
|
@ -55,7 +55,7 @@ component SettingsPersonal(user *arn.User)
|
||||
//- //- File upload
|
||||
//- if user.Settings().Avatar.Source == "FileSystem"
|
||||
|
||||
InputImage("avatar-input", "File", "/api/upload/avatar")
|
||||
InputFileUpload("avatar-input", "File", "image", "/api/upload/avatar")
|
||||
|
||||
.profile-image-container.avatar-preview
|
||||
if user.HasAvatar()
|
||||
@ -71,7 +71,7 @@ component SettingsPersonal(user *arn.User)
|
||||
Icon("picture-o")
|
||||
span Cover
|
||||
|
||||
InputImage("cover-input", "File", "/api/upload/cover")
|
||||
InputFileUpload("cover-input", "File", "image", "/api/upload/cover")
|
||||
|
||||
.cover-preview(title="Recommended: 1920 x 450 | PNG or JPG")
|
||||
img#cover-input-preview.profile-cover.lazy(data-src=user.CoverLink("small"), data-webp="true", alt="Cover image")
|
||||
|
@ -8,7 +8,7 @@ export function selectFile(arn: AnimeNotifier, button: HTMLButtonElement) {
|
||||
return
|
||||
}
|
||||
|
||||
let preview = document.getElementById(button.dataset.previewImageId) as HTMLImageElement
|
||||
let fileType = button.dataset.type
|
||||
let endpoint = button.dataset.endpoint
|
||||
|
||||
// Click on virtual file input element
|
||||
@ -22,18 +22,64 @@ export function selectFile(arn: AnimeNotifier, button: HTMLButtonElement) {
|
||||
return
|
||||
}
|
||||
|
||||
if(!file.type.startsWith("image/")) {
|
||||
// Check mime type for images
|
||||
if(fileType === "image" && !file.type.startsWith("image/")) {
|
||||
arn.statusMessage.showError(file.name + " is not an image file!")
|
||||
return
|
||||
}
|
||||
|
||||
previewImage(file, endpoint, preview)
|
||||
uploadFile(file, endpoint, arn)
|
||||
// Check mime type for videos
|
||||
if(fileType === "video" && !file.type.startsWith("video/webm")) {
|
||||
arn.statusMessage.showError(file.name + " is not a WebM video file!")
|
||||
return
|
||||
}
|
||||
|
||||
// Preview image
|
||||
if(fileType === "image") {
|
||||
let preview = document.getElementById(button.id + "-preview") as HTMLImageElement
|
||||
|
||||
if(preview) {
|
||||
previewImage(file, endpoint, preview)
|
||||
}
|
||||
}
|
||||
|
||||
uploadFile(file, fileType, endpoint, arn)
|
||||
}
|
||||
|
||||
input.click()
|
||||
}
|
||||
|
||||
// Upload file
|
||||
function uploadFile(file: File, fileType: string, endpoint: string, arn: AnimeNotifier) {
|
||||
let reader = new FileReader()
|
||||
|
||||
reader.onloadend = async () => {
|
||||
arn.statusMessage.showInfo(`Uploading ${fileType}...`, 60000)
|
||||
|
||||
let response = await fetch(endpoint, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/octet-stream"
|
||||
},
|
||||
body: reader.result
|
||||
})
|
||||
|
||||
if(endpoint === "/api/upload/avatar") {
|
||||
let newURL = await response.text()
|
||||
updateSideBarAvatar(newURL)
|
||||
}
|
||||
|
||||
if(response.ok) {
|
||||
arn.statusMessage.showInfo(`Successfully uploaded your new ${fileType}.`)
|
||||
} else {
|
||||
arn.statusMessage.showError(`Failed uploading your new ${fileType}.`)
|
||||
}
|
||||
}
|
||||
|
||||
reader.readAsArrayBuffer(file)
|
||||
}
|
||||
|
||||
// Preview image
|
||||
function previewImage(file: File, endpoint: string, preview: HTMLImageElement) {
|
||||
let reader = new FileReader()
|
||||
@ -54,37 +100,6 @@ function previewImage(file: File, endpoint: string, preview: HTMLImageElement) {
|
||||
reader.readAsDataURL(file)
|
||||
}
|
||||
|
||||
// Upload file
|
||||
function uploadFile(file: File, endpoint: string, arn: AnimeNotifier) {
|
||||
let reader = new FileReader()
|
||||
|
||||
reader.onloadend = async () => {
|
||||
arn.statusMessage.showInfo("Uploading image...", 60000)
|
||||
|
||||
let response = await fetch(endpoint, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/octet-stream"
|
||||
},
|
||||
body: reader.result
|
||||
})
|
||||
|
||||
if(endpoint === "/api/upload/avatar") {
|
||||
let newURL = await response.text()
|
||||
updateSideBarAvatar(newURL)
|
||||
}
|
||||
|
||||
if(response.ok) {
|
||||
arn.statusMessage.showInfo("Successfully uploaded your new image.")
|
||||
} else {
|
||||
arn.statusMessage.showError("Failed uploading your new image.")
|
||||
}
|
||||
}
|
||||
|
||||
reader.readAsArrayBuffer(file)
|
||||
}
|
||||
|
||||
// Update sidebar avatar
|
||||
function updateSideBarAvatar(url: string) {
|
||||
let sidebar = document.getElementById("sidebar")
|
||||
|
@ -120,7 +120,7 @@ func RenderField(b *bytes.Buffer, v *reflect.Value, field reflect.StructField, i
|
||||
// Try to infer the ID type by the field name
|
||||
if idType == "" {
|
||||
switch field.Name {
|
||||
case "AnimeID", "MainAnimeID":
|
||||
case "AnimeID":
|
||||
idType = "Anime"
|
||||
|
||||
case "CharacterID":
|
||||
@ -141,6 +141,8 @@ func RenderField(b *bytes.Buffer, v *reflect.Value, field reflect.StructField, i
|
||||
b.WriteString(components.InputSelection(idPrefix+field.Name, fieldValue.String(), field.Name, field.Tag.Get("tooltip"), values))
|
||||
} else if field.Tag.Get("type") == "textarea" {
|
||||
b.WriteString(components.InputTextArea(idPrefix+field.Name, fieldValue.String(), field.Name, field.Tag.Get("tooltip")))
|
||||
} else if field.Tag.Get("type") == "upload" {
|
||||
b.WriteString(components.InputFileUpload(idPrefix+field.Name, field.Name, field.Tag.Get("filetype"), field.Tag.Get("endpoint")))
|
||||
} else {
|
||||
b.WriteString(components.InputText(idPrefix+field.Name, fieldValue.String(), field.Name, field.Tag.Get("tooltip")))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user