diff --git a/manifest.json b/manifest.json index 6db5302..8bebac2 100644 --- a/manifest.json +++ b/manifest.json @@ -1,12 +1,13 @@ { "manifest_version": 3, "name": "Supernova's Tab Page", - "version": "1.0.4", "description": "This is my custom tab page extension I built to increase my productivity.", + "version": "1.0.5", "permissions": [ "storage", "scripting", "activeTab", + "topSites", "http://*/*", "https://*/*" ], @@ -20,7 +21,7 @@ }, "options_ui": { "page": "options.html", - "open_in_tab": true + "open_in_tab": false }, "icons": { "16": "icon16.png", diff --git a/newtab.css b/newtab.css index 7ade2df..f94af36 100644 --- a/newtab.css +++ b/newtab.css @@ -16,35 +16,30 @@ html, body { .quote { font-size: 24px; - color: var(--text-color); + color: var(--text-color, white); margin-bottom: 20px; } .time { font-size: 48px; - color: var(--text-color); + color: var(--text-color, white); margin-bottom: 20px; } .weather { font-size: 24px; - color: var(--text-color); + color: var(--text-color, white); + } + + .topSites { + font-size: 24px; + color: var(--text-color, white); } .container { position: relative; } - .quote, - .time, - .weather { - opacity: 0; - animation-name: fade-in; - animation-duration: 1s; - animation-delay: 0.5s; - animation-fill-mode: forwards; - } - @keyframes fade-in { 0% { opacity: 0; @@ -59,7 +54,14 @@ html, body { top: 10px; right: 10px; z-index: 9999; + opacity: 0; + animation-name: fade-in; + animation-duration: 1s; + animation-delay: 1.5s; + animation-fill-mode: forwards; } + + /* POPUP */ .popup { position: fixed; @@ -67,8 +69,8 @@ html, body { left: 50%; transform: translate(-50%, -50%); width: 400px; - height: 300px; - background-color: #fff; + height: 425px; + background-color: var(--wallpaper-color, white); box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); z-index: 9999; display: none; @@ -82,4 +84,45 @@ html, body { .popup.show { display: block; + } + + /* TOP SITES */ + + .top-sites { + display: grid; + grid-template-columns: repeat(9, 1fr); /* Display 8 sites per row */ + gap: 10px; /* Adjust the gap between site containers */ + } + + .site-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100px; /* Adjust the width of the site container */ + height: 100px; /* Adjust the height of the site container */ + background-color: var(--text-color, white); /* Set the background color of the site container */ + border-radius: 10px; /* Apply rounded corners to the site container */ + text-align: center; + overflow: hidden; + } + + .site-favicon { + width: 32px; /* Adjust the width of the favicon */ + height: 32px; /* Adjust the height of the favicon */ + } + + .site-title { + width: 100%; + margin-top: 5px; /* Adjust the margin between the favicon and the site title */ + font-size: 12px; /* Adjust the font size of the site title */ + color: var(--wallpaper-color, black); /* Set the color of the site title */ + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .container, .quote, .time, .weather, .top-sites { + opacity: 0; + animation: fade-in 1.5s ease-in-out forwards; } \ No newline at end of file diff --git a/newtab.html b/newtab.html index add8725..5f2a7ba 100644 --- a/newtab.html +++ b/newtab.html @@ -9,10 +9,14 @@ + +
+


+
diff --git a/newtab.js b/newtab.js index 6aef3c3..a6c12cc 100644 --- a/newtab.js +++ b/newtab.js @@ -2,9 +2,12 @@ document.addEventListener("DOMContentLoaded", function() { var quoteElement = document.querySelector(".quote"); var timeElement = document.querySelector(".time"); var weatherElement = document.querySelector(".weather"); + var topSitesElement = document.querySelector(".top-sites"); var containerElement = document.querySelector(".container"); var settingsIcon = document.querySelector(".settings-icon"); var popup = document.querySelector(".popup"); + const textColorInput = document.getElementById("textColor"); + const toggleTopSitesInput = document.getElementById("toggleTopSites"); // Display colors displayColors(); @@ -15,13 +18,21 @@ document.addEventListener("DOMContentLoaded", function() { // Get the weather information getWeather(); - + // Fetch the quote fetchQuote(); - settingsIcon.addEventListener("click", function() { - popup.classList.toggle("show"); - }); + // Get the top sites + var toggleTopSites = localStorage.getItem("toggleTopSites"); + if (toggleTopSites === "true") { + getTopSites(); + } + + if (settingsIcon && popup) { + settingsIcon.addEventListener("click", function() { + popup.classList.toggle("show"); + }); + } function displayColors() { containerElement.style.setProperty("--text-color", getTextColor()); @@ -61,7 +72,6 @@ document.addEventListener("DOMContentLoaded", function() { } function getWeather() { - setTimeout(function() { fetch('https://api.ip.sb/geoip') .then(res => res.json()) @@ -70,7 +80,8 @@ document.addEventListener("DOMContentLoaded", function() { localStorage.setItem('state', data.region) localStorage.setItem('country', data.country) }) - }, 5184000000); + }, 1000); + const city = localStorage.getItem('city'); const state = localStorage.getItem('region'); const country = localStorage.getItem('country'); @@ -81,37 +92,37 @@ document.addEventListener("DOMContentLoaded", function() { if(!temperatureUnit) { localStorage.setItem('temperatureUnit', "Fahrenheit") } - + if (!apiKey) { weatherElement.innerHTML = "Please provide an API Key in the options."; return; } - + var apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=${city},${state},${country}&appid=${apiKey}&units=metric`; - + fetch(apiUrl) .then(response => response.json()) .then(data => { var temperature = data.main.temp; var temperatureSymbol = temperatureUnit === "fahrenheit" ? "°F" : "°C"; var description = data.weather[0].description; - + if (temperatureUnit === "fahrenheit") { temperature = (temperature * 9 / 5) + 32; } - + temperature = temperature.toFixed(1); - + var weatherText = `Current temperature: ${temperature}${temperatureSymbol} / ${description}`; weatherElement.textContent = weatherText; - + // Show the container after weather data is loaded containerElement.classList.add("show"); }) .catch(error => { console.log("Error fetching weather:", error); weatherElement.innerHTML = "Failed to fetch weather data."; - + // Show the container even if weather data fails to load containerElement.classList.add("show"); }); @@ -127,22 +138,44 @@ document.addEventListener("DOMContentLoaded", function() { return textColor || "#ffffff"; } - const textColorInput = document.getElementById("textColor"); - - textColorInput.addEventListener("change", function () { - document.documentElement.style.setProperty( - "--text-color", - textColorInput.value - ); - }); - - function sleep(milliseconds) { - const date = Date.now(); - let currentDate = null; - do { - currentDate = Date.now(); - } while (currentDate - date < milliseconds); - } + function getTopSites() { + var showTopSites = localStorage.getItem("showTopSites"); + + // Check if the showTopSites option is enabled (default: true) + if (showTopSites !== "false") { + chrome.topSites.get(function (topSites) { + var topSitesContainer = document.querySelector(".top-sites"); + // hardcoded for now - make this customizable in future + for (var i = 0; i < 9 && i < topSites.length; i++) { + var site = topSites[i]; + + var siteContainer = document.createElement("a"); + siteContainer.href = site.url; + siteContainer.classList.add("site-container"); + siteContainer.setAttribute("target", "_blank"); + + var siteFavicon = document.createElement("img"); + siteFavicon.classList.add("site-favicon"); + siteFavicon.onerror = function () { + // Fallback to SVG if favicon is not available + siteFavicon.src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='icon icon-tabler icon-tabler-world' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='currentColor' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0'%3E%3C/path%3E%3Cpath d='M3.6 9h16.8'%3E%3C/path%3E%3Cpath d='M3.6 15h16.8'%3E%3C/path%3E%3Cpath d='M11.5 3a17 17 0 0 0 0 18'%3E%3C/path%3E%3Cpath d='M12.5 3a17 17 0 0 1 0 18'%3E%3C/path%3E%3C/svg%3E"; + }; + siteFavicon.src = "https://t1.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=" + encodeURIComponent(site.url) + "&size=32"; + + var siteTitle = document.createElement("span"); + siteTitle.classList.add("site-title"); + siteTitle.textContent = site.title; + + siteContainer.appendChild(siteFavicon); + siteContainer.appendChild(siteTitle); + topSitesContainer.appendChild(siteContainer); + + containerElement.classList.add("show"); + + } + }); + } + } -}); +}); \ No newline at end of file diff --git a/options.css b/options.css index 3345307..44613a7 100644 --- a/options.css +++ b/options.css @@ -68,4 +68,20 @@ input[type="color"]::-webkit-color-swatch { border: none; border-radius: 5px; padding: 0; -} \ No newline at end of file +} + +/* custom checkbox styling */ + +.checkbox-container { + display: flex; + align-items: center; +} + +.checkbox-label { + margin-left: 8px; +} + +.checkbox { + width: 20px; + height: 20px; +} diff --git a/options.html b/options.html index 77c496b..51ae4f5 100644 --- a/options.html +++ b/options.html @@ -1,14 +1,11 @@ - New Tab Page Options - -

New Tab Page Options

@@ -32,13 +29,15 @@

New Tab Page Options

+
+ + +
- - \ No newline at end of file diff --git a/options.js b/options.js index ac610c4..7b19daa 100644 --- a/options.js +++ b/options.js @@ -4,6 +4,7 @@ document.addEventListener("DOMContentLoaded", function() { var temperatureUnitInput = document.getElementById("temperatureUnit"); var wallpaperColorInput = document.getElementById("wallpaperColor"); var textColorInput = document.getElementById("textColor"); + var toggleTopSitesInput = document.getElementById("toggleTopSites"); loadOptions(); @@ -17,11 +18,13 @@ document.addEventListener("DOMContentLoaded", function() { var temperatureUnit = localStorage.getItem("temperatureUnit"); var wallpaperColor = localStorage.getItem("wallpaperColor"); var textColor = localStorage.getItem("textColor"); + var toggleTopSites = localStorage.getItem("toggleTopSites"); apiKeyInput.value = apiKey; temperatureUnitInput.value = temperatureUnit; wallpaperColorInput.value = wallpaperColor || "#000000"; textColorInput.value = textColor || "#ffffff"; + toggleTopSitesInput.checked = toggleTopSites === "true" ? true : false; } function saveOptions() { @@ -29,11 +32,13 @@ document.addEventListener("DOMContentLoaded", function() { var temperatureUnit = temperatureUnitInput.value; var wallpaperColor = wallpaperColorInput.value; var textColor = textColorInput.value; + var toggleTopSites = toggleTopSitesInput.checked; localStorage.setItem("apiKey", apiKey); localStorage.setItem("temperatureUnit", temperatureUnit); localStorage.setItem("wallpaperColor", wallpaperColor); localStorage.setItem("textColor", textColor); + localStorage.setItem("toggleTopSites", toggleTopSites); alert("Options saved successfully!"); }