Merge pull request #10 from JCionx/main

Added customizable homepage
This commit is contained in:
2024-06-08 22:57:43 +01:00
committed by GitHub
23 changed files with 371 additions and 1 deletions

View File

@@ -0,0 +1,16 @@
# Customizable browser homepage
This is a simple browser homepage with focus on customization.
Try is out [here](https://jcionx.github.io/homepage).
![](assets/screenshots/1.jpeg)
The search bar is hidden until you start typing.
![](assets/screenshots/2.jpeg)
The `config.json` file stores all your configs. There you can show/hide elements, change the colors, the background, the default search engine, and add aliases to more engines.
![](assets/screenshots/3.png)
If you want to use this as your homepage directly from GitHub Pages, you can add `?config=url_to_your_config.json` to use a custom config.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,106 @@
@font-face {
font-family: 'Roboto';
src: url('../fonts/Roboto-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('../fonts/Roboto-LightItalic.ttf') format('truetype');
font-weight: normal;
font-style: italic;
}
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
color: var(--primary-color);
text-align: center;
overflow: hidden;
margin: 0;
height: 100vh;
width: 100vw;
background-size: cover;
background-position: center center;
}
.clock {
display: none;
font-size: 10rem;
margin-top: 1.3rem;
}
.date {
display: none;
font-size: 2.5rem;
}
.quote {
display: none;
font-size: 1.6rem;
flex-direction: column;
align-items: center;
position: absolute;
bottom: 1.3rem;
width: 100vw;
}
#quote-text {
width: 50vw;
}
.quote-author {
font-style: italic;
font-weight: 200;
font-size: 1.2rem;
}
.search-box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
height: 50px;
display: flex;
flex-direction: row;
}
.search-bar {
width: 100%;
height: 100%;
outline: none;
border: solid 2px var(--primary-color);
border-radius: var(--border-radius);
color: var(--primary-color);
background-color: var(--secondary-color);
font-size: 1.5rem;
}
.search-icon {
height: 40px;
width: 40px;
position: relative;
left: -55px;
margin: 8px;
}
.search-bar:placeholder-shown {
opacity: 0;
transform: scale(0.95) translateY(1rem);
}
.search-bar:placeholder-shown ~ .search-icon {
opacity: 0;
transform: scale(0.95) translateY(1rem) translateX(-1.6rem);
}
.fade-in {
animation: fadeIn 1.5s;
}
@keyframes fadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}

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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 812 KiB

View File

@@ -0,0 +1,189 @@
// Load the config.json file (using JavaScript vanilla)
config_file = 'config.json';
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('json')) {
config_file = urlParams.get('json');
}
fetch(config_file)
.then(response => response.json())
.then(data => {
// Load the config.json file
console.log(data);
// Load the clock if the config.json file says so
if (data["show_clock"] == true) {
displayTime(data);
clock.style.display = "block";
setInterval(displayTime, 1000, data);
}
if (data["show_date"] == true) {
displayDate();
date.style.display = "block";
setInterval(displayDate, 60000);
}
if (data["random_quote"] == true) {
displayQuote();
quote.style.display = "flex";
}
search_engine = data["search_engine"];
alt_engines = data["alt_engines"];
console.log(alt_engines)
document.documentElement.style.setProperty('--primary-color', data["primary_color"]);
document.documentElement.style.setProperty('--secondary-color', data["secondary_color"]);
document.documentElement.style.setProperty('--border-radius', data["border_radius"]);
document.getElementById('search-icon').setAttribute('fill', data["primary_color"]);
document.body.style.backgroundImage = "url('" + data["wallpaper"] + "')";
if (data["animations"] == true) {
clock.classList.add('fade-in');
date.classList.add('fade-in');
quote.classList.add('fade-in');
document.getElementById('search-bar').style.transition = "0.1s";
document.getElementById('search-icon').style.transition = "0.1s";
}
if (data["enable_rickroll_at_2am"] == true) {
rickroll_at_2am = true;
}
if (data["hourly_buawawa"] == true) {
hourly_buawawa = true;
}
if (data["ctrl_o_woooaaauuuuu"] == true) {
document.addEventListener('keydown', function(e) {
if ((e.ctrlKey || e.metaKey) && e.key === 'o') {
let audio = new Audio('assets/audio/woooaaauuuuu.mp3');
audio.play();
e.preventDefault(); // Prevent the default action
}
});
}
}
);
rickroll_at_2am = false;
hourly_buawawa = false;
last_hour_buawawa = 0;
search_engine = "";
alt_engines = {}
clock = document.getElementById('clock');
clock_text = document.getElementById('clock-text');
date = document.getElementById('date');
date_text = document.getElementById('date-text');
quote = document.getElementById('quote');
quote_text = document.getElementById('quote-text');
quote_author = document.getElementById('quote-author');
function displayTime(config) {
if (config["24_hour"] == true) {
let date = new Date();
let hours = date.getHours();
let minutes = date.getMinutes();
minutes = minutes < 10 ? '0'+minutes : minutes;
let time = hours + ":" + minutes;
clock_text.innerHTML = time;
} else {
let date = new Date();
let hours = date.getHours();
let minutes = date.getMinutes();
let ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12;
hours = hours ? hours : 12;
minutes = minutes < 10 ? '0'+minutes : minutes;
let time = hours + ":" + minutes + " " + ampm;
clock_text.innerHTML = time;
}
if (rickroll_at_2am) {
let date = new Date();
let hours = date.getHours();
let minutes = date.getMinutes();
if (hours == 2 && minutes == 0) {
window.location.href = "https://www.youtube.com/watch?v=dQw4w9WgXcQ";
}
}
if (hourly_buawawa) {
let date = new Date();
let minutes = date.getMinutes();
if (minutes == 0 && last_hour_buawawa != date.getHours()) {
last_hour_buawawa = date.getHours();
let audio = new Audio('assets/audio/buawawa.mp3');
audio.play();
}
}
}
function displayDate() {
let date = new Date();
let days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
let day = days[date.getDay()];
let dayNumber = date.getDate();
let month = date.toLocaleString('default', { month: 'long' });
let year = date.getFullYear();
if (dayNumber == 1 || dayNumber == 21 || dayNumber == 31) {
dayNumber += "st";
} else if (dayNumber == 2 || dayNumber == 22) {
dayNumber += "nd";
} else if (dayNumber == 3 || dayNumber == 23) {
dayNumber += "rd";
} else {
dayNumber += "th";
}
let dateText = day + ", " + dayNumber + " " + month + " " + year;
date_text.innerHTML = dateText;
}
function displayQuote() {
fetch('https://api.quotable.io/random')
.then(response => response.json())
.then(data => {
quote_text.innerHTML = data["content"];
quote_author.innerHTML = "- " + data["author"];
}
);
}
// body on any keypress focus on search bar
document.body.onkeypress = function() {
document.getElementById("search-bar").focus();
}
function isValidUrl(url) {
const regex = /(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/;
return regex.test(url);
}
// Check if search bar pressed enter
document.getElementById("search-bar").addEventListener("keypress", function(e) {
if (e.key === 'Enter') {
let url = document.getElementById("search-bar").value;
// Check if starts with any of the alt engines
for (const [key, value] of Object.entries(alt_engines)) {
console.log(key, value)
if (url.startsWith(key)) {
window.location.href = value + url.replace(key, '');
return;
}
}
if (isValidUrl(url)) {
// Check if the url has http or https
if (!url.startsWith('http://') && !url.startsWith('https://')) {
url = 'http://' + url;
}
window.location.href = url;
} else {
window.location.href = search_engine + url;
}
}
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

View File

@@ -0,0 +1,34 @@
{
"show_clock": true,
"24_hour": true,
"show_date": true,
"primary_color": "#FFFFFF",
"secondary_color": "#4A4A4A",
"border_radius": "10px",
"wallpaper": "assets/images/wallpapers/1.jpg",
"random_quote": true,
"search_engine": "https://www.google.com/search?q=",
"animations": true,
"enable_rickroll_at_2am": true,
"hourly_buawawa": true,
"ctrl_o_woooaaauuuuu": true,
"alt_engines": {
"yt ": "https://www.youtube.com/results?search_query=",
"gh ": "https://github.com/search?q=",
"wiki ": "https://en.wikipedia.org/wiki/Special:Search?search=",
"aw ": "https://wiki.archlinux.org/index.php?search=",
"r/": "https://www.reddit.com/r/",
"u/": "https://www.reddit.com/u/",
"mc": "https://namemc.com/search?q=",
"pl": "https://www.planetminecraft.com/resources/?q=",
"ao3": "https://archiveofourown.org/works/search?utf8=%E2%9C%93&work_search%5Bquery%5D=",
"sof": "https://stackoverflow.com/search?q=",
"gl": "https://gitlab.com/search?search=",
"bb": "https://bitbucket.org/repo/all?name=",
"sf": "https://sourceforge.net/directory/?q=",
"npm": "https://www.npmjs.com/search?q=",
"yarn": "https://yarnpkg.com/packages?q=",
"pypi": "https://pypi.org/search/?q=",
"dh": "https://hub.docker.com/search?q="
}
}

View File

@@ -1 +1,26 @@
TEST HOMEPAGE
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="assets/css/style.css">
<title>Homepage</title>
</head>
<body>
<div class="clock" id="clock">
<span id="clock-text"></span>
</div>
<div class="date" id="date">
<span id="date-text"></span>
</div>
<div class="quote" id="quote">
<span id="quote-text"></span>
<span id="quote-author" class="quote-author"></span>
</div>
<div class="search-box">
<input type="text" class="search-bar" id="search-bar" placeholder=" " autocomplete="off" autofocus>
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed" class="search-icon" id="search-icon"><path d="M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z"></svg>
</div>
<script src="assets/js/script.js"></script>
</body>
</html>