diff --git a/mixins/Like.pixy b/mixins/Like.pixy new file mode 100644 index 00000000..d7b04634 --- /dev/null +++ b/mixins/Like.pixy @@ -0,0 +1,29 @@ +component LikeButton(label string, icon string, typeName string, likeable arn.Likeable, user *arn.User) + if user == nil + button.tip.action(aria-label="Login to like this " + typeName) + Icon(icon) + span= label + else + if likeable.LikedBy(user.ID) + button.tip.action(data-api="/api" + likeable.Link(), data-action="unlike", data-trigger="click", aria-label="Click to unlike this " + typeName) + Icon(icon) + span= label + else + button.tip.action(data-api="/api" + likeable.Link(), data-action="like", data-trigger="click", aria-label="Click to like this " + typeName) + Icon(icon + "-o") + span= label + +component LikeTab(label string, icon string, typeName string, likeable arn.Likeable, user *arn.User) + if user == nil + .tab.action(aria-label=label, title="Login to like this " + typeName) + Icon(icon) + span.tab-text= label + else + if likeable.LikedBy(user.ID) + .tab.action(data-api="/api" + likeable.Link(), data-action="unlike", data-trigger="click", aria-label=label, title="Click to unlike this " + typeName) + Icon(icon) + span.tab-text= label + else + .tab.action(data-api="/api" + likeable.Link(), data-action="like", data-trigger="click", aria-label=label, title="Click to like this " + typeName) + Icon(icon + "-o") + span.tab-text= label diff --git a/mixins/TabLike.pixy b/mixins/TabLike.pixy deleted file mode 100644 index 8f9fd7f6..00000000 --- a/mixins/TabLike.pixy +++ /dev/null @@ -1,14 +0,0 @@ -component TabLike(label string, icon string, typeName string, likeable arn.Likeable, user *arn.User) - if user == nil - .tab.action(aria-label=label, title="Login to like this " + typeName) - Icon(icon) - span.tab-text= label - else - if likeable.LikedBy(user.ID) - .tab.action(data-api="/api" + likeable.Link(), data-action="unlike", data-trigger="click", aria-label=label, title="Click to unlike this " + typeName) - Icon(icon) - span.tab-text= label - else - .tab.action(data-api="/api" + likeable.Link(), data-action="like", data-trigger="click", aria-label=label, title="Click to like this " + typeName) - Icon(icon + "-o") - span.tab-text= label diff --git a/pages/amv/amv.pixy b/pages/amv/amv.pixy index 11a6f634..79a4a120 100644 --- a/pages/amv/amv.pixy +++ b/pages/amv/amv.pixy @@ -47,7 +47,7 @@ component AnimeGridSmall(animes []*arn.Anime, user *arn.User) component AMVTabs(amv *arn.AMV, user *arn.User) .tabs - TabLike(strconv.Itoa(len(amv.Likes)), "heart", "amv", amv, user) + LikeTab(strconv.Itoa(len(amv.Likes)), "heart", "amv", amv, user) Tab("AMV", "video-camera", amv.Link()) if user != nil diff --git a/pages/character/character.pixy b/pages/character/character.pixy index e7a2decd..715e93be 100644 --- a/pages/character/character.pixy +++ b/pages/character/character.pixy @@ -10,6 +10,9 @@ component CharacterDetails(character *arn.Character, characterAnime []*arn.Anime .character-header .character-image-container.mountable img.character-image-large.lazy(data-src=character.ImageLink("large"), data-webp="true", data-color=character.AverageColor(), alt=character.Name.Canonical) + + .buttons + LikeButton(strconv.Itoa(len(character.Likes)), "heart", "character", character, user) .character-description-container h1.character-name.mountable= character.Name.Canonical diff --git a/pages/index.go b/pages/index.go index deac5d02..de537b43 100644 --- a/pages/index.go +++ b/pages/index.go @@ -54,6 +54,7 @@ import ( "github.com/animenotifier/notify.moe/pages/popular" "github.com/animenotifier/notify.moe/pages/posts" "github.com/animenotifier/notify.moe/pages/profile" + "github.com/animenotifier/notify.moe/pages/profile/profilecharacters" "github.com/animenotifier/notify.moe/pages/profile/profilequotes" "github.com/animenotifier/notify.moe/pages/profile/profiletracks" "github.com/animenotifier/notify.moe/pages/quote" @@ -205,6 +206,7 @@ func Configure(app *aero.Application) { // User profiles l.Page("/user", user.Get) l.Page("/user/:nick", profile.Get) + l.Page("/user/:nick/characters/liked", profilecharacters.Liked) l.Page("/user/:nick/forum/threads", profile.GetThreadsByUser) l.Page("/user/:nick/forum/posts", profile.GetPostsByUser) l.Page("/user/:nick/soundtracks/added", profiletracks.Added) diff --git a/pages/profile/profile.pixy b/pages/profile/profile.pixy index 7b91ac42..781baffd 100644 --- a/pages/profile/profile.pixy +++ b/pages/profile/profile.pixy @@ -11,7 +11,7 @@ component Profile(viewUser *arn.User, user *arn.User, animeList *arn.AnimeList, img.profile-watching-list-item-image.lazy(data-src=item.Anime().ImageLink("small"), data-webp="true", data-color=item.Anime().AverageColor(), alt=item.Anime().Title.ByUser(user)) .footer - .buttons + .buttons if user != nil && (user.Role == "admin" || user.Role == "editor") a.button.profile-action(href="/api/user/" + viewUser.ID, target="_blank", rel="noopener") Icon("search-plus") @@ -20,15 +20,12 @@ component Profile(viewUser *arn.User, user *arn.User, animeList *arn.AnimeList, component ProfileTabs(viewUser *arn.User, uri string) .tabs Tab("Anime", "th", "/+" + viewUser.Nick) - //- Tab("Collection", "list", "/+" + viewUser.Nick + "/animelist/watching") + Tab("Characters", "child", "/+" + viewUser.Nick + "/characters/liked") Tab("Forum", "comment", "/+" + viewUser.Nick + "/forum/threads") Tab("Tracks", "music", "/+" + viewUser.Nick + "/soundtracks/liked") Tab("Quotes", "quote-left", "/+" + viewUser.Nick + "/quotes/liked") Tab("Stats", "area-chart", "/+" + viewUser.Nick + "/stats") Tab("Followers", "users", "/+" + viewUser.Nick + "/followers") - - //- if strings.Contains(uri, "/animelist") - //- StatusTabs("/+" + viewUser.Nick + "/animelist") if strings.Contains(uri, "/soundtracks") .tabs diff --git a/pages/profile/profilecharacters/characters.pixy b/pages/profile/profilecharacters/characters.pixy new file mode 100644 index 00000000..6e71962a --- /dev/null +++ b/pages/profile/profilecharacters/characters.pixy @@ -0,0 +1,11 @@ +component ProfileCharacters(characters []*arn.Character, viewUser *arn.User, user *arn.User, uri string) + ProfileHeader(viewUser, user, uri) + + if len(characters) == 0 + p.no-data.mountable= viewUser.Nick + " hasn't liked any characters yet." + else + .characters.profile-characters + each character in characters + .mountable + Character(character) + \ No newline at end of file diff --git a/pages/profile/profilecharacters/characters.scarlet b/pages/profile/profilecharacters/characters.scarlet new file mode 100644 index 00000000..a0ee7eb8 --- /dev/null +++ b/pages/profile/profilecharacters/characters.scarlet @@ -0,0 +1,2 @@ +.profile-characters + justify-content center \ No newline at end of file diff --git a/pages/profile/profilecharacters/liked.go b/pages/profile/profilecharacters/liked.go new file mode 100644 index 00000000..e99bb11b --- /dev/null +++ b/pages/profile/profilecharacters/liked.go @@ -0,0 +1,44 @@ +package profilecharacters + +import ( + "net/http" + "sort" + + "github.com/aerogo/aero" + "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/components" + "github.com/animenotifier/notify.moe/utils" +) + +// Liked shows all liked characters of a particular user. +func Liked(ctx *aero.Context) string { + nick := ctx.Get("nick") + viewUser, err := arn.GetUserByNick(nick) + + if err != nil { + return ctx.Error(http.StatusNotFound, "User not found", err) + } + + characters := []*arn.Character{} + + for character := range arn.StreamCharacters() { + if arn.Contains(character.Likes, viewUser.ID) { + characters = append(characters, character) + } + } + + sort.Slice(characters, func(i, j int) bool { + return characters[i].Name.Canonical < characters[j].Name.Canonical + + // aLikes := len(characters[i].Likes) + // bLikes := len(characters[j].Likes) + + // if aLikes == bLikes { + // return characters[i].Name.Canonical < characters[j].Name.Canonical + // } + + // return aLikes > bLikes + }) + + return ctx.HTML(components.ProfileCharacters(characters, viewUser, utils.GetUser(ctx), ctx.URI())) +} diff --git a/pages/quote/quote.pixy b/pages/quote/quote.pixy index c5101789..3b240da0 100644 --- a/pages/quote/quote.pixy +++ b/pages/quote/quote.pixy @@ -50,7 +50,7 @@ component QuoteInformation(quote *arn.Quote, user *arn.User) component QuoteTabs(quote *arn.Quote, user *arn.User) .tabs - TabLike(strconv.Itoa(len(quote.Likes)), "heart", "quote", quote, user) + LikeTab(strconv.Itoa(len(quote.Likes)), "heart", "quote", quote, user) Tab("Quote", "quote-left", quote.Link()) if user != nil Tab("Edit", "pencil", quote.Link() + "/edit") diff --git a/pages/soundtrack/soundtrack.pixy b/pages/soundtrack/soundtrack.pixy index 97dce095..740c1f17 100644 --- a/pages/soundtrack/soundtrack.pixy +++ b/pages/soundtrack/soundtrack.pixy @@ -72,7 +72,7 @@ component SoundTrackPage(track *arn.SoundTrack, user *arn.User) component SoundTrackTabs(track *arn.SoundTrack, user *arn.User) .tabs - TabLike(strconv.Itoa(len(track.Likes)), "heart", "track", track, user) + LikeTab(strconv.Itoa(len(track.Likes)), "heart", "track", track, user) Tab("Soundtrack", "music", track.Link()) if track.HasLyrics() diff --git a/scripts/Actions/Like.ts b/scripts/Actions/Like.ts index 19c140f7..9375da44 100644 --- a/scripts/Actions/Like.ts +++ b/scripts/Actions/Like.ts @@ -2,7 +2,7 @@ import AnimeNotifier from "../AnimeNotifier" // like export async function like(arn: AnimeNotifier, element: HTMLElement) { - arn.statusMessage.showInfo("Liked!") + arn.statusMessage.showInfo("Liked!", 1000) let apiEndpoint = arn.findAPIEndpoint(element) await arn.post(apiEndpoint + "/like", null).catch(err => arn.statusMessage.showError(err)) @@ -11,7 +11,7 @@ export async function like(arn: AnimeNotifier, element: HTMLElement) { // unlike export async function unlike(arn: AnimeNotifier, element: HTMLElement) { - arn.statusMessage.showInfo("Disliked!") + arn.statusMessage.showInfo("Disliked!", 1000) let apiEndpoint = arn.findAPIEndpoint(element) await arn.post(apiEndpoint + "/unlike", null).catch(err => arn.statusMessage.showError(err))