123 lines
4.2 KiB
HTML
123 lines
4.2 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}{{ cfg.site.name }}{% endblock %}
|
|
{% block main_class %}full-page{% endblock %}
|
|
|
|
{% block nav_actions %}
|
|
<input type="text" id="title" placeholder="Title (optional)" class="nav-input" maxlength="100" autocomplete="off">
|
|
<select id="language" class="nav-select"></select>
|
|
<select id="expires_in" class="nav-select">
|
|
<option value="never">Never</option>
|
|
<option value="1hour">1 Hour</option>
|
|
<option value="1day">1 Day</option>
|
|
<option value="1week">1 Week</option>
|
|
<option value="1month">1 Month</option>
|
|
</select>
|
|
<button id="submitBtn" class="nav-btn nav-btn-save">Save</button>
|
|
{% if cfg.theme.allow_user_toggle %}
|
|
<button class="theme-toggle" onclick="toggleTheme()">🌙</button>
|
|
{% endif %}
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<textarea
|
|
id="content"
|
|
class="full-editor"
|
|
placeholder="Paste your code or text here…"
|
|
spellcheck="false"
|
|
autocomplete="off"
|
|
autocorrect="off"
|
|
autocapitalize="off"></textarea>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
const textarea = document.getElementById('content');
|
|
const submitBtn = document.getElementById('submitBtn');
|
|
const langSelect = document.getElementById('language');
|
|
|
|
// Load languages
|
|
fetch('/api/languages')
|
|
.then(r => r.json())
|
|
.then(langs => {
|
|
langSelect.innerHTML = '';
|
|
langs.forEach(l => {
|
|
const o = document.createElement('option');
|
|
o.value = l.value; o.textContent = l.name;
|
|
langSelect.appendChild(o);
|
|
});
|
|
// Restore saved preference
|
|
const saved = localStorage.getItem('preferred_language');
|
|
if (saved) langSelect.value = saved;
|
|
})
|
|
.catch(() => {});
|
|
|
|
langSelect.addEventListener('change', () =>
|
|
localStorage.setItem('preferred_language', langSelect.value));
|
|
|
|
const expirySelect = document.getElementById('expires_in');
|
|
const savedExpiry = localStorage.getItem('preferred_expiry');
|
|
if (savedExpiry) expirySelect.value = savedExpiry;
|
|
expirySelect.addEventListener('change', () =>
|
|
localStorage.setItem('preferred_expiry', expirySelect.value));
|
|
|
|
// Ctrl/Cmd+S to save
|
|
document.addEventListener('keydown', e => {
|
|
if ((e.ctrlKey || e.metaKey) && e.key === 's') {
|
|
e.preventDefault(); submitPaste();
|
|
}
|
|
});
|
|
|
|
submitBtn.addEventListener('click', submitPaste);
|
|
|
|
const E2E = {{ cfg.features.encrypt_pastes | tojson }};
|
|
|
|
async function submitPaste() {
|
|
const content = textarea.value;
|
|
const title = document.getElementById('title').value || 'Untitled';
|
|
const language = langSelect.value;
|
|
const expires_in = expirySelect.value;
|
|
|
|
if (!content.trim()) { textarea.focus(); return; }
|
|
|
|
submitBtn.disabled = true;
|
|
submitBtn.textContent = '…';
|
|
|
|
try {
|
|
let postBody, keyBase64 = null;
|
|
if (E2E) {
|
|
const key = await PasteCrypto.generateKey();
|
|
keyBase64 = await PasteCrypto.exportKey(key);
|
|
const plain = JSON.stringify({ title, content, language });
|
|
postBody = { encrypted_data: await PasteCrypto.encrypt(plain, key), expires_in };
|
|
} else {
|
|
postBody = { title, content, language, expires_in };
|
|
}
|
|
|
|
const resp = await fetch('/create', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(postBody)
|
|
});
|
|
const result = await resp.json();
|
|
|
|
if (result.error) {
|
|
alert('Error: ' + result.error);
|
|
submitBtn.disabled = false;
|
|
submitBtn.textContent = 'Save';
|
|
} else {
|
|
clearDraft();
|
|
window.location.href = result.url + (keyBase64 ? '#' + keyBase64 : '');
|
|
}
|
|
} catch (err) {
|
|
console.error(err);
|
|
alert('Failed to create paste. Try again.');
|
|
submitBtn.disabled = false;
|
|
submitBtn.textContent = 'Save';
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %}
|