Improved AMV UI
This commit is contained in:
parent
1ecc3e3fa4
commit
b6321de60b
@ -1,7 +1,18 @@
|
|||||||
component AMV(amv *arn.AMV, user *arn.User)
|
component AMV(amv *arn.AMV, user *arn.User)
|
||||||
p= amv.Title.ByUser(user)
|
|
||||||
|
|
||||||
.amv.mountable
|
.amv.mountable
|
||||||
.video-container
|
.video-container
|
||||||
video.video(controls="controls", controlsList="nodownload")
|
video.video(controls="controls", controlsList="nodownload")
|
||||||
source(src="", type="video/webm")
|
source(src="/videos/amvs/" + amv.File, type="video/webm")
|
||||||
|
|
||||||
|
AMVFooter(amv, user)
|
||||||
|
|
||||||
|
component AMVFooter(amv *arn.AMV, user *arn.User)
|
||||||
|
.amv-footer
|
||||||
|
if amv.Title.ByUser(user) == ""
|
||||||
|
a(href=amv.Link() + "/edit") untitled
|
||||||
|
else
|
||||||
|
a(href=amv.Link())= amv.Title.ByUser(user)
|
||||||
|
span posted
|
||||||
|
span.utc-date(data-date=amv.Created)
|
||||||
|
span by
|
||||||
|
a(href=amv.Creator().Link())= amv.Creator().Nick + " "
|
@ -1,10 +1,30 @@
|
|||||||
component AMVPage(amv *arn.AMV, user *arn.User)
|
component AMVPage(amv *arn.AMV, user *arn.User)
|
||||||
AMVTabs(amv, user)
|
AMVTabs(amv, user)
|
||||||
|
|
||||||
if amv.Title.String() == ""
|
.amv-page
|
||||||
h1 untitled
|
if amv.Title.String() == ""
|
||||||
else
|
h1.mountable untitled
|
||||||
h1= amv.Title.ByUser(user)
|
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)
|
component AMVTabs(amv *arn.AMV, user *arn.User)
|
||||||
.tabs
|
.tabs
|
||||||
|
39
pages/amv/amv.scarlet
Normal file
39
pages/amv/amv.scarlet
Normal 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
|
@ -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
|
|
@ -67,7 +67,24 @@ func Get(ctx *aero.Context) string {
|
|||||||
})
|
})
|
||||||
|
|
||||||
sort.Slice(tracks, func(i, j int) bool {
|
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
|
// Anime list item
|
||||||
@ -107,5 +124,5 @@ func Get(ctx *aero.Context) string {
|
|||||||
|
|
||||||
ctx.Data = openGraph
|
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))
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
.anime-main-column
|
.anime-main-column
|
||||||
AnimeMainColumn(anime, listItem, tracks, episodes, user)
|
AnimeMainColumn(anime, listItem, tracks, amvs, episodes, user)
|
||||||
.anime-side-column
|
.anime-side-column
|
||||||
AnimeSideColumn(anime, friends, listItems, user)
|
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)
|
.anime-header(data-id=anime.ID)
|
||||||
a.anime-image-container.mountable(href=anime.ImageLink("original"), target="_blank")
|
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))
|
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)
|
AnimeCharacters(anime, user, false)
|
||||||
AnimeRelations(anime, user, false)
|
AnimeRelations(anime, user, false)
|
||||||
AnimeTracks(anime, tracks, user, false)
|
AnimeTracks(anime, tracks, user, false)
|
||||||
|
AnimeAMVs(anime, amvs, user)
|
||||||
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")
|
|
||||||
|
|
||||||
AnimeEpisodes(anime, episodes, user, false)
|
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)
|
component AnimeSideColumn(anime *arn.Anime, friends []*arn.User, listItems map[*arn.User]*arn.AnimeListItem, user *arn.User)
|
||||||
AnimeTrailer(anime)
|
AnimeTrailer(anime)
|
||||||
AnimeInformation(anime)
|
AnimeInformation(anime)
|
||||||
|
@ -265,6 +265,7 @@ func Configure(app *aero.Application) {
|
|||||||
app.Post("/api/upload/avatar", upload.Avatar)
|
app.Post("/api/upload/avatar", upload.Avatar)
|
||||||
app.Post("/api/upload/cover", upload.Cover)
|
app.Post("/api/upload/cover", upload.Cover)
|
||||||
app.Post("/api/upload/anime/:id/image", upload.AnimeImage)
|
app.Post("/api/upload/anime/:id/image", upload.AnimeImage)
|
||||||
|
app.Post("/api/upload/amv/:id/file", upload.AMVFile)
|
||||||
|
|
||||||
// Admin
|
// Admin
|
||||||
l.Page("/admin", admin.Get)
|
l.Page("/admin", admin.Get)
|
||||||
|
@ -115,13 +115,7 @@ animation change-color
|
|||||||
filter brightness(50%)
|
filter brightness(50%)
|
||||||
|
|
||||||
.soundtrack-footer
|
.soundtrack-footer
|
||||||
text-align center
|
media-footer
|
||||||
margin-bottom 1rem
|
|
||||||
margin-top 0.4rem
|
|
||||||
font-size 0.9em
|
|
||||||
|
|
||||||
span
|
|
||||||
opacity 0.65
|
|
||||||
|
|
||||||
.soundtrack-anime-link
|
.soundtrack-anime-link
|
||||||
display none
|
display none
|
||||||
|
49
pages/upload/amv.go
Normal file
49
pages/upload/amv.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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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"
|
||||||
|
}
|
23
profiler.go
23
profiler.go
@ -1,16 +1,21 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/pprof"
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// Uncomment these if you want to enable live profiling via /debug/pprof
|
// Uncomment these if you want to enable live profiling via /debug/pprof
|
||||||
|
|
||||||
// app.Router.HandlerFunc("GET", "/debug/pprof/", http.HandlerFunc(pprof.Index))
|
app.Router.HandlerFunc("GET", "/debug/pprof/", http.HandlerFunc(pprof.Index))
|
||||||
// app.Router.HandlerFunc("GET", "/debug/pprof/cmdline", http.HandlerFunc(pprof.Cmdline))
|
app.Router.HandlerFunc("GET", "/debug/pprof/cmdline", http.HandlerFunc(pprof.Cmdline))
|
||||||
// app.Router.HandlerFunc("GET", "/debug/pprof/profile", http.HandlerFunc(pprof.Profile))
|
app.Router.HandlerFunc("GET", "/debug/pprof/profile", http.HandlerFunc(pprof.Profile))
|
||||||
// app.Router.HandlerFunc("GET", "/debug/pprof/symbol", http.HandlerFunc(pprof.Symbol))
|
app.Router.HandlerFunc("GET", "/debug/pprof/symbol", http.HandlerFunc(pprof.Symbol))
|
||||||
// app.Router.HandlerFunc("GET", "/debug/pprof/trace", http.HandlerFunc(pprof.Trace))
|
app.Router.HandlerFunc("GET", "/debug/pprof/trace", http.HandlerFunc(pprof.Trace))
|
||||||
|
|
||||||
// app.Router.Handler("GET", "/debug/pprof/goroutine", pprof.Handler("goroutine"))
|
app.Router.Handler("GET", "/debug/pprof/goroutine", pprof.Handler("goroutine"))
|
||||||
// app.Router.Handler("GET", "/debug/pprof/heap", pprof.Handler("heap"))
|
app.Router.Handler("GET", "/debug/pprof/heap", pprof.Handler("heap"))
|
||||||
// app.Router.Handler("GET", "/debug/pprof/threadcreate", pprof.Handler("threadcreate"))
|
app.Router.Handler("GET", "/debug/pprof/threadcreate", pprof.Handler("threadcreate"))
|
||||||
// app.Router.Handler("GET", "/debug/pprof/block", pprof.Handler("block"))
|
app.Router.Handler("GET", "/debug/pprof/block", pprof.Handler("block"))
|
||||||
}
|
}
|
||||||
|
8
styles/mixins/media-footer.scarlet
Normal file
8
styles/mixins/media-footer.scarlet
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
mixin media-footer
|
||||||
|
text-align center
|
||||||
|
margin-bottom 1rem
|
||||||
|
margin-top 0.4rem
|
||||||
|
font-size 0.9em
|
||||||
|
|
||||||
|
span
|
||||||
|
opacity 0.65
|
@ -142,7 +142,11 @@ func RenderField(b *bytes.Buffer, v *reflect.Value, field reflect.StructField, i
|
|||||||
} else if field.Tag.Get("type") == "textarea" {
|
} else if field.Tag.Get("type") == "textarea" {
|
||||||
b.WriteString(components.InputTextArea(idPrefix+field.Name, fieldValue.String(), field.Name, field.Tag.Get("tooltip")))
|
b.WriteString(components.InputTextArea(idPrefix+field.Name, fieldValue.String(), field.Name, field.Tag.Get("tooltip")))
|
||||||
} else if field.Tag.Get("type") == "upload" {
|
} else if field.Tag.Get("type") == "upload" {
|
||||||
b.WriteString(components.InputFileUpload(idPrefix+field.Name, field.Name, field.Tag.Get("filetype"), field.Tag.Get("endpoint")))
|
endpoint := field.Tag.Get("endpoint")
|
||||||
|
id := v.FieldByName("ID").String()
|
||||||
|
endpoint = strings.Replace(endpoint, ":id", id, 1)
|
||||||
|
|
||||||
|
b.WriteString(components.InputFileUpload(idPrefix+field.Name, field.Name, field.Tag.Get("filetype"), endpoint))
|
||||||
} else {
|
} else {
|
||||||
b.WriteString(components.InputText(idPrefix+field.Name, fieldValue.String(), field.Name, field.Tag.Get("tooltip")))
|
b.WriteString(components.InputText(idPrefix+field.Name, fieldValue.String(), field.Name, field.Tag.Get("tooltip")))
|
||||||
}
|
}
|
||||||
|
3
videos/amvs/.gitignore
vendored
Normal file
3
videos/amvs/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*
|
||||||
|
!*/
|
||||||
|
!.gitignore
|
Loading…
Reference in New Issue
Block a user