Add in mark as reaad button to list view, use ajax to preform the action without page refresh.
This commit is contained in:
@@ -5,16 +5,33 @@
|
||||
{{ if .Messages }}
|
||||
<ul class="list-group mb-4">
|
||||
{{ range .Messages }}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center {{ if .IsRead }}read{{ end }}" data-msg-id="{{ .ID }}">
|
||||
<div>
|
||||
<a href="/account/messages/read?id={{ .ID }}" class="fw-bold text-dark">{{ .Subject }}</a><br>
|
||||
<small class="text-muted">{{ .CreatedAt.Format "02 Jan 2006 15:04" }}</small>
|
||||
</div>
|
||||
<form method="POST" action="/account/messages/archive" class="m-0">
|
||||
<input type="hidden" name="csrf_token" value="{{ $.CSRFToken }}">
|
||||
<input type="hidden" name="id" value="{{ .ID }}">
|
||||
<button type="submit" class="btn btn-sm btn-outline-secondary">Archive</button>
|
||||
</form>
|
||||
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
|
||||
{{/* Archive form (existing) */}}
|
||||
<form method="POST" action="/account/messages/archive" class="m-0">
|
||||
<input type="hidden" name="csrf_token" value="{{ $.CSRFToken }}">
|
||||
<input type="hidden" name="id" value="{{ .ID }}">
|
||||
<button type="submit" class="btn btn-sm btn-outline-secondary">Archive</button>
|
||||
</form>
|
||||
|
||||
{{/* Mark-read: only show when unread */}}
|
||||
{{ if not .IsRead }}
|
||||
<!-- Non-AJAX fallback form (submit will refresh) -->
|
||||
<form method="POST" action="/account/messages/mark-read" class="m-0 d-inline-block mark-read-form">
|
||||
<input type="hidden" name="csrf_token" value="{{ $.CSRFToken }}">
|
||||
<input type="hidden" name="id" value="{{ .ID }}">
|
||||
<button type="submit" class="btn btn-sm btn-outline-primary mark-read-btn"
|
||||
data-msg-id="{{ .ID }}"
|
||||
data-csrf="{{ $.CSRFToken }}">Mark read</button>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
@@ -49,4 +66,74 @@
|
||||
<a href="/account/messages/archive" class="btn btn-outline-secondary ms-2">View Archived</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{/* AJAX enhancement: unobtrusive — safe fallback to regular form when JS disabled */}}
|
||||
<script>
|
||||
;(function(){
|
||||
// Ensure browser supports fetch + FormData; otherwise we fallback to regular form submit.
|
||||
if (!window.fetch || !window.FormData) return;
|
||||
|
||||
// Helper to decrement topbar message count badge (assumes badge element id="message-count")
|
||||
function decrementMessageCount() {
|
||||
var el = document.getElementById('message-count');
|
||||
if (!el) return;
|
||||
var current = parseInt(el.textContent || el.innerText || '0', 10) || 0;
|
||||
var next = Math.max(0, current - 1);
|
||||
if (next <= 0) {
|
||||
// remove badge or hide it
|
||||
el.remove();
|
||||
} else {
|
||||
el.textContent = String(next);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle clicks on mark-read buttons, submit via fetch, update DOM
|
||||
document.addEventListener('click', function(e){
|
||||
var btn = e.target.closest('.mark-read-btn');
|
||||
if (!btn) return;
|
||||
|
||||
// Prevent the default form POST (non-AJAX fallback)
|
||||
e.preventDefault();
|
||||
|
||||
var msgID = btn.dataset.msgId;
|
||||
var csrf = btn.dataset.csrf;
|
||||
|
||||
if (!msgID) {
|
||||
// fallback to normal submit if something's wrong
|
||||
var frm = btn.closest('form');
|
||||
if (frm) frm.submit();
|
||||
return;
|
||||
}
|
||||
|
||||
// Build urlencoded body like a regular form
|
||||
var body = new URLSearchParams();
|
||||
body.append('id', msgID);
|
||||
if (csrf) body.append('csrf_token', csrf);
|
||||
|
||||
fetch('/account/messages/mark-read', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
body: body.toString(),
|
||||
credentials: 'same-origin'
|
||||
}).then(function(resp){
|
||||
if (resp.ok) {
|
||||
// UI update: remove the mark-read button, give item a .read class, update topbar count
|
||||
var li = document.querySelector('li[data-msg-id="' + msgID + '"]');
|
||||
if (li) {
|
||||
li.classList.add('read');
|
||||
// remove any mark-read form/button inside
|
||||
var form = li.querySelector('.mark-read-form');
|
||||
if (form) form.remove();
|
||||
}
|
||||
decrementMessageCount();
|
||||
} else {
|
||||
// If server returned non-2xx, fall back to full reload to show flash
|
||||
resp.text().then(function(){ window.location.reload(); }).catch(function(){ window.location.reload(); });
|
||||
}
|
||||
}).catch(function(){ window.location.reload(); });
|
||||
}, false);
|
||||
})();
|
||||
</script>
|
||||
{{ end }}
|
||||
|
||||
Reference in New Issue
Block a user