diff --git a/pages/character/character.go b/pages/character/character.go index d4b77fad..c85f789e 100644 --- a/pages/character/character.go +++ b/pages/character/character.go @@ -8,9 +8,13 @@ import ( "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/components" "github.com/animenotifier/notify.moe/utils" + "github.com/fatih/color" ) -const maxDescriptionLength = 170 +const ( + maxDescriptionLength = 170 + maxRelevantCharacters = 12 +) // Get character. func Get(ctx *aero.Context) string { @@ -22,6 +26,7 @@ func Get(ctx *aero.Context) string { return ctx.Error(http.StatusNotFound, "Character not found", err) } + // Anime characterAnime := character.Anime() sort.Slice(characterAnime, func(i, j int) bool { @@ -36,6 +41,51 @@ func Get(ctx *aero.Context) string { return characterAnime[i].StartDate < characterAnime[j].StartDate }) + // Characters from the same anime + characterAppearances := map[string]int{} + + for _, anime := range characterAnime { + for _, animeCharacter := range anime.Characters().Items { + if animeCharacter.CharacterID == character.ID { + continue + } + + characterAppearances[animeCharacter.CharacterID]++ + } + } + + relevantCharacters := []*arn.Character{} + + for characterID := range characterAppearances { + relevantCharacter, err := arn.GetCharacter(characterID) + + if !relevantCharacter.HasImage() { + continue + } + + if err != nil { + color.Red(err.Error()) + continue + } + + relevantCharacters = append(relevantCharacters, relevantCharacter) + } + + sort.Slice(relevantCharacters, func(i, j int) bool { + aRelevance := characterAppearances[relevantCharacters[i].ID] + bRelevance := characterAppearances[relevantCharacters[j].ID] + + if aRelevance == bRelevance { + return relevantCharacters[i].Name.Canonical < relevantCharacters[j].Name.Canonical + } + + return aRelevance > bRelevance + }) + + if len(relevantCharacters) > maxRelevantCharacters { + relevantCharacters = relevantCharacters[:maxRelevantCharacters] + } + // Quotes mainQuote := character.MainQuote() quotes := character.Quotes() @@ -83,5 +133,5 @@ func Get(ctx *aero.Context) string { } } - return ctx.HTML(components.CharacterDetails(character, characterAnime, quotes, friends, mainQuote, user)) + return ctx.HTML(components.CharacterDetails(character, characterAnime, quotes, friends, relevantCharacters, mainQuote, user)) } diff --git a/pages/character/character.pixy b/pages/character/character.pixy index d20aa06d..bdec269c 100644 --- a/pages/character/character.pixy +++ b/pages/character/character.pixy @@ -5,7 +5,7 @@ component CharacterTabs(character *arn.Character, user *arn.User) Tab("Images", "image", character.Link() + "/edit/images") Tab("History", "history", character.Link() + "/history") -component CharacterDetails(character *arn.Character, characterAnime []*arn.Anime, quotes []*arn.Quote, friends []*arn.User, mainQuote *arn.Quote, user *arn.User) +component CharacterDetails(character *arn.Character, characterAnime []*arn.Anime, quotes []*arn.Quote, friends []*arn.User, relevantCharacters []*arn.Character, mainQuote *arn.Quote, user *arn.User) .character-page .character-left-column .character-header @@ -62,6 +62,14 @@ component CharacterDetails(character *arn.Character, characterAnime []*arn.Anime else td.character-attributes-value= attribute.Value + if len(relevantCharacters) > 0 + h3.mountable Relevant + + .relevant-characters.mountable + each relevantCharacter in relevantCharacters + .mountable(data-mountable-type="relevant-character") + CharacterSmall(relevantCharacter, user) + if len(friends) > 0 .character-friends h3.mountable Friends diff --git a/pages/character/character.scarlet b/pages/character/character.scarlet index 1e785ff9..03cef071 100644 --- a/pages/character/character.scarlet +++ b/pages/character/character.scarlet @@ -61,6 +61,9 @@ .user-avatars justify-content flex-start +.relevant-characters + horizontal-wrap + > 1250px .character-page horizontal