Noah
cd1b349fcc
* Add the user photo gallery for profile pages. Paginated, grid or full (blog style) view options. In grid view clicking a photo opens a large modal to see it; full view already shows large photos. * Edit page: can also re-crop and set an existing pic to be your profile pic. * Delete page: remove photos from the DB and hard drive. * Photos are cleaned up from disk when not needed, e.g. during a re-crop the old cropped photo is removed before the new one replaces it. * Fixed bug with cropping pictures.
240 lines
8.4 KiB
HTML
240 lines
8.4 KiB
HTML
{{define "title"}}Photos of {{.User.Username}}{{end}}
|
|
|
|
<!-- Reusable card body -->
|
|
{{define "card-body"}}
|
|
<div>
|
|
<small class="has-text-grey">Uploaded {{.CreatedAt.Format "Jan _2 2006 15:04:05"}}</small>
|
|
</div>
|
|
<div class="mt-2">
|
|
{{if .Explicit}}
|
|
<span class="tag is-danger is-light">
|
|
<span class="icon"><i class="fa fa-fire"></i></span>
|
|
<span>Explicit</span>
|
|
</span>
|
|
{{end}}
|
|
|
|
<span class="tag is-info is-light">
|
|
<span class="icon"><i class="fa fa-eye"></i></span>
|
|
<span>
|
|
{{if eq .Visibility "public"}}Public{{end}}
|
|
{{if eq .Visibility "private"}}Private{{end}}
|
|
{{if eq .Visibility "friends"}}Friends{{end}}
|
|
</span>
|
|
</span>
|
|
|
|
{{if .Gallery}}
|
|
<span class="tag is-success is-light">
|
|
<span class="icon"><i class="fa fa-image"></i></span>
|
|
<span>Gallery</span>
|
|
</span>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
|
|
<!-- Reusable card footer -->
|
|
{{define "card-footer"}}
|
|
<footer class="card-footer">
|
|
<a class="card-footer-item" href="/photo/edit?id={{.ID}}">
|
|
<span class="icon"><i class="fa fa-edit"></i></span>
|
|
Edit
|
|
</a>
|
|
<a class="card-footer-item has-text-danger" href="/photo/delete?id={{.ID}}">
|
|
<span class="icon"><i class="fa fa-trash"></i></span>
|
|
Delete
|
|
</a>
|
|
</footer>
|
|
{{end}}
|
|
|
|
<!-- Reusable pager -->
|
|
{{define "pager"}}
|
|
<nav class="pagination" role="navigation" aria-label="pagination">
|
|
<a class="pagination-previous{{if not .Pager.HasPrevious}} is-disabled{{end}}" title="Previous"
|
|
href="{{.Request.URL.Path}}?view={{.ViewStyle}}&page={{.Pager.Previous}}">Previous</a>
|
|
<a class="pagination-next{{if not .Pager.HasNext}} is-disabled{{end}}" title="Next"
|
|
href="{{.Request.URL.Path}}?view={{.ViewStyle}}&page={{.Pager.Next}}">Next page</a>
|
|
<ul class="pagination-list">
|
|
{{$Root := .}}
|
|
{{range .Pager.Iter}}
|
|
<li>
|
|
<a class="pagination-link{{if .IsCurrent}} is-current{{end}}"
|
|
aria-label="Page {{.Page}}"
|
|
href="{{$Root.Request.URL.Path}}?view={{$Root.ViewStyle}}&page={{.Page}}">
|
|
{{.Page}}
|
|
</a>
|
|
</li>
|
|
{{end}}
|
|
</ul>
|
|
</nav>
|
|
{{end}}
|
|
|
|
<!-- Main content template -->
|
|
{{define "content"}}
|
|
<div class="container">
|
|
<section class="hero is-info is-bold">
|
|
<div class="hero-body">
|
|
<div class="level">
|
|
<div class="level-left">
|
|
<h1 class="title">
|
|
Photos of {{.User.Username}}
|
|
</h1>
|
|
</div>
|
|
{{if .IsOwnPhotos}}
|
|
<div class="level-right">
|
|
<div>
|
|
<a href="/photo/upload" class="button">
|
|
<span class="icon"><i class="fa fa-upload"></i></span>
|
|
<span>Upload Photos</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ugly hack.. needed by the card-footers later below. -->
|
|
{{$Root := .}}
|
|
|
|
<div class="block p-4">
|
|
<div class="tabs is-boxed">
|
|
<ul>
|
|
<li>
|
|
<a href="/u/{{.User.Username}}">
|
|
<span class="icon is-small">
|
|
<i class="fa fa-user"></i>
|
|
</span>
|
|
<span>Profile</span>
|
|
</a>
|
|
</li>
|
|
<li class="is-active">
|
|
<a>
|
|
<span class="icon is-small">
|
|
<i class="fa fa-image"></i>
|
|
</span>
|
|
<span>Photos</span>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- Photo Detail Modal -->
|
|
<div class="modal" id="detail-modal">
|
|
<div class="modal-background"></div>
|
|
<div class="modal-content photo-modal">
|
|
<div class="image is-fullwidth">
|
|
<img id="detailImg">
|
|
</div>
|
|
</div>
|
|
<button class="modal-close is-large" aria-label="close"></button>
|
|
</div>
|
|
|
|
<div class="block">
|
|
<div class="level">
|
|
<div class="level-left">
|
|
<div class="level-item">
|
|
<span>
|
|
Found <strong>{{.Pager.Total}}</strong> photos (page {{.Pager.Page}} of {{.Pager.Pages}}).
|
|
</span>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div class="level-right">
|
|
<div class="level-item">
|
|
<div class="tabs is-toggle is-small">
|
|
<ul>
|
|
<li{{if eq .ViewStyle "cards"}} class="is-active"{{end}}>
|
|
<a href="{{.Request.URL.Path}}?view=cards">Cards</a>
|
|
</li>
|
|
<li{{if eq .ViewStyle "full"}} class="is-active"{{end}}>
|
|
<a href="{{.Request.URL.Path}}?view=full">Full</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{template "pager" .}}
|
|
|
|
<!-- "Full" view style? (blog style) -->
|
|
{{if eq .ViewStyle "full"}}
|
|
{{range .Photos}}
|
|
<div class="card block">
|
|
<header class="card-header has-background-link">
|
|
<p class="card-header-title has-text-light">
|
|
<span class="icon">
|
|
<i class="fa fa-image"></i>
|
|
</span>
|
|
{{or .Caption "Photo"}}
|
|
</p>
|
|
</header>
|
|
|
|
<div class="card-content">
|
|
<img src="{{PhotoURL .Filename}}">
|
|
|
|
{{template "card-body" .}}
|
|
</div>
|
|
{{if or $Root.IsOwnPhotos $Root.CurrentUser.IsAdmin}}
|
|
{{template "card-footer" .}}
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
|
|
<!-- "Cards" style (default) -->
|
|
{{else}}
|
|
<div class="columns is-multiline">
|
|
{{range .Photos}}
|
|
<div class="column is-one-quarter-desktop is-half-tablet">
|
|
<div class="card">
|
|
<div class="card-image">
|
|
<figure class="image">
|
|
<a href="{{PhotoURL .Filename}}" target="_blank"
|
|
class="js-modal-trigger" data-target="detail-modal"
|
|
onclick="setModalImage(this.href)">
|
|
<img src="{{PhotoURL .Filename}}">
|
|
</a>
|
|
</figure>
|
|
</div>
|
|
<div class="card-content">
|
|
{{if .Caption}}
|
|
{{.Caption}}
|
|
{{else}}<em>No caption</em>{{end}}
|
|
|
|
{{template "card-body" .}}
|
|
</div>
|
|
{{if or $Root.IsOwnPhotos $Root.CurrentUser.IsAdmin}}
|
|
{{template "card-footer" .}}
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
{{end}}<!-- ViewStyle -->
|
|
|
|
{{template "pager" .}}
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
// Get our modal to trigger it on click of a detail img.
|
|
let $modal = document.querySelector("#detail-modal");
|
|
document.querySelectorAll(".js-modal-trigger").forEach(node => {
|
|
node.addEventListener("click", (e) => {
|
|
e.preventDefault();
|
|
setModalImage(node.href);
|
|
$modal.classList.add("is-active");
|
|
})
|
|
});
|
|
});
|
|
function setModalImage(url) {
|
|
let $modalImg = document.querySelector("#detailImg");
|
|
$modalImg.src = url;
|
|
return false;
|
|
}
|
|
</script>
|
|
{{end}} |