264 lines
9.4 KiB
HTML
264 lines
9.4 KiB
HTML
{% extends "base.html" %}
|
||
{% block body_class %}themed-bg{% endblock %}
|
||
{% load static %}
|
||
|
||
{% block content %}
|
||
<div class="result-wrap">
|
||
|
||
<!-- Top bar: back + counter + clear Prev/Next -->
|
||
<div class="result-toolbar">
|
||
<div class="rt-left">
|
||
<a class="btn btn-secondary" href="{% url 'search' %}">← Back to Search</a>
|
||
{% if count %}
|
||
<span class="rt-count">{{ position }} of {{ count }}</span>
|
||
{% endif %}
|
||
</div>
|
||
<div class="rt-right">
|
||
<form method="get" action="{% url 'nav_prev' %}" class="inline">
|
||
<!-- send current zero-based index (position-1); view will subtract 1 -->
|
||
<input type="hidden" name="i" value="{{ position|add:'-1' }}">
|
||
<button class="btn btn-lg" {% if position <= 1 %}disabled{% endif %}>‹ Prev</button>
|
||
</form>
|
||
<form method="get" action="{% url 'nav_next' %}" class="inline">
|
||
<!-- send current zero-based index (position-1); view will add 1 -->
|
||
<input type="hidden" name="i" value="{{ position|add:'-1' }}">
|
||
<button class="btn btn-lg btn-primary" {% if position >= count %}disabled{% endif %}>Next ›</button>
|
||
</form>
|
||
|
||
<!-- NEW: Share button -->
|
||
<button class="btn btn-lg" id="share-btn" type="button" title="Copy illustration to clipboard">
|
||
<!-- iOS-like share icon (square with up arrow) -->
|
||
<svg width="18" height="18" viewBox="0 0 24 24" aria-hidden="true" style="margin-right:6px; vertical-align:-3px;">
|
||
<path fill="currentColor" d="M12 3a1 1 0 0 1 1 1v7.586l1.293-1.293a1 1 0 1 1 1.414 1.414l-3.004 3.004a1 1 0 0 1-1.414 0L8.285 11.707a1 1 0 1 1 1.414-1.414L11 11.586V4a1 1 0 0 1 1-1z"/>
|
||
<path fill="currentColor" d="M6 8a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2h-2a1 1 0 1 0 0 2h2v8H6v-8h2a1 1 0 1 0 0-2H6z"/>
|
||
</svg>
|
||
Share
|
||
</button>
|
||
|
||
{% if user.is_authenticated and user.is_staff %}
|
||
<a class="btn btn-outline" href="{% url 'entry_edit' entry.id %}">Edit</a>
|
||
<a class="btn btn-danger" href="{% url 'entry_delete' entry.id %}">Delete</a>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Main card -->
|
||
<div class="result-card">
|
||
<!-- SUBJECT pills (WOL-linked) -->
|
||
<div class="subject-pills">
|
||
{% if subject_list %}
|
||
{% for s in subject_list %}
|
||
<a
|
||
class="chip chip-subject"
|
||
href="https://wol.jw.org/en/wol/s/r1/lp-e?q={{ s }}"
|
||
target="_blank" rel="noopener noreferrer"
|
||
title="Search WOL for {{ s }}"
|
||
>{{ s }}</a>
|
||
{% endfor %}
|
||
{% else %}
|
||
<span class="chip chip-muted">(no subject)</span>
|
||
{% endif %}
|
||
</div>
|
||
|
||
<!-- ILLUSTRATION -->
|
||
<div class="section">
|
||
<div class="section-label">Illustration</div>
|
||
<div id="illustrationText" class="section-body lead-text">
|
||
{{ entry.illustration|linebreaksbr|default:"—" }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- APPLICATION -->
|
||
<div class="section">
|
||
<div class="section-label">Application</div>
|
||
<div id="applicationText" class="section-body lead-text">
|
||
{{ entry.application|linebreaksbr|default:"—" }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Meta (smaller) -->
|
||
<div class="meta-grid">
|
||
<div class="meta-item">
|
||
<div class="meta-label">Source</div>
|
||
<div class="meta-value">
|
||
{% if entry.source %}
|
||
{% with s=entry.source|strip %}
|
||
{% with sl=s|lower %}
|
||
{% if
|
||
sl|slice:":2" == "w " or sl|startswith:"w" or
|
||
sl|slice:":2" == "wp" or sl|slice:":2" == "ws" or sl|slice:":1" == "g" or
|
||
sl|slice:":2" == "yb" or sl|slice:":2" == "kt" or
|
||
sl|slice:":2" == "km" or sl|slice:":3" == "mwb" or
|
||
sl|slice:":2" == "ap" or sl|slice:":3" == "apf" or sl|slice:":2" == "be" or sl|slice:":2" == "bh" or
|
||
sl|slice:":2" == "br" or sl|slice:":2" == "bt" or sl|slice:":3" == "btg" or sl|slice:":2" == "cf" or
|
||
sl|slice:":2" == "cl" or sl|slice:":2" == "ct" or sl|slice:":2" == "dp" or sl|slice:":2" == "fg" or
|
||
sl|slice:":2" == "fy" or sl|slice:":2" == "gt" or sl|slice:":2" == "hb" or sl|slice:":2" == "im" or
|
||
sl|slice:":2" == "ip" or sl|slice:":2" == "it" or sl|slice:":2" == "jv" or sl|slice:":2" == "ka" or
|
||
sl|slice:":2" == "kj" or sl|slice:":2" == "kl" or sl|slice:":2" == "lf" or sl|slice:":3" == "lff" or
|
||
sl|slice:":2" == "ll" or sl|slice:":2" == "ly" or sl|slice:":2" == "my" or sl|slice:":2" == "od" or
|
||
sl|slice:":2" == "pe" or sl|slice:":2" == "po" or sl|slice:":2" == "pt" or sl|slice:":2" == "rr" or
|
||
sl|slice:":2" == "rs" or sl|slice:":2" == "sg" or sl|slice:":2" == "sh" or sl|slice:":2" == "si" or
|
||
sl|slice:":2" == "td" or sl|slice:":2" == "tp" or sl|slice:":2" == "tr" or sl|slice:":2" == "ts" or
|
||
sl|slice:":2" == "un"
|
||
%}
|
||
<a class="chip chip-link"
|
||
href="https://wol.jw.org/en/wol/l/r1/lp-e?q={{ s|urlencode }}"
|
||
target="_blank" rel="noopener noreferrer">
|
||
{{ s }}
|
||
</a>
|
||
{% else %}
|
||
<a class="chip chip-link"
|
||
href="https://www.google.com/search?q={{ s|urlencode }}"
|
||
target="_blank" rel="noopener noreferrer">
|
||
{{ s }}
|
||
</a>
|
||
{% endif %}
|
||
{% endwith %}
|
||
{% endwith %}
|
||
{% else %}—{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="meta-item">
|
||
<div class="meta-label">Scripture</div>
|
||
<div class="meta-value">
|
||
{% if scripture_list %}
|
||
{% for sc in scripture_list %}
|
||
<a class="chip chip-link"
|
||
href="https://wol.jw.org/en/wol/l/r1/lp-e?q={{ sc|urlencode }}"
|
||
target="_blank" rel="noopener noreferrer">
|
||
{{ sc }}
|
||
</a>
|
||
{% endfor %}
|
||
{% else %}—{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="meta-item">
|
||
<div class="meta-label">Code</div>
|
||
<div class="meta-value">{{ entry.entry_code|default:"—" }}</div>
|
||
</div>
|
||
|
||
<div class="meta-item">
|
||
<div class="meta-label">Talk</div>
|
||
<div class="meta-value">
|
||
{% if entry.talk_title %}{{ entry.talk_title }}{% else %}—{% endif %}
|
||
{% if entry.talk_number %}<span class="chip chip-muted">#{{ entry.talk_number }}</span>{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="meta-item">
|
||
<div class="meta-label">Dates</div>
|
||
<div class="meta-value small">
|
||
{% if entry.date_added %}Added: {{ entry.date_added }}{% else %}Added: —{% endif %}
|
||
{% if entry.date_edited %} • Edited: {{ entry.date_edited }}{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- subject pill styling kept -->
|
||
<style>
|
||
.subject-pills{
|
||
display:flex;
|
||
flex-wrap:wrap;
|
||
gap:10px;
|
||
margin:0 0 10px;
|
||
}
|
||
.chip-subject{
|
||
font-weight:700;
|
||
font-size:16px;
|
||
padding:8px 14px;
|
||
border-radius:999px;
|
||
background:#eef5fc;
|
||
border:1px solid #d7e6f7;
|
||
color:#0f172a;
|
||
text-decoration:none;
|
||
text-transform: capitalize;
|
||
}
|
||
.chip-subject:hover{
|
||
background:#e2effc;
|
||
border-color:#c9def5;
|
||
}
|
||
|
||
/* Toast */
|
||
.copy-toast {
|
||
position: fixed;
|
||
right: 16px;
|
||
bottom: 16px;
|
||
background: #111827;
|
||
color: #fff;
|
||
border-radius: 10px;
|
||
padding: 10px 14px;
|
||
font-size: 14px;
|
||
line-height: 1.3;
|
||
box-shadow: 0 8px 24px rgba(0,0,0,.18);
|
||
opacity: 0;
|
||
transform: translateY(8px);
|
||
pointer-events: none;
|
||
transition: opacity .15s ease, transform .15s ease;
|
||
z-index: 9999;
|
||
}
|
||
.copy-toast.show {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
</style>
|
||
|
||
<!-- Toast container -->
|
||
<div id="copyToast" class="copy-toast" role="status" aria-live="polite">
|
||
The Illustration was copied to the clipboard
|
||
</div>
|
||
|
||
<!-- Share script -->
|
||
<script>
|
||
(function () {
|
||
const btn = document.getElementById('share-btn');
|
||
const toast = document.getElementById('copyToast');
|
||
|
||
function showToast() {
|
||
toast.classList.add('show');
|
||
setTimeout(() => toast.classList.remove('show'), 5000);
|
||
}
|
||
|
||
function getText(el) {
|
||
// innerText preserves visual line breaks from <br>, which is what we want for copying plain text.
|
||
return (el && el.innerText ? el.innerText.trim() : "").replace(/\s+$/,'');
|
||
}
|
||
|
||
async function copyIllustration() {
|
||
const illEl = document.getElementById('illustrationText');
|
||
const appEl = document.getElementById('applicationText');
|
||
|
||
const ill = getText(illEl);
|
||
const app = getText(appEl);
|
||
|
||
const text = `${ill}${ill && app ? " " : ""}${app}`; // two spaces between if both exist
|
||
|
||
try {
|
||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||
await navigator.clipboard.writeText(text);
|
||
} else {
|
||
// Fallback
|
||
const ta = document.createElement('textarea');
|
||
ta.value = text;
|
||
ta.style.position = 'fixed';
|
||
ta.style.top = '-9999px';
|
||
document.body.appendChild(ta);
|
||
ta.select();
|
||
document.execCommand('copy');
|
||
document.body.removeChild(ta);
|
||
}
|
||
showToast();
|
||
} catch (e) {
|
||
// If it fails silently, at least try to show something
|
||
showToast();
|
||
}
|
||
}
|
||
|
||
if (btn) btn.addEventListener('click', copyIllustration);
|
||
})();
|
||
</script>
|
||
{% endblock %} |