Improved AMV UI

This commit is contained in:
2018-04-15 10:36:51 +02:00
parent 1ecc3e3fa4
commit b6321de60b
13 changed files with 190 additions and 67 deletions

View File

@ -1,10 +1,30 @@
component AMVPage(amv *arn.AMV, user *arn.User)
AMVTabs(amv, user)
if amv.Title.String() == ""
h1 untitled
else
h1= amv.Title.ByUser(user)
.amv-page
if amv.Title.String() == ""
h1.mountable untitled
else
h1.mountable= amv.Title.ByUser(user)
if amv.File != ""
AMV(amv, user)
if amv.MainAnimeID != "" || len(amv.ExtraAnimeIDs) > 0
h3.mountable Anime
if amv.MainAnimeID != ""
.amv-main-anime.mountable
AnimeGrid([]*arn.Anime{amv.MainAnime()}, user)
if len(amv.ExtraAnimeIDs) > 0
.amv-extra-anime.mountable
AnimeGridSmall(amv.ExtraAnime(), user)
component AnimeGridSmall(animes []*arn.Anime, user *arn.User)
each anime in animes
a.mountable(href=anime.Link(), title=anime.Title.ByUser(user))
img.lazy(data-src=anime.ImageLink("small"), data-webp="true", data-color=anime.AverageColor(), alt=anime.Title.ByUser(user))
component AMVTabs(amv *arn.AMV, user *arn.User)
.tabs

39
pages/amv/amv.scarlet Normal file
View File

@ -0,0 +1,39 @@
.amvs
vertical
margin-top 1rem
.amv
width 100%
margin calc(content-padding / 2)
.video-container
box-shadow shadow-medium
.amv-footer
media-footer
.amv-page
vertical
align-items center
.amv-main-anime
margin-bottom 1rem
.amv-extra-anime
horizontal-wrap
a
display block
margin 0.4rem
img
border-radius ui-element-border-radius
> 500px
.amvs
horizontal-wrap
justify-content flex-start
margin-top 0
.amv
max-width 380px

View File

@ -1,17 +0,0 @@
.amvs
vertical
margin-top 1rem
.amv
width 100%
margin calc(content-padding / 2)
box-shadow shadow-medium
> 500px
.amvs
horizontal-wrap
justify-content flex-start
margin-top 0
.amv
max-width 380px

View File

@ -67,7 +67,24 @@ func Get(ctx *aero.Context) string {
})
sort.Slice(tracks, func(i, j int) bool {
return tracks[i].Title.ByUser(user) < tracks[j].Title.ByUser(user)
if len(tracks[i].Likes) == len(tracks[j].Likes) {
return tracks[i].Title.ByUser(user) < tracks[j].Title.ByUser(user)
}
return len(tracks[i].Likes) > len(tracks[j].Likes)
})
// AMVs
amvs := arn.FilterAMVs(func(track *arn.AMV) bool {
return !track.IsDraft && track.MainAnimeID == anime.ID
})
sort.Slice(amvs, func(i, j int) bool {
if len(amvs[i].Likes) == len(amvs[j].Likes) {
return amvs[i].Title.ByUser(user) < amvs[j].Title.ByUser(user)
}
return len(amvs[i].Likes) > len(amvs[j].Likes)
})
// Anime list item
@ -107,5 +124,5 @@ func Get(ctx *aero.Context) string {
ctx.Data = openGraph
return ctx.HTML(components.Anime(anime, animeListItem, tracks, episodes, friends, friendsAnimeListItems, user))
return ctx.HTML(components.Anime(anime, animeListItem, tracks, amvs, episodes, friends, friendsAnimeListItems, user))
}

View File

@ -1,11 +1,11 @@
component Anime(anime *arn.Anime, listItem *arn.AnimeListItem, tracks []*arn.SoundTrack, episodes []*arn.AnimeEpisode, friends []*arn.User, listItems map[*arn.User]*arn.AnimeListItem, user *arn.User)
component Anime(anime *arn.Anime, listItem *arn.AnimeListItem, tracks []*arn.SoundTrack, amvs []*arn.AMV, episodes []*arn.AnimeEpisode, friends []*arn.User, listItems map[*arn.User]*arn.AnimeListItem, user *arn.User)
.anime
.anime-main-column
AnimeMainColumn(anime, listItem, tracks, episodes, user)
AnimeMainColumn(anime, listItem, tracks, amvs, episodes, user)
.anime-side-column
AnimeSideColumn(anime, friends, listItems, user)
component AnimeMainColumn(anime *arn.Anime, listItem *arn.AnimeListItem, tracks []*arn.SoundTrack, episodes []*arn.AnimeEpisode, user *arn.User)
component AnimeMainColumn(anime *arn.Anime, listItem *arn.AnimeListItem, tracks []*arn.SoundTrack, amvs []*arn.AMV, episodes []*arn.AnimeEpisode, user *arn.User)
.anime-header(data-id=anime.ID)
a.anime-image-container.mountable(href=anime.ImageLink("original"), target="_blank")
img.anime-cover-image.lazy(data-src=anime.ImageLink("large"), data-webp="true", data-color=anime.AverageColor(), alt=anime.Title.ByUser(user))
@ -28,29 +28,18 @@ component AnimeMainColumn(anime *arn.Anime, listItem *arn.AnimeListItem, tracks
AnimeCharacters(anime, user, false)
AnimeRelations(anime, user, false)
AnimeTracks(anime, tracks, user, false)
if anime.ID == "LbbCcKiig"
section.anime-section.mountable
h3.anime-section-name AMVs
.amvs
.amv.mountable
.video-container
video.video(controls="controls", controlsList="nodownload")
source(src="/videos/unchained.webm", type="video/webm")
if anime.ID == "7VjCpFiiR"
section.anime-section.mountable
h3.anime-section-name AMVs
.amvs
.amv.mountable
.video-container
video.video(controls="controls", controlsList="nodownload")
source(src="/videos/sunlight.webm", type="video/webm")
AnimeAMVs(anime, amvs, user)
AnimeEpisodes(anime, episodes, user, false)
component AnimeAMVs(anime *arn.Anime, amvs []*arn.AMV, user *arn.User)
if len(amvs) > 0
section.anime-section.mountable
h3.anime-section-name AMVs
.amvs
each amv in amvs
AMV(amv, user)
component AnimeSideColumn(anime *arn.Anime, friends []*arn.User, listItems map[*arn.User]*arn.AnimeListItem, user *arn.User)
AnimeTrailer(anime)
AnimeInformation(anime)

View File

@ -265,6 +265,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/amv/:id/file", upload.AMVFile)
// Admin
l.Page("/admin", admin.Get)

View File

@ -115,13 +115,7 @@ animation change-color
filter brightness(50%)
.soundtrack-footer
text-align center
margin-bottom 1rem
margin-top 0.4rem
font-size 0.9em
span
opacity 0.65
media-footer
.soundtrack-anime-link
display none

49
pages/upload/amv.go Normal file
View File

@ -0,0 +1,49 @@
package upload
import (
"net/http"
"github.com/animenotifier/arn"
"github.com/aerogo/aero"
"github.com/animenotifier/notify.moe/utils"
)
// AMVFile handles the video upload for AMV files.
func AMVFile(ctx *aero.Context) string {
user := utils.GetUser(ctx)
amvID := ctx.Get("id")
if user == nil {
return ctx.Error(http.StatusUnauthorized, "Not logged in", nil)
}
amv, err := arn.GetAMV(amvID)
if err != nil {
return ctx.Error(http.StatusNotFound, "AMV 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 amv image file
err = amv.SetVideoBytes(data)
if err != nil {
return ctx.Error(http.StatusInternalServerError, "Invalid video format", err)
}
// Save image information
amv.Save()
// Write log entry
logEntry := arn.NewEditLogEntry(user.ID, "edit", "AMV", amv.ID, "File", "", "")
logEntry.Save()
return "ok"
}