Improved soundtracks

This commit is contained in:
Eduard Urbach 2017-10-15 20:19:45 +02:00
parent c0b28c9b0a
commit d1c26252ac
11 changed files with 60 additions and 26 deletions

View File

@ -182,7 +182,7 @@ func configure(app *aero.Application) *aero.Application {
middleware.Firewall(), middleware.Firewall(),
middleware.Log(), middleware.Log(),
middleware.Session(), middleware.Session(),
middleware.UserInfo() middleware.UserInfo(),
) )
// API // API

View File

@ -18,7 +18,7 @@ component InputSelection(id string, value string, label string, placeholder stri
label(for=id)= label + ":" label(for=id)= label + ":"
select.widget-ui-element.action(id=id, data-field=id, value=value, title=placeholder, data-action="save", data-trigger="change") select.widget-ui-element.action(id=id, data-field=id, value=value, title=placeholder, data-action="save", data-trigger="change")
component InputTags(id string, value []string, label string) component InputTags(id string, value []string, label string, tooltip string)
.widget-section .widget-section
label(for=id)= label + ":" label(for=id)= label + ":"
.tags(id=id) .tags(id=id)
@ -31,3 +31,5 @@ component InputTags(id string, value []string, label string)
button.tag-add.action(data-action="arrayAppend", data-trigger="click", data-field=id) button.tag-add.action(data-action="arrayAppend", data-trigger="click", data-field=id)
RawIcon("plus") RawIcon("plus")
p!= tooltip

View File

@ -23,7 +23,9 @@ func Get(ctx *aero.Context) string {
return ctx.Error(http.StatusNotFound, "Anime not found", err) return ctx.Error(http.StatusNotFound, "Anime not found", err)
} }
tracks, err := arn.GetSoundTracksByTag("anime:" + anime.ID) tracks, err := arn.FilterSoundTracks(func(track *arn.SoundTrack) bool {
return !track.IsDraft && len(track.Media) > 0 && arn.Contains(track.Tags, "anime:"+anime.ID)
})
if err != nil { if err != nil {
return ctx.Error(http.StatusNotFound, "Error fetching soundtracks", err) return ctx.Error(http.StatusNotFound, "Error fetching soundtracks", err)

View File

@ -19,7 +19,9 @@ func GetSoundTracksByUser(ctx *aero.Context) string {
return ctx.Error(http.StatusNotFound, "User not found", err) return ctx.Error(http.StatusNotFound, "User not found", err)
} }
tracks, err := arn.GetSoundTracksByUser(viewUser) tracks, err := arn.FilterSoundTracks(func(track *arn.SoundTrack) bool {
return !track.IsDraft && len(track.Media) > 0 && track.CreatedBy == viewUser.ID
})
if err != nil { if err != nil {
return ctx.Error(http.StatusInternalServerError, "Error fetching soundtracks", err) return ctx.Error(http.StatusInternalServerError, "Error fetching soundtracks", err)

View File

@ -89,7 +89,15 @@ func RenderField(b *bytes.Buffer, v *reflect.Value, field reflect.StructField, i
case "string": case "string":
b.WriteString(components.InputText(idPrefix+field.Name, fieldValue.String(), field.Name, "")) b.WriteString(components.InputText(idPrefix+field.Name, fieldValue.String(), field.Name, ""))
case "[]string": case "[]string":
b.WriteString(components.InputTags(idPrefix+field.Name, fieldValue.Interface().([]string), field.Name)) b.WriteString(components.InputTags(idPrefix+field.Name, fieldValue.Interface().([]string), field.Name, field.Tag.Get("tooltip")))
case "bool":
if field.Name == "IsDraft" {
if fieldValue.Bool() {
b.WriteString(`<div class="buttons"><button class="action" data-action="publish" data-trigger="click">` + utils.Icon("unlock-alt") + `Publish</button></div>`)
} else {
b.WriteString(`<div class="buttons"><button class="action" data-action="unpublish" data-trigger="click">` + utils.Icon("lock") + `Unpublish</button></div>`)
}
}
case "[]*arn.ExternalMedia": case "[]*arn.ExternalMedia":
for sliceIndex := 0; sliceIndex < fieldValue.Len(); sliceIndex++ { for sliceIndex := 0; sliceIndex < fieldValue.Len(); sliceIndex++ {
b.WriteString(`<div class="widget-section">`) b.WriteString(`<div class="widget-section">`)

View File

@ -20,12 +20,15 @@ func Get(ctx *aero.Context) string {
ctx.Data = &arn.OpenGraph{ ctx.Data = &arn.OpenGraph{
Tags: map[string]string{ Tags: map[string]string{
"og:title": track.Title, "og:title": track.Title,
"og:image": track.MainAnime().Image.Large,
"og:url": "https://" + ctx.App.Config.Domain + track.Link(), "og:url": "https://" + ctx.App.Config.Domain + track.Link(),
"og:site_name": "notify.moe", "og:site_name": "notify.moe",
"og:type": "music.song", "og:type": "music.song",
}, },
} }
if track.MainAnime() != nil {
ctx.Data.(*arn.OpenGraph).Tags["og:image"] = track.MainAnime().Image.Large
}
return ctx.HTML(components.Track(track)) return ctx.HTML(components.Track(track))
} }

View File

@ -14,6 +14,12 @@ component Track(track *arn.SoundTrack)
.sound-track-media .sound-track-media
ExternalMedia(media) ExternalMedia(media)
.widget.mountable
h3.widget-title Tags
ul
each tag in track.Tags
li= tag
.footer.text-center.mountable .footer.text-center.mountable
if track.EditedBy != "" if track.EditedBy != ""
span Edited span Edited

View File

@ -13,7 +13,7 @@ const maxTracks = 9
// Get renders the soundtracks page. // Get renders the soundtracks page.
func Get(ctx *aero.Context) string { func Get(ctx *aero.Context) string {
tracks, err := arn.FilterSoundTracks(func(track *arn.SoundTrack) bool { tracks, err := arn.FilterSoundTracks(func(track *arn.SoundTrack) bool {
return !track.IsDraft return !track.IsDraft && len(track.Media) > 0
}) })
if err != nil { if err != nil {

View File

@ -2,7 +2,7 @@ component SoundTracks(tracks []*arn.SoundTrack)
h1 Soundtracks h1 Soundtracks
.music-buttons .music-buttons
a.button.ajax(href="/new/soundtrack") a.button.action(data-action="newSoundTrack", data-trigger="click")
Icon("plus") Icon("plus")
span Add soundtrack span Add soundtrack

View File

@ -195,21 +195,29 @@ export function createThread(arn: AnimeNotifier) {
.catch(err => arn.statusMessage.showError(err)) .catch(err => arn.statusMessage.showError(err))
} }
// Create soundtrack // New soundtrack
export function createSoundTrack(arn: AnimeNotifier, button: HTMLButtonElement) { export function newSoundTrack(arn: AnimeNotifier, button: HTMLButtonElement) {
let soundcloud = arn.app.find("soundcloud-link") as HTMLInputElement arn.post("/api/new/soundtrack", "")
let youtube = arn.app.find("youtube-link") as HTMLInputElement .then(response => response.json())
let anime = arn.app.find("anime-link") as HTMLInputElement .then(response => console.log(response))
let osu = arn.app.find("osu-link") as HTMLInputElement .catch(err => arn.statusMessage.showError(err))
}
let soundtrack = { // Publish
soundcloud: soundcloud.value, export function publish(arn: AnimeNotifier, button: HTMLButtonElement) {
youtube: youtube.value, let endpoint = arn.findAPIEndpoint(button)
tags: [anime.value, osu.value],
}
arn.post("/api/new/soundtrack", soundtrack) arn.post(endpoint + "/publish", "")
.then(() => arn.app.load("/soundtracks")) .then(() => arn.reloadContent())
.catch(err => arn.statusMessage.showError(err))
}
// Unpublish
export function unpublish(arn: AnimeNotifier, button: HTMLButtonElement) {
let endpoint = arn.findAPIEndpoint(button)
arn.post(endpoint + "/unpublish", "")
.then(() => arn.reloadContent())
.catch(err => arn.statusMessage.showError(err)) .catch(err => arn.statusMessage.showError(err))
} }

View File

@ -671,7 +671,7 @@ export class AnimeNotifier {
post(url: string, body: any) { post(url: string, body: any) {
if(this.isLoading) { if(this.isLoading) {
return Promise.resolve() return Promise.resolve(null)
} }
if(typeof body !== "string") { if(typeof body !== "string") {
@ -685,13 +685,16 @@ export class AnimeNotifier {
body, body,
credentials: "same-origin" credentials: "same-origin"
}) })
.then(response => response.text()) .then(response => {
.then(body => {
this.loading(false) this.loading(false)
if(body !== "ok") { if(response.status === 200) {
throw body return Promise.resolve(response)
} }
return response.text().then(err => {
throw err
})
}) })
.catch(err => { .catch(err => {
this.loading(false) this.loading(false)