98 lines
2.1 KiB
Go
Raw Normal View History

2018-03-21 21:57:06 +00:00
package explorecolor
import (
"math"
"strconv"
"strings"
"github.com/aerogo/aero"
"github.com/animenotifier/arn"
"github.com/animenotifier/notify.moe/components"
"github.com/animenotifier/notify.moe/utils"
2018-03-21 22:18:08 +00:00
"github.com/animenotifier/notify.moe/utils/infinitescroll"
)
const (
animeFirstLoad = 50
2018-03-21 22:20:19 +00:00
animePerScroll = 30
2018-03-21 21:57:06 +00:00
)
// AnimeByAverageColor returns all anime with an image in the given color.
func AnimeByAverageColor(ctx *aero.Context) string {
user := utils.GetUser(ctx)
color := ctx.Get("color")
2018-03-21 22:18:08 +00:00
index, _ := ctx.GetInt("index")
allAnimes := filterAnimeByColor(color)
arn.SortAnimeByQuality(allAnimes)
// Slice the part that we need
animes := allAnimes[index:]
maxLength := animeFirstLoad
if index > 0 {
maxLength = animePerScroll
}
if len(animes) > maxLength {
animes = animes[:maxLength]
}
2018-03-21 21:57:06 +00:00
2018-03-21 22:18:08 +00:00
// Next index
nextIndex := infinitescroll.NextIndex(ctx, len(allAnimes), maxLength, index)
// In case we're scrolling, send animes only (without the page frame)
if index > 0 {
return ctx.HTML(components.AnimeGridScrollable(animes, user))
}
2018-03-21 21:57:06 +00:00
2018-03-21 22:18:08 +00:00
// Otherwise, send the full page
return ctx.HTML(components.ExploreColor(animes, nextIndex, len(allAnimes), color, user))
2018-03-21 21:57:06 +00:00
}
func filterAnimeByColor(colorText string) []*arn.Anime {
if !strings.HasPrefix(colorText, "hsl:") {
return nil
}
colorText = colorText[len("hsl:"):]
parts := strings.Split(colorText, ",")
if len(parts) != 3 {
return nil
}
hue, err := strconv.ParseFloat(parts[0], 64)
if err != nil {
return nil
}
saturation, err := strconv.ParseFloat(parts[1], 64)
if err != nil {
return nil
}
lightness, err := strconv.ParseFloat(parts[2], 64)
if err != nil {
return nil
}
color := arn.HSLColor{
Hue: hue,
Saturation: saturation,
Lightness: lightness,
}
return arn.FilterAnime(func(anime *arn.Anime) bool {
animeColor := anime.Image.AverageColor
hueDifference := color.Hue - animeColor.Hue
saturationDifference := color.Saturation - animeColor.Saturation
lightnessDifference := color.Lightness - animeColor.Lightness
return math.Abs(hueDifference) < 0.05 && math.Abs(saturationDifference) < 0.125 && math.Abs(lightnessDifference) < 0.25
})
}