<!-- Photo Gallery Template, shared by Site Photos + User Photos. When Site Gallery: .IsSiteGallery is defined and true. When User Gallery: .User is defined, .IsOwnPhotos may be. --> {{define "title"}} {{if .IsSiteGallery}} Member Gallery {{else}} Photos of {{.User.Username}} {{if eq .User.Visibility "private"}}<sup class="fa fa-mask ml-2 is-size-6" title="Private Profile"></sup>{{end}} {{end}} {{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}} {{if eq .Visibility "public"}} <span class="tag is-info is-light"> <span class="icon"><i class="fa fa-eye"></i></span> <span> Public </span> </span> {{else if eq .Visibility "friends"}} <span class="tag is-warning is-light"> <span class="icon"><i class="fa fa-user-group"></i></span> <span> Friends </span> </span> {{else}} <span class="tag is-private is-light"> <span class="icon"><i class="fa fa-lock"></i></span> <span> Private </span> </span> {{end}} {{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"}} <a class="card-footer-item" href="/photo/edit?id={{.ID}}"> <span class="icon"><i class="fa fa-edit"></i></span> <span>Edit</span> </a> <a class="card-footer-item has-text-danger" href="/photo/delete?id={{.ID}}"> <span class="icon"><i class="fa fa-trash"></i></span> <span>Delete</span> </a> {{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"> {{if .IsSiteGallery}} <h1 class="title"> {{template "title" .}} </h1> {{else}} <div class="level"> <div class="level-left"> <h1 class="title"> {{template "title" .}} </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> {{end}} </div> </section> <!-- ugly hack.. needed by the card-footers later below. --> {{$Root := .}} <div class="block p-4"> <!-- Profile Tab for user view --> {{if not .IsSiteGallery}} <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 {{if .PhotoCount}}<span class="tag is-link is-light ml-1">{{.PhotoCount}}</span>{{end}} </span> </a> </li> </ul> </div> {{end}} <!-- 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{{if .IsOwnPhotos}}mb-0{{end}}"> <div class="level-left"> <div class="level-item"> <span> Found <strong>{{.Pager.Total}}</strong> photo{{Pluralize64 .Pager.Total}} (page {{.Pager.Page}} of {{.Pager.Pages}}). {{if .ExplicitCount}} {{.ExplicitCount}} explicit photo{{Pluralize64 .ExplicitCount}} hidden per your settings. {{end}} </span> </div> </div> <div class="level-right"> <div class="level-item"> <div class="tabs is-toggle is-small is-hidden-mobile"> <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> {{if .IsSiteGallery}} <div class="block"> <form action="/photo/gallery" method="GET"> <div class="card nonshy-collapsible-mobile"> <header class="card-header has-background-link-light"> <p class="card-header-title"> Search Filters <span class="tag is-success ml-2">NEW</span> </p> <button class="card-header-icon" type="button"> <span class="icon"> <i class="fa fa-angle-up"></i> </span> </button> </header> <div class="card-content"> <div class="columns is-multiline mb-0"> {{if .CurrentUser.Explicit}} <div class="column"> <div class="field"> <label class="label" for="explicit">Explicit:</label> <div class="select is-fullwidth"> <select id="explicit" name="explicit"> <option value="">Show all</option> <option value="true"{{if eq .FilterExplicit "true"}} selected{{end}}>Only explicit</option> <option value="false"{{if eq .FilterExplicit "false"}} selected{{end}}>Hide explicit</option> </select> </div> </div> </div> {{end}} <div class="column"> <div class="field"> <label class="label" for="visibility">Visibility:</label> <div class="select is-fullwidth"> <select id="visibility" name="visibility"> <option value="">All photos</option> <option value="public"{{if eq .FilterVisibility "public"}} selected{{end}}>Public only</option> <option value="friends"{{if eq .FilterVisibility "friends"}} selected{{end}}>Friends only</option> <option value="private"{{if eq .FilterVisibility "private"}} selected{{end}}>Private only</option> </select> </div> </div> </div> <div class="column"> <div class="field"> <label class="label" for="sort">Sort by:</label> <div class="select is-fullwidth"> <select id="sort" name="sort"> <option value="created_at desc"{{if eq .Sort "created_at desc"}} selected{{end}}>Most recent</option> <option value="created_at asc"{{if eq .Sort "created_at asc"}} selected{{end}}>Oldest first</option> </select> </div> </div> </div> </div> <div class="has-text-centered"> <a href="/photo/gallery" class="button">Reset</a> <button type="submit" class="button is-success"> Apply Filters </button> </div> </div> </div> </form> </div> {{end}} {{if .IsOwnPhotos}} <div class="block"> <a href="/photo/private" class="has-text-private"> <span class="icon"><i class="fa fa-lock"></i></span> <span>Manage who can see <strong>my</strong> private photos</span> <span class="tag is-success">NEW</span> </a> </div> {{else if and (not .IsSiteGallery) (not .IsMyPrivateUnlockedFor)}} <div class="block"> <a href="/photo/private/share?to={{.User.Username}}" class="has-text-private"> <span class="icon"><i class="fa fa-unlock"></i></span> <span>Grant <strong>{{.User.Username}}</strong> access to see <strong>my</strong> private photos</span> <span class="tag is-success">NEW</span> </a> </div> {{else if and (not .IsSiteGallery) .IsMyPrivateUnlockedFor}} <div class="block"> <span class="icon"><i class="fa fa-unlock has-text-private"></i></span> <span>You had granted <strong>{{.User.Username}}</strong> access to see <strong>your</strong> private photos.</span> <a href="/photo/private">Manage that here.</a> <span class="tag is-success">NEW</span> </div> {{end}} {{template "pager" .}} <!-- "Full" view style? (blog style) --> {{if eq .ViewStyle "full"}} {{range .Photos}} <div class="card block"> <header class="card-header {{if .Explicit}}has-background-danger{{else}}has-background-link{{end}}"> <!-- Site Gallery header --> {{if $Root.IsSiteGallery}} <div class="card-header-title has-text-light"> {{if $Root.UserMap.Has .UserID}} {{$Owner := $Root.UserMap.Get .UserID}} <div class="columns is-mobile is-gapless nonshy-fullwidth"> <div class="column is-narrow"> <figure class="image is-24x24 mr-2"> {{if gt $Owner.ProfilePhoto.ID 0}} <img src="{{PhotoURL $Owner.ProfilePhoto.CroppedFilename}}" class="is-rounded"> {{else}} <img src="/static/img/shy.png" class="is-rounded has-background-warning"> {{end}} </figure> </div> <div class="column"> <a href="/u/{{$Owner.Username}}" class="has-text-light"> {{$Owner.Username}} <i class="fa fa-external-link ml-2"></i> </a> </div> <div class="column is-narrow"> <span class="icon"> {{if eq .Visibility "friends"}} <i class="fa fa-user-group has-text-warning" title="Friends"></i> {{else if eq .Visibility "private"}} <i class="fa fa-lock has-text-private-light" title="Private"></i> {{else}} <i class="fa fa-eye has-text-link-light" title="Public"></i> {{end}} </span> </div> </div> {{else}} <span class="fa fa-user mr-2"></span> <span>[deleted]</span> {{end}} </div> {{else}} <!-- User Gallery Full Header --> <p class="card-header-title has-text-light"> <span class="icon"> <i class="fa fa-image"></i> </span> {{or .Caption "Photo"}} </p> {{end}} </header> <div class="card-image"> <figure class="image"> <img src="{{PhotoURL .Filename}}"> </figure> </div> <div class="card-content"> {{if .Caption}} {{.Caption}} {{else}}<em>No caption</em>{{end}} {{template "card-body" .}} <!-- Like & Comments buttons --> <div class="mt-4 columns is-centered is-mobile is-gapless"> <div class="column is-narrow mr-1"> {{$Like := $Root.LikeMap.Get .ID}} <button type="button" class="button is-small nonshy-like-button" data-table-name="photos" data-table-id="{{.ID}}" title="Like"> <span class="icon{{if $Like.UserLikes}} has-text-danger{{end}}"><i class="fa fa-heart"></i></span> <span class="nonshy-likes"> Like {{if gt $Like.Count 0}} ({{$Like.Count}}) {{end}} </span> </button> </div> <div class="column is-narrow"> {{$Comments := $Root.CommentMap.Get .ID}} <a href="/photo/view?id={{.ID}}#comments" class="button is-small"> <span class="icon"><i class="fa fa-comment"></i></span> <span>{{$Comments}} Comment{{Pluralize64 $Comments}}</span> </a> </div> </div> </div> <footer class="card-footer"> {{if or $Root.IsOwnPhotos $Root.CurrentUser.IsAdmin}} {{template "card-footer" .}} {{end}} {{if not $Root.IsOwnPhotos}} <a class="card-footer-item has-text-danger" href="/contact?intent=report&subject=report.photo&id={{.ID}}"> <span class="icon"><i class="fa fa-flag"></i></span> <span>Report</span> </a> {{end}} </footer> </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"> <!-- Header only on Site Gallery version --> {{if $Root.IsSiteGallery}} <header class="card-header {{if .Explicit}}has-background-danger{{else}}has-background-link{{end}}"> <div class="card-header-title has-text-light"> {{if $Root.UserMap.Has .UserID}} {{$Owner := $Root.UserMap.Get .UserID}} <div class="columns is-mobile is-gapless nonshy-fullwidth"> <div class="column is-narrow"> <figure class="image is-24x24 mr-2"> {{if gt $Owner.ProfilePhoto.ID 0}} <img src="{{PhotoURL $Owner.ProfilePhoto.CroppedFilename}}" class="is-rounded"> {{else}} <img src="/static/img/shy.png" class="is-rounded has-background-warning"> {{end}} </figure> </div> <div class="column"> <a href="/u/{{$Owner.Username}}" class="has-text-light"> {{$Owner.Username}} <i class="fa fa-external-link ml-2"></i> </a> </div> <div class="column is-narrow"> <span class="icon"> {{if eq .Visibility "friends"}} <i class="fa fa-user-group has-text-warning" title="Friends"></i> {{else if eq .Visibility "private"}} <i class="fa fa-lock has-text-private-light" title="Private"></i> {{else}} <i class="fa fa-eye has-text-link-light" title="Public"></i> {{end}} </span> </div> </div> {{else}} <span class="fa fa-user mr-2"></span> <span>[deleted]</span> {{end}} </div> </header> {{end}} <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" .}} <!-- Like & Comments buttons --> <div class="mt-4 columns is-centered is-mobile is-gapless"> <div class="column is-narrow mr-1"> {{$Like := $Root.LikeMap.Get .ID}} <button type="button" class="button is-small nonshy-like-button" data-table-name="photos" data-table-id="{{.ID}}" title="Like"> <span class="icon{{if $Like.UserLikes}} has-text-danger{{end}}"><i class="fa fa-heart"></i></span> <span class="nonshy-likes"> Like {{if gt $Like.Count 0}} ({{$Like.Count}}) {{end}} </span> </button> </div> <div class="column is-narrow"> {{$Comments := $Root.CommentMap.Get .ID}} <a href="/photo/view?id={{.ID}}#comments" class="button is-small"> <span class="icon"><i class="fa fa-comment"></i></span> <span>{{$Comments}} Comment{{Pluralize64 $Comments}}</span> </a> </div> </div> </div> <footer class="card-footer"> {{if or $Root.IsOwnPhotos $Root.CurrentUser.IsAdmin}} {{template "card-footer" .}} {{end}} {{if not $Root.IsOwnPhotos}} <a class="card-footer-item has-text-danger" href="/contact?intent=report&subject=report.photo&id={{.ID}}"> <span class="icon"><i class="fa fa-flag"></i></span> <span class="is-hidden-desktop">Report</span> </a> {{end}} </footer> </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}}