mirror of
https://codeberg.org/ashley/poke
synced 2025-05-28 18:19:43 +00:00
stuff
This commit is contained in:
parent
bb1d09ea20
commit
b4d7b3da11
@ -17,179 +17,13 @@
|
||||
along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
-->
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>PokeTranslate</title>
|
||||
<link rel="icon" href="/static/yt-ukraine.svg">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta content="PokeTranslate" property=og:title>
|
||||
<meta content="Translate text - Anonymously!" property=twitter:description>
|
||||
<meta content="https://cdn.glitch.global/d68d17bb-f2c0-4bc3-993f-50902734f652/aa70111e-5bcd-4379-8b23-332a33012b78.image.png?v=1701898829884" property="og:image" />
|
||||
<meta content=summary_large_image name=twitter:card>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
|
||||
<meta name="referrer" content="no-referrer">
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<style>
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.wrap {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.wrap.languages {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
|
||||
.item-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 450px;
|
||||
margin: 5px 10px;
|
||||
}
|
||||
|
||||
button,
|
||||
select,
|
||||
input,
|
||||
textarea {
|
||||
border-radius: 1em;
|
||||
padding: 10px;
|
||||
background-color: #131618;
|
||||
border: 2px solid #495057;
|
||||
color: #f8f9fa;
|
||||
}
|
||||
|
||||
body {
|
||||
justify-content: center;
|
||||
font-family: sans-serif;
|
||||
background-color: #2c2f33;
|
||||
color: #f8f9fa;
|
||||
}
|
||||
|
||||
#translation-form {
|
||||
background-color: #1f2023;
|
||||
border-radius: 1em;
|
||||
padding: 20px;
|
||||
width: 90%;
|
||||
max-width: 800px;
|
||||
margin: auto;
|
||||
box-shadow: 0 0 15px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #5bc0de;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
#definitions_and_translations {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
grid-template-areas: "definitions translations";
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
#definitions_and_translations {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"definitions definitions"
|
||||
"translations translations";
|
||||
}
|
||||
}
|
||||
|
||||
div.definitions,
|
||||
div.translations {
|
||||
padding: 10px;
|
||||
background-color: #3a3f44;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
|
||||
textarea:focus,
|
||||
input:focus,
|
||||
button:focus {
|
||||
border-color: #478061;
|
||||
outline: 1px solid #478061;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #599bf6;
|
||||
}
|
||||
|
||||
/* Additional styles to match the calendar page */
|
||||
header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#switchbutton {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.center button {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
/* Responsive design */
|
||||
@media screen and (max-width: 768px) {
|
||||
#translation-form {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.wrap {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.item-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<% if (isMobile) { %>
|
||||
<style>
|
||||
body {
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
<% } %>
|
||||
|
||||
<% if (!isMobile) { %>
|
||||
<style>
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
<% } %>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="translation-form">
|
||||
<header class="center">
|
||||
<h1>PokeTranslate</h1>
|
||||
</header>
|
||||
|
||||
<% const languageOptions = [
|
||||
<% const languageOptions = [
|
||||
{ code: 'autodetect', name: 'Autodetect' },
|
||||
{ code: 'af', name: 'Afrikaans' },
|
||||
{ code: 'sq', name: 'Albanian' },
|
||||
{ code: 'am', name: 'Amharic' },
|
||||
{ code: 'ar', name: 'Arabic' },
|
||||
{ code: 'hy', name: 'Armenian' },
|
||||
{ code: 'hy', name: 'Armenian' },
|
||||
{ code: 'as', name: 'Assamese' },
|
||||
{ code: 'ay', name: 'Aymara' },
|
||||
{ code: 'az', name: 'Azerbaijani' },
|
||||
@ -278,71 +112,271 @@
|
||||
{ code: 'yi', name: 'Yiddish' },
|
||||
{ code: 'yo', name: 'Yoruba' },
|
||||
{ code: 'zu', name: 'Zulu' }
|
||||
]; %>
|
||||
<form action="/translate" method="GET" id="translation-form">
|
||||
<!-- from and to language -->
|
||||
<div class="wrap languages">
|
||||
<div class="language">
|
||||
<select name="from_language" id="from_language">
|
||||
<% languageOptions.forEach(language => { %>
|
||||
<option value="<%= language.code %>" <%= language.code === (from_language || 'autodetect') ? 'selected' : '' %>>
|
||||
<%= language.name %>
|
||||
</option>
|
||||
<% }); %>
|
||||
</select>
|
||||
]; %>
|
||||
|
||||
<select name="to_language" id="to_language">
|
||||
<% languageOptions.slice(1).forEach(language => { %>
|
||||
<option value="<%= language.code %>" <%= language.code === to_language ? 'selected' : '' %>>
|
||||
<%= language.name %>
|
||||
</option>
|
||||
<% }); %>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>PokeTranslate</title>
|
||||
<link rel="icon" href="/static/yt-ukraine.svg">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta content="PokeTranslate" property=og:title>
|
||||
<meta content="Translate text - Anonymously!" property=twitter:description>
|
||||
<meta content="https://cdn.glitch.global/d68d17bb-f2c0-4bc3-993f-50902734f652/aa70111e-5bcd-4379-8b23-332a33012b78.image.png?v=1701898829884" property="og:image" />
|
||||
<meta content=summary_large_image name=twitter:card>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
|
||||
<meta name="referrer" content="no-referrer">
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link href="https://fonts.bunny.net/css?family=poppins:400,500,600" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
|
||||
<!-- text boxes -->
|
||||
<div class="wrap">
|
||||
<div class="item-wrapper">
|
||||
<textarea autofocus class="item" id="input" name="input" dir="auto" placeholder="<%- text %>">
|
||||
<%- text %>
|
||||
</textarea>
|
||||
</div>
|
||||
<style>
|
||||
:root {
|
||||
--accent-1: #ff6b6b;
|
||||
--accent-2: #f7d794;
|
||||
--bg-light: #fafafa;
|
||||
--bg-dark: #202027;
|
||||
--card-light: rgba(255,255,255,0.55);
|
||||
--card-dark: rgba(18,18,24,0.55);
|
||||
--radius: 20px;
|
||||
--transition: 0.3s ease;
|
||||
}
|
||||
* { margin:0; padding:0; box-sizing:border-box; }
|
||||
body {
|
||||
font-family:'Poppins',sans-serif;
|
||||
background: var(--bg-light);
|
||||
color: #fff; /* all text white */
|
||||
display:flex; align-items:center; justify-content:center;
|
||||
min-height:100vh; padding:20px;
|
||||
transition: background var(--transition), color var(--transition);
|
||||
overflow:hidden;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body { background: var(--bg-dark); }
|
||||
}
|
||||
|
||||
<div class="item-wrapper">
|
||||
<textarea id="output" class="translation item" dir="auto" placeholder="Translation" readonly>
|
||||
<%- translation %>
|
||||
</textarea>
|
||||
</div>
|
||||
</div>
|
||||
.glass {
|
||||
position: relative;
|
||||
background: var(--card-light);
|
||||
backdrop-filter: blur(30px) saturate(200%);
|
||||
border-radius: var(--radius);
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
|
||||
width:100%; max-width:840px; overflow:hidden;
|
||||
transition: background var(--transition), box-shadow var(--transition);
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.glass {
|
||||
background: var(--card-dark);
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.7);
|
||||
}
|
||||
}
|
||||
|
||||
<div class="center">
|
||||
<button type="submit">Translate :3</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
/* Blobs */
|
||||
.blob {
|
||||
position:absolute; width:300px; height:300px;
|
||||
background: linear-gradient(45deg,var(--accent-1),var(--accent-2));
|
||||
border-radius: 45% 55% 70% 30%/30% 60% 40% 70%;
|
||||
animation: blobMove 8s infinite; opacity:0.3; z-index:0;
|
||||
}
|
||||
.blob:nth-child(1){ top:-80px; left:-60px; }
|
||||
.blob:nth-child(2){ bottom:-100px; right:-80px; animation-duration:10s; }
|
||||
@keyframes blobMove {
|
||||
0%,100% { transform:translate(0,0) scale(1); }
|
||||
50% { transform:translate(20px,20px) scale(1.1); }
|
||||
}
|
||||
|
||||
<script>
|
||||
document.getElementById("input").addEventListener("keydown", function (event) {
|
||||
if (event.keyCode === 13 && (event.metaKey || event.ctrlKey)) {
|
||||
document.getElementById("translation-form").submit();
|
||||
}
|
||||
header {
|
||||
position:relative; padding:28px; text-align:center;
|
||||
background: linear-gradient(60deg,var(--accent-1),var(--accent-2));
|
||||
background-size:200% 200%; animation:gradientAnimation 6s ease infinite;
|
||||
z-index:1;
|
||||
}
|
||||
@keyframes gradientAnimation {
|
||||
0%{ background-position:0% 50%; }
|
||||
50%{ background-position:100% 50%; }
|
||||
100%{ background-position:0% 50%; }
|
||||
}
|
||||
|
||||
/* Rainbow title unless user prefers reduced motion */
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
header h1 {
|
||||
font-size:2.4rem; font-weight:600; letter-spacing:1.5px;
|
||||
background: conic-gradient(
|
||||
red, orange, yellow, green, blue, indigo, violet, red
|
||||
);
|
||||
background-size: 300%;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
animation: rainbow 4s linear infinite;
|
||||
}
|
||||
@keyframes rainbow {
|
||||
0% { background-position: 0% 50%; }
|
||||
50% { background-position: 100% 50%; }
|
||||
100% { background-position: 0% 50%; }
|
||||
}
|
||||
}
|
||||
|
||||
/* Static white title when reduced-motion is set */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
header h1 {
|
||||
font-size:2.4rem; font-weight:600; letter-spacing:1.5px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
form { position:relative; z-index:2; }
|
||||
.language-bar {
|
||||
display:flex; align-items:center; gap:12px; padding:16px 24px;
|
||||
}
|
||||
.language-select { flex:1; }
|
||||
.language-select select {
|
||||
width:100%; padding:14px 18px; border-radius:var(--radius);
|
||||
border:1px solid rgba(255,255,255,0.5); background:transparent;
|
||||
font-size:1rem; appearance:none; cursor:pointer;
|
||||
color:#fff;
|
||||
transition:border-color var(--transition);
|
||||
}
|
||||
.language-select select:focus {
|
||||
border-color: var(--accent-1); outline:none;
|
||||
}
|
||||
.swap-button {
|
||||
font-size:2rem; color:var(--accent-1); text-decoration:none;
|
||||
transition:transform var(--transition),color var(--transition);
|
||||
}
|
||||
.swap-button:hover {
|
||||
transform:rotate(180deg) scale(1.1);
|
||||
color:var(--accent-2);
|
||||
}
|
||||
|
||||
.panels {
|
||||
display:grid; grid-template-columns:1fr 1fr; gap:20px;
|
||||
padding:0 24px 24px;
|
||||
}
|
||||
.panel { position:relative; }
|
||||
.panel label {
|
||||
display:block; margin-bottom:8px; font-weight:500; font-size:0.95rem;
|
||||
color:#fff;
|
||||
}
|
||||
.panel textarea {
|
||||
width:100%; min-height:160px; padding:16px; border-radius:var(--radius);
|
||||
border:1px solid rgba(255,255,255,0.5); resize:vertical; font-size:1rem;
|
||||
line-height:1.5; background:rgba(255,255,255,0.2); color:#fff;
|
||||
transition:border-color var(--transition),box-shadow var(--transition);
|
||||
}
|
||||
.panel textarea::placeholder {
|
||||
color: rgba(255,255,255,0.7);
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.panel textarea {
|
||||
background:rgba(20,20,25,0.5);
|
||||
}
|
||||
}
|
||||
.panel textarea:focus {
|
||||
border-color: var(--accent-1);
|
||||
box-shadow: 0 0 8px var(--accent-1);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display:flex; justify-content:center; padding-bottom:24px;
|
||||
}
|
||||
.actions button {
|
||||
padding:16px 36px; font-size:1.1rem; font-weight:600; border:none;
|
||||
border-radius:var(--radius); cursor:pointer;
|
||||
background:linear-gradient(60deg,var(--accent-1),var(--accent-2));
|
||||
background-size:200% 200%; animation:gradientAnimation 6s ease infinite;
|
||||
color: #fff;
|
||||
box-shadow:0 4px 14px rgba(0,0,0,0.2);
|
||||
transition:transform var(--transition),opacity var(--transition);
|
||||
}
|
||||
.actions button:hover {
|
||||
transform:scale(1.03); opacity:0.9;
|
||||
}
|
||||
|
||||
@media (max-width:768px) {
|
||||
.panels { grid-template-columns:1fr; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="glass">
|
||||
<div class="blob"></div>
|
||||
<div class="blob"></div>
|
||||
|
||||
<header><h1>PokeTranslate</h1></header>
|
||||
|
||||
<form action="/translate" method="GET">
|
||||
<div class="language-bar">
|
||||
<div class="language-select">
|
||||
<select name="from_language" id="from_language">
|
||||
<% languageOptions.forEach(lang => { %>
|
||||
<option value="<%= lang.code %>" <%= lang.code === (from_language||'autodetect')?'selected':''%>>
|
||||
<%= lang.name %>
|
||||
</option>
|
||||
<% }); %>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<a
|
||||
href="?from_language=<%= to_language %>&to_language=<%= from_language %>&input=<%= encodeURIComponent(text) %>"
|
||||
id="swapBtn"
|
||||
class="material-icons swap-button"
|
||||
>swap_horiz</a>
|
||||
|
||||
<div class="language-select">
|
||||
<select name="to_language" id="to_language">
|
||||
<% languageOptions.slice(1).forEach(lang => { %>
|
||||
<option value="<%= lang.code %>" <%= lang.code===to_language?'selected':''%>>
|
||||
<%= lang.name %>
|
||||
</option>
|
||||
<% }); %>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panels">
|
||||
<div class="panel input">
|
||||
<label for="input">Input</label>
|
||||
<textarea id="input" name="input" placeholder="Enter text…"><%= text %></textarea>
|
||||
</div>
|
||||
<div class="panel output">
|
||||
<label for="output">Translation</label>
|
||||
<textarea id="output" readonly placeholder="Translated text…"><%= translation %></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button type="submit">Translate :3</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
const swapBtn = document.getElementById('swapBtn');
|
||||
if(swapBtn){
|
||||
swapBtn.addEventListener('click', function(e){
|
||||
e.preventDefault();
|
||||
const from = document.getElementById('from_language');
|
||||
const to = document.getElementById('to_language');
|
||||
const inp = document.getElementById('input');
|
||||
const out = document.getElementById('output');
|
||||
[from.value, to.value] = [to.value, from.value];
|
||||
[inp.value, out.value] = [out.value, inp.value];
|
||||
});
|
||||
|
||||
var input = document.getElementById("input");
|
||||
var output = document.getElementById("output");
|
||||
input.setAttribute("style", "height:" + output.scrollHeight + "px;overflow-y:scroll;");
|
||||
output.setAttribute("style", "height:" + output.scrollHeight + "px;overflow-y:scroll;");
|
||||
input.addEventListener("input", function (e) {
|
||||
this.style.height = 150 + "px";
|
||||
this.style.height = this.scrollHeight + "px";
|
||||
});
|
||||
</script>
|
||||
<script src="/static/custom-css.js"></script>
|
||||
}
|
||||
document.querySelectorAll('textarea').forEach(el=>{
|
||||
const resize = ()=>{ el.style.height='auto'; el.style.height=el.scrollHeight+'px'; };
|
||||
el.addEventListener('input', resize);
|
||||
resize();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user