mirror of
https://codeberg.org/ashley/poke.git
synced 2024-11-15 04:28:43 +01:00
Merge branch 'main' into main
This commit is contained in:
commit
af49f2c4ae
5 changed files with 412 additions and 255 deletions
|
@ -125,10 +125,12 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="/game-hub" class="poke-app-btn"><i class="fa-light fa-gamepad"></i>Games</a>
|
<a href="/game-hub" class="poke-app-btn"><i class="fa-light fa-gamepad"></i>Games</a>
|
||||||
<a href="/web" class="poke-app-btn"><i class="fa-light fa-search"></i>Web Search</a>
|
<a href="/search" class="poke-app-btn"><i class="fa-light fa-search"></i>Search</a>
|
||||||
<a href="/translate" class="poke-app-btn"><i class="fa-light fa-language"></i>Translate</a>
|
<a href="/translate" class="poke-app-btn"><i class="fa-light fa-language"></i>Translate</a>
|
||||||
<a href="/map" class="poke-app-btn"><i class="fa-light fa-map-marker-alt"></i>Maps</a>
|
<a href="/map" class="poke-app-btn"><i class="fa-light fa-map-marker-alt"></i>Maps</a>
|
||||||
<a href="/app" class="poke-app-btn"><i class="fa-light fa-play"></i>PokeTube</a>
|
<a href="https://social.poketube.fun" class="poke-app-btn"><i class="fa-brands fa-mastodon"></i>Fediverse</a>
|
||||||
|
<a href="/calendar" class="poke-app-btn"><i class="fa-light fa-calendar"></i>Calendar</a>
|
||||||
|
<a href="/app" class="poke-app-btn"><i class="fa-light fa-play"></i>Watch</a>
|
||||||
<a href="/settings" class="poke-app-btn"><i class="fa-light fa-cogs"></i>Settings</a>
|
<a href="/settings" class="poke-app-btn"><i class="fa-light fa-cogs"></i>Settings</a>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
188
html/calendar.ejs
Normal file
188
html/calendar.ejs
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="manifest" href="/manifest.json">
|
||||||
|
<link href="css/yt-ukraine.svg" rel="icon">
|
||||||
|
<title>Poke! Calendar</title>
|
||||||
|
<meta content="PokeCalendar" property="og:title">
|
||||||
|
<meta content="Worlds first no js web calendar :3" 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 http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
|
||||||
|
<meta name="referrer" content="no-referrer">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #121212;
|
||||||
|
color: #ffffff;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
background-color: #333333;
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center; /* Center items vertically */
|
||||||
|
justify-content: space-between; /* Space items evenly */
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar h1 {
|
||||||
|
margin: 0;
|
||||||
|
color: #bb86fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .years {
|
||||||
|
color: #bb86fc; /* Year text color */
|
||||||
|
display: flex; /* Use flexbox for alignment */
|
||||||
|
gap: 20px; /* Space between year elements */
|
||||||
|
flex-wrap: wrap; /* Allow wrapping on smaller screens */
|
||||||
|
justify-content: center; /* Center items on smaller screens */
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #1e1e1e;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
width: 90%;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2, h3 {
|
||||||
|
color: #bb86fc;
|
||||||
|
margin: 10px 0; /* Margin between h2 elements */
|
||||||
|
}
|
||||||
|
|
||||||
|
.month-title {
|
||||||
|
font-size: 1.5em; /* Adjust the size as needed */
|
||||||
|
margin: 20px 0; /* Spacing above and below */
|
||||||
|
color: #bb86fc; /* Month title color */
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table th, .calendar-table td {
|
||||||
|
padding: 15px;
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid #333333;
|
||||||
|
font-size: 0.9em; /* Smaller font size for better fit */
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table th {
|
||||||
|
background-color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table td {
|
||||||
|
background-color: #2c2c2c;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-links {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #bb86fc;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin: 0 10px;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover {
|
||||||
|
background-color: #9c62f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive styles */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.navbar {
|
||||||
|
flex-direction: column; /* Stack navbar items vertically on small screens */
|
||||||
|
align-items: center; /* Center items horizontally */
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 100%; /* Full width on small screens */
|
||||||
|
height: 100vh; /* Full height of the viewport */
|
||||||
|
border-radius: 0; /* Remove border-radius for full-screen effect */
|
||||||
|
box-shadow: none; /* Remove shadow for a flatter design */
|
||||||
|
padding: 10px; /* Adjust padding for mobile */
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-table th, .calendar-table td {
|
||||||
|
padding: 10px; /* Reduced padding for smaller screens */
|
||||||
|
font-size: 0.8em; /* Smaller font size */
|
||||||
|
}
|
||||||
|
|
||||||
|
.month-title {
|
||||||
|
font-size: 1.2em; /* Smaller month title */
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
padding: 8px 15px; /* Smaller button size */
|
||||||
|
margin: 5px 0; /* Vertical spacing */
|
||||||
|
display: block; /* Stack buttons vertically */
|
||||||
|
width: 100%; /* Full width */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="navbar">
|
||||||
|
<a class="class" href="/143" style="font-family: Inter, sans-serif; color: #fff">
|
||||||
|
<img style="transform: scale(1.3); padding-left: 0.9em; width: 8.5em; display: block; margin-left: auto; margin-right: auto;" src="/css/logo-poke.svg?v=5">
|
||||||
|
</a>
|
||||||
|
<div class="years">
|
||||||
|
<h2>Gregorian Year: <%= year %></h2>
|
||||||
|
<h2>Islamic Year: <%= islamicYear %></h2>
|
||||||
|
<h2>Persian Year: <%= persianYear %></h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container" style="margin-top: 1em;">
|
||||||
|
<h2 class="month-title"><%= queryDate.toLocaleString('default', { month: 'long' }) %> <%= year %></h2> <!-- Month and Year Display -->
|
||||||
|
|
||||||
|
<table class="calendar-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Sunday</th>
|
||||||
|
<th>Monday</th>
|
||||||
|
<th>Tuesday</th>
|
||||||
|
<th>Wednesday</th>
|
||||||
|
<th>Thursday</th>
|
||||||
|
<th>Friday</th>
|
||||||
|
<th>Saturday</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% for (let i = 0; i < 6; i++) { %>
|
||||||
|
<tr>
|
||||||
|
<% for (let j = 0; j < 7; j++) { %>
|
||||||
|
<td>
|
||||||
|
<% const day = days[i * 7 + j]; %>
|
||||||
|
<%= day ? day.getDate() : '' %>
|
||||||
|
</td>
|
||||||
|
<% } %>
|
||||||
|
</tr>
|
||||||
|
<% } %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="nav-links">
|
||||||
|
<a href="/calendar?date=<%= new Date(currentDate.getFullYear(), month - 1, 1).toISOString() %>" class="button">Previous Month</a>
|
||||||
|
<a href="/calendar?date=<%= new Date(currentDate.getFullYear(), month + 1, 1).toISOString() %>" class="button">Next Month</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -16,23 +16,22 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see https://www.gnu.org/licenses/.
|
along with this program. If not, see https://www.gnu.org/licenses/.
|
||||||
-->
|
-->
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
|
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
|
||||||
<title>PokeTranslate</title>
|
<head>
|
||||||
<link rel="icon" href="/static/yt-ukraine.svg">
|
<title>PokeTranslate</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<link rel="icon" href="/static/yt-ukraine.svg">
|
||||||
<meta content="PokeTranslate" property=og:title>
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta content="Translate text - Anonymously!" property=twitter:description>
|
<meta content="PokeTranslate" property=og:title>
|
||||||
<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="Translate text - Anonymously!" property=twitter:description>
|
||||||
<meta content=summary_large_image name=twitter:card>
|
<meta content="https://cdn.glitch.global/d68d17bb-f2c0-4bc3-993f-50902734f652/aa70111e-5bcd-4379-8b23-332a33012b78.image.png?v=1701898829884" property="og:image" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta content=summary_large_image name=twitter:card>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
|
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
|
||||||
<meta name="referrer" content="no-referrer">
|
<meta name="referrer" content="no-referrer">
|
||||||
<link rel="manifest" href="/manifest.json">
|
<link rel="manifest" href="/manifest.json">
|
||||||
<style>
|
<style>
|
||||||
.center {
|
.center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
@ -41,43 +40,96 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
margin: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wrap.languages {
|
.wrap.languages {
|
||||||
flex-wrap: nowrap;
|
margin-bottom: 30px;
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#could_not_switch_languages_text {
|
|
||||||
color: red;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 150px;
|
height: 150px;
|
||||||
border-radius:1em;
|
border-radius: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-wrapper {
|
.item-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 450px;
|
width: 450px;
|
||||||
margin: 5px 10px;
|
margin: 5px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
.language,
|
select,
|
||||||
.switch_languages {
|
input,
|
||||||
display: flex;
|
textarea {
|
||||||
|
border-radius: 1em;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #131618;
|
||||||
|
border: 2px solid #495057;
|
||||||
|
color: #f8f9fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.language {
|
body {
|
||||||
margin: 0px 10px;
|
justify-content: center;
|
||||||
|
font-family: sans-serif;
|
||||||
|
background-color: #2c2f33;
|
||||||
|
color: #f8f9fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.switch_languages {
|
#translation-form {
|
||||||
margin: 0px 5px;
|
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 {
|
#switchbutton {
|
||||||
|
@ -86,164 +138,51 @@
|
||||||
|
|
||||||
button {
|
button {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
padding: 4px 10px;
|
|
||||||
border: 2px solid #888888;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input,
|
.center button {
|
||||||
select,
|
margin-top: 15px;
|
||||||
textarea {
|
|
||||||
width: 100%;
|
|
||||||
font-size: 1rem;
|
|
||||||
padding: 4px;
|
|
||||||
border: 2px solid #888888;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea {
|
/* Responsive design */
|
||||||
resize: vertical;
|
@media screen and (max-width: 768px) {
|
||||||
height: 5rem;
|
#translation-form {
|
||||||
font-family: sans-serif;
|
padding: 10px;
|
||||||
width: 100%;
|
}
|
||||||
|
|
||||||
|
.wrap {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
input:focus,
|
<% if (isMobile) { %>
|
||||||
select:focus,
|
<style>
|
||||||
textarea:focus,
|
|
||||||
button:focus {
|
|
||||||
border-color: #478061;
|
|
||||||
outline: 1px solid #478061;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
justify-content: center;
|
overflow: auto;
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
#definitions_and_translations {
|
|
||||||
display: grid;
|
|
||||||
margin: auto;
|
|
||||||
width: 1100px;
|
|
||||||
gap: 10px;
|
|
||||||
grid-template-areas: "definitions translations";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.def_type {
|
|
||||||
color: #007979;
|
|
||||||
text-transform: capitalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.syn {
|
|
||||||
color: #804700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.syn_type {
|
|
||||||
color: #007979;
|
|
||||||
}
|
|
||||||
|
|
||||||
.use_in_sentence {
|
|
||||||
color: #009902;
|
|
||||||
}
|
|
||||||
|
|
||||||
.definitions li:not(:last-child) {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 1200px) {
|
|
||||||
#definitions_and_translations {
|
|
||||||
display: grid;
|
|
||||||
width: 90vw;
|
|
||||||
grid-template-areas:
|
|
||||||
"definitions definitions"
|
|
||||||
"translations translations";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
div.definitions {
|
|
||||||
grid-area: definitions;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.translations {
|
|
||||||
grid-area: translations;
|
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<% if (!isMobile) { %>
|
||||||
|
<style>
|
||||||
body {
|
body {
|
||||||
background-color: #212529;
|
overflow: hidden;
|
||||||
color: #f8f9fa;
|
}
|
||||||
}
|
</style>
|
||||||
|
<% } %>
|
||||||
|
</head>
|
||||||
|
|
||||||
#could_not_switch_languages_text {
|
<body>
|
||||||
color: #F13333;
|
<div id="translation-form">
|
||||||
}
|
<header class="center">
|
||||||
|
<h1>PokeTranslate</h1>
|
||||||
a:visited {
|
</header>
|
||||||
color: #9759f6;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #599bf6;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
input,
|
|
||||||
select,
|
|
||||||
button,
|
|
||||||
textarea {
|
|
||||||
background-color: #131618;
|
|
||||||
border-color: #495057;
|
|
||||||
color: #f8f9fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.def_type {
|
|
||||||
color: cyan;
|
|
||||||
text-transform: capitalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.syn {
|
|
||||||
color: burlywood;
|
|
||||||
}
|
|
||||||
|
|
||||||
.syn_type {
|
|
||||||
color: cyan;
|
|
||||||
}
|
|
||||||
|
|
||||||
.use_in_sentence {
|
|
||||||
color: yellow;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<% if (isMobile) { %>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<% } %>
|
|
||||||
|
|
||||||
<% if (!isMobile) { %>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<% } %>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div style="border-radius: 3em;background: #1a1a1a;padding: 1em;display: flex;flex-direction: column;height: fit-content;align-self: center;margin-top: 6em;">
|
|
||||||
|
|
||||||
<header class="center"><h1>PokeTranslate</h1></header>
|
|
||||||
|
|
||||||
<form action="/translate" method="GET" id="translation-form">
|
|
||||||
|
|
||||||
<!-- from and to language -->
|
|
||||||
<div class="wrap languages">
|
|
||||||
<div class="language">
|
|
||||||
|
|
||||||
<% const languageOptions = [
|
<% const languageOptions = [
|
||||||
{ code: 'autodetect', name: 'Autodetect' },
|
{ code: 'autodetect', name: 'Autodetect' },
|
||||||
{ code: 'af', name: 'Afrikaans' },
|
{ code: 'af', name: 'Afrikaans' },
|
||||||
|
@ -307,7 +246,7 @@
|
||||||
{ code: 'km', name: 'Khmer' },
|
{ code: 'km', name: 'Khmer' },
|
||||||
{ code: 'rw', name: 'Kinyarwanda' },
|
{ code: 'rw', name: 'Kinyarwanda' },
|
||||||
{ code: 'kok', name: 'Konkani' },
|
{ code: 'kok', name: 'Konkani' },
|
||||||
{ code: 'ko', name: 'Korean' },
|
{ code: 'ko', name: 'Korean (PROK)' },
|
||||||
{ code: 'kri', name: 'Krio' },
|
{ code: 'kri', name: 'Krio' },
|
||||||
{ code: 'ku', name: 'Kurdish (Kurmanji)' },
|
{ code: 'ku', name: 'Kurdish (Kurmanji)' },
|
||||||
{ code: 'sd', name: 'Sindhi' },
|
{ code: 'sd', name: 'Sindhi' },
|
||||||
|
@ -339,93 +278,71 @@
|
||||||
{ code: 'yi', name: 'Yiddish' },
|
{ code: 'yi', name: 'Yiddish' },
|
||||||
{ code: 'yo', name: 'Yoruba' },
|
{ code: 'yo', name: 'Yoruba' },
|
||||||
{ code: 'zu', name: 'Zulu' }
|
{ 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">
|
||||||
<!-- Source language select -->
|
<% languageOptions.slice(1).forEach(language => { %>
|
||||||
<select name="from_language" id="from_language" style="margin-right: 1em;border-radius: 1em;padding: 7px;" aria-label="Source language">
|
<option value="<%= language.code %>" <%= language.code === to_language ? 'selected' : '' %>>
|
||||||
<% languageOptions.forEach(language => { %>
|
<%= language.name %>
|
||||||
<option value="<%= language.code %>" <%= language.code === (from_language || 'autodetect') ? 'selected' : '' %>><%= language.name %></option>
|
</option>
|
||||||
<% }); %>
|
<% }); %>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
||||||
<!-- Target language select -->
|
|
||||||
<select name="to_language" id="to_language" style="margin-right: 1em;border-radius: 1em;padding: 7px;" aria-label="Target language">
|
|
||||||
<% languageOptions.slice(1).forEach(language => { %>
|
|
||||||
<option value="<%= language.code %>" <%= language.code === to_language ? 'selected' : '' %>><%= language.name %></option>
|
|
||||||
<% }); %>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- text boxes -->
|
<!-- text boxes -->
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<div class="item-wrapper">
|
<div class="item-wrapper">
|
||||||
<textarea autofocus class="item" id="input" name="input" dir="auto" placeholder="<%- text %>"><%- text %>
|
<textarea autofocus class="item" id="input" name="input" dir="auto" placeholder="<%- text %>">
|
||||||
</textarea>
|
<%- text %>
|
||||||
</div>
|
</textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="item-wrapper">
|
<div class="item-wrapper">
|
||||||
<textarea id="output" class="translation item" dir="auto" placeholder="Translation" readonly> <%- translation %> </textarea>
|
<textarea id="output" class="translation item" dir="auto" placeholder="Translation" readonly>
|
||||||
</div>
|
<%- translation %>
|
||||||
|
</textarea>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<!-- translate button -->
|
<button type="submit">Translate :3</button>
|
||||||
<button type="submit" style="border-radius: 1em;padding: 7px;">Translate :3</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.getElementById("input").addEventListener("keydown", function (event) {
|
||||||
|
if (event.keyCode === 13 && (event.metaKey || event.ctrlKey)) {
|
||||||
|
document.getElementById("translation-form").submit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
<br>
|
var input = document.getElementById("input");
|
||||||
<br>
|
var output = document.getElementById("output");
|
||||||
<br>
|
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>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0
|
|
||||||
// this code submits the translation form when pressing Ctrl/Meta+Enter while focussed on the input text field
|
|
||||||
document.getElementById("input").addEventListener("keydown", function(event) {
|
|
||||||
if (event.keyCode === 13 && (event.metaKey || event.ctrlKey)) {
|
|
||||||
document.getElementById("translation-form").submit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Auto resize textarea to fit words inside it without need to scroll -- Thanks to: https://stackoverflow.com/a/25621277
|
|
||||||
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";
|
|
||||||
});
|
|
||||||
|
|
||||||
// @license-end
|
|
||||||
</script>
|
|
||||||
<script src="/static/custom-css.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -88,7 +88,7 @@ module.exports = function (app, config, renderTemplate) {
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/search", async (req, res) => {
|
app.get("/search", async (req, res) => {
|
||||||
const query = req.query.query.replace("ohio", "things to do in ohio");
|
const query = req.query.query ? req.query.query.replace("ohio", "things to do in ohio") : '';
|
||||||
const tab = req.query.tab;
|
const tab = req.query.tab;
|
||||||
const { fetch } = await import("undici");
|
const { fetch } = await import("undici");
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,56 @@ module.exports = function (app, config, renderTemplate) {
|
||||||
renderTemplate(res, req, "content-settings.ejs");
|
renderTemplate(res, req, "content-settings.ejs");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function gregorianToIslamic(gDate) {
|
||||||
|
const jd = Math.floor((gDate - new Date(1970, 0, 1)) / (24 * 60 * 60 * 1000)) + 2440588;
|
||||||
|
const islamicYear = Math.floor((30 * (jd - 1948440) + 10646) / 10631);
|
||||||
|
return islamicYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
function gregorianToPersian(gDate) {
|
||||||
|
const persianEpoch = 226895; // Julian Day of Persian Epoch
|
||||||
|
const jd = Math.floor((gDate - new Date(1970, 0, 1)) / (24 * 60 * 60 * 1000)) + 2440588;
|
||||||
|
const persianYear = Math.floor((jd - persianEpoch) / 365.2421985) + 1;
|
||||||
|
return persianYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
app.get('/calendar', (req, res) => {
|
||||||
|
// Get the date from query or default to today
|
||||||
|
const queryDate = req.query.date ? new Date(req.query.date) : new Date();
|
||||||
|
|
||||||
|
// Extract the year and month from the date
|
||||||
|
const year = queryDate.getFullYear();
|
||||||
|
const month = queryDate.getMonth(); // 0 (January) to 11 (December)
|
||||||
|
|
||||||
|
const monthOffset = parseInt(req.query.month) || 0;
|
||||||
|
const newDate = new Date(year, month + monthOffset, 1);
|
||||||
|
const newYear = newDate.getFullYear();
|
||||||
|
const newMonth = newDate.getMonth();
|
||||||
|
|
||||||
|
const firstDay = new Date(newYear, newMonth, 1);
|
||||||
|
const firstDayWeekday = firstDay.getDay(); // Day of the week (0-6)
|
||||||
|
|
||||||
|
const days = Array.from({ length: 42 }, (_, i) => {
|
||||||
|
const day = new Date(newYear, newMonth, i - firstDayWeekday + 1);
|
||||||
|
return (day.getMonth() === newMonth) ? day : null;
|
||||||
|
});
|
||||||
|
|
||||||
|
const islamicYear = gregorianToIslamic(newDate);
|
||||||
|
const persianYear = gregorianToPersian(newDate);
|
||||||
|
|
||||||
|
renderTemplate(res, req, "calendar.ejs", {
|
||||||
|
year: newYear,
|
||||||
|
islamicYear,
|
||||||
|
persianYear,
|
||||||
|
currentDate: newDate,
|
||||||
|
days,
|
||||||
|
month: newMonth,
|
||||||
|
queryDate,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
app.get("/offline", function (req, res) {
|
app.get("/offline", function (req, res) {
|
||||||
res.sendFile("offline.html", { root: location_pwa });
|
res.sendFile("offline.html", { root: location_pwa });
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue