Achieve consistency by using a single Image type
This commit is contained in:
parent
3d526f9198
commit
dd36c852d3
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -35,6 +35,7 @@
|
|||||||
"**/*.ogg": true,
|
"**/*.ogg": true,
|
||||||
"**/*.m4a": true,
|
"**/*.m4a": true,
|
||||||
"**/*.webm": true,
|
"**/*.webm": true,
|
||||||
|
"**/*.log": true
|
||||||
},
|
},
|
||||||
"[jade]": {
|
"[jade]": {
|
||||||
"files.trimTrailingWhitespace": false
|
"files.trimTrailingWhitespace": false
|
||||||
|
@ -55,6 +55,7 @@ type User struct {
|
|||||||
IP string `json:"ip" private:"true"`
|
IP string `json:"ip" private:"true"`
|
||||||
UserAgent string `json:"agent" private:"true"`
|
UserAgent string `json:"agent" private:"true"`
|
||||||
Balance int `json:"balance" private:"true"`
|
Balance int `json:"balance" private:"true"`
|
||||||
|
Image Image `json:"image"`
|
||||||
Avatar UserAvatar `json:"avatar"`
|
Avatar UserAvatar `json:"avatar"`
|
||||||
Cover UserCover `json:"cover"`
|
Cover UserCover `json:"cover"`
|
||||||
Accounts UserAccounts `json:"accounts" private:"true"`
|
Accounts UserAccounts `json:"accounts" private:"true"`
|
||||||
@ -138,7 +139,7 @@ func RegisterUser(user *User) {
|
|||||||
|
|
||||||
if err == nil && response.StatusCode() == http.StatusOK {
|
if err == nil && response.StatusCode() == http.StatusOK {
|
||||||
data := response.Bytes()
|
data := response.Bytes()
|
||||||
err = user.SetAvatarBytes(data)
|
err = user.SetImageBytes(data)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
@ -65,8 +65,8 @@ type UserAvatar struct {
|
|||||||
LastModified int64 `json:"lastModified"`
|
LastModified int64 `json:"lastModified"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAvatarBytes accepts a byte buffer that represents an image file and updates the avatar.
|
// SetImageBytes accepts a byte buffer that represents an image file and updates the avatar.
|
||||||
func (user *User) SetAvatarBytes(data []byte) error {
|
func (user *User) SetImageBytes(data []byte) error {
|
||||||
// Decode
|
// Decode
|
||||||
img, format, err := image.Decode(bytes.NewReader(data))
|
img, format, err := image.Decode(bytes.NewReader(data))
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/akyoto/color"
|
"github.com/akyoto/color"
|
||||||
"github.com/animenotifier/notify.moe/arn"
|
|
||||||
"github.com/animenotifier/kitsu"
|
"github.com/animenotifier/kitsu"
|
||||||
|
"github.com/animenotifier/notify.moe/arn"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -27,7 +27,7 @@ func main() {
|
|||||||
Japanese: kitsuCharacter.Attributes.Names.JaJp,
|
Japanese: kitsuCharacter.Attributes.Names.JaJp,
|
||||||
Synonyms: kitsuCharacter.Attributes.OtherNames,
|
Synonyms: kitsuCharacter.Attributes.OtherNames,
|
||||||
},
|
},
|
||||||
Image: arn.CharacterImage{
|
Image: arn.Image{
|
||||||
Extension: path.Ext(kitsu.FixImageURL(kitsuCharacter.Attributes.Image.Original)),
|
Extension: path.Ext(kitsu.FixImageURL(kitsuCharacter.Attributes.Image.Original)),
|
||||||
},
|
},
|
||||||
Description: kitsuCharacter.Attributes.Description,
|
Description: kitsuCharacter.Attributes.Description,
|
||||||
|
@ -54,8 +54,8 @@ func Register(app *aero.Application) {
|
|||||||
app.Post("/api/soundtrack/:id/download", soundtrack.Download)
|
app.Post("/api/soundtrack/:id/download", soundtrack.Download)
|
||||||
|
|
||||||
// Upload
|
// Upload
|
||||||
app.Post("/api/upload/avatar", upload.Avatar)
|
app.Post("/api/upload/user/image", upload.UserImage)
|
||||||
app.Post("/api/upload/cover", upload.Cover)
|
app.Post("/api/upload/user/cover", upload.UserCover)
|
||||||
app.Post("/api/upload/anime/:id/image", upload.AnimeImage)
|
app.Post("/api/upload/anime/:id/image", upload.AnimeImage)
|
||||||
app.Post("/api/upload/character/:id/image", upload.CharacterImage)
|
app.Post("/api/upload/character/:id/image", upload.CharacterImage)
|
||||||
app.Post("/api/upload/group/:id/image", upload.GroupImage)
|
app.Post("/api/upload/group/:id/image", upload.GroupImage)
|
||||||
|
@ -49,7 +49,7 @@ component SettingsPersonal(user *arn.User)
|
|||||||
Icon("picture-o")
|
Icon("picture-o")
|
||||||
span Cover
|
span Cover
|
||||||
|
|
||||||
InputFileUpload("cover-input", "File", "image", "/api/upload/cover")
|
InputFileUpload("cover-input", "File", "image", "/api/upload/user/cover")
|
||||||
|
|
||||||
.cover-preview(title="Recommended: 1920 x 450 | PNG or JPG")
|
.cover-preview(title="Recommended: 1920 x 450 | PNG or JPG")
|
||||||
img.profile-cover.cover-input-preview.lazy(data-src=user.CoverLink("small"), data-webp="true", alt="Cover image")
|
img.profile-cover.cover-input-preview.lazy(data-src=user.CoverLink("small"), data-webp="true", alt="Cover image")
|
||||||
@ -59,7 +59,7 @@ component SettingsPersonal(user *arn.User)
|
|||||||
p PRO account required.
|
p PRO account required.
|
||||||
|
|
||||||
component AvatarInput(user *arn.User)
|
component AvatarInput(user *arn.User)
|
||||||
InputFileUpload("avatar-input", "File", "image", "/api/upload/avatar")
|
InputFileUpload("avatar-input", "File", "image", "/api/upload/user/image")
|
||||||
|
|
||||||
.profile-image-container.avatar-preview
|
.profile-image-container.avatar-preview
|
||||||
if user.HasAvatar()
|
if user.HasAvatar()
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
"github.com/animenotifier/notify.moe/utils"
|
"github.com/animenotifier/notify.moe/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Cover handles the cover image upload.
|
// UserCover handles the cover image upload.
|
||||||
func Cover(ctx aero.Context) error {
|
func UserCover(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
if user == nil {
|
if user == nil {
|
@ -7,8 +7,8 @@ import (
|
|||||||
"github.com/animenotifier/notify.moe/utils"
|
"github.com/animenotifier/notify.moe/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Avatar handles the avatar upload.
|
// UserImage handles the avatar upload.
|
||||||
func Avatar(ctx aero.Context) error {
|
func UserImage(ctx aero.Context) error {
|
||||||
user := utils.GetUser(ctx)
|
user := utils.GetUser(ctx)
|
||||||
|
|
||||||
if user == nil {
|
if user == nil {
|
||||||
@ -23,7 +23,7 @@ func Avatar(ctx aero.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set avatar file
|
// Set avatar file
|
||||||
err = user.SetAvatarBytes(data)
|
err = user.SetImageBytes(data)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx.Error(http.StatusInternalServerError, "Invalid image format", err)
|
return ctx.Error(http.StatusInternalServerError, "Invalid image format", err)
|
@ -6,7 +6,7 @@ export function selectFile(arn: AnimeNotifier, button: HTMLButtonElement) {
|
|||||||
let fileType = button.dataset.type
|
let fileType = button.dataset.type
|
||||||
let endpoint = button.dataset.endpoint
|
let endpoint = button.dataset.endpoint
|
||||||
|
|
||||||
if(endpoint === "/api/upload/cover" && arn.user && arn.user.dataset.pro !== "true") {
|
if(endpoint === "/api/upload/user/cover" && arn.user && arn.user.dataset.pro !== "true") {
|
||||||
alert("Please buy a PRO account to use this feature.")
|
alert("Please buy a PRO account to use this feature.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -47,14 +47,14 @@ export function selectFile(arn: AnimeNotifier, button: HTMLButtonElement) {
|
|||||||
let img = await loadImage(dataURL)
|
let img = await loadImage(dataURL)
|
||||||
|
|
||||||
switch(endpoint) {
|
switch(endpoint) {
|
||||||
case "/api/upload/avatar":
|
case "/api/upload/user/image":
|
||||||
if(img.naturalWidth <= 280 || img.naturalHeight < 280) {
|
if(img.naturalWidth <= 280 || img.naturalHeight < 280) {
|
||||||
arn.statusMessage.showError(`Your image has a resolution of ${img.naturalWidth} x ${img.naturalHeight} pixels which is too small. Recommended: 560 x 560. Minimum: 280 x 280.`, 8000)
|
arn.statusMessage.showError(`Your image has a resolution of ${img.naturalWidth} x ${img.naturalHeight} pixels which is too small. Recommended: 560 x 560. Minimum: 280 x 280.`, 8000)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
case "/api/upload/cover":
|
case "/api/upload/user/cover":
|
||||||
if(img.naturalWidth <= 960 || img.naturalHeight < 225) {
|
if(img.naturalWidth <= 960 || img.naturalHeight < 225) {
|
||||||
arn.statusMessage.showError(`Your image has a resolution of ${img.naturalWidth} x ${img.naturalHeight} pixels which is too small. Recommended: 1920 x 450. Minimum: 960 x 225.`, 8000)
|
arn.statusMessage.showError(`Your image has a resolution of ${img.naturalWidth} x ${img.naturalHeight} pixels which is too small. Recommended: 1920 x 450. Minimum: 960 x 225.`, 8000)
|
||||||
return
|
return
|
||||||
@ -101,7 +101,7 @@ function uploadFile(file: File, fileType: string, endpoint: string, arn: AnimeNo
|
|||||||
|
|
||||||
arn.statusMessage.showInfo(`Successfully uploaded your new ${fileType}.`)
|
arn.statusMessage.showInfo(`Successfully uploaded your new ${fileType}.`)
|
||||||
|
|
||||||
if(endpoint === "/api/upload/avatar") {
|
if(endpoint === "/api/upload/user/image") {
|
||||||
// We received the new avatar URL
|
// We received the new avatar URL
|
||||||
updateSideBarAvatar(responseText)
|
updateSideBarAvatar(responseText)
|
||||||
}
|
}
|
||||||
@ -152,7 +152,7 @@ function loadImage(url: string): Promise<HTMLImageElement> {
|
|||||||
|
|
||||||
// Preview image
|
// Preview image
|
||||||
function previewImage(dataURL: string, endpoint: string, previews: HTMLCollectionOf<Element>) {
|
function previewImage(dataURL: string, endpoint: string, previews: HTMLCollectionOf<Element>) {
|
||||||
if(endpoint === "/api/upload/avatar") {
|
if(endpoint === "/api/upload/user/image") {
|
||||||
let svgPreview = document.getElementById("avatar-input-preview-svg") as HTMLImageElement
|
let svgPreview = document.getElementById("avatar-input-preview-svg") as HTMLImageElement
|
||||||
|
|
||||||
if(svgPreview) {
|
if(svgPreview) {
|
||||||
|
@ -478,7 +478,6 @@ var routeTests = map[string][]string{
|
|||||||
"/settings/accounts": nil,
|
"/settings/accounts": nil,
|
||||||
"/settings/notifications": nil,
|
"/settings/notifications": nil,
|
||||||
"/settings/info": nil,
|
"/settings/info": nil,
|
||||||
"/settings/avatar": nil,
|
|
||||||
"/settings/style": nil,
|
"/settings/style": nil,
|
||||||
"/settings/extras": nil,
|
"/settings/extras": nil,
|
||||||
"/shop": nil,
|
"/shop": nil,
|
||||||
|
Loading…
Reference in New Issue
Block a user