1c013aa8d8
* If a Certified member deletes the final picture from their gallery page, their Certification Photo will be automatically rejected and they are instructed to begin the process again from the beginning. * Add nice Alert and Confirm modals around the website in place of the standard browser feature. Note: the inline confirm on submit buttons are still using the standard feature for now, as intercepting submit buttons named "intent" causes problems in getting the final form to submit.
209 lines
7.5 KiB
HTML
209 lines
7.5 KiB
HTML
<!-- "Likes" modal to see who liked a thing -->
|
|
|
|
<!-- Reusable "Liked by Alice, Bob and 5 others" widget that invokes
|
|
the Like Modal. Requirements: pass in a context providing the
|
|
following variables:
|
|
|
|
- LikeExample: slice of users
|
|
- LikeRemainder: integer
|
|
- LikeTableName: like 'photos'
|
|
- LikeTableID: integer
|
|
|
|
Call this like: {{template "like-example" .}}
|
|
-->
|
|
{{define "like-example"}}
|
|
{{$Outer := .}}
|
|
{{if .LikeExample}}
|
|
<div class="mt-4 mb-2 has-text-centered">
|
|
Liked by
|
|
|
|
<!-- User list -->
|
|
{{range $i, $User := .LikeExample}}
|
|
<!-- Avatar -->
|
|
<figure class="image is-16x16 is-inline-block">
|
|
<a href="/u/{{$User.Username}}" class="has-text-dark">
|
|
{{if $User.ProfilePhoto.ID}}
|
|
{{if and (eq $User.ProfilePhoto.Visibility "private") (not $User.UserRelationship.IsPrivateGranted)}}
|
|
<img class="is-rounded" src="/static/img/shy-private.png">
|
|
{{else if and (eq $User.ProfilePhoto.Visibility "friends") (not $User.UserRelationship.IsFriend)}}
|
|
<img class="is-rounded" src="/static/img/shy-friends.png">
|
|
{{else}}
|
|
<img class="is-rounded" src="{{PhotoURL $User.ProfilePhoto.CroppedFilename}}">
|
|
{{end}}
|
|
{{else}}
|
|
<img class="is-rounded" src="/static/img/shy.png">
|
|
{{end}}
|
|
</a>
|
|
</figure>
|
|
|
|
<!-- Username plus a comma if multiple -->
|
|
<a href="/u/{{$User.Username}}">
|
|
{{- $User.Username -}}
|
|
</a>{{if and (eq (len $Outer.LikeExample) 2) (not $Outer.LikeRemainder)}}
|
|
{{if eq $i 0}}
|
|
and
|
|
{{end}}
|
|
{{- else if gt (len $Outer.LikeExample) 1}},{{end}}
|
|
{{end}}
|
|
|
|
<!-- Others -->
|
|
{{if .LikeRemainder}}
|
|
and
|
|
<a
|
|
href="#"
|
|
onclick="ShowLikeModal('{{.LikeTableName}}', {{.LikeTableID}}); return false"
|
|
>
|
|
{{.LikeRemainder}} other{{Pluralize64 .LikeRemainder}}</a>.
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
{{end}}
|
|
|
|
{{define "like-modal"}}
|
|
<div id="like-modal-app">
|
|
<div class="modal vue-managed" :class="{'is-active': visible}">
|
|
<div class="modal-background" @click="visible=false"></div>
|
|
<div class="modal-content">
|
|
<div class="card">
|
|
<div class="card-header has-background-info">
|
|
<p class="card-header-title has-text-light">
|
|
<i class="fa fa-heart mr-2"></i> [[title]]
|
|
</p>
|
|
</div>
|
|
<div class="card-content">
|
|
|
|
<div v-if="busy">
|
|
<i class="fa fa-spinner fa-spin"></i> Loading likes...
|
|
</div>
|
|
<div v-else>
|
|
<p class="block">
|
|
Found [[ total ]] like[[ total === 1 ? '' : 's' ]]
|
|
(page [[ page ]] of [[ pages ]]).
|
|
</p>
|
|
|
|
<div class="columns is-multiline">
|
|
<div class="column is-one-third"
|
|
v-for="row in result">
|
|
|
|
<!-- Avatar -->
|
|
<figure class="image is-16x16 is-inline-block mr-2">
|
|
<a :href="'/u/'+row.username" class="has-text-dark">
|
|
<img class="is-rounded" :src="row.avatar">
|
|
</a>
|
|
</figure>
|
|
|
|
<!-- Username link -->
|
|
<a :href="'/u/'+row.username" target="_blank">[[ row.username ]]</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Pager buttons -->
|
|
<div class="columns is-mobile">
|
|
<div class="column is-narrow">
|
|
<button type="button" class="button"
|
|
@click="prevPage()"
|
|
:disabled="page <= 1">
|
|
Previous
|
|
</button>
|
|
</div>
|
|
<div class="column is-narrow">
|
|
<button type="button" class="button"
|
|
@click="nextPage()"
|
|
:disabled="page >= pages">
|
|
Next page
|
|
</button>
|
|
</div>
|
|
<div class="column has-text-right">
|
|
<button type="button" class="button is-primary"
|
|
@click="visible=false">
|
|
Close
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
// Implemented in Vue widget.
|
|
var ShowLikeModal = function(tableName, tableID) {};
|
|
|
|
const likeModalApp = Vue.createApp({
|
|
delimiters: ['[[', ']]'],
|
|
data() {
|
|
return {
|
|
visible: false,
|
|
title: "Likes",
|
|
|
|
busy: false,
|
|
tableName: "photos",
|
|
tableID: 0,
|
|
page: 1,
|
|
pages: 0,
|
|
total: 0,
|
|
result: [],
|
|
}
|
|
},
|
|
mounted() {
|
|
ShowLikeModal = this.ShowLikeModal;
|
|
},
|
|
methods: {
|
|
ShowLikeModal(tableName, tableID) {
|
|
this.tableName = tableName;
|
|
this.tableID = tableID;
|
|
this.visible = true;
|
|
this.page = 1;
|
|
this.get();
|
|
},
|
|
|
|
prevPage() {
|
|
this.page--;
|
|
if (this.page <= 1) {
|
|
this.page = 1;
|
|
}
|
|
this.get();
|
|
},
|
|
nextPage() {
|
|
this.page++;
|
|
this.get();
|
|
},
|
|
|
|
get() {
|
|
this.busy = true;
|
|
return fetch("/v1/likes/users?" + new URLSearchParams({
|
|
table_name: this.tableName,
|
|
table_id: this.tableID,
|
|
page: this.page,
|
|
}), {
|
|
method: "GET",
|
|
mode: "same-origin",
|
|
cache: "no-cache",
|
|
credentials: "same-origin",
|
|
})
|
|
.then((response) => response.json())
|
|
.then((data) => {
|
|
if (data.StatusCode !== 200) {
|
|
modalAlert({message: data.data.error});
|
|
return;
|
|
}
|
|
|
|
let likes = data.data.likes;
|
|
this.pages = data.data.pages;
|
|
this.total = data.data.pager.Total;
|
|
this.result = likes;
|
|
}).catch(resp => {
|
|
console.error(resp);
|
|
}).finally(() => {
|
|
this.busy = false;
|
|
});
|
|
},
|
|
},
|
|
});
|
|
likeModalApp.mount("#like-modal-app");
|
|
</script>
|
|
{{end}}
|