214 lines
10 KiB
HTML
214 lines
10 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
<title>View Paste - I2P Secure Share</title>
|
|
<link rel="stylesheet" href="/static/css/tailwind.css"/>
|
|
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
|
|
|
|
<style>
|
|
body { background-color: #1a202c; color: #cbd5e0; }
|
|
.link-box { background-color: #2d3748; border:1px solid #4a5568; word-break:break-all; }
|
|
.btn { background-color:#4299e1; transition:background-color .3s ease; }
|
|
.btn:hover { background-color:#3182ce; }
|
|
.code-container {
|
|
background-color:#2d3748; border-radius:0.5rem; border:1px solid #4a5568; overflow:hidden;
|
|
}
|
|
.syntax pre {
|
|
margin:0; padding:1rem; white-space:pre-wrap; word-wrap:break-word;
|
|
}
|
|
.announcement-bar { background-color:#2563eb; border-bottom:1px solid #1e3a8a; }
|
|
.wide-container { max-width: 85rem; }
|
|
.alert-success { background-color:#38a169; }
|
|
.alert-error { background-color:#e53e3e; }
|
|
|
|
/* Pygments 'monokai' theme CSS */
|
|
.syntax .hll { background-color: #49483e }
|
|
.syntax { background: #272822; color: #f8f8f2 }
|
|
.syntax .c { color: #75715e } /* Comment */
|
|
.syntax .err { color: #960050; background-color: #1e0010 } /* Error */
|
|
.syntax .k { color: #66d9ef } /* Keyword */
|
|
.syntax .l { color: #ae81ff } /* Literal */
|
|
.syntax .n { color: #f8f8f2 } /* Name */
|
|
.syntax .o { color: #f92672 } /* Operator */
|
|
.syntax .p { color: #f8f8f2 } /* Punctuation */
|
|
.syntax .ch { color: #75715e } /* Comment.Hashbang */
|
|
.syntax .cm { color: #75715e } /* Comment.Multiline */
|
|
.syntax .cp { color: #75715e } /* Comment.Preproc */
|
|
.syntax .cpf { color: #75715e } /* Comment.PreprocFile */
|
|
.syntax .c1 { color: #75715e } /* Comment.Single */
|
|
.syntax .cs { color: #75715e } /* Comment.Special */
|
|
.syntax .gd { color: #f92672 } /* Generic.Deleted */
|
|
.syntax .ge { font-style: italic } /* Generic.Emph */
|
|
.syntax .gi { color: #a6e22e } /* Generic.Inserted */
|
|
.syntax .gs { font-weight: bold } /* Generic.Strong */
|
|
.syntax .gu { color: #75715e } /* Generic.Subheading */
|
|
.syntax .kc { color: #66d9ef } /* Keyword.Constant */
|
|
.syntax .kd { color: #66d9ef } /* Keyword.Declaration */
|
|
.syntax .kn { color: #f92672 } /* Keyword.Namespace */
|
|
.syntax .kp { color: #66d9ef } /* Keyword.Pseudo */
|
|
.syntax .kr { color: #66d9ef } /* Keyword.Reserved */
|
|
.syntax .kt { color: #66d9ef } /* Keyword.Type */
|
|
.syntax .ld { color: #e6db74 } /* Literal.Date */
|
|
.syntax .m { color: #ae81ff } /* Literal.Number */
|
|
.syntax .s { color: #e6db74 } /* Literal.String */
|
|
.syntax .na { color: #a6e22e } /* Name.Attribute */
|
|
.syntax .nb { color: #f8f8f2 } /* Name.Builtin */
|
|
.syntax .nc { color: #a6e22e } /* Name.Class */
|
|
.syntax .no { color: #66d9ef } /* Name.Constant */
|
|
.syntax .nd { color: #a6e22e } /* Name.Decorator */
|
|
.syntax .ni { color: #f8f8f2 } /* Name.Entity */
|
|
.syntax .ne { color: #a6e22e } /* Name.Exception */
|
|
.syntax .nf { color: #a6e22e } /* Name.Function */
|
|
.syntax .nl { color: #f8f8f2 } /* Name.Label */
|
|
.syntax .nn { color: #f8f8f2 } /* Name.Namespace */
|
|
.syntax .nx { color: #a6e22e } /* Name.Other */
|
|
.syntax .py { color: #f8f8f2 } /* Name.Property */
|
|
.syntax .nt { color: #f92672 } /* Name.Tag */
|
|
.syntax .nv { color: #f8f8f2 } /* Name.Variable */
|
|
.syntax .ow { color: #f92672 } /* Operator.Word */
|
|
.syntax .w { color: #f8f8f2 } /* Text.Whitespace */
|
|
.syntax .mb { color: #ae81ff } /* Literal.Number.Bin */
|
|
.syntax .mf { color: #ae81ff } /* Literal.Number.Float */
|
|
.syntax .mh { color: #ae81ff } /* Literal.Number.Hex */
|
|
.syntax .mi { color: #ae81ff } /* Literal.Number.Integer */
|
|
.syntax .mo { color: #ae81ff } /* Literal.Number.Oct */
|
|
.syntax .sa { color: #e6db74 } /* Literal.String.Affix */
|
|
.syntax .sb { color: #e6db74 } /* Literal.String.Backtick */
|
|
.syntax .sc { color: #e6db74 } /* Literal.String.Char */
|
|
.syntax .dl { color: #e6db74 } /* Literal.String.Delimiter */
|
|
.syntax .sd { color: #e6db74 } /* Literal.String.Doc */
|
|
.syntax .s2 { color: #e6db74 } /* Literal.String.Double */
|
|
.syntax .se { color: #ae81ff } /* Literal.String.Escape */
|
|
.syntax .sh { color: #e6db74 } /* Literal.String.Heredoc */
|
|
.syntax .si { color: #e6db74 } /* Literal.String.Interpol */
|
|
.syntax .sx { color: #e6db74 } /* Literal.String.Other */
|
|
.syntax .sr { color: #e6db74 } /* Literal.String.Regex */
|
|
.syntax .s1 { color: #e6db74 } /* Literal.String.Single */
|
|
.syntax .ss { color: #e6db74 } /* Literal.String.Symbol */
|
|
.syntax .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
|
|
.syntax .fm { color: #a6e22e } /* Name.Function.Magic */
|
|
.syntax .vc { color: #f8f8f2 } /* Name.Variable.Class */
|
|
.syntax .vg { color: #f8f8f2 } /* Name.Variable.Global */
|
|
.syntax .vi { color: #f8f8f2 } /* Name.Variable.Instance */
|
|
.syntax .vm { color: #f8f8f2 } /* Name.Variable.Magic */
|
|
.syntax .il { color: #ae81ff } /* Literal.Number.Integer.Long */
|
|
</style>
|
|
</head>
|
|
<body class="font-sans">
|
|
|
|
{% if announcement_enabled and announcement_message %}
|
|
<div id="announcement-bar" class="announcement-bar text-white text-center p-2 relative shadow-lg">
|
|
<span>{{ announcement_message }}</span>
|
|
<button id="close-announcement" class="absolute top-0 right-0 mt-2 mr-4 text-white hover:text-gray-200 text-2xl leading-none">×</button>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="flex items-center justify-center min-h-screen py-8">
|
|
<div class="w-full wide-container mx-auto p-6">
|
|
{% if password_required %}
|
|
<div class="content-container rounded-lg p-10 shadow-lg"></div>
|
|
<h2 class="text-2xl font-semibold text-white mb-6">Enter Password to View Paste</h2>
|
|
<form method="POST">
|
|
<div class="mb-6">
|
|
<label for="password" class="block text-gray-300 text-sm font-bold mb-2">Password:</label>
|
|
<input type="password" name="password" id="password"
|
|
class="w-full p-2 rounded-md text-white bg-gray-700 border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
required>
|
|
</div>
|
|
<button type="submit" class="btn w-full text-white font-bold py-3 px-5 rounded-md">Unlock Paste</button>
|
|
</form>
|
|
</div>
|
|
{% else %}
|
|
<header class="text-center mb-8">
|
|
<a href="/" class="inline-block mb-4">
|
|
<img src="/static/images/stormycloud.svg" alt="StormyCloud Logo" style="width:350px; max-width:100%;" class="mx-auto"/>
|
|
</a>
|
|
<h1 class="text-3xl font-bold text-white">View Paste</h1>
|
|
<p class="text-gray-400 mt-2 text-xl">Expires in: {{ time_left }}</p>
|
|
</header>
|
|
|
|
<main>
|
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
|
{% if messages %}
|
|
<div class="mb-4">
|
|
{% for category, message in messages %}
|
|
<div class="alert-{{category}} text-white p-3 rounded-md shadow-lg"
|
|
role="alert">{{ message }}</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
{% endwith %}
|
|
|
|
<div class="flex justify-end mb-2">
|
|
<form method="GET" action="" class="flex items-center space-x-2">
|
|
<label for="language-switcher" class="text-sm text-gray-400">Syntax:</label>
|
|
<select name="lang" id="language-switcher" onchange="this.form.submit()" class="text-sm rounded-md p-1 bg-gray-700 border border-gray-600 focus:outline-none focus:ring-1 focus:ring-blue-500 cursor-pointer">
|
|
{% for lang in languages %}
|
|
<option value="{{ lang }}" {% if lang == selected_language %}selected{% endif %}>
|
|
{{ lang|capitalize }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<noscript><button type="submit" class="btn text-sm py-1 px-3">Update</button></noscript>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="code-container mb-6 syntax">
|
|
{{ highlighted_content|safe }}
|
|
</div>
|
|
|
|
<div class="link-box rounded-lg p-4 mb-4">
|
|
<label for="share-link" class="block text-gray-300 text-sm font-bold mb-2">Shareable Link:</label>
|
|
<div class="flex items-center space-x-2">
|
|
<input type="text" id="share-link"
|
|
class="bg-gray-700 text-white w-full p-2 border border-gray-600 rounded-md"
|
|
value="{{ request.url }}" readonly>
|
|
<button id="copy-button"
|
|
class="btn whitespace-nowrap flex-shrink-0 text-white font-bold py-3 px-5 rounded-md">
|
|
Copy
|
|
</button>
|
|
<a href="/paste/{{ paste_id }}/raw"
|
|
target="_blank"
|
|
class="btn whitespace-nowrap flex-shrink-0 text-white font-bold py-3 px-5 rounded-md">
|
|
Raw
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="text-center mt-8">
|
|
<a href="/" class="text-blue-400 hover:text-blue-300">Create another paste</a>
|
|
</div>
|
|
<div class="text-center mt-4 text-sm">
|
|
<p class="text-gray-500">Find this service useful? <a href="/donate" class="text-blue-400 hover:underline">Consider supporting its future.</a></p>
|
|
</div>
|
|
|
|
</main>
|
|
{% endif %}
|
|
|
|
<footer class="text-center text-gray-500 mt-16 border-t border-gray-700 pt-8 pb-8">
|
|
<a href="http://stormycloud.i2p" class="hover:text-gray-400">StormyCloud</a>
|
|
<span class="mx-2">|</span>
|
|
<a href="/donate" class="hover:text-gray-400">Donate</a>
|
|
</footer>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const copyBtn = document.getElementById('copy-button');
|
|
if (copyBtn) {
|
|
copyBtn.addEventListener('click', () => {
|
|
const inp = document.getElementById('share-link');
|
|
inp.select(); document.execCommand('copy');
|
|
copyBtn.textContent = 'Copied!';
|
|
setTimeout(() => copyBtn.textContent = 'Copy', 2000);
|
|
});
|
|
}
|
|
const closeBtn = document.getElementById('close-announcement');
|
|
if (closeBtn) closeBtn.addEventListener('click', () =>
|
|
document.getElementById('announcement-bar').style.display = 'none'
|
|
);
|
|
</script>
|
|
</body>
|
|
</html> |