Added cover image upload
This commit is contained in:
parent
22f3a767a8
commit
d583d9d6f9
2
images/covers/.gitignore
vendored
Normal file
2
images/covers/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
@ -30,10 +30,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)
|
||||
component InputImage(id string, label string, endpoint string)
|
||||
.widget-section
|
||||
label(for=id)= label + ":"
|
||||
button.action(data-action="selectFile", data-trigger="click", data-preview-image-id=id + "-preview")
|
||||
button.action(data-action="selectFile", data-trigger="click", data-preview-image-id=id + "-preview", data-endpoint=endpoint)
|
||||
Icon("upload")
|
||||
span Select file
|
||||
|
||||
|
@ -190,6 +190,7 @@ func Configure(app *aero.Application) {
|
||||
|
||||
// Upload
|
||||
app.Post("/api/upload/avatar", upload.Avatar)
|
||||
app.Post("/api/upload/cover", upload.Cover)
|
||||
|
||||
// Admin
|
||||
l.Page("/admin", admin.Get)
|
||||
|
@ -39,7 +39,7 @@ component ProfileHeader(viewUser *arn.User, user *arn.User, uri string)
|
||||
|
||||
component ProfileHead(viewUser *arn.User, user *arn.User, uri string)
|
||||
.profile
|
||||
img.profile-cover.lazy(data-src=viewUser.CoverImageURL(), data-webp="true", alt="Cover image")
|
||||
img.profile-cover.lazy(data-src=viewUser.CoverLink("large"), data-webp="true", alt="Cover image")
|
||||
|
||||
.profile-image-container.mountable.never-unmount
|
||||
ProfileImage(viewUser)
|
||||
|
@ -27,7 +27,7 @@ component SettingsPersonal(user *arn.User)
|
||||
|
||||
.widget.mountable(data-api="/api/settings/" + user.ID)
|
||||
h3.widget-title
|
||||
Icon("picture-o")
|
||||
Icon("camera")
|
||||
span Avatar
|
||||
|
||||
//- .widget-section
|
||||
@ -55,16 +55,26 @@ component SettingsPersonal(user *arn.User)
|
||||
//- //- File upload
|
||||
//- if user.Settings().Avatar.Source == "FileSystem"
|
||||
|
||||
InputImage("avatar-input", "File")
|
||||
InputImage("avatar-input", "File", "/api/upload/avatar")
|
||||
|
||||
.profile-image-container.avatar-preview
|
||||
if user.HasAvatar()
|
||||
img#avatar-input-preview.profile-image.mountable(src=user.AvatarLink("large"), alt="Profile image", title="Recommended: 560 x 560 | PNG or JPG")
|
||||
img#avatar-input-preview.profile-image.lazy(data-src=user.AvatarLink("large"), data-webp="true", alt="Profile image", title="Recommended: 560 x 560 | PNG or JPG")
|
||||
else
|
||||
img#avatar-input-preview.profile-image.hidden(src=user.AvatarLink("large"), alt="Profile image", title="Recommended: 560 x 560 | PNG or JPG")
|
||||
|
||||
#avatar-input-preview-svg
|
||||
SVGProfileImage(user)
|
||||
|
||||
.widget.mountable(data-api="/api/settings/" + user.ID)
|
||||
h3.widget-title
|
||||
Icon("picture-o")
|
||||
span Cover
|
||||
|
||||
InputImage("cover-input", "File", "/api/upload/cover")
|
||||
|
||||
.cover-preview
|
||||
img#cover-input-preview.profile-cover.lazy(data-src=user.CoverLink("small"), data-webp="true", alt="Cover image")
|
||||
|
||||
component SettingsNotifications(user *arn.User)
|
||||
SettingsTabs
|
||||
@ -237,13 +247,13 @@ component SettingsAccounts(user *arn.User)
|
||||
|
||||
ImportLists(user)
|
||||
|
||||
.widget.mountable
|
||||
h3.widget-title
|
||||
Icon("upload")
|
||||
span Export
|
||||
//- .widget.mountable
|
||||
//- h3.widget-title
|
||||
//- Icon("upload")
|
||||
//- span Export
|
||||
|
||||
.widget-section
|
||||
label JSON:
|
||||
a.button(href="/api/animelist/" + user.ID)
|
||||
Icon("upload")
|
||||
span Export anime list as JSON
|
||||
//- .widget-section
|
||||
//- label JSON:
|
||||
//- a.button(href="/api/animelist/" + user.ID)
|
||||
//- Icon("upload")
|
||||
//- span Export anime list as JSON
|
@ -16,6 +16,16 @@
|
||||
.avatar-preview
|
||||
margin 0 auto
|
||||
|
||||
.cover-preview
|
||||
width 100%
|
||||
height 0
|
||||
padding-top 25%
|
||||
position relative
|
||||
margin 0 auto
|
||||
|
||||
#cover-input-preview
|
||||
border-radius 3px
|
||||
|
||||
.settings-info-text
|
||||
text-align center
|
||||
font-size 0.9rem
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"github.com/animenotifier/notify.moe/utils"
|
||||
)
|
||||
|
||||
// Avatar ...
|
||||
// Avatar handles the avatar upload.
|
||||
func Avatar(ctx *aero.Context) string {
|
||||
user := utils.GetUser(ctx)
|
||||
|
||||
|
36
pages/upload/cover.go
Normal file
36
pages/upload/cover.go
Normal file
@ -0,0 +1,36 @@
|
||||
package upload
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/aerogo/aero"
|
||||
"github.com/animenotifier/notify.moe/utils"
|
||||
)
|
||||
|
||||
// Cover handles the cover image upload.
|
||||
func Cover(ctx *aero.Context) string {
|
||||
user := utils.GetUser(ctx)
|
||||
|
||||
if user == nil {
|
||||
return ctx.Error(http.StatusUnauthorized, "Not logged in", nil)
|
||||
}
|
||||
|
||||
// Retrieve file from post body
|
||||
data, err := ctx.Request().Body().Bytes()
|
||||
|
||||
if err != nil {
|
||||
return ctx.Error(http.StatusInternalServerError, "Reading request body failed", err)
|
||||
}
|
||||
|
||||
// Set cover image file
|
||||
err = user.SetCoverBytes(data)
|
||||
|
||||
if err != nil {
|
||||
return ctx.Error(http.StatusInternalServerError, "Invalid image format", err)
|
||||
}
|
||||
|
||||
// Save cover image information
|
||||
user.Save()
|
||||
|
||||
return "ok"
|
||||
}
|
@ -3,8 +3,11 @@ import { StatusMessage } from "../StatusMessage"
|
||||
|
||||
// Select file
|
||||
export function selectFile(arn: AnimeNotifier, button: HTMLButtonElement) {
|
||||
let input = document.createElement("input")
|
||||
let preview = document.getElementById(button.dataset.previewImageId) as HTMLImageElement
|
||||
let endpoint = button.dataset.endpoint
|
||||
|
||||
// Click on virtual file input element
|
||||
let input = document.createElement("input")
|
||||
input.setAttribute("type", "file")
|
||||
|
||||
input.onchange = () => {
|
||||
@ -19,22 +22,24 @@ export function selectFile(arn: AnimeNotifier, button: HTMLButtonElement) {
|
||||
return
|
||||
}
|
||||
|
||||
previewImage(file, preview)
|
||||
uploadFile(file, "/api/upload/avatar", arn)
|
||||
previewImage(file, endpoint, preview)
|
||||
uploadFile(file, endpoint, arn)
|
||||
}
|
||||
|
||||
input.click()
|
||||
}
|
||||
|
||||
// Preview image
|
||||
function previewImage(file: File, preview: HTMLImageElement) {
|
||||
function previewImage(file: File, endpoint: string, preview: HTMLImageElement) {
|
||||
let reader = new FileReader()
|
||||
|
||||
reader.onloadend = () => {
|
||||
let svgPreview = document.getElementById("avatar-input-preview-svg") as HTMLImageElement
|
||||
if(endpoint === "/api/upload/avatar") {
|
||||
let svgPreview = document.getElementById("avatar-input-preview-svg") as HTMLImageElement
|
||||
|
||||
if(svgPreview) {
|
||||
svgPreview.classList.add("hidden")
|
||||
if(svgPreview) {
|
||||
svgPreview.classList.add("hidden")
|
||||
}
|
||||
}
|
||||
|
||||
preview.classList.remove("hidden")
|
||||
@ -49,7 +54,7 @@ function uploadFile(file: File, endpoint: string, arn: AnimeNotifier) {
|
||||
let reader = new FileReader()
|
||||
|
||||
reader.onloadend = async () => {
|
||||
arn.statusMessage.showInfo("Uploading avatar...", 60000)
|
||||
arn.statusMessage.showInfo("Uploading image...", 60000)
|
||||
|
||||
let response = await fetch(endpoint, {
|
||||
method: "POST",
|
||||
@ -60,13 +65,15 @@ function uploadFile(file: File, endpoint: string, arn: AnimeNotifier) {
|
||||
body: reader.result
|
||||
})
|
||||
|
||||
let newURL = await response.text()
|
||||
updateSideBarAvatar(newURL)
|
||||
if(endpoint === "/api/upload/avatar") {
|
||||
let newURL = await response.text()
|
||||
updateSideBarAvatar(newURL)
|
||||
}
|
||||
|
||||
if(response.ok) {
|
||||
arn.statusMessage.showInfo("Successfully uploaded your new avatar.")
|
||||
arn.statusMessage.showInfo("Successfully uploaded your new image.")
|
||||
} else {
|
||||
arn.statusMessage.showError("Failed uploading your new avatar.")
|
||||
arn.statusMessage.showError("Failed uploading your new image.")
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user