Added ability to upload new character images
This commit is contained in:
parent
7807aec249
commit
1f26c44a49
@ -1,9 +1,9 @@
|
||||
component Character(character *arn.Character)
|
||||
a.character(href="/character/" + character.ID)
|
||||
img.character-image.lazy(data-src=character.ImageLink("medium"), data-webp="true", data-color=character.AverageColor(), alt=character.Name.Canonical)
|
||||
img.character-image-medium.lazy(data-src=character.ImageLink("medium"), data-webp="true", data-color=character.AverageColor(), alt=character.Name.Canonical)
|
||||
.image-title
|
||||
.image-title-text= character.Name.Canonical
|
||||
|
||||
component CharacterSmall(character *arn.Character)
|
||||
a.character.tip(href="/character/" + character.ID, aria-label=character.Name.Canonical)
|
||||
img.character-image.character-image-small.lazy(data-src=character.ImageLink("small"), data-webp="true", data-color=character.AverageColor(), alt=character.Name.Canonical)
|
||||
img.character-image-small.lazy(data-src=character.ImageLink("small"), data-webp="true", data-color=character.AverageColor(), alt=character.Name.Canonical)
|
@ -12,13 +12,16 @@
|
||||
.image-title
|
||||
opacity 1
|
||||
|
||||
.character-image
|
||||
.character-image-medium
|
||||
width 112px
|
||||
height 112px
|
||||
border-radius 5%
|
||||
box-shadow shadow-medium
|
||||
object-fit cover
|
||||
width 112px
|
||||
height 112px
|
||||
|
||||
.character-image-small
|
||||
width 56px
|
||||
height 56px
|
||||
height 56px
|
||||
border-radius ui-element-border-radius
|
||||
box-shadow shadow-light
|
||||
object-fit cover
|
@ -2,6 +2,7 @@ component CharacterTabs(character *arn.Character, user *arn.User)
|
||||
.tabs
|
||||
Tab("Character", "user", character.Link())
|
||||
Tab("Edit", "pencil", character.Link() + "/edit")
|
||||
Tab("Images", "image", character.Link() + "/edit/images")
|
||||
Tab("History", "history", character.Link() + "/history")
|
||||
|
||||
component CharacterDetails(character *arn.Character, characterAnime []*arn.Anime, quotes []*arn.Quote, friends []*arn.User, mainQuote *arn.Quote, user *arn.User)
|
||||
|
@ -21,6 +21,7 @@
|
||||
.character-image-large
|
||||
width 219px
|
||||
height 344px
|
||||
object-fit cover
|
||||
border-radius ui-element-border-radius
|
||||
box-shadow shadow-light
|
||||
|
||||
|
@ -22,3 +22,16 @@ func Edit(ctx *aero.Context) string {
|
||||
|
||||
return ctx.HTML(components.CharacterTabs(character, user) + editform.Render(character, "Edit character", user))
|
||||
}
|
||||
|
||||
// EditImages renders the form to edit the character images.
|
||||
func EditImages(ctx *aero.Context) string {
|
||||
id := ctx.Get("id")
|
||||
character, err := arn.GetCharacter(id)
|
||||
user := utils.GetUser(ctx)
|
||||
|
||||
if err != nil {
|
||||
return ctx.Error(http.StatusNotFound, "Character not found", err)
|
||||
}
|
||||
|
||||
return ctx.HTML(components.EditCharacterImages(character, user))
|
||||
}
|
||||
|
21
pages/character/images.pixy
Normal file
21
pages/character/images.pixy
Normal file
@ -0,0 +1,21 @@
|
||||
component EditCharacterImages(character *arn.Character, user *arn.User)
|
||||
CharacterTabs(character, user)
|
||||
|
||||
.widget-form
|
||||
h1.mountable Edit character images
|
||||
|
||||
.widget.mountable(data-api="/api/character/" + character.ID)
|
||||
h3.widget-title
|
||||
Icon("picture-o")
|
||||
span Image
|
||||
|
||||
InputFileUpload("character-image-input", "File", "image", "/api/upload/character/" + character.ID + "/image")
|
||||
|
||||
.character-image-container.mountable
|
||||
img.character-image-input-preview.character-image-large.lazy(data-src=character.ImageLink("large"), data-webp="true", data-color=character.AverageColor(), alt="Character image")
|
||||
|
||||
.character-image-container.mountable
|
||||
img.character-image-input-preview.character-image-medium.lazy(data-src=character.ImageLink("medium"), data-webp="true", data-color=character.AverageColor(), alt="Character image")
|
||||
|
||||
.character-image-container.mountable
|
||||
img.character-image-input-preview.character-image-small.lazy(data-src=character.ImageLink("small"), data-webp="true", data-color=character.AverageColor(), alt="Character image")
|
@ -12,4 +12,4 @@ component EditAnimeImages(anime *arn.Anime)
|
||||
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")
|
||||
img.anime-image-input-preview.anime-cover-image.lazy(data-src=anime.ImageLink("large"), data-webp="true", data-color=anime.AverageColor(), alt="Anime image")
|
@ -142,6 +142,7 @@ func Configure(app *aero.Application) {
|
||||
// Characters
|
||||
l.Page("/character/:id", character.Get)
|
||||
l.Page("/character/:id/edit", character.Edit)
|
||||
l.Page("/character/:id/edit/images", character.EditImages)
|
||||
l.Page("/character/:id/history", character.History)
|
||||
|
||||
// AMVs
|
||||
@ -274,6 +275,7 @@ func Configure(app *aero.Application) {
|
||||
app.Post("/api/upload/avatar", upload.Avatar)
|
||||
app.Post("/api/upload/cover", upload.Cover)
|
||||
app.Post("/api/upload/anime/:id/image", upload.AnimeImage)
|
||||
app.Post("/api/upload/character/:id/image", upload.CharacterImage)
|
||||
app.Post("/api/upload/amv/:id/file", upload.AMVFile)
|
||||
|
||||
// Admin
|
||||
|
@ -59,9 +59,9 @@ component SettingsPersonal(user *arn.User)
|
||||
|
||||
.profile-image-container.avatar-preview
|
||||
if user.HasAvatar()
|
||||
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")
|
||||
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")
|
||||
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)
|
||||
@ -74,7 +74,7 @@ component SettingsPersonal(user *arn.User)
|
||||
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")
|
||||
img.cover-input-preview.profile-cover.lazy(data-src=user.CoverLink("small"), data-webp="true", alt="Cover image")
|
||||
|
||||
if !user.IsPro()
|
||||
.footer
|
||||
|
@ -23,7 +23,7 @@
|
||||
position relative
|
||||
margin 0 auto
|
||||
|
||||
#cover-input-preview
|
||||
.cover-input-preview
|
||||
border-radius ui-element-border-radius
|
||||
filter none
|
||||
|
||||
|
49
pages/upload/character.go
Normal file
49
pages/upload/character.go
Normal file
@ -0,0 +1,49 @@
|
||||
package upload
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/animenotifier/arn"
|
||||
|
||||
"github.com/aerogo/aero"
|
||||
"github.com/animenotifier/notify.moe/utils"
|
||||
)
|
||||
|
||||
// CharacterImage handles the character image upload.
|
||||
func CharacterImage(ctx *aero.Context) string {
|
||||
user := utils.GetUser(ctx)
|
||||
characterID := ctx.Get("id")
|
||||
|
||||
if user == nil || (user.Role != "editor" && user.Role != "admin") {
|
||||
return ctx.Error(http.StatusUnauthorized, "Not authorized", nil)
|
||||
}
|
||||
|
||||
character, err := arn.GetCharacter(characterID)
|
||||
|
||||
if err != nil {
|
||||
return ctx.Error(http.StatusNotFound, "Character not found", err)
|
||||
}
|
||||
|
||||
// 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 character image file
|
||||
err = character.SetImageBytes(data)
|
||||
|
||||
if err != nil {
|
||||
return ctx.Error(http.StatusInternalServerError, "Invalid image format", err)
|
||||
}
|
||||
|
||||
// Save image information
|
||||
character.Save()
|
||||
|
||||
// Write log entry
|
||||
logEntry := arn.NewEditLogEntry(user.ID, "edit", "Character", character.ID, "Image", "", "")
|
||||
logEntry.Save()
|
||||
|
||||
return "ok"
|
||||
}
|
@ -37,10 +37,10 @@ export function selectFile(arn: AnimeNotifier, button: HTMLButtonElement) {
|
||||
|
||||
// Preview image
|
||||
if(fileType === "image") {
|
||||
let preview = document.getElementById(button.id + "-preview") as HTMLImageElement
|
||||
let previews = document.getElementsByClassName(button.id + "-preview")
|
||||
|
||||
if(preview) {
|
||||
previewImage(file, endpoint, preview)
|
||||
for(let preview of previews) {
|
||||
previewImage(file, endpoint, previews)
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,7 +94,7 @@ function uploadFile(file: File, fileType: string, endpoint: string, arn: AnimeNo
|
||||
}
|
||||
|
||||
// Preview image
|
||||
function previewImage(file: File, endpoint: string, preview: HTMLImageElement) {
|
||||
function previewImage(file: File, endpoint: string, previews: HTMLCollectionOf<Element>) {
|
||||
let reader = new FileReader()
|
||||
|
||||
reader.onloadend = () => {
|
||||
@ -106,8 +106,11 @@ function previewImage(file: File, endpoint: string, preview: HTMLImageElement) {
|
||||
}
|
||||
}
|
||||
|
||||
preview.classList.remove("hidden")
|
||||
preview.src = reader.result
|
||||
for(let preview of previews) {
|
||||
let img = preview as HTMLImageElement
|
||||
img.classList.remove("hidden")
|
||||
img.src = reader.result
|
||||
}
|
||||
}
|
||||
|
||||
reader.readAsDataURL(file)
|
||||
|
@ -170,7 +170,7 @@ func RenderField(b *bytes.Buffer, v *reflect.Value, field reflect.StructField, i
|
||||
character, err := arn.GetCharacter(characterID)
|
||||
|
||||
if err == nil {
|
||||
b.WriteString(components.EditFormImagePreview(character.Link(), character.ImageLink("small"), false))
|
||||
b.WriteString(components.EditFormImagePreview(character.Link(), character.ImageLink("medium"), false))
|
||||
}
|
||||
|
||||
case "":
|
||||
|
Loading…
Reference in New Issue
Block a user