diff --git a/main.js b/main.js index e096bca..86a4cc4 100644 --- a/main.js +++ b/main.js @@ -7,11 +7,12 @@ const fs = require('fs') const path = require('path'); const icon = __dirname + '/favicon.ico' const { spawn } = require('child_process'); +const exeName = path.basename(process.execPath) // starts the app at login app.setLoginItemSettings({ openAtLogin: true, - path: path.join(app.getPath('exe').replace('samsung-widgets.exe', 'Samsung Widgets.exe')) + path: exeName }); // starts the background Serivce which provides information for the music and device care widget @@ -36,6 +37,7 @@ let countdownWidget = null; let quickNotesWidget = null; let untisWidget = null; let digitalClockWidget = null; +let forecastWidget = null; const folderPath = path.join(os.homedir(), 'AppData', 'Local', 'Samsung-Widgets'); @@ -58,6 +60,7 @@ const positionData = { quickNotesWidget: { y: "750", x: "475" }, untisWidget: { y: "900", x: "75" }, digitalClockWidget: { y: "75", x: "875" }, + forecastWidget: { y: "200", x: "875" }, }; const stateData = { @@ -73,6 +76,7 @@ const stateData = { quickNotesWidget: { show: "true" }, untisWidget: { show: "false" }, digitalClockWidget: { show: "true" }, + forecastWidget: { show: "false" }, }; const weatherData = { @@ -92,12 +96,23 @@ const colorData = { }; function createJSONFile(filePath, data) { - if (!fs.existsSync(filePath)) { - fs.writeFileSync(filePath, JSON.stringify(data, null, 4)); + let existingData = {}; + + if (fs.existsSync(filePath)) { + const fileContent = fs.readFileSync(filePath); + existingData = JSON.parse(fileContent); } + + // Merge existing data with new data, adding missing keys and setting default values + const updatedData = { + ...data, + ...existingData, + }; + + fs.writeFileSync(filePath, JSON.stringify(updatedData, null, 4)); } -// creates all jsons needed for the app if they dont exist +// Creates or updates JSON files for the app createJSONFile(path.join(folderPath, 'widgetPositions.json'), positionData); createJSONFile(path.join(folderPath, 'widgetStates.json'), stateData); createJSONFile(path.join(folderPath, 'weatherOptions.json'), weatherData); @@ -120,6 +135,7 @@ const widgetsData = { { name: "quickNotesWidget", width: 390, height: 175, html: "./src/widgets/notes/quickNotes.html", "clickthrough": false }, { name: "untisWidget", width: 390, height: 125, html: "./src/widgets/untis.html", "clickthrough": true }, { name: "digitalClockWidget", width: 390, height: 100, html: "./src/widgets/clock/digitalClock.html", "clickthrough": true }, + { name: "forecastWidget", width: 390, height: 150, html: "./src/widgets/weather/forecast.html", "clickthrough": true }, ], }; diff --git a/src/css/widgets/weather/forecast.css b/src/css/widgets/weather/forecast.css new file mode 100644 index 0000000..c4a351f --- /dev/null +++ b/src/css/widgets/weather/forecast.css @@ -0,0 +1,48 @@ +body { + height: 100vh; + top: 0; + margin: 0; +} + +#container-main { + height: 100%; + width: 100%; + border-radius: 33px; + display: flex; + padding: 20px 40px 20px 40px; + box-sizing: border-box; + align-items: center; + color: var(--text); + flex-direction: column; + justify-content: center; + gap: 10px; +} + +.weather-icon { + width: 40px; +} + +.container-day { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +#container-days { + display: flex; + justify-content: center; + gap: 10px; + width: 100%; +} + +#city { + font-size: 20px; + font-weight: 900; +} + +#container-info { + display: flex; + flex-direction: column; + align-items: center; +} \ No newline at end of file diff --git a/src/js/music/music.js b/src/js/music/music.js index 42b27d1..547f6ee 100644 --- a/src/js/music/music.js +++ b/src/js/music/music.js @@ -26,7 +26,7 @@ window.addEventListener("DOMContentLoaded", () => { if (jsonData.CoverUrl == "") { containerMain.style.background = `linear-gradient(135deg, rgb(${colorData.red}, ${colorData.green}, ${colorData.blue}) 0%, rgb(${colorData.red - 35}, ${colorData.green - 35}, ${colorData.blue - 35}) 100%)`; - document.getElementById("music-cover").src = "../res/generic-cover.png"; + document.getElementById("music-cover").src = "../../res/generic-cover.png"; } else { document.getElementById("music-cover").src = jsonData.CoverUrl + "?" + Date.now(); Vibrant.from(jsonData.CoverUrl).getPalette() diff --git a/src/js/weather/forecast.js b/src/js/weather/forecast.js new file mode 100644 index 0000000..17000bf --- /dev/null +++ b/src/js/weather/forecast.js @@ -0,0 +1,87 @@ +const os = require('os') +const fs = require('fs') +const path = require('path'); +const contrast = require('wcag-contrast') + +const folderPath = path.join(os.homedir(), 'AppData', 'Local', 'Samsung-Widgets'); + +const weatherOptions = JSON.parse(fs.readFileSync(folderPath + "\\weatherOptions.json"), 'utf8') +const weatherConditions = require('../../json/weather_conditions.json'); + +window.addEventListener("DOMContentLoaded", () => { + const containerMain = document.getElementById("container-main"); + + const secondaryColors = [ + [179, 179, 179], + [142, 142, 142] + ]; + + const textColors = [ + [0, 0, 0], + [250, 250, 250] + ]; + + // change color based on Setting + const colorData = JSON.parse(fs.readFileSync(path.join(folderPath, 'color.json'), 'utf8')); + + function findBetterContrast(rgb1, rgb2) { + const contrast1 = contrast.rgb(rgb1, [colorData.red, colorData.green, colorData.blue]) + const contrast2 = contrast.rgb(rgb2, [colorData.red, colorData.green, colorData.blue]) + if (contrast1 > contrast2) { + return `rgb(${rgb1[0]}, ${rgb1[1]}, ${rgb1[2]})`; + } else { + return `rgb(${rgb2[0]}, ${rgb2[1]}, ${rgb2[2]})`; + } + } + + const textColor = findBetterContrast(textColors[0], textColors[1]) + const secondaryColor = findBetterContrast(secondaryColors[0], secondaryColors[1]) + + containerMain.style.color = textColor; + + containerMain.style.background = `linear-gradient(135deg, rgb(${colorData.red}, ${colorData.green}, ${colorData.blue}) 0%, rgb(${colorData.red - 35}, ${colorData.green - 35}, ${colorData.blue - 35}) 100%)`; + + document.getElementById('temparature').style.color = secondaryColor; + + async function setWeatherInfo() { + const responseIP = await fetch('https://api.ipify.org?format=json'); + const dataIP = await responseIP.json(); + const publicIP = dataIP.ip; + + const responseLocation = await fetch(`http://ip-api.com/json/${publicIP}`); + const dataLocation = await responseLocation.json(); + const IPLocation = dataLocation.city; + + + if (weatherOptions.iplocation == true) { + var weatherURL = `https://api.weatherapi.com/v1/forecast.json?key=0d6f65c595974c82b19143504232708&q=${IPLocation}&days=6&aqi=no&alerts=no` + } else if (weatherOptions.iplocation == false && weatherOptions.country != "" && weatherOptions.name != "") { + const Location = weatherOptions.weather_name + "," + weatherOptions.weather_country + var weatherURL = `https://api.weatherapi.com/v1/forecast.json?key=0d6f65c595974c82b19143504232708&q=${Location}&days=6&aqi=no&alerts=no` + } + + const responseForecast = await fetch(weatherURL); + const forecastData = await responseForecast.json(); + + console.log(forecastData) + + document.getElementById('city').innerHTML = forecastData.location.name; + document.getElementById('temparature').innerHTML = forecastData.current.temp_c + "°"; + + for (i = 0; i < 3; i++) { + const date = new Date(forecastData.forecast.forecastday[i].date_epoch * 1000) + console.log(date.getDay()) + const weatherIcons = document.getElementsByClassName('weather-icon') + const days = document.getElementsByClassName('day') + + const weatherImageData = weatherConditions.find(codeObj => codeObj.code === forecastData.forecast.forecastday[i].day.condition.code); + + weatherIcons[i].src = `../../res/weather/${weatherImageData.day}` + + var dayNames = ['Sun', 'Mon', 'Tues', 'Wed', 'Thrus', 'Fri', 'Sat']; + + days[i].innerHTML = dayNames[date.getDay()] + } + } + setWeatherInfo() +}) \ No newline at end of file diff --git a/src/js/weather/weather.js b/src/js/weather/weather.js index 78a2611..a18c70f 100644 --- a/src/js/weather/weather.js +++ b/src/js/weather/weather.js @@ -42,7 +42,6 @@ async function changeWeatherInfo() { } else { document.getElementById("weather-icon").src = `../../res/weather/${weatherImageData.night}` document.getElementById("container-main").style.background = `linear-gradient(180deg, rgba(${dataWeather.current.temp_c * 4}, 70, 120, 1) 0%, rgba(${dataWeather.current.temp_c * 3},55,105, 1) 100%)` - } } diff --git a/src/widgets/weather/forecast.html b/src/widgets/weather/forecast.html new file mode 100644 index 0000000..f6c755b --- /dev/null +++ b/src/widgets/weather/forecast.html @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + London + 17° + + + + + + + Mon + + + + + Tue + + + + + Wed + + + + + + + \ No newline at end of file