Added cover image upload

This commit is contained in:
Eduard Urbach 2018-03-07 14:00:14 +01:00
parent 22f3a767a8
commit d583d9d6f9
9 changed files with 94 additions and 28 deletions

2
images/covers/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -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

View 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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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
View 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"
}

View File

@ -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.")
}
}