16 Commits
0.2 ... perso

Author SHA1 Message Date
6110949622 Update js/main.js 2025-10-27 15:28:16 +01:00
91890c9091 Update js/main.js 2025-10-27 15:26:29 +01:00
57a98a1cbd Update config.json
Customization
2025-10-27 15:21:18 +01:00
Abdelrhman Nile
97a194d962 Update README.md 2021-11-12 06:50:17 +00:00
AbdelrhmanNile
53d8f1f6b3 fixing some colors 2021-11-12 08:45:23 +02:00
Abdelrhman Nile
246a28e493 Update README.md 2021-11-10 18:37:22 +00:00
AbdelrhmanNile
6ca2898a50 README 2021-11-10 20:35:24 +02:00
AbdelrhmanNile
05df302ecd README 2021-11-10 20:29:51 +02:00
AbdelrhmanNile
26320c5909 changing color palette to onedark, replacing bing with brave search engine, changing timezone and weather location 2021-11-10 20:18:01 +02:00
Deepjyoti Barman
8cad9b0d21 Add theming ability for various aspects of the startpage
Add support for theming varisou aspects of the page all from the
config.

Thanks to @benjih for the PR.
2021-04-24 19:27:31 +05:30
Deepjyoti Barman
3661f92c15 Remove an unnecessary value in config 2021-04-24 18:57:14 +05:30
Deepjyoti Barman
a12b03ad6b Add function to update the autocomplete highlight color 2021-04-24 18:33:02 +05:30
Benji Hooper
94894c7e6f Include additional configuration for the line divider and the weather 2021-04-16 22:33:07 +01:00
Benji Hooper
8b7e59ca50 Make some background colors and text colors configurable through new style configuration object 2021-04-16 17:51:17 +01:00
Deepjyoti Barman
dc818bd2b5 Add styling for the title if it will be a link as well
The title in the cards are now optionally clickable. If the `url`
attribute is passed to the square in the config then the title will be
clickable and will open that particular `url`.

If not `url` is passed, it will be a plain old heading without any
link.
2020-11-30 13:25:28 +05:30
Deepjyoti Barman
53198646bb Add ability to pass URL for the card title 2020-11-30 13:23:39 +05:30
7 changed files with 242 additions and 101 deletions

View File

@@ -1,19 +1,7 @@
<div align="center">
<h1>Minimal Startpage</h1>
<h4>Just another minimal startpage for browsers.</h4>
</div>
my fork of [this](https://github.com/deepjyoti30/startpage/) start page
<img src=".github/startpage.gif">
<div align="center">
<br>
<img src="https://img.shields.io/badge/Maintained%3F-Yes-blueviolet?style=for-the-badge">
<a href="LICENSE.md"><img src="https://img.shields.io/badge/License-MIT-pink.svg?style=for-the-badge"></a> <a href="http://makeapullrequest.com"><img src="https://img.shields.io/badge/PRs-welcome-lightblue.svg?style=for-the-badge"></a> <img src="https://img.shields.io/badge/supports-chrome-lightgreen.svg?style=for-the-badge"> <img src="https://img.shields.io/badge/supports-firefox-orange.svg?style=for-the-badge"><a href="https://www.paypal.me/deepjyoti30" target="_blank"><img alt="undefined" src="https://img.shields.io/badge/paypal-deepjyoti30-blue?style=for-the-badge&logo=paypal"></a>
<a href="https://ko-fi.com/deepjyoti30" target="_blank"><img alt="undefined" src="https://img.shields.io/badge/KoFi-deepjyoti30-red?style=for-the-badge&logo=ko-fi"></a>
<br>
<h3>
<a href="https://github.com/deepjyoti30/startpage/wiki/Installation">Installation</a> | <a href="https://github.com/deepjyoti30/startpage/wiki/Configuration">Configuration</a> | <a href="https://github.com/deepjyoti30/startpage/wiki">Wiki</a>
</h3>
</div>
i just changed the color palette to onedark,
you will find the documentations and everything on the original repo
# SCREENSHOTS
<img src = "https://i.imgur.com/s5T9dKK.png">
<img src = "https://i.imgur.com/wJagxIv.png">

View File

@@ -1,51 +1,66 @@
{
"squares": [
{ "name": "media",
"color": "red",
"color": "#61afef",
"links": [
{ "name": "Spotify", "url": "https://open.spotify.com/" },
{ "name": "YoutubeMusic", "url": "https://music.youtube.com/" },
{ "name": "Netflix", "url": "https://netflix.com" },
{ "name": "Youtube", "url": "https://youtube.com" }
{ "name": "Youtube", "url": "https://youtube.com" },
{ "name": "Jellyfin", "url": "https://stream.kawa.zip/" },
{ "name": "KawaMusic", "url": "https://music.kawawete.xyz/" },
{ "name": "Tidal", "url": "https://tidal.com" },
{ "name": "Tidal", "url": "https://zic.kawa.zip" }
]
},
{ "name": "work",
"color": "#26A69A",
{ "name": "homelab",
"color": "#e06c75",
"links": [
{ "name": "Github", "url": "https://github.com" },
{ "name": "Heroku", "url": "http://heroku.com/" },
{ "name": "localhost", "url": "http://localhost:8000/" }
{ "name": "Front 1 Portainer", "url": "https://port.team4kw.fr" },
{ "name": "Front 2 Portainer", "url": "https://port.azuze.fr/" },
{ "name": "IIRIAM Dockge", "url": "https://yacht.iiriam.fr/" }
]
},
{ "name": "social",
"color": "#e5c07b",
"links": [
{ "name": "Reddit", "url": "https://reddit.com" },
{ "name": "Unixporn Love", "url": "https://deepjyoti30.github.io/unixporn-love/" },
{ "name": "r/unixporn", "url": "https://www.reddit.com/r/unixporn/" },
{ "name": "r/mk", "url": "https://www.reddit.com/r/MechanicalKeyboards/" }
{ "name": "9GAG", "url": "https://9gag.com" },
{ "name": "Twitter", "url": "https://x.com/" },
{ "name": "Instagram", "url": "https://instagram.com/" }
]
},
{
"name": "Others",
"name": "tools",
"color": "#98c379",
"links": [
{"name": "Material Colors", "url": "http://materialuicolors.co/"},
{"name": "Gmail", "url": "http://gmail.com/"},
{"name": "neo4j Local", "url": "http://localhost:7474/"},
{"name": "rarbg", "url": "http://rarbg.to"}
{"name": "PDF", "url": "https://pdf.larrache.fr/"},
{"name": "YT DL", "url": "https://ytdl.kawa.zip/"},
{"name": "OmniTools", "url": "https://tools.larrache.fr/"},
{"name": "Penpot", "url": "https://id.larrache.fr"}
]
}
],
"searchEngine":"DuckDuckGo",
"user": "Deepjyoti",
"searchEngine":"FindShit",
"user": "Kawa",
"disableMessage": false,
"disableDate": false,
"disableSearchBar": false,
"disable24Hour": false,
"disableWeather": true,
"timeZone": "America/Los_Angeles",
"disableWeather": false,
"timeZone": "Europe/Paris",
"weatherConf": {
"location": "Pune India",
"location": "Melun",
"unit": "cel"
},
"settingsIcon": false
"settingsIcon": false,
"style": {
"backgroundColor": "#282c34",
"messageColor": "#fff",
"dateColor": "#c8ccd4",
"lineColor": "#fff",
"weatherColor": "#c8ccd4",
"searchColor": "#c8ccd4",
"searchBackgroundColor": "#1e222a",
"squareColor": "#abb2bf",
"squareBackgroundColor": "#1e222a",
"autocompleteHighlightBackgroundColor": "#3e4451"
}
}

View File

@@ -72,7 +72,8 @@ body {
font-size: 18px;
color: #fff;
box-sizing: border-box;
z-index: -1; }
z-index: -1;
cursor: pointer; }
.main #search-bar .autocomplete-items-container .autocomplete-item:hover {
background: #3b3b3b; }
.main #search-bar .autocomplete-items-container .autocomplete-active {
@@ -97,6 +98,9 @@ body {
.main #other-content .sqr h4 {
font-size: 18px;
margin: 15px; }
.main #other-content .sqr h4 a {
color: inherit;
font-size: inherit; }
.main #other-content .sqr:hover {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); }

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>startpage</title>
<title>New Tab</title>
<!--Json Editor-->
<link rel="stylesheet" href="css/jsoneditor.min.css" type="text/css">
<!--Custom CSS-->

View File

@@ -1,4 +1,4 @@
function autocomplete(inp, passedValues) {
function autocomplete(inp, passedValues, style) {
var currentFocus;
/*execute a function when someone writes in the text field:*/
@@ -18,6 +18,9 @@ function autocomplete(inp, passedValues) {
parentContainer.setAttribute("id", this.id + "-autocomplete-list");
parentContainer.style.paddingBottom = "1rem";
if(style["searchBackgroundColor"]) {
parentContainer.style.backgroundColor = style["searchBackgroundColor"];
}
/*for each item in the array...*/
Object.keys(passedValues).forEach((el, i, arr) => {
@@ -30,6 +33,14 @@ function autocomplete(inp, passedValues) {
// Add the url as an attribute
item.setAttribute('url', passedValues[el]);
if(style["searchBackgroundColor"]) {
item.style.backgroundColor = style["searchBackgroundColor"];
}
if(style["searchColor"]) {
item.style.color = style["searchColor"];
}
/*make the matching letters bold:*/
item.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>";
item.innerHTML += arr[i].substr(val.length);

View File

@@ -17,7 +17,7 @@ timeZ = undefined
otherContentId = "other-content"
userName = ""
disable24Hour = false;
appId = "fd2c04ed7f9802656bd2cc23bddc7ad9"
appId = "d319d5bd85895258efbd0bffc9e9a894"
apiUrl = "http://api.openweathermap.org/data/2.5/weather"
bgClassContainer = [
"media",
@@ -32,8 +32,9 @@ bgClassContainer = [
]
searchEngines = {
"Google": "https://www.google.com/search?q=",
"FindShit": "https://findsh.it/search?q=",
"DuckDuckGo": "https://duckduckgo.com/?q=",
"Bing": "https://www.bing.com/search?q=",
"Brave": "https://search.brave.com/search?q=",
"Yahoo": "https://search.yahoo.com/search?p=",
"Ecosia": "https://www.ecosia.org/search?q="
}
@@ -46,7 +47,7 @@ validQuickLinks = {}
function initBody() {
/**
* Function called when the body is loaded.
*
*
* Do everything like adding an event listener to
* other things.
*/
@@ -71,7 +72,7 @@ function initSearchBar(jsonData) {
searchEngine = "Google"
}
searchUrl = this.searchEngines[searchEngine]
document.getElementById(searchBarId).placeholder = `Search something on ${searchEngine}`
document.getElementById(searchBarId).placeholder = `${searchEngine} Search`
document.getElementById(searchBarId).addEventListener("keypress", (event) => {
if (event.key != 'Enter') return
@@ -96,7 +97,7 @@ function initSearchBar(jsonData) {
function buildMsg() {
/**
* Build a nice message for the user.
*
*
* Following is how the message would be decided.
* 0 - 5:59 : It's too late, take some sleep
* 6 - 8:59 : You're up early
@@ -111,17 +112,17 @@ function buildMsg() {
currentTime = currentHour + (0.01 * currentMinute)
if (inRange(currentTime, 0, 5.59))
return "It's too late, take some sleep"
if (inRange(currentTime, 6, 8.59))
return "You're up early"
if (inRange(currentTime, 9, 11.59))
return "Have a good day ahead"
return "Rendort toi..."
if (inRange(currentTime, 6, 8.30))
return "Trop tot pour bosser"
if (inRange(currentTime, 8.31, 11.59))
return "Je sens que ca va etre une bonne journée"
if (inRange(currentTime, 12, 16.59))
return "Good Afternoon"
return "Bon aprem"
if (inRange(currentTime, 17, 19.59))
return "Good Evening"
return "Bonne soirée"
if (inRange(currentTime, 20, 24))
return "It's time to wrap up for the day"
return "Allez hop, on remballe"
else
return ""
}
@@ -129,14 +130,14 @@ function buildMsg() {
function handleMessage(userName) {
/**
* Handle the creation of the message
*
*
* Build the message based on the time of the day.
* If the message is null then add just the username
* Else, add the username before the message.
*/
var builtMsg = buildMsg()
builtMsg == "" ?
builtMsg = `Hello ${userName}` : builtMsg = `Hey ${userName}, ${builtMsg}!`
builtMsg == "" ?
builtMsg = `Salut ${userName}` : builtMsg = `Hey ${userName}, ${builtMsg}!`
return builtMsg;
}
@@ -146,13 +147,13 @@ function updateTime() {
*/
currentDate = new Date()
options = {
day: 'numeric',
month: 'short',
hour: 'numeric',
minute: 'numeric',
hour12: disable24Hour,
timeZone: timeZ
}
day: 'numeric',
month: 'short',
hour: 'numeric',
minute: 'numeric',
hour12: disable24Hour,
timeZone: timeZ
}
finalDate = currentDate.toLocaleString(undefined, options)
document.getElementById(dateId).textContent = finalDate
}
@@ -173,7 +174,7 @@ function updateWeather(weatherConfig) {
userLocation = weatherConfig["location"].replace(/\ /g, ",")
passedUnit = weatherConfig["unit"]
unit = validWeatherUnit.includes(passedUnit.substring(0, 3)) ?
passedUnit : "cel"
passedUnit : "cel"
fetchUrl = apiUrl + `?q=${userLocation}&appid=${appId}&units=metric`
@@ -184,7 +185,7 @@ function updateWeather(weatherConfig) {
weatherType = jsonData["weather"][0]["main"]
temp = !unit.includes("cel") ?
getFahrenheit(temp) + "&deg;F" : temp + "&deg;C"
getFahrenheit(temp) + "&deg;F" : temp + "&deg;C"
weatherText = temp + ", " + indexUppercase(weatherType)
document.getElementById(weatherId).innerHTML = weatherText
})
@@ -216,13 +217,13 @@ function parseAndCreate(jsonData) {
if (jsonData["settingsIcon"]) enableCog();
// If the user has not passed any custom message
if (Object.keys(jsonData).includes("message") &&
if (Object.keys(jsonData).includes("message") &&
typeof(jsonData["message"]) == "string" &&
jsonData["message"] != "")
builtMsg = jsonData["message"]
else
builtMsg = this.handleMessage(this.userName);
document.getElementById(messageId).textContent = builtMsg
// Check if 24 hour is disabled
disable24Hour = jsonData["disable24Hour"]
@@ -252,19 +253,66 @@ function parseAndCreate(jsonData) {
sqrs = jsonData["squares"]
// Extract the quicklinks from the sqrs
extractQuickLinks(sqrs);
sqrs.forEach((element, index) => {
sqr = createSqr(element, index)
document.getElementById(otherContentId).appendChild(sqr)
})
// Apply styling if present
if (jsonData["style"]) {
styleData = jsonData["style"]
if (styleData["backgroundColor"]) {
document.body.style.backgroundColor = styleData["backgroundColor"]
}
if (styleData["messageColor"]) {
document.getElementById(messageId).style.color = styleData["messageColor"]
}
if (styleData["dateColor"]) {
document.getElementById(dateId).style.color = styleData["dateColor"]
}
if (styleData["lineColor"]) {
document.getElementById(lineId).style.color = styleData["lineColor"]
}
if (styleData["weatherColor"]) {
document.getElementById(weatherId).style.color = styleData["weatherColor"]
}
if (styleData["searchColor"]) {
document.getElementById(searchBarId).style.color = styleData["searchColor"]
}
if (styleData["searchBackgroundColor"]) {
document.getElementById(searchBarId).style.backgroundColor = styleData["searchBackgroundColor"]
autocompleteBackgroundColor = styleData["searchBackgroundColor"]
}
if (styleData["searchPlaceholderColor"]) {
document.getElementById(searchBarId).classList.add(createPlaceholderStyleClass(styleData["searchPlaceholderColor"]));
}
if (styleData["autocompleteHighlightBackgroundColor"]) {
addAutocompleteStyleClass(styleData["autocompleteHighlightBackgroundColor"]);
}
if (styleData["squareBackgroundColor"]) {
elements = document.getElementsByClassName("sqr")
var i;
for (i = 0; i < elements.length; i++) {
elements[i].style.backgroundColor = styleData["squareBackgroundColor"]
}
}
if (styleData["squareColor"]) {
elements = document.querySelectorAll(".sqr a")
var i;
for (i = 0; i < elements.length; i++) {
elements[i].style.color = styleData["squareColor"]
}
}
}
// Extract the quicklinks from the sqrs
extractQuickLinks(sqrs, jsonData["style"]);
}
function createSqr(sqrData, index) {
// Create a new square division with the passed element
name = sqrData["name"];
link = sqrData["url"];
links = sqrData["links"];
color = sqrData["color"];
@@ -286,16 +334,14 @@ function createSqr(sqrData, index) {
div.classList.add(customClass);
h4 = document.createElement("h4")
h4.textContent = name
h4 = getTitle(name, link);
div.appendChild(h4)
links.forEach(element => {
aName = element["name"]
aHref = element["url"]
a = document.createElement("a")
attrHref = document.createAttribute("href")
attrHref.value = aHref
@@ -309,6 +355,32 @@ function createSqr(sqrData, index) {
return div
}
function getTitle(titleContent, linkHref=null) {
/**
* Create the title for the sqr card.
*
* The card will be optionally clicable and will open
* a new link.
*
* If the link is not passed in the config then the title
* will not be clickable.
*/
h4 = document.createElement("h4");
if (!linkHref) {
h4.textContent = titleContent;
return h4;
}
// If the link is passed, create a nested child
a = document.createElement("a");
a.setAttribute("href", linkHref);
a.textContent = titleContent;
h4.appendChild(a);
return h4;
}
// Utility functions
function isValidTimeZone(tz) {
@@ -342,7 +414,7 @@ function inRange(number, min, max) {
function isColorValid(color) {
/**
* Check if the passed color is valid.
*
*
* Currently supports only css color names
* or hex colors having 3 or 6 characters.
*/
@@ -359,12 +431,12 @@ function createClass(color) {
/**
* Create a new class in a style and add it to
* the head.
*
*
* I did check other alternatives since adding something like
* this in the innerHTML is not a preferred way to go,
* especially since I'm building this as an extension,
* however, there's no other way.
*
* however, there's no other way.
*
* Since I also want to add hover effects, there seriously
* is no other way to do that without adding a style or using
* a library (cannot/don't want to do that because this is an extension).
@@ -378,11 +450,56 @@ function createClass(color) {
return newClassName;
}
function createPlaceholderStyleClass(color) {
/**
* Create a new class with for placeholder styling.
*
* This is pretty much a continuation of what has done preivously
* in the createClass function.
*/
var style = document.createElement('style');
const newClassName = `bg-${Math.random().toString(36).substring(7)}`;
style.type = 'text/css';
style.innerHTML = `::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
color: ${color} !important;
opacity: 1; /* Firefox */
}
function extractQuickLinks(passedSqrs) {
:-ms-input-placeholder { /* Internet Explorer 10-11 */
color: ${color} !important;
}
::-ms-input-placeholder { /* Microsoft Edge */color: ${color} !important;}`;
document.getElementsByTagName('head')[0].appendChild(style);
return newClassName;
}
function addAutocompleteStyleClass(color) {
/**
* Add some colors for the autocomplete classes in order to
* keep. We need to add styles for :hover property so it is
* easier to just inject some CSS.
*/
var style = document.createElement("style");
style.type = "text/css";
style.innerHTML = `
.autocomplete-item:hover {
background: ${color} !important;
}
.autocomplete-active {
background: ${color} !important;
}
`;
document.getElementsByTagName('head')[0].appendChild(style);
}
function extractQuickLinks(passedSqrs, style) {
/**
* Extract the quicklinks passed in the config
*
*
* Cache the quicklinks passed by the user in the config JSON
* so that they can be used as a shortcut called from the
* search bar.
@@ -392,7 +509,7 @@ function extractQuickLinks(passedSqrs) {
});
// Start the autocomplete
autocomplete(document.getElementById("search-bar-input"), this.validQuickLinks);
autocomplete(document.getElementById("search-bar-input"), this.validQuickLinks, style);
}
// Listen to key click
@@ -410,10 +527,10 @@ function listenForSettings() {
function enableCog() {
/**
* Enable the settings cog.
*
*
* It will be disabled by default, however, if the user
* wishes to enable it through the config, it will be shown.
*
*
* Once shown, we need to add some event listeners to it as
* well so it works the right way.
*/
@@ -432,4 +549,4 @@ function enableCog() {
hideSettings(editor);
}
}
}
}

View File

@@ -1,12 +1,12 @@
$background: #212121;
$foreground: #fff;
$background: #282c34;
$foreground: #abb2bf;
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
$media: #4DD0E1;
$work: #F06292;
$social: #FFF176;
$others: #81C784;
$funky: #4DB6AC;
$purple: #9575CD;
$media: #61afef;
$work: #e06c75;
$social: #e5c07b;
$others: #98c379;
$funky: #56b6c2;
$purple: #c678dd;
$upvoty: #FF8A65;
$indigo: #7986CB;
$foxxy: #A1887F;
@@ -108,6 +108,7 @@ body {
color: $foreground;
box-sizing: border-box;
z-index: -1;
cursor: pointer;
&:hover {
background: lighten($background, 10);
@@ -143,6 +144,11 @@ body {
h4 {
font-size: 18px;
margin: 15px;
a {
color: inherit;
font-size: inherit;
}
}
&:hover {
@@ -182,7 +188,7 @@ body {
h4, a:hover {
color: $social;
}
}
.others {
@@ -261,10 +267,10 @@ body {
right: 25px;
transition: 2s ease-in;
display: none;
&:hover .cog {
fill: white;
stroke: white;
transition: 2s ease-in;
}
}
}