mirror of
https://codeberg.org/VnPower/PixivFE
synced 2024-12-06 19:16:23 +01:00
221 lines
11 KiB
HTML
221 lines
11 KiB
HTML
{{- extends "layout/default" }}
|
|
{{- import "blocks/pagination" }}
|
|
{{- import "blocks/underlinenavUser" }}
|
|
{{- block body() }}
|
|
<div class="row justify-content-center g-4">
|
|
<!-- NOTE: mb-5 used here to give the underlinenav a bit more space at the cost of some consistency -->
|
|
<div class="col-12 col-lg-9 mb-5">
|
|
<div class="custom-card bg-charcoal-surface1">
|
|
<!-- Profile background image -->
|
|
{{- if .User.BackgroundImage }}
|
|
<div class="d-flex position-relative mb-5">
|
|
<img src="{{ .User.BackgroundImage }}" alt="{{ .User.Name }} profile background image"
|
|
class="img-fluid rounded-top-5 object-fit-cover w-100"
|
|
style="max-height: 200px;" />
|
|
<img src="{{.User.Avatar}}" alt="User avatar"
|
|
class="d-inline-block d-md-none border border-5 border-neutral-800 rounded-circle object-fit-cover position-absolute z-1"
|
|
style="width: 150px; height: 150px; bottom: 0; left: 50%; transform: translate(-50%, 50%);">
|
|
</div>
|
|
{{- end }}
|
|
|
|
<div class="custom-card-body p-4 mt-md-0">
|
|
{{- if !.User.BackgroundImage }}
|
|
<img src="{{.User.Avatar}}" alt="User avatar"
|
|
class="d-flex d-md-none border border-5 border-neutral-800 rounded-circle object-fit-cover mx-auto"
|
|
style="width: 150px; height: 150px">
|
|
{{- end }}
|
|
|
|
<div class="row g-4 mt-3 mt-md-0">
|
|
<!-- User avatar and external link to pixiv.net -->
|
|
<div class="col-12 col-md-3 d-none d-md-block mt-0">
|
|
<div class="d-flex flex-column align-items-center">
|
|
<img src="{{.User.Avatar}}" alt="User avatar" class="rounded-circle object-fit-cover mb-3" style="width: 150px; height: 150px">
|
|
|
|
<div class="d-inline-flex border border-neutral-700 rounded py-1 px-2 mb-3">
|
|
<small class="text-center">
|
|
<i class="bi bi-box-arrow-up-right me-1"></i>
|
|
<a href="https://pixiv.net/u/{{ .User.ID }}" class="text-body-secondary fw-semibold">
|
|
View on pixiv.net
|
|
</a>
|
|
</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-9 mt-0">
|
|
<!-- User name and follow/unfollow buttons -->
|
|
<div class="d-flex flex-column flex-md-row flex-wrap justify-content-xl-between align-items-center mb-3 mb-md-2">
|
|
<h1 class="flex-grow-1 mb-2 mb-md-0">{{ .User.Name }}</h1>
|
|
<p class="d-inline-block d-md-none text-body-secondary text-center">{{ .User.Following }} Following | {{ .User.MyPixiv }} MyPixiv</p>
|
|
{{- include "fragments/followButtons" . }}
|
|
</div>
|
|
|
|
<!-- Social media links -->
|
|
<p class="d-none d-md-inline-block text-body-secondary text-md-start">{{ .User.Following }} Following | {{ .User.MyPixiv }} MyPixiv</p>
|
|
<div class="d-flex justify-content-center justify-content-md-start mb-3">
|
|
{{- if .User.Webpage }}
|
|
<a href="{{ .User.Webpage }}" class="btn btn-custom-color text-body rounded-pill me-2">
|
|
<i class="bi bi-globe"></i>
|
|
</a>
|
|
{{- end }}
|
|
{{- range index, item := .User.Social }}
|
|
{{- if index == "pawoo" }}
|
|
<a href="{{ item.url }}" class="btn btn-custom-color text-body rounded-pill me-2">
|
|
<i class="bi bi-mastodon"></i>
|
|
</a>
|
|
{{- else }}
|
|
<a href="{{ item.url }}" class="btn btn-custom-color text-body rounded-pill me-2">
|
|
<i class="bi bi-{{ index }}"></i>
|
|
</a>
|
|
{{- end }}
|
|
{{- end }}
|
|
</div>
|
|
|
|
<!-- User bio and frequently used tags -->
|
|
<p class="mb-4">{{ raw: parsePixivRedirect(.User.Comment) }}</p>
|
|
|
|
{* NOTE: this button definitely needs to be in a different place *}
|
|
<div class="d-inline-flex d-md-none border border-neutral-700 rounded py-1 px-2 mb-3">
|
|
<small>
|
|
<i class="bi bi-box-arrow-up-right me-1"></i>
|
|
<a href="https://pixiv.net/u/{{ .User.ID }}" class="text-body-secondary fw-semibold stretched-link">
|
|
View on pixiv.net
|
|
</a>
|
|
</small>
|
|
</div>
|
|
|
|
<div class="border border-2 border-neutral-700 rounded-5 p-4">
|
|
<h3><i class="bi bi-tags-fill"></i> Frequently used tags</h3>
|
|
<div class="d-flex flex-wrap">
|
|
{{- range .User.FrequentTags }}
|
|
<div class="me-2 mb-2">
|
|
<small>
|
|
<a href="/tags/{{ escapeString(.Name) }}" class="text-primary-emphasis fw-semibold text-decoration-none text-wrap">#{{ .Name }}</a>
|
|
{{- if .TranslatedName }}
|
|
<small class="text-body-secondary fw-medium">({{ .TranslatedName }})</small>
|
|
{{- end }}
|
|
</small>
|
|
</div>
|
|
{{- end }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-12 mb-4" id="checkpoint">
|
|
<!-- Navigation -->
|
|
<div class="d-flex flex-column flex-md-row align-items-center justify-content-center justify-content-md-between mx-auto mb-4">
|
|
{{- baseURL := "/users/" + .User.ID + "/" }}
|
|
{{- paths := slice("" + "#checkpoint", "illustrations" + "#checkpoint", "manga" + "#checkpoint", "novels" + "#checkpoint", "bookmarks" + "#checkpoint") }}
|
|
{{- names := slice("Home", "Illustrations", "Manga", "Novels", "Bookmarks") }}
|
|
{{- categoryCounts := slice(.User.WorkCounts.All, .User.WorkCounts.Illustrations, .User.WorkCounts.Manga, .User.WorkCounts.Novels, .User.WorkCounts.Bookmarks) }}
|
|
{{- yield UnderlineNavUser(baseURL=baseURL, paths=paths, names=names, categoryCounts=categoryCounts, activeState=.Category + "#checkpoint") }}
|
|
</div>
|
|
|
|
<!-- User content -->
|
|
|
|
<!-- Home category (all works) -->
|
|
{{- if .Category == "" || .Category == "artworks" }}
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
{* NOTE: using sentence case here to be more consistent with the rest of our UI, even though pixiv uses title case *}
|
|
<h2 class="d-flex align-items-baseline mb-0">Works<span class="fs-6 bg-charcoal-surface1 rounded px-2 py-1 ms-2">{{ .User.WorkCounts.All }}</span></h2>
|
|
</div>
|
|
|
|
{{ if len(.User.Illustrations) != 0 }}
|
|
<h2 class="d-flex align-items-baseline">Illustrations<span class="fs-6 bg-charcoal-surface1 rounded px-2 py-1 ms-2">{{ .User.WorkCounts.Illustrations }}</span></h2>
|
|
<div class="row row-cols-2 row-cols-md-4 row-cols-lg-6 g-4">
|
|
{{- include "fragments/small-tn" .User.Illustrations }}
|
|
</div>
|
|
{{- end }}
|
|
|
|
{{ if len(.User.Manga) != 0 }}
|
|
<hr class="my-4">
|
|
<h2 class="d-flex align-items-baseline">Manga<span class="fs-6 bg-charcoal-surface1 rounded px-2 py-1 ms-2">{{ .User.WorkCounts.Manga }}</span></h2>
|
|
<div class="row row-cols-2 row-cols-md-4 row-cols-lg-6 g-4">
|
|
{{- include "fragments/small-tn" .User.Manga }}
|
|
</div>
|
|
{{- end }}
|
|
|
|
{{ if len(.User.Novels) != 0 }}
|
|
<hr class="my-4">
|
|
<h2 class="d-flex align-items-baseline">Novels<span class="fs-6 bg-charcoal-surface1 rounded px-2 py-1 ms-2">{{ .User.WorkCounts.Novels }}</span></h2>
|
|
<div class="row row-cols-1 row-cols-lg-2 g-4">
|
|
{{- range .User.Novels }}
|
|
<div class="col mt-1">
|
|
<div class="custom-novel-card bg-transparent p-3 py-4 thumbnail-hover-dark">
|
|
{{- include "fragments/novel-tn" . }}
|
|
</div>
|
|
<hr class="my-0">
|
|
</div>
|
|
{{- end }}
|
|
</div>
|
|
{{- end }}
|
|
{{- end }}
|
|
|
|
<!-- Illustrations category -->
|
|
{{- if .Category == "illustrations" }}
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h2 class="d-flex align-items-baseline mb-0">Illustrations<span class="fs-6 bg-charcoal-surface1 rounded px-2 py-1 ms-2">{{ .User.WorkCounts.Illustrations }}</span></h2>
|
|
{{- combinedUrl := "/artworks-multi/" + joinArtworkIds(.User.Illustrations) }}
|
|
<a href="{{combinedUrl}}" class="custom-btn-secondary">View all</a>
|
|
</div>
|
|
<div class="row row-cols-2 row-cols-md-4 row-cols-lg-6 g-4">
|
|
{{- include "fragments/small-tn" .User.Illustrations }}
|
|
</div>
|
|
{{- end }}
|
|
|
|
<!-- Manga category -->
|
|
{{- if .Category == "manga" }}
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h2 class="d-flex align-items-baseline mb-0">Manga<span class="fs-6 bg-charcoal-surface1 rounded px-2 py-1 ms-2">{{ .User.WorkCounts.Manga }}</span></h2>
|
|
{{- combinedUrl := "/artworks-multi/" + joinArtworkIds(.User.Manga) }}
|
|
<a href="{{combinedUrl}}" class="custom-btn-secondary">View all</a>
|
|
</div>
|
|
<div class="row row-cols-2 row-cols-md-4 row-cols-lg-6 g-4">
|
|
{{- include "fragments/small-tn" .User.Manga }}
|
|
</div>
|
|
{{- end }}
|
|
|
|
<!-- Novels category -->
|
|
{{- if .Category == "novels" }}
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h2 class="d-flex align-items-baseline mb-0">Novels<span class="fs-6 bg-charcoal-surface1 rounded px-2 py-1 ms-2">{{ .User.WorkCounts.Novels }}</span></h2>
|
|
</div>
|
|
<div class="row row-cols-1 row-cols-lg-2 g-4">
|
|
{{- range .User.Novels }}
|
|
<div class="col mt-1">
|
|
<div class="custom-novel-card bg-transparent p-3 py-4 thumbnail-hover-dark">
|
|
{{- include "fragments/novel-tn" . }}
|
|
</div>
|
|
<hr class="my-0">
|
|
</div>
|
|
{{- end }}
|
|
</div>
|
|
{{- end }}
|
|
|
|
<!-- Bookmarks category -->
|
|
{{- if .Category == "bookmarks" }}
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h2 class="d-flex align-items-baseline mb-0">Bookmarks<span class="fs-6 bg-charcoal-surface1 rounded px-2 py-1 ms-2">{{ .User.WorkCounts.Bookmarks }}</span></h2>
|
|
</div>
|
|
{* NOTE: using .User.Artworks since there's no need to create a separate bookmarks slice; the category handles it *}
|
|
<div class="row row-cols-2 row-cols-md-4 row-cols-lg-6 g-4">
|
|
{{- include "fragments/small-tn" .User.Artworks }}
|
|
</div>
|
|
{{- end }}
|
|
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
{* TODO: figure out how to 'paginate' the home tab correctly; htmx for swapping in categories? *}
|
|
{{- if .Category == "illustrations" || .Category == "manga" || .Category == "novels" || .Category == "bookmarks" }}
|
|
{{- url := "/users/" + .User.ID + "/" + .Category + "?page="}}
|
|
{{- paginationData := createPaginator(url, "#checkpoint", .Page, .PageLimit, 1, 5) }}
|
|
{{- yield pagination(data=paginationData) }}
|
|
{{- end }}
|
|
</div>
|
|
{{- end }}
|