create bug.tools

This commit is contained in:
4DBug
2026-02-28 21:33:31 -06:00
commit 91cee9a33a
63 changed files with 2019 additions and 0 deletions
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

+281
View File
@@ -0,0 +1,281 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>bug.tools</title>
<link id="dynamic-favicon" rel="icon" href="./images/snowflake/frame001.png" type="image/png">
<link href="style.css" rel="stylesheet" type="text/css" media="all">
<link rel="icon" type="image/x-icon" href="images/favicon.ico">
<script src="js/onLoad.js" defer></script>
<script src="js/switchPage.js" defer></script>
<script src="js/updates.js" defer></script>
<script src="js/player.js" defer></script>
<script src="js/counter.js" defer></script>
<script src="js/favicon.js" defer></script>
</head>
<body>
<div class="row">
<div class="column left">
<div class="navbar">
<img src="images/loadercircle.png" id="loadercircle">
<div class="navbar-title">bug</div>
<div class="navbar-title-2">.tools</div>
<table id="navtable">
<tr>
<td id="navhover"><a href="#" onclick="switchPage('home'); return false;">HOME</a></td>
</tr>
<tr>
<td id="navhover"><a href="#" onclick="switchPage('links'); return false;">LINKS</a></td>
</tr>
<tr>
<td id="navhover"><a href="#" onclick="switchPage('contact'); return false;">CONTACT</a></td>
</tr>
<tr>
<td id="navhover"><a href="#" onclick="switchPage('sitemap'); return false;">SITEMAP</a></td>
</tr>
<tr>
<td id="navhover"><a href="gallery.html">GALLERY</a></td>
</tr>
<tr>
<td id="navhover"><a href="#"><!-- Empty --></a>
</td>
</tr>
</table>
</div>
<div id="vidbutton">
<button id="vidBtn" onclick="PlayPauseVideo()">TURN OFF</button>
<p>moving background</p>
</div>
<div class="small-content-mood">
<div class="small-content-toolbar">
<span data-text="toolbar text">STATUS</span>
<img src="images/xbutton.png" id="small-xbutton-right">
</div>
<div class="small-content-inner">
<span class="status-text" style="margin-top:20px;">
<div id="status" class="fade-in visible">
<div id="status-username"><a href="https://bug.tools/" target="_blank">bug</a> ❄️</div>
<div id="status-content">working on something...</div>
<div id="status-date">// 3 days ago</div>
</div>
</span>
</div>
</div>
<div class="small-content-mood">
<div class="small-content-toolbar">
<span data-text="toolbar text">STATS</span>
<img src="images/xbutton.png" id="small-xbutton-right">
</div>
<div class="small-content-inner"
style="height: 30px; padding-left:0px; padding-right:0px; padding-bottom:0px; margin-top:40px;">
<span style="top:-22px; left:10px; font-family: 'Aldrich', sans-serif;">
your digital ID number<br>
</span>
<span
style="height:25px; margin-left:auto; margin-right:auto; margin-top:-8px; margin-bottom:5px;text-align: center;">
<span id="counter" style="font-variant-numeric: tabular-nums;">0000000</span>
</span>
</div>
</div>
</div>
<div class="column middle">
<div class="content">
<div class="content-toolbar">
<span data-text="welcome" id="toolbar-title">welcome</span>
<img src="images/xbutton.png" id="xbutton">
</div>
<div class="content-inner">
<div id="page-content" class="fade-in"></div>
<template id="page-home">
<h1>Where am I?</h1>
<span>
Welcome to my corner of the web. I'm bug, a self-taught programmer.
This site is my personal space where I collect, create, and share
whatever catches my interest.
</span>
<span class="blink_text" style="color: #93bdec;">
this website is meant to be viewed on a computer.
still under construction, thank you for your patience.
</span>
<h1 style="margin-top:-10px;">What lies here?
<img src="images/ascii_cat.gif"
style="mix-blend-mode: normal; opacity: 0.5; display:inline; margin-left:90px;">
</h1>
<span>
I run <a href="https://nixos.org">NixOS</a> on everything, desktop, laptop, and my home server that this site is hosted on.
You can find my <a href="https://git.bug.tools/bug/nix/" target="_blank">nix configuration</a> on my git instance.
<a href="https://www.lua.org">Lua</a> is my favorite
programming language, though I dabble in plenty of others. I'm a strong believer in
privacy and self-hosting; if there's a service I can run myself, I probably do.
I also have a deep appreciation for digital archival and preserving things that
might otherwise disappear from the internet.
The <a href="https://git.bug.tools/bug/bug.tools/" target="_blank">source code for this website</a> is also available if you're curious.
</span>
<h1 style="margin-top:-10px;">A little about me.
<img src="images/ascii_cat_sleep.gif"
style="mix-blend-mode: normal; opacity: 0.5; display:inline; margin-left:90px;">
</h1>
<span>
When I'm not writing code, I'm usually listening to music or playing games. My taste
in music spans metal, DnB, and a lot in between, some of my favorite artists are
<a href="https://files.bug.tools/music/Pendulum/">Pendulum</a>, <a href="https://files.bug.tools/music/The%20Qemists/">The Qemists</a>, <a href="https://files.bug.tools/music/Linkin%20Park/">Linkin Park</a>, <a href="https://files.bug.tools/music/GUNSHIP/">GUNSHIP</a>.
I also love playing <a href="https://store.steampowered.com/app/2073850/THE_FINALS/">THE FINALS</a> and <a href="https://store.steampowered.com/app/2694490/Path_of_Exile_2/">Path of Exile 2</a>, and I'm always down for a good MMORPG.
Feel free to check out the music player on this page or explore the rest of
the site, there's always something being worked on.
</span>
</template>
<template id="page-contact">
<h1>Traces of me on the web</h1>
<span>
<img src="images/navcircleblue.png" style="margin-top:5px; margin-left:15px;"> <a href="mailto:contact@bug.tools" target="_blank">Email</a> (my contact email)<br>
<img src="images/navcircleblue.png" style="margin-top:10px; margin-left:15px;"> <a href="https://git.bug.tools/bug" target="_blank">Gitea</a> (my personal
Gitea instance)<br>
<img src="images/navcircleblue.png" style="margin-top:10px; margin-left:15px;"> <a href="https://github.com/4DBug" target="_blank">GitHub</a> (my
GitHub account)<br>
<img src="images/navcircleblue.png" style="margin-top:10px; margin-left:15px;"> <a href="https://discordapp.com/users/1475869049526292534" target="_blank">Discord</a> (my discord profile)<br>
<img src="images/navcircleblue.png" style="margin-top:10px; margin-left:15px;"> <a href="https://steamcommunity.com/id/0zBug/" target="_blank">Steam</a> (where I play games)<br>
<img src="images/navcircleblue.png" style="margin-top:10px; margin-left:15px;"> <a href="https://www.roblox.com/users/2520646240/profile" target="_blank">Roblox</a> (where I waste my time)<br>
</span>
<h1>Contact me ?</h1>
<span>
Feel free to send me a message on any of my social medias, I do my best to respond to
everyone.<br>
</span>
<span class="ascii-art" style="width:100%;">
<img src="images/ascii-lab.gif" alt="ascii-lab">
</span>
</template>
<template id="page-links">
<h1>Links</h1>
<span>The links page still needs to be implemented.</span>
</template>
<template id="page-sitemap">
<span style="font-family: 'Source Code Pro', monospace;">
<b style="font-weight: 600;">.bug.tools</b><br>
<br>
├──<b style="font-weight: 600;"><a href="https://bug.tools/">@.</a></b>_the homepage (you are here) <br>
│  ├── <b style="font-weight: 600;">links</b>_cool or useful links<br>
│  ├── <b style="font-weight: 600;">contact</b>_how to contact me<br>
│  ├── <b style="font-weight: 600;">sitemap</b>_map of all pages<br>
│  └── <b style="font-weight: 600;">gallery</b>_gallery<br>
<br>
├──<b style="font-weight: 600;"><a href="https://tv.bug.tools/">tv.</a></b>_movie and television streaming <br>
│  ├── <b style="font-weight: 600;">search</b>_search for entertainment<br>
│  └── <b style="font-weight: 600;">watch</b>_watch movies and tv shows<br>
<br>
├──<b style="font-weight: 600;"><a href="https://fm.bug.tools/">fm.</a></b>_music streaming site<br>
<br>
├──<b style="font-weight: 600;"><a href="https://git.bug.tools/">git.</a></b>_gitea instance<br>
│  └── <b style="font-weight: 600;"><a href="https://git.bug.tools/bug">bug</a></b>_my gitea account<br>
<br>
├──<b style="font-weight: 600;"><a href="https://files.bug.tools/">files.</a></b>_files storage<br>
│  ├── <b style="font-weight: 600;">music</b>_my music collection<br>
│  ├── <b style="font-weight: 600;">raknet</b>_raknet documentation<br>
│  └── <b style="font-weight: 600;">media</b>_various media<br>
<br>
├──<b style="font-weight: 600;">project.</b>_generic project<br>
│  ├── <b style="font-weight: 600;">docs</b>_documentation<br>
│  ├── <b style="font-weight: 600;">src</b>_source files<br>
│  ├── <b style="font-weight: 600;">assets</b>_static assets<br>
│  ├── <b style="font-weight: 600;">tests</b>_test files<br>
│  └── <b style="font-weight: 600;">misc</b>_other files<br>
<br>
├── <b style="font-weight: 600;"><a href="https://gallery.bug.tools/">gallery.</a></b>_gallery of random images<br>
<br>
└── <b style="font-weight: 600;"><a href="https://monitor.bug.tools/">monitor.</a></b>_status of my homeserver<br>
</span>
</template>
</div>
<div class="content-footer"><span id="factDisplay"></span></div>
</div>
<div id="middle-column-img">
<img src="images/dotloader.gif" style="mix-blend-mode: normal; width:500px; opacity: 0.3;">
</div>
</div>
<div class="column right">
<div class="small-content-updates"
style="position: relative; top: 0px; left: 0px; width: 285px; height: auto;">
<div class="small-content-toolbar">
<span data-text="toolbar text">UPDATES</span>
<img src="images/xbutton.png" id="small-xbutton-right">
</div>
<div id="small-content-pictochat">
<div id="pictochat-content">
<div class="picto"></div>
<img src="images/pitcochatmenu.png"
style="border-radius: 0 0 10px 10px; position:relative; top: 0px; left:1px; width:257px; image-rendering: pixelated;">
</div>
</div>
</div>
<div class="small-content-updates"
style="position:relative; top:15px; left:0; width:285px; height:auto; margin-bottom:25px;">
<div class="small-content-toolbar">
<span data-text="toolbar text">MUSIC</span>
<img src="images/xbutton.png" id="small-xbutton-right">
</div>
<div id="small-content-todo" class="fade-in">
<div id="music-player">
<div id="mp-info">
<div id="mp-title">no track selected</div>
<div id="mp-artist">---</div>
</div>
<div id="mp-progress-bg">
<div id="mp-progress-fill"></div>
<input type="range" id="mp-seek" min="0" max="100" value="0" step="0.1">
</div>
<div id="mp-time">
<span id="mp-current">0:00</span>
<span id="mp-duration">0:00</span>
</div>
<div id="mp-controls">
<button class="mp-btn mp-btn-sm" id="mp-loop" title="Loop">&#8635;</button>
<button class="mp-btn" id="mp-prev">&#9664;&#9664;</button>
<button class="mp-btn mp-btn-play" id="mp-play">&#9654;</button>
<button class="mp-btn" id="mp-next">&#9654;&#9654;</button>
<button class="mp-btn mp-btn-sm" id="mp-shuffle" title="Shuffle">&#8644;</button>
</div>
<div id="mp-vol-row">
<span id="mp-vol-icon">&#9836;</span>
<input type="range" id="mp-volume" min="0" max="1" step="0.01" value="0.7">
</div>
<ul id="mp-playlist"></ul>
</div>
</div>
</div>
</div>
</div>
<div id="bgVideoContainer">
<video autoplay muted loop id="bgVideo" style="pointer-events: none">
<source src="background.mp4" type="video/mp4" style="pointer-events: none">
</video>
</div>
</body>
</html>
+21
View File
@@ -0,0 +1,21 @@
(function () {
const COUNTER_DURATION = 2000;
fetch("https://counter.bug-dev-mail.workers.dev")
.then(r => r.text())
.then(count => {
const target = parseInt(count, 10);
const el = document.getElementById("counter");
const start = performance.now();
function tick(now) {
const t = Math.min((now - start) / COUNTER_DURATION, 1);
const eased = 1 - Math.pow(1 - t, 3);
const current = Math.round(eased * target);
el.textContent = String(current).padStart(7, '0');
if (t < 1) requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
});
})();
+33
View File
@@ -0,0 +1,33 @@
const frames = [
'./images/snowflake/frame001.png',
'./images/snowflake/frame002.png',
'./images/snowflake/frame003.png',
'./images/snowflake/frame004.png',
'./images/snowflake/frame005.png',
'./images/snowflake/frame006.png',
'./images/snowflake/frame007.png',
'./images/snowflake/frame008.png',
'./images/snowflake/frame009.png',
'./images/snowflake/frame010.png',
'./images/snowflake/frame011.png',
'./images/snowflake/frame012.png',
'./images/snowflake/frame013.png',
'./images/snowflake/frame014.png',
'./images/snowflake/frame015.png',
'./images/snowflake/frame016.png',
'./images/snowflake/frame017.png',
'./images/snowflake/frame018.png',
'./images/snowflake/frame019.png',
'./images/snowflake/frame020.png',
'./images/snowflake/frame021.png',
'./images/snowflake/frame022.png',
'./images/snowflake/frame023.png'
];
let current = 0;
const favicon = document.getElementById('dynamic-favicon');
setInterval(() => {
current = (current + 1) % frames.length;
favicon.href = frames[current];
}, 150);
+51
View File
@@ -0,0 +1,51 @@
function newFact() {
const facts = [
'Are you watching me, or am I watching you?',
'Is the self you know, the self that exists?',
'When freedom is lost, what is left?',
'Protect your privacy, embrace your freedom',
'I am a wizard, and this is my realm.',
];
const randomFact = Math.floor(Math.random() * facts.length);
const factDisplayElement = document.getElementById("factDisplay");
if (factDisplayElement) {
factDisplayElement.innerHTML = facts[randomFact];
} else {
console.warn('Element with ID "factDisplay" not found.');
}
}
function initVideoControls() {
const video = document.getElementById("bgVideo");
const btn = document.getElementById("vidBtn");
window.PlayPauseVideo = function PlayPauseVideo() {
if (!video || !btn) return;
if (video.paused) {
video.play();
btn.innerHTML = "TURN OFF";
} else {
video.pause();
btn.innerHTML = "TURN ON";
}
};
}
function applyFadeIn() {
const fadeInElements = document.querySelectorAll(".fade-in");
fadeInElements.forEach((element) => {
requestAnimationFrame(() => {
element.classList.add("visible");
});
});
}
document.addEventListener("DOMContentLoaded", function () {
newFact();
applyFadeIn();
initVideoControls();
});
+249
View File
@@ -0,0 +1,249 @@
(function () {
const playlist = [
//{ title: "Sanctuary OS", artist: "Dusqk", src: "music/SanctuaryOS.flac" },
{ title: "Sanctuary 1", artist: "Dusqk", src: "music/sanctuary_1.m4a" },
{ title: "cloud zone", artist: "oooz", src: "music/cloud_zone.m4a" },
{ title: "ketamina", artist: "yaego", src: "music/ketamina.m4a" },
{ title: "fine night", artist: "goreshit", src: "music/fine_night.m4a" },
{ title: "what we did in the desert", artist: "eightiesheadachetape", src: "music/what_we_did_in_the_desert.m4a" },
{ title: "Fleeting Frozen Heart", artist: "Xxtarlit⚸", src: "music/fleeting_frozen_heart.m4a" },
{ title: "Heaven", artist: "i\\believe\\in\\angels", src: "music/heaven.m4a" },
{ title: "i wish to have a happy end", artist: "イア / ia", src: "music/i_wish_to_have_a_happy_end.m4a" },
{ title: "it is not my fault and never will be", artist: "Skeinn", src: "music/it_is_not_my_fault_and_never_will_be.m4a" },
{ title: "Sanctuary 10", artist: "Dusqk", src: "music/sanctuary_10.m4a" },
{ title: "Lexapro Delirium", artist: "sewerslvt", src: "music/lexapro_delirium.m4a" },
];
let currentIdx = -1;
let isPlaying = false;
let isShuffle = false;
let isLoop = false;
let wasEnded = false;
const audio = new Audio();
audio.volume = 0.7;
audio.preload = "metadata";
const elTitle = document.getElementById('mp-title');
const elArtist = document.getElementById('mp-artist');
const elPlay = document.getElementById('mp-play');
const elPrev = document.getElementById('mp-prev');
const elNext = document.getElementById('mp-next');
const elShuffle = document.getElementById('mp-shuffle');
const elLoop = document.getElementById('mp-loop');
const elSeek = document.getElementById('mp-seek');
const elFill = document.getElementById('mp-progress-fill');
const elCurrent = document.getElementById('mp-current');
const elDur = document.getElementById('mp-duration');
const elVol = document.getElementById('mp-volume');
const elList = document.getElementById('mp-playlist');
function buildList() {
elList.innerHTML = '';
if (!playlist.length) {
const li = document.createElement('li');
li.className = 'mp-empty';
li.textContent = 'playlist is empty';
elList.appendChild(li);
return;
}
playlist.forEach((track, i) => {
const li = document.createElement('li');
li.textContent = (i + 1) + '. ' + track.title;
li.title = track.title + (track.artist ? ' · ' + track.artist : '');
li.addEventListener('click', () => loadTrack(i, true));
elList.appendChild(li);
});
}
function formatTime(s) {
if (isNaN(s) || s < 0) return '0:00';
const m = Math.floor(s / 60);
const sec = Math.floor(s % 60);
return m + ':' + (sec < 10 ? '0' : '') + sec;
}
function highlightRow(idx) {
const items = elList.querySelectorAll('li');
items.forEach((li, i) => li.classList.toggle('playing', i === idx));
}
function setPlayIcon() {
elPlay.innerHTML = isPlaying ? '&#9646;&#9646;' : '&#9654;';
}
function loadTrack(idx, autoplay) {
if (!playlist.length) return;
currentIdx = idx;
const t = playlist[idx];
audio.src = t.src;
elTitle.textContent = t.title || 'untitled';
elArtist.textContent = t.artist || '---';
elFill.style.width = '0%';
elSeek.value = 0;
elCurrent.textContent = '0:00';
elDur.textContent = '0:00';
highlightRow(idx);
if (autoplay) {
audio.play().then(() => { isPlaying = true; setPlayIcon(); })
.catch(() => {});
} else {
isPlaying = false;
setPlayIcon();
}
}
function nextTrack() {
if (!playlist.length) return;
let idx;
if (isShuffle) {
idx = Math.floor(Math.random() * playlist.length);
} else {
idx = (currentIdx + 1) % playlist.length;
}
loadTrack(idx, true);
}
function prevTrack() {
if (!playlist.length) return;
if (audio.currentTime > 3) {
audio.currentTime = 0;
return;
}
let idx = (currentIdx - 1 + playlist.length) % playlist.length;
loadTrack(idx, true);
}
elPlay.addEventListener('click', () => {
if (!playlist.length) return;
if (currentIdx === -1) { loadTrack(0, true); return; }
if (isPlaying) {
audio.pause();
isPlaying = false;
} else {
audio.play().catch(() => {});
isPlaying = true;
}
setPlayIcon();
});
elNext.addEventListener('click', nextTrack);
elPrev.addEventListener('click', prevTrack);
elShuffle.addEventListener('click', () => {
isShuffle = !isShuffle;
elShuffle.classList.toggle('active', isShuffle);
});
elLoop.addEventListener('click', () => {
isLoop = !isLoop;
audio.loop = isLoop;
elLoop.classList.toggle('active', isLoop);
});
function updateVolFill() {
const pct = (elVol.value / elVol.max) * 100;
elVol.style.background = 'linear-gradient(90deg, #a9c6f0 0%, #74a4db ' + pct + '%, #e8ecf0 ' + pct + '%)';
}
elVol.addEventListener('input', () => { audio.volume = elVol.value; updateVolFill(); });
elSeek.addEventListener('input', () => {
if (audio.duration) {
audio.currentTime = (elSeek.value / 100) * audio.duration;
}
});
audio.addEventListener('timeupdate', () => {
if (!audio.duration) return;
const pct = (audio.currentTime / audio.duration) * 100;
elFill.style.width = pct + '%';
elSeek.value = pct;
elCurrent.textContent = formatTime(audio.currentTime);
});
audio.addEventListener('loadedmetadata', () => {
elDur.textContent = formatTime(audio.duration);
});
audio.addEventListener('ended', () => {
if (!isLoop) nextTrack();
});
audio.addEventListener('play', () => { isPlaying = true; setPlayIcon(); });
audio.addEventListener('pause', () => { isPlaying = false; setPlayIcon(); });
function setCookie(name, value, days) {
const d = new Date();
d.setTime(d.getTime() + days * 86400000);
document.cookie = name + '=' + encodeURIComponent(value) + ';expires=' + d.toUTCString() + ';path=/;SameSite=Lax';
}
function getCookie(name) {
const match = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]*)'));
return match ? decodeURIComponent(match[1]) : null;
}
function saveState() {
setCookie('mp_track', currentIdx, 30);
setCookie('mp_time', Math.floor(audio.currentTime), 30);
setCookie('mp_volume', audio.volume, 30);
setCookie('mp_shuffle', isShuffle ? '1' : '0', 30);
setCookie('mp_loop', isLoop ? '1' : '0', 30);
}
setInterval(saveState, 5000);
window.addEventListener('beforeunload', saveState);
buildList();
setPlayIcon();
updateVolFill();
const savedTrack = getCookie('mp_track');
const savedTime = getCookie('mp_time');
const savedVol = getCookie('mp_volume');
const savedShuf = getCookie('mp_shuffle');
const savedLoop = getCookie('mp_loop');
if (savedVol !== null) {
audio.volume = parseFloat(savedVol);
elVol.value = audio.volume;
updateVolFill();
}
if (savedShuf === '1') {
isShuffle = true;
elShuffle.classList.add('active');
}
if (savedLoop === '1') {
isLoop = true;
audio.loop = true;
elLoop.classList.add('active');
}
if (savedTrack !== null && playlist[parseInt(savedTrack)]) {
const idx = parseInt(savedTrack);
loadTrack(idx, false);
if (savedTime !== null) {
audio.addEventListener('loadedmetadata', function onceSeek() {
audio.currentTime = Math.min(parseInt(savedTime), audio.duration || 0);
audio.removeEventListener('loadedmetadata', onceSeek);
});
}
}
function autoplayOnce() {
if (currentIdx >= 0 && !isPlaying) {
audio.play().catch(() => {});
}
document.removeEventListener('click', autoplayOnce);
document.removeEventListener('keydown', autoplayOnce);
}
document.addEventListener('click', autoplayOnce);
document.addEventListener('keydown', autoplayOnce);
})();
+41
View File
@@ -0,0 +1,41 @@
const pages = {
home: { title: "welcome" },
contact: { title: "contact" },
links: { title: "links" },
sitemap: { title: "sitemap" }
};
function switchPage(pageKey) {
const page = pages[pageKey];
const template = document.getElementById('page-' + pageKey);
if (!page || !template) return;
const contentDiv = document.getElementById('page-content');
const toolbarTitle = document.getElementById('toolbar-title');
location.hash = pageKey === 'home' ? '' : pageKey;
contentDiv.style.opacity = 0;
setTimeout(() => {
contentDiv.innerHTML = '';
contentDiv.appendChild(template.content.cloneNode(true));
if (toolbarTitle) {
toolbarTitle.textContent = page.title;
toolbarTitle.setAttribute('data-text', page.title);
}
contentDiv.style.transition = 'opacity 0.3s ease';
contentDiv.style.opacity = 1;
}, 150);
}
document.addEventListener('DOMContentLoaded', () => {
const hash = location.hash.replace('#', '');
switchPage(pages[hash] ? hash : 'home');
});
window.addEventListener('hashchange', () => {
const hash = location.hash.replace('#', '');
switchPage(pages[hash] ? hash : 'home');
});
+40
View File
@@ -0,0 +1,40 @@
const updates = [
{ date: "28.02.2026", message: 'Music player now remembers your track and position via cookies \uE026' },
{ date: "28.02.2026", message: 'Added autoplay on first interaction \uE026' },
{ date: "28.02.2026", message: 'Added hash-based routing so refreshing keeps your page \uE026' },
{ date: "27.02.2026", message: 'Added the music player with shuffle, loop, and volume controls \uE026' },
{ date: "27.02.2026", message: 'Created the sitemap page \uE026' },
{ date: "27.02.2026", message: 'Created the contact page \uE026' },
{ date: "26.02.2026", message: 'Created the links page \uE026' },
{ date: "26.02.2026", message: 'Added this pictochat updates box \uE026' },
{ date: "25.02.2026", message: 'Wrote the home page' },
{ date: "24.02.2026", message: 'Styled everything with custom CSS \uE026' },
{ date: "24.02.2026", message: 'Added the video background \uE026' },
{ date: "23.02.2026", message: 'Built the page switching system \uE026' },
{ date: "23.02.2026", message: 'Created the navigation menu' },
{ date: "22.02.2026", message: 'Set up the main layout' },
{ date: "21.02.2026", message: 'Started building the site \uE026' },
];
(function () {
const picto = document.querySelector('#pictochat-content .picto');
if (!picto) return;
updates.forEach(({ date, message }) => {
const entry = document.createElement('div');
entry.style.setProperty('--col', '#90c9ff');
const nameDiv = document.createElement('div');
nameDiv.textContent = 'bug';
const msgDiv = document.createElement('div');
msgDiv.innerHTML = message;
entry.appendChild(nameDiv);
entry.appendChild(document.createTextNode(date));
entry.appendChild(document.createElement('br'));
entry.appendChild(msgDiv);
picto.appendChild(entry);
});
})();
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1303
View File
File diff suppressed because it is too large Load Diff