Noah
aa8d719fc4
* Add ability to (un)subscribe from comment threads on Forums and Photos. * Creating a forum post, replying to a post or adding a comment to a photo automatically subscribes you to be notified when somebody else adds a comment to the thing later. * At the top of each comment thread is a link to disable or re-enable your subscription. You can join a subscription without even needing to comment. If you click to disable notifications, they stay disabled even if you add another comment later.
369 lines
20 KiB
HTML
369 lines
20 KiB
HTML
{{define "title"}}My Dashboard{{end}}
|
|
{{define "content"}}
|
|
<div class="container">
|
|
<section class="hero is-info is-bold">
|
|
<div class="hero-body">
|
|
<div class="container">
|
|
<h1 class="title">User Dashboard</h1>
|
|
<h2 class="subtitle">to your account</h2>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<div class="block p-4">
|
|
<div class="columns">
|
|
<div class="column">
|
|
<!-- Onboarding Checklist -->
|
|
{{if or (not .CurrentUser.Certified) (not .CurrentUser.ProfilePhoto.ID)}}
|
|
<div class="card block">
|
|
<header class="card-header has-background-danger">
|
|
<p class="card-header-title has-text-light">
|
|
<span class="icon"><i class="fa fa-check"></i></span>
|
|
<span>Onboarding Checklist</span>
|
|
</p>
|
|
</header>
|
|
|
|
<div class="card-content">
|
|
<p class="block">
|
|
You're almost there! Please review the following checklist items to gain
|
|
full access to this website. Members are expected to have a face picture
|
|
as their default Profile Pic and upload a Verification Photo to become
|
|
certified as being a real person.
|
|
</p>
|
|
|
|
<ul class="menu-list block">
|
|
<li>
|
|
<a href="/photo/upload?intent=profile_pic">
|
|
{{if .CurrentUser.ProfilePhoto.ID}}
|
|
<span class="icon"><i class="fa fa-circle-check has-text-success"></i></span>
|
|
{{else}}
|
|
<span class="icon"><i class="fa fa-circle has-text-danger"></i></span>
|
|
{{end}}
|
|
<span>
|
|
Add a Profile Picture
|
|
{{if not .CurrentUser.ProfilePhoto.ID}}
|
|
<span class="icon"><i class="fa fa-external-link"></i></span>
|
|
{{end}}
|
|
</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/photo/certification">
|
|
{{if .CurrentUser.Certified}}
|
|
<span class="icon"><i class="fa fa-circle-check has-text-success"></i></span>
|
|
{{else}}
|
|
<span class="icon"><i class="fa fa-circle has-text-danger"></i></span>
|
|
{{end}}
|
|
<span>
|
|
Get certified by uploading a verification selfie
|
|
{{if not .CurrentUser.Certified}}
|
|
<span class="icon"><i class="fa fa-external-link"></i></span>
|
|
{{end}}
|
|
</span>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
<div class="card block">
|
|
<header class="card-header has-background-link">
|
|
<p class="card-header-title has-text-light">My Account</p>
|
|
</header>
|
|
|
|
<div class="card-content">
|
|
<ul class="menu-list">
|
|
<li>
|
|
<a href="/u/{{.CurrentUser.Username}}">
|
|
<span class="icon"><i class="fa fa-user"></i></span>
|
|
My Profile
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="/photo/u/{{.CurrentUser.Username}}">
|
|
<span class="icon"><i class="fa fa-image"></i></span>
|
|
My Photos
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="/photo/upload">
|
|
<span class="icon"><i class="fa fa-upload"></i></span>
|
|
Upload Photos
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="/settings">
|
|
<span class="icon"><i class="fa fa-edit"></i></span>
|
|
Edit Profile & Settings
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="/photo/certification">
|
|
<span class="icon"><i class="fa fa-certificate"></i></span>
|
|
Certification Photo
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="/users/blocked">
|
|
<span class="icon"><i class="fa fa-hand"></i></span>
|
|
Blocked Users
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="/logout">
|
|
<span class="icon"><i class="fa fa-arrow-right-from-bracket"></i></span>
|
|
Log out
|
|
</a>
|
|
</li>
|
|
{{if .SessionImpersonated}}
|
|
<li>
|
|
<a href="/admin/unimpersonate" class="has-text-danger">
|
|
<span class="icon"><i class="fa fa-ghost"></i></span>
|
|
<span>Unimpersonate</span>
|
|
</a>
|
|
</li>
|
|
{{end}}
|
|
<li>
|
|
<a href="/account/delete">
|
|
<span class="icon"><i class="fa fa-trash"></i></span>
|
|
Delete account
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{$Root := .}}
|
|
|
|
<div class="column">
|
|
<div class="card" id="notifications">
|
|
<header class="card-header has-background-warning">
|
|
<p class="card-header-title">Notifications</p>
|
|
</header>
|
|
|
|
<div class="card-content">
|
|
<div class="columns">
|
|
<div class="column">
|
|
{{if gt .NavUnreadNotifications 0}}
|
|
{{.NavUnreadNotifications}} unread notification{{Pluralize64 .NavUnreadNotifications}}.
|
|
{{else}}
|
|
No unread notifications.
|
|
{{end}}
|
|
</div>
|
|
<div class="column is-narrow">
|
|
<a href="/me?intent=read-notifications" class="button is-link is-light is-small">
|
|
<span class="icon-text">
|
|
<span class="icon"><i class="fa fa-check"></i></span>
|
|
<span>Mark all as read</span>
|
|
</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<table class="table is-striped is-fullwidth is-hoverable">
|
|
<tbody>
|
|
{{range .Notifications}}
|
|
{{$Body := $Root.NotifMap.Get .ID}}
|
|
<tr>
|
|
<td class="nonshy-notification-row" data-notification-id="{{.ID}}">
|
|
<div class="columns">
|
|
<div class="column is-narrow has-text-centered">
|
|
{{if not .Read}}
|
|
<div class="mb-2 nonshy-notification-new">
|
|
<strong class="tag is-success">NEW!</strong>
|
|
</div>
|
|
{{end}}
|
|
<a href="/u/{{.AboutUser.Username}}">
|
|
<figure class="image is-48x48 is-inline-block">
|
|
{{if .AboutUser.ProfilePhoto.ID}}
|
|
<img src="{{PhotoURL .AboutUser.ProfilePhoto.CroppedFilename}}">
|
|
{{else}}
|
|
<img src="/static/img/shy.png">
|
|
{{end}}
|
|
</figure>
|
|
</a>
|
|
</div>
|
|
<div class="column">
|
|
<div class="mb-1">
|
|
{{if eq .Type "like"}}
|
|
<span class="icon"><i class="fa fa-heart has-text-danger"></i></span>
|
|
<span>
|
|
<a href="/u/{{.AboutUser.Username}}"><strong>{{.AboutUser.Username}}</strong></a>
|
|
liked your
|
|
{{if eq .TableName "photos"}}
|
|
{{if $Body.Photo}}
|
|
<a href="/photo/view?id={{$Body.Photo.ID}}">photo</a>.
|
|
{{else}}
|
|
photo.
|
|
{{end}}
|
|
{{else if eq .TableName "users"}}
|
|
profile page.
|
|
{{else}}
|
|
{{.TableName}}.
|
|
{{end}}
|
|
</span>
|
|
{{else if eq .Type "comment"}}
|
|
<span class="icon"><i class="fa fa-comment has-text-success"></i></span>
|
|
<span>
|
|
<a href="/u/{{.AboutUser.Username}}"><strong>{{.AboutUser.Username}}</strong></a>
|
|
commented on your
|
|
<a href="{{.Link}}">
|
|
{{if eq .TableName "photos"}}
|
|
photo:
|
|
{{else}}
|
|
{{.TableName}}:
|
|
{{end}}
|
|
</a>
|
|
</span>
|
|
{{else if eq .Type "also_comment"}}
|
|
<span class="icon"><i class="fa fa-comment has-text-success"></i></span>
|
|
<span>
|
|
<a href="/u/{{.AboutUser.Username}}"><strong>{{.AboutUser.Username}}</strong></a>
|
|
also commented on a
|
|
<a href="{{.Link}}">
|
|
{{if eq .TableName "photos"}}
|
|
photo
|
|
{{else}}
|
|
{{.TableName}}
|
|
{{end}}
|
|
</a>
|
|
that you replied to:
|
|
</span>
|
|
{{else if eq .Type "also_posted"}}
|
|
<span class="icon"><i class="fa fa-comments has-text-success"></i></span>
|
|
<span>
|
|
<a href="/u/{{.AboutUser.Username}}"><strong>{{.AboutUser.Username}}</strong></a>
|
|
replied to <a href="{{.Link}}">a forum thread</a> that you follow:
|
|
</span>
|
|
{{else if eq .Type "friendship_approved"}}
|
|
<span class="icon"><i class="fa fa-user-group has-text-success"></i></span>
|
|
<span>
|
|
<a href="/u/{{.AboutUser.Username}}"><strong>{{.AboutUser.Username}}</strong></a>
|
|
accepted your friend request!
|
|
</span>
|
|
{{else if eq .Type "cert_approved"}}
|
|
<span class="icon"><i class="fa fa-certificate has-text-success"></i></span>
|
|
<span>
|
|
Your <strong>certification photo</strong> was approved!
|
|
</span>
|
|
{{else if eq .Type "cert_rejected"}}
|
|
<span class="icon"><i class="fa fa-certificate has-text-danger"></i></span>
|
|
<span>
|
|
Your <strong>certification photo</strong> was rejected!
|
|
</span>
|
|
{{else}}
|
|
{{.AboutUser.Username}} {{.Type}} {{.TableName}} {{.TableID}}
|
|
{{end}}
|
|
</div>
|
|
|
|
<!-- Attached message? -->
|
|
{{if .Message}}
|
|
<div class="block content mb-1">
|
|
<blockquote class="p-2 pl-4">{{ToMarkdown (TrimEllipses .Message 256)}}</blockquote>
|
|
</div>
|
|
{{end}}
|
|
|
|
<!-- Attached forum thread? -->
|
|
{{if $Body.Thread}}
|
|
<div>
|
|
On thread: <a href="{{.Link}}">{{$Body.Thread.Title}}</a>
|
|
</div>
|
|
{{end}}
|
|
|
|
<!-- Photo caption? -->
|
|
{{if $Body.Photo}}
|
|
<div class="block">
|
|
<!-- If it's a comment, have a link to view it -->
|
|
{{if eq .Type "comment"}}
|
|
<div class="is-size-7 pt-1">
|
|
<span class="icon"><i class="fa fa-arrow-right"></i></span>
|
|
<a href="{{.Link}}">See all comments</a>
|
|
</div>
|
|
{{else}}
|
|
<em>{{or $Body.Photo.Caption "No caption."}}</em>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
|
|
<hr class="has-background-light mb-1">
|
|
<small title="{{.CreatedAt.Format "2006-01-02 15:04:05"}}">
|
|
{{SincePrettyCoarse .CreatedAt}} ago
|
|
</small>
|
|
</div>
|
|
|
|
<!-- Attached photo? -->
|
|
{{if $Body.PhotoID}}
|
|
<div class="column is-one-quarter">
|
|
<a href="/photo/view?id={{$Body.Photo.ID}}">
|
|
<img src="{{PhotoURL $Body.Photo.Filename}}">
|
|
</a>
|
|
|
|
{{if $Body.Photo.Caption}}
|
|
<small>{{$Body.Photo.Caption}}</small>
|
|
{{else}}
|
|
<small><em>No caption.</em></small>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
|
|
</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
|
|
{{if .Pager.HasNext}}
|
|
<div class="has-text-centered">
|
|
<a href="{{.Request.URL.Path}}?page={{.Pager.Next}}" class="button">View older notifications</a>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
// Notifications helper.
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
let busy = false;
|
|
|
|
// Bind to the notification table rows.
|
|
(document.querySelectorAll(".nonshy-notification-row") || []).forEach(node => {
|
|
node.addEventListener("click", (e) => {
|
|
if (busy) return;
|
|
|
|
let $newBadge = node.querySelector(".nonshy-notification-new"),
|
|
ID = node.dataset.notificationId;
|
|
$newBadge.style.display = "none";
|
|
|
|
return fetch("/v1/notifications/read", {
|
|
method: "POST",
|
|
mode: "same-origin",
|
|
cache: "no-cache",
|
|
credentials: "same-origin",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
"id": parseInt(ID),
|
|
}),
|
|
})
|
|
.then((response) => response.json())
|
|
.then((data) => {
|
|
console.log(data);
|
|
}).catch(resp => {
|
|
window.alert(resp);
|
|
}).finally(() => {
|
|
busy = false;
|
|
})
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
{{end}} |