Compare commits

..

2 Commits

Author SHA1 Message Date
02d8209a6e changed margins 2024-08-24 22:54:05 +02:00
2a7660b62f minimal branch 2024-08-24 22:38:11 +02:00
10 changed files with 229 additions and 583 deletions

View File

@ -56,7 +56,7 @@
}, },
{ {
"name": "Matrix", "name": "Matrix",
"href": "https://brulijam.com/mtrx/#/@brulijam:brulijam.com?web-instance[element.io]=app.element.io", "href": "https://brulijam.com/mtrx/#/@brulijam:brulijam.com?web-instance[element.io]=app.element.io&client=element.io",
"icon": "https://simpleicons.org/icons/matrix.svg", "icon": "https://simpleicons.org/icons/matrix.svg",
"group": 1 "group": 1
}, },
@ -116,7 +116,7 @@
}, },
{ {
"name": "Telegram", "name": "Telegram",
"href": "https://t.me/brulijam", "href": "https://t.me/julian_brammer",
"icon": "https://simpleicons.org/icons/telegram.svg", "icon": "https://simpleicons.org/icons/telegram.svg",
"group": 1 "group": 1
}, },
@ -125,37 +125,12 @@
"href": "https://youtube.com/@brulijam", "href": "https://youtube.com/@brulijam",
"icon": "https://simpleicons.org/icons/youtube.svg", "icon": "https://simpleicons.org/icons/youtube.svg",
"group": 2 "group": 2
},
{
"name": "source code",
"href": "https://git.brulijam.com/brulijam/introduction-website",
"group": "footer"
},
{
"name": "links json",
"href": "content/links.json",
"group": "footer"
},
{
"name": "status",
"href": "https://status.brulijam.com/status/brulijam",
"group": "footer"
},
{
"name": "files",
"href": "https://brulijam.com/files",
"group": "footer"
},
{
"name": "music",
"href": "https://brulijam.com/music",
"group": "footer"
} }
], ],
"groupNames": { "groupNames": {
"1": "social", "1": "Social",
"2": "stuff", "2": "Content",
"3": "games", "3": "Games",
"4": "other" "4": "Other"
} }
} }

View File

@ -1,260 +1,183 @@
/* Root Variables */
:root { :root {
--bg-color: rgb(15, 15, 15); --bg-color: rgb(16, 16, 16);
--primary: rgb(240, 240, 240); --primary: rgb(240, 240, 240);
--secondary-color: hsl(210, 80%, 80%);
--secondary-color2: hsl(210, 60%, 40%); --secondary-color: hsl(200, 60%, 60%);
--secondary-color-bg: hsl(210, 40%, 5%); /*--secondary-color: rgb(0, 138, 216);*/
--font-weight: 350; --hue-rotation: 0;
--font-weight: 400;
--font-family: "Lucida Console"; --font-family: "Lucida Console";
--bigger-font-weight: 700;
--link-border-radius: 1000px; --link-font-weight: 1000;
--page-max-width: 700px; --link-border-radius: 10px;
--page-max-width: 800px;
} }
/* General Styles */ /* General */
body { body {
background-color: var(--secondary-color-bg); background-color: var(--bg-color);
color: var(--primary); color: var(--primary);
/*color: var(--primary);*/
font-family: var(--font-family), monospace; font-family: var(--font-family), monospace;
font-weight: var(--font-weight); font-weight: var(--font-weight);
overflow-x: hidden; overflow-x: hidden;
margin: 0; margin: 20px;
position: relative;
height: 100%; & a {
color: var(--secondary-color);
} }
h1, p { & a:hover {
text-decoration: none;
}
& h1, p {
margin: 0; margin: 0;
}
} }
main { main {
position: relative;
z-index: 1;
max-width: var(--page-max-width); max-width: var(--page-max-width);
margin: 0 auto; margin: 0 auto;
padding: 20px;
filter: drop-shadow(0 0 2px var(--secondary-color)) brightness(1);
} }
::selection { /* Header*/
color: var(--bg-color);
background: var(--secondary-color);
}
/* Header Styles */
header { header {
text-align: center; text-align: center;
width: max-content; width: max-content;
margin: 0 auto; margin: 0 auto;
}
header .names { & .names {
/*margin: 0 auto;*/
width: min-content; width: min-content;
white-space: nowrap; white-space: nowrap;
}
header h1, header p { & h1, p {
text-align: left; text-align: left;
color: var(--secondary-color); color: var(--secondary-color);
} }
}
header img { & img {
border-radius: 50%; border-radius: 50%;
max-width: 300px; max-width: 300px;
padding: 0; padding: 0;
}
/* Links Styles */
h2 {
width: 100%;
margin: 0;
@media only screen and (max-width: 480px) {
text-align: center; /* slim */
margin: 10px auto;
}
@media only screen and (min-width: 480px) {
text-align: left; /* wide */
margin: 0;
} }
} }
.text-link::before {
content: "[";
}
.text-link::after {
content: "]";
}
.text-link {
color: var(--secondary-color);
text-decoration: none;
position: relative;
padding: 5px;
white-space: nowrap;
display: inline-block;
}
.text-link:hover {
filter: drop-shadow(0 0 5px var(--secondary-color2)) brightness(1.02);
top: -2px;
}
/* Links Container */
.links { .links {
padding: 0 10px; /* if wide */
} /*@media only screen and (min-width: 480px) {*/
/* Link Group */
.linkGroup {
margin: auto;
@media only screen and (min-width: 480px) {
display: flex; display: flex;
flex-wrap: wrap; /* wide */ flex-wrap: wrap;
} /*}*/
}
.linkGroup {
min-width: min-content;
margin: 20px auto;
} }
/* Link Styles */
.link { .link {
height: fit-content; font-size: large;
position: relative; margin: 10px 20px;
transition: top 100ms ease, filter 100ms ease; /* Added filter transition */
@media only screen and (max-width: 480px) {
margin: 10px 5%; /* slim */
}
@media only screen and (min-width: 480px) {
padding: 5px; /* wide */
}
} }
/* Button Styles */ h2 {
.linkButton { margin: 10px 20px;
font-weight: var(--bigger-font-weight); font-size: larger;
font-size: 25px;
line-height: 25px;
text-align: center;
text-decoration: none;
text-transform: lowercase;
color: var(--bg-color);
background-color: var(--secondary-color);
display: block;
box-sizing: border-box;
padding: 10px 20px;
border-radius: var(--link-border-radius);
width: 100%; /* slim */
@media only screen and (min-width: 480px) {
width: auto; /* wide */
}
} }
.linkButton .icon { /*!* Links *!*/
width: 25px; /*.linkGroup {*/
height: 25px; /* margin: auto;*/
padding-right: 10px; /* box-sizing: border-box;*/
padding-bottom: 2px;
vertical-align: middle;
}
/* Default Hover Effect */ /* !* if wide *!*/
.hoverHighlight:hover { /* @media only screen and (min-width: 480px) {*/
@media only screen and (min-width: 480px) { /* display: flex;*/
filter: drop-shadow(0 0 8px var(--secondary-color)) brightness(1.1); /* flex-wrap: wrap;*/
top: -2px; /* }*/
}
}
.links:hover .hoverHighlight:not(:hover) {
@media only screen and (min-width: 480px) {
filter: brightness(0.8);
}
}
/* Search Highlighting */ /* & .link {*/
.highlightSearch { /* height: fit-content;*/
filter: drop-shadow(0 0 8px var(--secondary-color)) brightness(1.1); /* position: relative;*/
z-index: 1; /* top: 0;*/
@media only screen and (min-width: 480px) { /* transition: top ease 100ms;*/
top: -2px;
}
}
.notHighlightSearch { /* !* if slim *!*/
filter: brightness(0.5); /* @media only screen and (max-width: 480px) {*/
@media only screen and (max-width: 480px) { /* margin-bottom: 10px;*/
/* margin-left: 10%;*/
/* margin-right: 10%;*/
/* }*/
/* !* if wide *!*/
/* @media only screen and (min-width: 480px) {*/
/* padding: 5px;*/
/* }*/
/* }*/
/*}*/
/*.linkButton {*/
/* font-weight: var(--link-font-weight);*/
/* font-size: 25px;*/
/* line-height: 30px;*/
/* text-align: center;*/
/* text-decoration: none;*/
/* color: rgb(0, 0, 0);*/
/* background-color: var(--secondary-color);*/
/* display: block;*/
/* box-sizing: border-box;*/
/* padding: 10px 20px;*/
/* border-radius: var(--link-border-radius);*/
/* !* if slim *!*/
/* @media only screen and (max-width: 480px) {*/
/* width: 100%;*/
/* }*/
/* & .icon {*/
/* width: 20px;*/
/* height: 20px;*/
/* padding-right: 10px;*/
/* padding-bottom: 4px;*/
/* vertical-align: middle;*/
/* }*/
/*}*/
/*.link:hover {*/
/* filter: drop-shadow(0px 0px 5px var(--secondary-color)) brightness(1.05);*/
/* top: -2px;*/
/*}*/
/*.links:hover .link:not(:hover) a {*/
/* filter: brightness(0.8);*/
/*}*/
/*.linkButton:active {*/
/* transform: scale(0.95); top: +2px;*/
/* box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);*/
/*}*/
/* Links minimal WIP */
.icon {
display: none; display: none;
}
} }
.linkButton:active {
transform: scale(0.95);
top: 2px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
/* Search Input Field Styles */
.fuzzysearch {
margin: 10px auto;
text-align: center;
max-width: var(--page-max-width);
}
#link-search { /* Timers */
background-color: var(--secondary-color2);
color: var(--secondary-color);
border: 2px solid var(--secondary-color2);
border-radius: 50px;
padding: 10px 15px;
font-size: 16px;
text-align: center;
font-weight: var(--bigger-font-weight);
width: 100%;
max-width: 400px; /* Adjust width as needed */
/*box-shadow: 0 0 5px var(--secondary-color2);*/
transition: background-color 100ms ease, border-color 100ms ease, box-shadow 100ms ease;
}
#link-search::placeholder {
color: var(--secondary-color);
opacity: 0.9; /* Placeholder text opacity */
}
#link-search:focus::placeholder {
color: var(--secondary-color);
opacity: 0.9; /* Placeholder text opacity */
}
#link-search:focus {
outline: none;
background-color: var(--secondary-color-bg);
box-shadow: 0 0 10px var(--secondary-color);
border-color: var(--secondary-color2);
color: var(--secondary-color);
}
@media only screen and (max-width: 480px) {
#link-search {
padding: 8px 12px;
max-width: 90%; /* Responsive width for small screens */
}
}
@media only screen and (min-width: 480px) {
#link-search {
padding: 10px 15px;
}
}
/* Timers Styles */
.timer p { .timer p {
/* if slim */
@media only screen and (max-width: 480px) { @media only screen and (max-width: 480px) {
margin-bottom: 20px; /* slim */ margin-bottom: 20px;
} }
} }
@ -263,7 +186,11 @@ h2 {
text-decoration: none; text-decoration: none;
} }
/* Footer Styles */ /* Footer */
footer { footer {
text-align: center; text-align: center;
& a {
padding: 0 2px;
}
} }

View File

@ -3,12 +3,10 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Julian Brammer</title> <title>Brulijam</title>
<link rel="stylesheet" href="css/main.css"> <link rel="stylesheet" href="css/main.css">
<link rel="me" href="https://social.brulijam.com/@brulijam"> <link rel="me" href="https://social.brulijam.com/@brulijam">
<script src="js/main.js"></script> <script src="js/main.js"></script>
<script src="js/fuzzysearch.js" type="module"></script>
<script src="js/links.js"></script>
<script src="js/timer.js"></script> <script src="js/timer.js"></script>
</head> </head>
<body> <body>
@ -22,30 +20,34 @@
</header> </header>
<br> <br>
<section class="description"> <section class="description">
<p>css is pain and I used way too much math to implement that fuzzy search.</p> <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et
<p>One day I will write something meaningful in this paragraph.</p> dolore magna aliquyam erat, sed diam
</section> voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea
<br> takimata sanctus est Lorem ipsum dolor sit
<section class="fuzzysearch"> amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut
<input type="text" id="link-search" placeholder="fuzzy search"> labore et dolore magna aliquyam erat, sed
diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea
takimata sanctus est Lorem ipsum dolor sit
amet.</p>
</section> </section>
<br> <br>
<script src="js/links.js"></script>
<section class="links"> <section class="links">
<noscript> <noscript>
<p>javascript is not available. You can still see a list of my links <a class="text-link" href="content/links.json">here</a>.</p> <p>javascript is not available. You can still see a list of my links <a href="content/links.json">here</a>.</p>
</noscript> </noscript>
</section> </section>
<br> <br>
<section class="timer"> <section class="timer">
<p class="js-required">alive for <span id="timer-alive-since-s"></span><span id="timer-alive-since-ms"></span> seconds.</p> <p class="js-required">alive for <span id="timer-alive-since-s"></span><span id="timer-alive-since-ms"></span> seconds.</p>
<p class="js-required">next birthday in <span id="timer-until-birthday-s"></span><span id="timer-until-birthday-ms"></span> seconds.</p> <p class="js-required">next birthday in <span id="timer-until-birthday-s"></span><span id="timer-until-birthday-ms"></span> seconds.</p>
<p class="js-required">employed at <a class="text-link" href="https://subshell.com/">subshell</a> for <span id="timer-employed-since-s"></span><span <p class="js-required">employed at <a href="https://subshell.com/">subshell</a> for <span id="timer-employed-since-s"></span><span
id="timer-employed-since-ms"></span> id="timer-employed-since-ms"></span>
seconds. seconds.
</p> </p>
<noscript> <noscript>
<p>alive since <span>1999-07-20T00:00:00</span>.</p> <p>alive since <span>1999-07-20T00:00:00</span>.</p>
<p>working at <a class="text-link" href="https://subshell.com/">subshell</a> since <span>2024-05-02T09:00:00</span>.</p> <p>working at <a href="https://subshell.com/">subshell</a> since <span>2024-05-02T09:00:00</span>.</p>
<style> <style>
.js-required { .js-required {
display: none; display: none;
@ -54,7 +56,13 @@
</noscript> </noscript>
</section> </section>
<br> <br>
<footer></footer> <footer>
<a href="https://git.brulijam.com/brulijam/introduction-website" target="_blank">source code</a>
<a href="content/links.json" target="_blank">links.json</a>
<a href="https://status.brulijam.com/status/brulijam">status</a>
<a href="https://brulijam.com/files" target="_blank">files</a>
<a href="https://brulijam.com/music" target="_blank">music</a>
</footer>
</main> </main>
</body> </body>
</html> </html>

View File

@ -1,70 +0,0 @@
function levenshtein(a, b) {
const m = a.length;
const n = b.length;
const d = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
for (let i = 0; i <= m; i++) d[i][0] = i;
for (let j = 0; j <= n; j++) d[0][j] = j;
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
d[i][j] = Math.min(
d[i - 1][j] + 1,
d[i][j - 1] + 1,
d[i - 1][j - 1] + cost
);
}
}
return d[m][n];
}
function jaroWinkler(s1, s2) {
if (s1 === s2) return 1;
const len1 = s1.length;
const len2 = s2.length;
const maxDist = Math.floor(Math.max(len1, len2) / 2) - 1;
const s1Matches = Array(len1).fill(false);
const s2Matches = Array(len2).fill(false);
let matches = 0;
let transpositions = 0;
for (let i = 0; i < len1; i++) {
const start = Math.max(0, i - maxDist);
const end = Math.min(len2, i + maxDist + 1);
for (let j = start; j < end; j++) {
if (s2Matches[j]) continue;
if (s1[i] !== s2[j]) continue;
s1Matches[i] = true;
s2Matches[j] = true;
matches++;
break;
}
}
if (matches === 0) return 0;
let k = 0;
for (let i = 0; i < len1; i++) {
if (!s1Matches[i]) continue;
while (!s2Matches[k]) k++;
if (s1[i] !== s2[k]) transpositions++;
k++;
}
transpositions /= 2;
return (matches / len1 + matches / len2 + (matches - transpositions) / matches) / 3;
}
export function calculateSimilarityScore(query, linkName) {
const levenshteinDistance = levenshtein(query.toLowerCase(), linkName.toLowerCase());
const jaroWinklerScore = jaroWinkler(query.toLowerCase(), linkName.toLowerCase());
return jaroWinklerScore - levenshteinDistance / Math.max(query.length, linkName.length);
}

View File

@ -1,128 +0,0 @@
import { calculateSimilarityScore } from './distance.js';
function applyFuzzySearch(linksData) {
const searchInput = document.getElementById("link-search");
searchInput.addEventListener("input", function () {
const query = searchInput.value.toLowerCase().trim();
if (query === "") {
clearHighlights();
return;
}
searchInput.scrollIntoView({ behavior: 'auto', block: 'start' });
const allLinks = linksData.links;
const scores = allLinks.map(link => ({
link: link,
score: calculateSimilarityScore(query, link.name)
}));
// Sort scores in descending order
scores.sort((a, b) => b.score - a.score);
const highestScore = scores[0].score;
const threshold = Math.max(0.01, highestScore * 0.5) - 0.1; // Adjust as needed
const matchingLinks = scores
.filter(entry => entry.score >= threshold)
.map(entry => entry.link);
highlightLinks(matchingLinks);
});
searchInput.addEventListener("keydown", function (event) {
if (event.key === "Enter") {
const matchingLinksCount = document.querySelectorAll(".links .link.highlightSearch").length;
if (matchingLinksCount === 1) {
const bestMatch = document.querySelector(".links .link.highlightSearch .linkButton");
if (bestMatch) {
bestMatch.click();
}
}
} else if (event.key === "Escape") {
searchInput.value = '';
clearHighlights();
}
});
}
function highlightLinks(matchingLinks) {
clearHighlights();
const allLinks = document.querySelectorAll(".links .link");
allLinks.forEach(linkDiv => {
const link = linkDiv.querySelector('a');
const linkHref = link.getAttribute('href');
const isMatching = matchingLinks.some(matchingLink => matchingLink.href === linkHref);
if (isMatching) {
linkDiv.classList.add('highlightSearch');
linkDiv.classList.remove('notHighlightSearch');
linkDiv.classList.remove('hoverHighlight');
} else {
linkDiv.classList.add('notHighlightSearch');
linkDiv.classList.remove('highlightSearch');
linkDiv.classList.remove('hoverHighlight');
}
});
// Add or remove notHighlightSearch
const groupContainers = document.querySelectorAll('.linkGroup');
groupContainers.forEach(groupContainer => {
const hasHighlightedLink = groupContainer.querySelector('.link.highlightSearch');
const groupHeader = groupContainer.querySelector('h2');
if (hasHighlightedLink) {
groupHeader.classList.remove('notHighlightSearch');
} else {
groupHeader.classList.add('notHighlightSearch');
}
});
document.querySelector('.links').classList.remove('hoverHighlight');
}
function clearHighlights() {
const linkDivs = document.querySelectorAll(".links .link");
linkDivs.forEach(linkDiv => {
linkDiv.classList.remove('highlightSearch');
linkDiv.classList.remove('notHighlightSearch');
linkDiv.classList.add('hoverHighlight');
});
const groupHeaders = document.querySelectorAll('.linkGroup h2');
groupHeaders.forEach(header => {
header.classList.remove('notHighlightSearch');
});
}
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('link-search');
if (searchInput) {
searchInput.value = '';
}
});
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById("link-search");
if (searchInput) {
searchInput.value = '';
document.addEventListener('keydown', function (event) {
const key = event.key;
if (key.length === 1) {
searchInput.focus();
}
});
}
});
fetch('content/links.json')
.then(response => response.json())
.then(data => {
applyFuzzySearch(data);
})
.catch(error => console.error('Error fetching links:', error));

View File

@ -1,7 +1,6 @@
function createLinkDiv(link) { function createLinkDiv(link) {
const linkDiv = document.createElement('div'); const linkDiv = document.createElement('div');
linkDiv.className = 'link'; linkDiv.className = 'link';
linkDiv.classList.add('hoverHighlight');
const anchor = document.createElement('a'); const anchor = document.createElement('a');
anchor.className = 'linkButton'; anchor.className = 'linkButton';
@ -13,38 +12,23 @@ function createLinkDiv(link) {
return linkDiv; return linkDiv;
} }
function createFooterLink(link) {
const footerLink = document.createElement('a');
footerLink.className = 'text-link';
footerLink.href = link.href;
footerLink.target = '_blank';
footerLink.textContent = link.name;
return footerLink;
}
function createGroups(linksData, groupNames) { function createGroups(linksData, groupNames) {
const container = document.querySelector('.links'); const container = document.querySelector('.links');
const footer = document.querySelector('footer');
// Extract unique groups and sort them
const groups = [...new Set(linksData.map(link => link.group))].sort((a, b) => a - b); const groups = [...new Set(linksData.map(link => link.group))].sort((a, b) => a - b);
groups.forEach((group, index) => { groups.forEach((group, index) => {
if (group === "footer") { // Create a container for the group
linksData
.filter(link => link.group === "footer")
.forEach(link => {
const footerLink = createFooterLink(link);
footer.appendChild(footerLink);
});
} else {
// Handle regular links
const groupContainer = document.createElement('div'); const groupContainer = document.createElement('div');
groupContainer.className = 'linkGroup'; groupContainer.className = 'linkGroup';
// Create and append the group header
const groupHeader = document.createElement('h2'); const groupHeader = document.createElement('h2');
groupHeader.textContent = `${groupNames[group]}`; groupHeader.textContent = `${groupNames[group]}`; // Display numeric identifier and name
groupContainer.appendChild(groupHeader); groupContainer.appendChild(groupHeader);
// Filter links that belong to this group and create link elements
linksData linksData
.filter(link => link.group === group) .filter(link => link.group === group)
.forEach(link => { .forEach(link => {
@ -52,13 +36,14 @@ function createGroups(linksData, groupNames) {
groupContainer.appendChild(linkElement); groupContainer.appendChild(linkElement);
}); });
// Append the group container to the main container
container.appendChild(groupContainer); container.appendChild(groupContainer);
// Optionally add a line break between groups
if (index < groups.length - 1) { if (index < groups.length - 1) {
const br = document.createElement('br'); const br = document.createElement('br');
container.appendChild(br); container.appendChild(br);
} }
}
}); });
} }

View File

@ -1,12 +1,34 @@
let hue = Math.floor(Math.random() * 360); // const secondaryColors = [
// // "rgb(240, 240, 240)",
// // "rgb(136, 139, 141)",
// "rgb(224, 231, 34)",
// "rgb(255, 173, 0)",
// "rgb(244,54,76)",
// // "rgb(219, 62, 177)",
// "rgb(250, 150, 250)",
// "rgb(250, 150, 150)",
// "rgb(242, 172, 185)",
// "rgb(0, 138, 216)",
// "rgb(0, 178, 169)",
// "rgb(88, 188, 64)",
// "rgb(173, 223, 179)"
// ];
//
// function setRandomSecondaryColor() {
// const randomColor = secondaryColors[Math.floor(Math.random() * secondaryColors.length)];
// document.documentElement.style.setProperty('--secondary-color', randomColor);
// }
//
// setRandomSecondaryColor();
let hue = 200;
const colorChangeInterval = 150; const colorChangeInterval = 150;
function setRainbowColor() { function setRainbowColor() {
const color = `hsl(${hue}, 80%, 80%)`; const color = `hsl(${hue}, 60%, 60%)`;
document.documentElement.style.setProperty('--secondary-color', color); document.documentElement.style.setProperty('--secondary-color', color);
document.documentElement.style.setProperty('--secondary-color2', `hsl(${hue}, 40%, 40%)`); document.documentElement.style.setProperty('--hue-rotation', `${hue}deg`);
document.documentElement.style.setProperty('--secondary-color-bg', `hsl(${hue}, 20%, 5%)`);
hue = (hue + 1) % 360; hue = (hue + 1) % 360;
} }

View File

@ -1,60 +0,0 @@
import {calculateSimilarityScore} from './distance.js';
document.addEventListener("DOMContentLoaded", function() {
handleRedirection();
});
function handleRedirection() {
let path = window.location.pathname.substring(1).toLowerCase();
if (path === "") {
window.location.href = "/";
return;
}
fetch('/content/links.json')
.then(response => response.json())
.then(data => {
const bestMatch = findBestMatch(path, data.links);
if (bestMatch) {
window.location.href = bestMatch.href;
} else {
displayNotFound();
}
})
.catch(error => {
console.error('Error fetching links.json:', error);
displayError();
});
}
function findBestMatch(path, links) {
let bestMatch = null;
let highestScore = -Infinity;
const threshold = 0.5;
for (let item of links) {
const itemName = item.name.toLowerCase();
const score = calculateSimilarityScore(path, itemName);
if (score > highestScore) {
highestScore = score;
bestMatch = item;
}
}
if (highestScore < threshold) {
window.location.href = "/";
return null;
}
return bestMatch;
}
function displayNotFound() {
document.body.innerHTML = '<h1>Not Found</h1><p>The requested page could not be found.</p>';
}
function displayError() {
document.body.innerHTML = '<h1>Error</h1><p>There was an error retrieving the redirection data.</p>';
}

View File

@ -34,7 +34,7 @@ function calculateTime() {
employedSinceTenthOfASecond = employedSinceTenthOfASecond.toString().padStart(2, "0"); employedSinceTenthOfASecond = employedSinceTenthOfASecond.toString().padStart(2, "0");
const employedSinceS = Math.floor(employedSinceMs / 1000); const employedSinceS = Math.floor(employedSinceMs / 1000);
// update Document // Update Document
updateDocument("timer-alive-since-s", `${formatNumber(aliveSinceS)}`) updateDocument("timer-alive-since-s", `${formatNumber(aliveSinceS)}`)
updateDocument("timer-alive-since-ms", `.${formatNumber(aliveSinceTenthOfASecond)}`) updateDocument("timer-alive-since-ms", `.${formatNumber(aliveSinceTenthOfASecond)}`)
updateDocument("timer-until-birthday-s", `${formatNumber(nextBirthdayS)}`) updateDocument("timer-until-birthday-s", `${formatNumber(nextBirthdayS)}`)

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Redirecting...</title>
<link rel="stylesheet" href="css/main.css">
<script src="js/redirect.js" type="module"></script>
</head>
<body>
<h1>Redirecting...</h1>
</body>
</html>