component Profile(viewUser *arn.User, user *arn.User, animeList *arn.AnimeList, completedList *arn.AnimeList, characters []*arn.Character, friends []*arn.User, topGenres []string, topStudios []*arn.Company, animeWatchingTime time.Duration, dayToActivityCount map[int]int, uri string) .profile ProfileHeader(viewUser, animeList, user, uri) .profile-columns //- Favorites .profile-column.profile-favorites.mountable(data-mountable-type="column") //- Anime .profile-section h3.profile-column-header.mountable(data-mountable-type="favorites") Anime if len(completedList.Items) == 0 p.no-data.mountable(data-mountable-type="favorites") Nothing here yet. else .profile-favorite-anime-container.mountable(data-mountable-type="favorites") each item in completedList.Top(6) a.profile-favorite-anime.tip.mountable(href=item.Anime().Link(), aria-label=item.Anime().Title.ByUser(user), data-mountable-type="anime") img.profile-favorite-anime-image.lazy(data-src=item.Anime().ImageLink("small"), data-webp=true, alt=item.Anime().Title.ByUser(user)) //- Characters .profile-section h3.profile-column-header.mountable(data-mountable-type="favorites") a(href=viewUser.Link() + "/characters/liked") Characters if len(characters) == 0 p.no-data.mountable(data-mountable-type="favorites") Nothing here yet. else .profile-favorite-characters-container.mountable(data-mountable-type="favorites") each character in characters .mountable(data-mountable-type="character") CharacterSmall(character, user) //- Posts .profile-column.profile-activity.mountable(data-mountable-type="column") .profile-section h3.profile-column-header.mountable(data-mountable-type="activity") Posts Comments(viewUser, user) //- Extra .profile-column.profile-extra.mountable(data-mountable-type="column") //- Genres .profile-section h3.profile-column-header.mountable(data-mountable-type="extra") Genres if len(topGenres) == 0 p.no-data.mountable(data-mountable-type="extra") Nothing here yet. else .anime-genres.mountable(data-mountable-type="extra") each genre in topGenres a.anime-genre.mountable(href="/genre/" + strings.ToLower(genre), data-mountable-type="genre")= genre //- Studios .profile-section h3.profile-column-header.mountable(data-mountable-type="extra") Studios if len(topStudios) == 0 p.no-data.mountable(data-mountable-type="extra") Nothing here yet. else .anime-studios.mountable(data-mountable-type="extra") each company in topStudios a.anime-studio.mountable(href=company.Link(), data-mountable-type="company")= company.Name.English //- Friends .profile-section.profile-section-friends h3.profile-column-header.mountable(data-mountable-type="extra") Friends if len(friends) == 0 p.no-data.mountable(data-mountable-type="extra") Nothing here yet. else .profile-friends.mountable(data-mountable-type="extra") each friend in friends .profile-friend.mountable(data-mountable-type="friend") Avatar(friend) //- Activity .profile-section.profile-section-activity h3.profile-column-header.mountable(data-mountable-type="extra") Activity .profile-activities.mountable(data-mountable-type="extra") for month := 5; month >= 0; month-- .activities-month for week := 3; week >= 0; week-- .activities-week for day := 6; day >= 0; day-- if dayToActivityCount[month * 28 + week * 7 + day] == 0 .box.mountable(data-count="0", data-mountable-type=fmt.Sprintf("month-%d", month)) else .box.tip.mountable(aria-label=fmt.Sprintf("%s: %s", time.Weekday((6 - day + 1) % 7).String(), stringutils.Plural(dayToActivityCount[month * 28 + week * 7 + day], "activity")), data-count=dayToActivityCount[month * 28 + week * 7 + day], data-mountable-type=fmt.Sprintf("month-%d", month)) if day == 2 .spacer-box .footer.activities-footer.mountable(data-mountable-type="extra") span= viewUser.Nick + " spent " span= stringutils.Plural(int(animeWatchingTime / time.Hour / 24), "day") span watching anime. component ProfileHeader(viewUser *arn.User, animeList *arn.AnimeList, user *arn.User, uri string) ProfileHead(viewUser, animeList, user, uri) component ProfileHead(viewUser *arn.User, animeList *arn.AnimeList, user *arn.User, uri string) .profile-head img.profile-cover.lazy(data-src=viewUser.CoverLink("large"), data-webp="true", alt="Cover image") .profile-image-container.mountable.never-unmount a(href=viewUser.Link()) ProfileImage(viewUser) .profile-info.mountable.never-unmount h1#nick a(href=viewUser.Link())= viewUser.Nick .profile-introduction!= markdown.Render(viewUser.Introduction) .profile-tags-container .profile-tags a.profile-tag.mountable.never-unmount(href="/+" + viewUser.Nick + "/animelist/watching", data-mountable-type="header") Icon("list") span= fmt.Sprintf("%d anime", len(animeList.Items)) if user != nil && viewUser.Settings().Privacy.ShowAge && viewUser.Settings().Privacy.ShowGender && viewUser.AgeInYears() != 0 .profile-tag.mountable.never-unmount(data-mountable-type="header") if viewUser.Gender == "male" Icon("mars") else if viewUser.Gender == "female" Icon("venus") else Icon("venus-mars") span= viewUser.AgeInYears() if user != nil && viewUser.Settings().Privacy.ShowLocation && viewUser.Location.CountryName != "" a.profile-tag.mountable.never-unmount(href="/users/country/" + strings.ToLower(viewUser.Location.CountryName), data-mountable-type="header") Icon("map-marker") span= viewUser.Location.CountryName if viewUser.IsPro() a.profile-tag.mountable.never-unmount(href="/support", aria-label="Supporter", data-mountable-type="header") Icon("star") span.profile-pro-status-text PRO if viewUser.Role != "" a.profile-tag.mountable.never-unmount(href="/users/staff", aria-label="Staff member", data-mountable-type="header") Icon("rocket") span= stringutils.Capitalize(viewUser.Role) if viewUser.Registered != "" .profile-tag.mountable.never-unmount(title="Member since", data-mountable-type="header") Icon("calendar") span= viewUser.RegisteredTime().Format("Jan 2006") if !viewUser.IsActive() .profile-tag.mountable.never-unmount(title="Hasn't been online for the past 2 weeks", data-mountable-type="header") Icon("bed") span Inactive .profile-tag.action.tip.mountable.never-unmount(data-action="showMore", data-trigger="click", aria-label="Show more", data-mountable-type="header") RawIcon("ellipsis-h") if viewUser.Website != "" a.profile-tag.tip.mountable.never-unmount.show-more(href=viewUser.WebsiteURL(), target="_blank", rel="noopener", aria-label=viewUser.WebsiteShortURL(), data-mountable-type="header") RawIcon("globe") if viewUser.Accounts.Osu.Nick != "" && viewUser.Accounts.Osu.PP >= 100 a.profile-tag.tip.mountable.never-unmount.show-more(href="https://osu.ppy.sh/u/" + viewUser.Accounts.Osu.Nick, aria-label=fmt.Sprintf("osu! | %.0f pp | Level %.0f | Accuracy: %.1f%%", viewUser.Accounts.Osu.PP, viewUser.Accounts.Osu.Level, viewUser.Accounts.Osu.Accuracy), target="_blank", rel="noopener", data-mountable-type="header") RawIcon("trophy") if viewUser.Accounts.Overwatch.BattleTag != "" && viewUser.Accounts.Overwatch.SkillRating >= 1000 a.profile-tag.tip.mountable.never-unmount.show-more(href="https://playoverwatch.com/en-us/career/pc/" + strings.Replace(viewUser.Accounts.Overwatch.BattleTag, "#", "-", 1), aria-label=fmt.Sprintf("Overwatch | %d SR | %s", viewUser.Accounts.Overwatch.SkillRating, stringutils.Capitalize(viewUser.Accounts.Overwatch.Tier)), target="_blank", rel="noopener", data-mountable-type="header") RawIcon("overwatch") if viewUser.Accounts.FinalFantasyXIV.Nick != "" && viewUser.Accounts.FinalFantasyXIV.Class != "" .profile-tag.tip.mountable.never-unmount.show-more(aria-label=fmt.Sprintf("Final Fantasy XIV | %s | Level %d | IL %d", viewUser.Accounts.FinalFantasyXIV.Class, viewUser.Accounts.FinalFantasyXIV.Level, viewUser.Accounts.FinalFantasyXIV.ItemLevel), data-mountable-type="header") RawIcon("gamepad") if viewUser.Accounts.Discord.Nick != "" && viewUser.Accounts.Discord.Verified a.profile-tag.tip.mountable.never-unmount.show-more(href="https://discord.gg/0kimAmMCeXGXuzNF", aria-label=fmt.Sprintf("Discord | %s", viewUser.Accounts.Discord.Nick), data-mountable-type="header") RawIcon("discord") if user != nil && user.ID != viewUser.ID a.profile-tag.tip.mountable.never-unmount.show-more(href="/compare/animelist/" + user.Nick + "/" + viewUser.Nick, aria-label="Compare", data-mountable-type="header") RawIcon("exchange") a.profile-tag.tip.mountable.never-unmount.show-more(href="/+" + viewUser.Nick + "/anime/recommended", aria-label="Recommendations", data-mountable-type="header") RawIcon("archive") a.profile-tag.tip.mountable.never-unmount.show-more(href="/+" + viewUser.Nick + "/anime/sequels", aria-label="Sequels", data-mountable-type="header") RawIcon("forward") if user != nil && (user.Role == "editor" || user.Role == "admin") a.profile-tag.tip.mountable.never-unmount.show-more(href="/+" + viewUser.Nick + "/log", aria-label="Log", data-mountable-type="header") RawIcon("list") if user != nil && user.Role == "admin" a.profile-tag.tip.mountable.never-unmount.show-more(href="/api/user/" + viewUser.ID, aria-label="API", target="_blank", rel="noopener", data-mountable-type="header") RawIcon("search-plus") .profile-actions if user != nil && user.ID != viewUser.ID if !user.Follows().Contains(viewUser.ID) button.profile-action.action.mountable.never-unmount(data-action="followUser", data-trigger="click", data-api="/api/userfollows/" + user.ID + "/add/" + viewUser.ID) Icon("user-plus") span Follow else button.profile-action.action.mountable.never-unmount(data-action="unfollowUser", data-trigger="click", data-api="/api/userfollows/" + user.ID + "/remove/" + viewUser.ID) Icon("user-times") span Unfollow