From ab721edbd2d51ad9a4d458df9bd658816adbcdeb Mon Sep 17 00:00:00 2001 From: Jas Singh Date: Sat, 20 Jul 2024 22:59:25 -0700 Subject: [PATCH] Finish all options sets --- .gitignore | 1 + modules/bar/battery/index.js | 23 +- modules/menus/audio/active/index.js | 2 +- modules/menus/bluetooth/devices/index.js | 6 +- modules/menus/calendar/time/index.js | 62 ++-- .../calendar/weather/hourly/icon/index.js | 28 ++ .../menus/calendar/weather/hourly/index.js | 44 +++ .../weather/hourly/temperature/index.js | 27 ++ .../calendar/weather/hourly/time/index.js | 18 ++ modules/menus/calendar/weather/icon/index.js | 25 ++ modules/menus/calendar/weather/index.js | 286 ++---------------- modules/menus/calendar/weather/stats/index.js | 52 ++++ .../calendar/weather/temperature/index.js | 92 ++++++ modules/menus/dashboard/directories/index.js | 101 ++++--- modules/notifications/index.js | 5 +- options.ts | 54 ++-- scss/style/menus/audiomenu.scss | 16 + scss/style/menus/bluetooth.scss | 2 + scss/style/menus/calendar.scss | 18 +- scss/style/menus/energy.scss | 9 + scss/style/menus/menu.scss | 8 +- scss/style/menus/network.scss | 8 + scss/style/notifications/popups.scss | 8 +- scss/variables.scss | 11 +- 24 files changed, 514 insertions(+), 392 deletions(-) create mode 100644 .gitignore create mode 100644 modules/menus/calendar/weather/hourly/icon/index.js create mode 100644 modules/menus/calendar/weather/hourly/index.js create mode 100644 modules/menus/calendar/weather/hourly/temperature/index.js create mode 100644 modules/menus/calendar/weather/hourly/time/index.js create mode 100644 modules/menus/calendar/weather/icon/index.js create mode 100644 modules/menus/calendar/weather/stats/index.js create mode 100644 modules/menus/calendar/weather/temperature/index.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2458c1e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.weather.json diff --git a/modules/bar/battery/index.js b/modules/bar/battery/index.js index 1083c46..a4c6bad 100644 --- a/modules/bar/battery/index.js +++ b/modules/bar/battery/index.js @@ -1,5 +1,8 @@ const battery = await Service.import("battery"); import { openMenu } from "../utils.js"; +import options from "options"; + +const { show_label } = options.bar.battery; const BatteryLabel = () => { const isVis = Variable(battery.available); @@ -37,16 +40,26 @@ const BatteryLabel = () => { class_name: "battery", visible: battery.bind("available"), tooltip_text: battery.bind("time_remaining").as((t) => t.toString()), - setup: (self) => { - self.hook(battery, () => { - if (battery.available) { - self.children = [ + children: Utils.merge( + [battery.bind("available"), show_label.bind("value")], + (batAvail, showLabel) => { + if (batAvail && showLabel) { + return [ Widget.Icon({ icon: icon() }), Widget.Label({ label: battery.bind("percent").as((p) => ` ${p}%`), }), ]; - + } else if (batAvail && !showLabel) { + return [Widget.Icon({ icon: icon() })]; + } else { + return []; + } + }, + ), + setup: (self) => { + self.hook(battery, () => { + if (battery.available) { self.tooltip_text = generateTooltip( battery.time_remaining, battery.charging, diff --git a/modules/menus/audio/active/index.js b/modules/menus/audio/active/index.js index 44573b1..84d14bf 100644 --- a/modules/menus/audio/active/index.js +++ b/modules/menus/audio/active/index.js @@ -7,7 +7,7 @@ const activeDevices = () => { vertical: true, children: [ Widget.Box({ - class_name: "menu-label-container volume", + class_name: "menu-label-container volume selected", hpack: "fill", child: Widget.Label({ class_name: "menu-label audio volume", diff --git a/modules/menus/bluetooth/devices/index.js b/modules/menus/bluetooth/devices/index.js index 7393bd0..750570c 100644 --- a/modules/menus/bluetooth/devices/index.js +++ b/modules/menus/bluetooth/devices/index.js @@ -8,10 +8,10 @@ const Devices = () => { vertical: true, children: [ label(bluetooth), - Widget.Scrollable({ + Widget.Box({ class_name: "menu-items-section", - hscroll: 'never', - vscroll: 'always', + // hscroll: 'never', + // vscroll: 'always', child: Widget.Box({ class_name: "menu-content", vertical: true, diff --git a/modules/menus/calendar/time/index.js b/modules/menus/calendar/time/index.js index 95130a8..11a4639 100644 --- a/modules/menus/calendar/time/index.js +++ b/modules/menus/calendar/time/index.js @@ -1,3 +1,7 @@ +import options from "options"; + +const { military } = options.menus.clock.time; + const time = Variable("", { poll: [1000, 'date "+%I:%M:%S"'], }); @@ -6,6 +10,10 @@ const period = Variable("", { poll: [1000, 'date "+%p"'], }); +const militaryTime = Variable("", { + poll: [1000, 'date "+%H:%M:%S"'], +}); + const TimeWidget = () => { return Widget.Box({ class_name: "calendar-menu-item-container clock", @@ -17,27 +25,43 @@ const TimeWidget = () => { vpack: "center", hpack: "center", class_name: "clock-content-items", - children: [ - Widget.Box({ - hpack: "center", - children: [ - Widget.Label({ - class_name: "clock-content-time", - label: time.bind(), + children: military.bind("value").as((is24hr) => { + if (!is24hr) { + return [ + Widget.Box({ + hpack: "center", + children: [ + Widget.Label({ + class_name: "clock-content-time", + label: time.bind(), + }), + ], }), - ], - }), - Widget.Box({ - hpack: "center", - children: [ - Widget.Label({ - vpack: "end", - class_name: "clock-content-period", - label: period.bind(), + Widget.Box({ + hpack: "center", + children: [ + Widget.Label({ + vpack: "end", + class_name: "clock-content-period", + label: period.bind(), + }), + ], }), - ], - }), - ], + ]; + } + + return [ + Widget.Box({ + hpack: "center", + children: [ + Widget.Label({ + class_name: "clock-content-time", + label: militaryTime.bind(), + }), + ], + }), + ]; + }), }), }); }; diff --git a/modules/menus/calendar/weather/hourly/icon/index.js b/modules/menus/calendar/weather/hourly/icon/index.js new file mode 100644 index 0000000..d5ce499 --- /dev/null +++ b/modules/menus/calendar/weather/hourly/icon/index.js @@ -0,0 +1,28 @@ +import icons from "../../../../../icons/index.js"; + +export const HourlyIcon = (theWeather, getNextEpoch) => { + return Widget.Icon({ + class_name: "hourly-weather-icon", + icon: theWeather.bind("value").as((w) => { + if (!Object.keys(w).length) { + return "-"; + } + + const nextEpoch = getNextEpoch(w); + const weatherAtEpoch = w.forecast.forecastday[0].hour.find( + (h) => h.time_epoch === nextEpoch, + ); + + let iconQuery = weatherAtEpoch?.condition.text + .trim() + .toLowerCase() + .replaceAll(" ", "_"); + + if (!weatherAtEpoch?.isDay && iconQuery === "partly_cloudy") { + iconQuery = "partly_cloudy_night"; + } + + return icons.weather[iconQuery]; + }), + }); +}; diff --git a/modules/menus/calendar/weather/hourly/index.js b/modules/menus/calendar/weather/hourly/index.js new file mode 100644 index 0000000..bfde498 --- /dev/null +++ b/modules/menus/calendar/weather/hourly/index.js @@ -0,0 +1,44 @@ +import { HourlyIcon } from "./icon/index.js"; +import { HourlyTemp } from "./temperature/index.js"; +import { HourlyTime } from "./time/index.js"; + +export const Hourly = (theWeather) => { + return Widget.Box({ + vertical: false, + hexpand: true, + hpack: "fill", + class_name: "hourly-weather-container", + children: [1, 2, 3, 4].map((hoursFromNow) => { + const getNextEpoch = (wthr) => { + const currentEpoch = wthr.location.localtime_epoch; + const epochAtHourStart = currentEpoch - (currentEpoch % 3600); + let nextEpoch = 3600 * hoursFromNow + epochAtHourStart; + + const curHour = new Date(currentEpoch * 1000).getHours(); + + /* + * NOTE: Since the API is only capable of showing the current day; if + * the hours left in the day are less than 4 (aka spilling into the next day), + * then rewind to contain the prediction within the current day. + */ + if (curHour > 19) { + const hoursToRewind = curHour - 19; + nextEpoch = + 3600 * hoursFromNow + epochAtHourStart - hoursToRewind * 3600; + } + return nextEpoch; + }; + + return Widget.Box({ + class_name: "hourly-weather-item", + hexpand: true, + vertical: true, + children: [ + HourlyTime(theWeather, getNextEpoch), + HourlyIcon(theWeather, getNextEpoch), + HourlyTemp(theWeather, getNextEpoch), + ], + }); + }), + }); +}; diff --git a/modules/menus/calendar/weather/hourly/temperature/index.js b/modules/menus/calendar/weather/hourly/temperature/index.js new file mode 100644 index 0000000..1ba4324 --- /dev/null +++ b/modules/menus/calendar/weather/hourly/temperature/index.js @@ -0,0 +1,27 @@ +import options from "options"; + +const { unit } = options.menus.clock.weather; + +export const HourlyTemp = (theWeather, getNextEpoch) => { + return Widget.Label({ + class_name: "hourly-weather-temp", + label: Utils.merge( + [theWeather.bind("value"), unit.bind("value")], + (wthr, unt) => { + if (!Object.keys(wthr).length) { + return "-"; + } + + const nextEpoch = getNextEpoch(wthr); + const weatherAtEpoch = wthr.forecast.forecastday[0].hour.find( + (h) => h.time_epoch === nextEpoch, + ); + + if (unt === "imperial") { + return `${weatherAtEpoch ? Math.ceil(weatherAtEpoch.temp_f) : "-"}° F`; + } + return `${weatherAtEpoch ? Math.ceil(weatherAtEpoch.temp_c) : "-"}° C`; + }, + ), + }); +}; diff --git a/modules/menus/calendar/weather/hourly/time/index.js b/modules/menus/calendar/weather/hourly/time/index.js new file mode 100644 index 0000000..d244602 --- /dev/null +++ b/modules/menus/calendar/weather/hourly/time/index.js @@ -0,0 +1,18 @@ +export const HourlyTime = (theWeather, getNextEpoch) => { + return Widget.Label({ + class_name: "hourly-weather-time", + label: theWeather.bind("value").as((w) => { + if (!Object.keys(w).length) { + return "-"; + } + + const nextEpoch = getNextEpoch(w); + const dateAtEpoch = new Date(nextEpoch * 1000); + let hours = dateAtEpoch.getHours(); + const ampm = hours >= 12 ? "PM" : "AM"; + hours = hours % 12 || 12; + + return `${hours}${ampm}`; + }), + }); +}; diff --git a/modules/menus/calendar/weather/icon/index.js b/modules/menus/calendar/weather/icon/index.js new file mode 100644 index 0000000..3d5371f --- /dev/null +++ b/modules/menus/calendar/weather/icon/index.js @@ -0,0 +1,25 @@ +import icons from "../../../../icons/index.js"; + +export const TodayIcon = (theWeather) => { + return Widget.Box({ + vpack: "center", + hpack: "start", + class_name: "calendar-menu-weather today icon container", + children: [ + Widget.Icon({ + class_name: "calendar-menu-weather today icon", + icon: theWeather.bind("value").as((v) => { + let iconQuery = v.current.condition.text + .trim() + .toLowerCase() + .replaceAll(" ", "_"); + + if (!v.current.isDay && iconQuery === "partly_cloudy") { + iconQuery = "partly_cloudy_night"; + } + return icons.weather[iconQuery]; + }), + }), + ], + }); +}; diff --git a/modules/menus/calendar/weather/index.js b/modules/menus/calendar/weather/index.js index bb85bc1..7c7a4dd 100644 --- a/modules/menus/calendar/weather/index.js +++ b/modules/menus/calendar/weather/index.js @@ -1,5 +1,10 @@ -import icons from "../../../icons/index.js"; -import { keyRing } from "../../../../../../Documents/Keys/keyList.js"; +import options from "options"; +import { TodayIcon } from "./icon/index.js"; +import { TodayStats } from "./stats/index.js"; +import { TodayTemperature } from "./temperature/index.js"; +import { Hourly } from "./hourly/index.js"; + +const { key, interval } = options.menus.clock.weather; const defaultWeather = { location: { @@ -34,53 +39,31 @@ const defaultWeather = { const theWeather = Variable(defaultWeather); -const getIcon = (fahren) => { - const icons = { - 100: "", - 75: "", - 50: "", - 25: "", - 0: "", - }; - const colors = { - 100: "weather-color red", - 75: "weather-color orange", - 50: "weather-color lavender", - 25: "weather-color blue", - 0: "weather-color sky", - }; - - const threshold = - fahren < 0 - ? 0 - : [100, 75, 50, 25, 0].find((threshold) => threshold <= fahren); - - return { - icon: icons[threshold], - color: colors[threshold], - }; -}; - const WeatherWidget = () => { return Widget.Box({ class_name: "calendar-menu-item-container weather", child: Widget.Box({ class_name: "weather-container-box", setup: (self) => { - Utils.interval(60 * 1000, () => { - Utils.execAsync( - `curl "https://api.weatherapi.com/v1/forecast.json?key=${keyRing.weatherapi}&q=93722&days=1&aqi=no&alerts=no"`, - ) - .then((res) => { - if (typeof res === "string") { - theWeather.value = JSON.parse(res); - } - }) - .catch((err) => { - console.error(`Failed to fetch weather: ${err}`); - theWeather.value = defaultWeather; + Utils.merge( + [key.bind("value"), interval.bind("value")], + (weatherKey, weatherInterval) => { + Utils.interval(weatherInterval, () => { + Utils.execAsync( + `curl "https://api.weatherapi.com/v1/forecast.json?key=${weatherKey}&q=93722&days=1&aqi=no&alerts=no"`, + ) + .then((res) => { + if (typeof res === "string") { + theWeather.value = JSON.parse(res); + } + }) + .catch((err) => { + console.error(`Failed to fetch weather: ${err}`); + theWeather.value = defaultWeather; + }); }); - }); + }, + ); return (self.child = Widget.Box({ vertical: true, @@ -90,226 +73,15 @@ const WeatherWidget = () => { class_name: "calendar-menu-weather today", hexpand: true, children: [ - Widget.Box({ - vpack: "center", - hpack: "start", - class_name: "calendar-menu-weather today icon container", - children: [ - Widget.Icon({ - class_name: "calendar-menu-weather today icon", - icon: theWeather.bind("value").as((v) => { - let iconQuery = v.current.condition.text - .trim() - .toLowerCase() - .replaceAll(" ", "_") - - if (!v.current.isDay && iconQuery === "partly_cloudy") { - iconQuery = "partly_cloudy_night"; - } - return icons.weather[iconQuery]; - }), - }), - ], - }), - Widget.Box({ - hpack: "center", - vpack: "center", - vertical: true, - children: [ - Widget.Box({ - hexpand: true, - vpack: "center", - class_name: "calendar-menu-weather today temp container", - vertical: false, - children: [ - Widget.Box({ - hexpand: true, - hpack: "center", - children: [ - Widget.Label({ - class_name: - "calendar-menu-weather today temp label", - label: theWeather - .bind("value") - .as((v) => `${Math.ceil(v.current.temp_f)}° F`), - }), - Widget.Label({ - class_name: theWeather - .bind("value") - .as( - (v) => - `calendar-menu-weather today temp label icon ${getIcon(Math.ceil(v.current.temp_f)).color}`, - ), - label: theWeather - .bind("value") - .as( - (v) => - getIcon(Math.ceil(v.current.temp_f)).icon, - ), - }), - ], - }), - ], - }), - Widget.Box({ - hpack: "center", - child: Widget.Label({ - max_width_chars: 17, - truncate: "end", - lines: 2, - class_name: theWeather - .bind("value") - .as( - (v) => - `calendar-menu-weather today condition label ${getIcon(Math.ceil(v.current.temp_f)).color}`, - ), - label: theWeather - .bind("value") - .as((v) => v.current.condition.text), - }), - }), - ], - }), - Widget.Box({ - class_name: "calendar-menu-weather today stats container", - hpack: "end", - vpack: "center", - vertical: true, - children: [ - Widget.Box({ - class_name: "weather wind", - children: [ - Widget.Label({ - class_name: "weather wind icon", - label: "", - }), - Widget.Label({ - class_name: "weather wind label", - label: theWeather - .bind("value") - .as((v) => `${Math.floor(v.current.wind_mph)} mph`), - }), - ], - }), - Widget.Box({ - class_name: "weather precip", - children: [ - Widget.Label({ - class_name: "weather precip icon", - label: "", - }), - Widget.Label({ - class_name: "weather precip label", - label: theWeather - .bind("value") - .as( - (v) => - `${v.forecast.forecastday[0].day.daily_chance_of_rain}%`, - ), - }), - ], - }), - ], - }), + TodayIcon(theWeather), + TodayTemperature(theWeather), + TodayStats(theWeather), ], }), Widget.Separator({ class_name: "menu-separator weather", }), - Widget.Box({ - vertical: false, - hexpand: true, - hpack: "fill", - class_name: "hourly-weather-container", - children: [1, 2, 3, 4].map((hoursFromNow) => { - const getNextEpoch = (wthr) => { - const currentEpoch = wthr.location.localtime_epoch; - const epochAtHourStart = currentEpoch - (currentEpoch % 3600); - let nextEpoch = 3600 * hoursFromNow + epochAtHourStart; - - const curHour = new Date(currentEpoch * 1000).getHours(); - - /* - * NOTE: Since the API is only capable of showing the current day; if - * the hours left in the day are less than 4 (aka spilling into the next day), - * then rewind to contain the prediction within the current day. - */ - if (curHour > 19) { - const hoursToRewind = curHour - 19; - nextEpoch = - 3600 * hoursFromNow + - epochAtHourStart - - hoursToRewind * 3600; - } - return nextEpoch; - }; - - return Widget.Box({ - class_name: "hourly-weather-item", - hexpand: true, - vertical: true, - children: [ - Widget.Label({ - class_name: "hourly-weather-time", - label: theWeather.bind("value").as((w) => { - if (!Object.keys(w).length) { - return "-"; - } - - const nextEpoch = getNextEpoch(w); - const dateAtEpoch = new Date(nextEpoch * 1000); - let hours = dateAtEpoch.getHours(); - const ampm = hours >= 12 ? "PM" : "AM"; - hours = hours % 12 || 12; - - return `${hours}${ampm}`; - }), - }), - Widget.Icon({ - class_name: "hourly-weather-icon", - icon: theWeather.bind("value").as((w) => { - if (!Object.keys(w).length) { - return "-"; - } - - const nextEpoch = getNextEpoch(w); - const weatherAtEpoch = - w.forecast.forecastday[0].hour.find( - (h) => h.time_epoch === nextEpoch, - ); - - let iconQuery = weatherAtEpoch?.condition.text - .trim() - .toLowerCase() - .replaceAll(" ", "_") - - if (!weatherAtEpoch?.isDay && iconQuery === "partly_cloudy") { - iconQuery = "partly_cloudy_night"; - } - - return icons.weather[iconQuery]; - }), - }), - Widget.Label({ - class_name: "hourly-weather-temp", - label: theWeather.bind("value").as((w) => { - if (!Object.keys(w).length) { - return "-"; - } - - const nextEpoch = getNextEpoch(w); - const weatherAtEpoch = - w.forecast.forecastday[0].hour.find( - (h) => h.time_epoch === nextEpoch, - ); - - return `${weatherAtEpoch ? Math.ceil(weatherAtEpoch.temp_f) : "-"}° F`; - }), - }), - ], - }); - }), - }), + Hourly(theWeather), ], })); }, diff --git a/modules/menus/calendar/weather/stats/index.js b/modules/menus/calendar/weather/stats/index.js new file mode 100644 index 0000000..def90db --- /dev/null +++ b/modules/menus/calendar/weather/stats/index.js @@ -0,0 +1,52 @@ +import options from "options"; + +const { unit } = options.menus.clock.weather; + +export const TodayStats = (theWeather) => { + return Widget.Box({ + class_name: "calendar-menu-weather today stats container", + hpack: "end", + vpack: "center", + vertical: true, + children: [ + Widget.Box({ + class_name: "weather wind", + children: [ + Widget.Label({ + class_name: "weather wind icon", + label: "", + }), + Widget.Label({ + class_name: "weather wind label", + label: Utils.merge( + [theWeather.bind("value"), unit.bind("value")], + (wthr, unt) => { + if (unt === "imperial") { + return `${Math.floor(wthr.current.wind_mph)} mph`; + } + return `${Math.floor(wthr.current.wind_kph)} kph`; + }, + ), + }), + ], + }), + Widget.Box({ + class_name: "weather precip", + children: [ + Widget.Label({ + class_name: "weather precip icon", + label: "", + }), + Widget.Label({ + class_name: "weather precip label", + label: theWeather + .bind("value") + .as( + (v) => `${v.forecast.forecastday[0].day.daily_chance_of_rain}%`, + ), + }), + ], + }), + ], + }); +}; diff --git a/modules/menus/calendar/weather/temperature/index.js b/modules/menus/calendar/weather/temperature/index.js new file mode 100644 index 0000000..f03a972 --- /dev/null +++ b/modules/menus/calendar/weather/temperature/index.js @@ -0,0 +1,92 @@ +import options from "options"; +const { unit } = options.menus.clock.weather; + +export const TodayTemperature = (theWeather) => { + const getIcon = (fahren) => { + const icons = { + 100: "", + 75: "", + 50: "", + 25: "", + 0: "", + }; + const colors = { + 100: "weather-color red", + 75: "weather-color orange", + 50: "weather-color lavender", + 25: "weather-color blue", + 0: "weather-color sky", + }; + + const threshold = + fahren < 0 + ? 0 + : [100, 75, 50, 25, 0].find((threshold) => threshold <= fahren); + + return { + icon: icons[threshold], + color: colors[threshold], + }; + }; + + return Widget.Box({ + hpack: "center", + vpack: "center", + vertical: true, + children: [ + Widget.Box({ + hexpand: true, + vpack: "center", + class_name: "calendar-menu-weather today temp container", + vertical: false, + children: [ + Widget.Box({ + hexpand: true, + hpack: "center", + children: [ + Widget.Label({ + class_name: "calendar-menu-weather today temp label", + label: Utils.merge( + [theWeather.bind("value"), unit.bind("value")], + (wthr, unt) => { + if (unt === "imperial") { + return `${Math.ceil(wthr.current.temp_f)}° F`; + } else { + return `${Math.ceil(wthr.current.temp_c)}° C`; + } + }, + ), + }), + Widget.Label({ + class_name: theWeather + .bind("value") + .as( + (v) => + `calendar-menu-weather today temp label icon ${getIcon(Math.ceil(v.current.temp_f)).color}`, + ), + label: theWeather + .bind("value") + .as((v) => getIcon(Math.ceil(v.current.temp_f)).icon), + }), + ], + }), + ], + }), + Widget.Box({ + hpack: "center", + child: Widget.Label({ + max_width_chars: 17, + truncate: "end", + lines: 2, + class_name: theWeather + .bind("value") + .as( + (v) => + `calendar-menu-weather today condition label ${getIcon(Math.ceil(v.current.temp_f)).color}`, + ), + label: theWeather.bind("value").as((v) => v.current.condition.text), + }), + }), + ], + }); +}; diff --git a/modules/menus/dashboard/directories/index.js b/modules/menus/dashboard/directories/index.js index 572fadd..7bd24a4 100644 --- a/modules/menus/dashboard/directories/index.js +++ b/modules/menus/dashboard/directories/index.js @@ -1,8 +1,9 @@ import GLib from "gi://GLib"; +import options from "options"; + +const { left, right } = options.menus.dashboard.directories; const Directories = () => { - const homeDir = GLib.get_home_dir(); - return Widget.Box({ class_name: "dashboard-card directories-container", vpack: "fill", @@ -18,45 +19,51 @@ const Directories = () => { hpack: "start", expand: true, class_name: "directory-link left top", - on_primary_click: () => { - App.closeWindow("dashboardmenu"); - Utils.execAsync(`dolphin ${homeDir}/Downloads`).catch( - (err) => `Failed to open Dolphin: ${err}`, - ); - }, + on_primary_click: left.directory1.command + .bind("value") + .as((cmd) => { + return () => { + App.closeWindow("dashboardmenu"); + Utils.execAsync(cmd); + }; + }), child: Widget.Label({ hpack: "start", - label: "󰉍 Downloads", + label: left.directory1.label.bind("value"), }), }), Widget.Button({ expand: true, hpack: "start", class_name: "directory-link left middle", - on_primary_click: () => { - App.closeWindow("dashboardmenu"); - Utils.execAsync(`dolphin ${homeDir}/Videos`).catch( - (err) => `Failed to open Dolphin: ${err}`, - ); - }, + on_primary_click: left.directory2.command + .bind("value") + .as((cmd) => { + return () => { + App.closeWindow("dashboardmenu"); + Utils.execAsync(cmd); + }; + }), child: Widget.Label({ hpack: "start", - label: "󰉏 Videos", + label: left.directory2.label.bind("value"), }), }), Widget.Button({ expand: true, hpack: "start", class_name: "directory-link left bottom", - on_primary_click: () => { - App.closeWindow("dashboardmenu"); - Utils.execAsync(`dolphin ${homeDir}/Projects`).catch( - (err) => `Failed to open Dolphin: ${err}`, - ); - }, + on_primary_click: left.directory3.command + .bind("value") + .as((cmd) => { + return () => { + App.closeWindow("dashboardmenu"); + Utils.execAsync(cmd); + }; + }), child: Widget.Label({ hpack: "start", - label: "󰚝 Projects", + label: left.directory3.label.bind("value"), }), }), ], @@ -70,45 +77,51 @@ const Directories = () => { hpack: "start", expand: true, class_name: "directory-link right top", - on_primary_click: () => { - App.closeWindow("dashboardmenu"); - Utils.execAsync(`dolphin ${homeDir}/Documents`).catch( - (err) => `Failed to open Dolphin: ${err}`, - ); - }, + on_primary_click: right.directory1.command + .bind("value") + .as((cmd) => { + return () => { + App.closeWindow("dashboardmenu"); + Utils.execAsync(cmd); + }; + }), child: Widget.Label({ hpack: "start", - label: "󱧶 Documents", + label: right.directory1.label.bind("value"), }), }), Widget.Button({ expand: true, hpack: "start", class_name: "directory-link right middle", - on_primary_click: () => { - App.closeWindow("dashboardmenu"); - Utils.execAsync(`dolphin ${homeDir}/Pictures`).catch( - (err) => `Failed to open Dolphin: ${err}`, - ); - }, + on_primary_click: right.directory2.command + .bind("value") + .as((cmd) => { + return () => { + App.closeWindow("dashboardmenu"); + Utils.execAsync(cmd); + }; + }), child: Widget.Label({ hpack: "start", - label: "󰉏 Pictures", + label: right.directory2.label.bind("value"), }), }), Widget.Button({ expand: true, hpack: "start", class_name: "directory-link right bottom", - on_primary_click: () => { - App.closeWindow("dashboardmenu"); - Utils.execAsync(`dolphin ${homeDir}/`).catch( - (err) => `Failed to open Dolphin: ${err}`, - ); - }, + on_primary_click: right.directory3.command + .bind("value") + .as((cmd) => { + return () => { + App.closeWindow("dashboardmenu"); + Utils.execAsync(cmd); + }; + }), child: Widget.Label({ hpack: "start", - label: "󱂵 Home", + label: right.directory3.label.bind("value"), }), }), ], diff --git a/modules/notifications/index.js b/modules/notifications/index.js index c3873b6..f22bfef 100644 --- a/modules/notifications/index.js +++ b/modules/notifications/index.js @@ -1,4 +1,5 @@ const notifs = await Service.import("notifications"); +import options from "options"; import { notifHasImg } from "../menus/notifications/utils.js"; import { Image } from "./image/index.js"; import { Action } from "./actions/index.js"; @@ -6,6 +7,8 @@ import { Header } from "./header/index.js"; import { Body } from "./body/index.js"; import { CloseButton } from "./close/index.js"; +const { position } = options.notifications; + export default () => { notifs.popupTimeout = 7000; @@ -14,7 +17,7 @@ export default () => { class_name: "notifications-window", monitor: 2, layer: "top", - anchor: ["top", "right"], + anchor: position.bind("value"), exclusivity: "ignore", child: Widget.Box({ class_name: "notification-card-container", diff --git a/options.ts b/options.ts index d9ef080..1e9ab11 100644 --- a/options.ts +++ b/options.ts @@ -41,8 +41,7 @@ const options = mkOptions(OPTIONS, { notification: { background: opt(colors.mantle), actions: { - background: opt(colors.surface0), - hover: opt(colors.surface1), + background: opt(colors.lavender), text: opt(colors.mantle), }, label: opt(colors.lavender), @@ -138,10 +137,10 @@ const options = mkOptions(OPTIONS, { monochrome: opt(true), background: opt(colors.crust), cards: opt(colors.base), + card_radius: opt("0.4em"), border: { size: opt("0.13 em"), radius: opt("0.7em"), - card_radius: opt("0.4em"), color: opt(colors.surface0) }, text: opt(colors.text), @@ -640,72 +639,55 @@ const options = mkOptions(OPTIONS, { shortcut3: { icon: opt("󰄀"), tooltip: opt("Screenshot"), - command: opt("./services/snapshot.sh") + command: opt("bash -c \"$HOME/.config/ags/services/snapshot.sh\"") }, } }, directories: { left: { directory1: { - label: opt(""), - command: opt("") + label: opt("󰉍 Downloads"), + command: opt("bash -c \"dolphin $HOME/Downloads/\"") }, directory2: { - label: opt(""), - command: opt("") + label: opt("󰉏 Videos"), + command: opt("bash -c \"dolphin $HOME/Videos/\"") }, directory3: { - label: opt(""), - command: opt("") + label: opt("󰚝 Projects"), + command: opt("bash -c \"dolphin $HOME/Projects/\"") }, }, right: { directory1: { - label: opt(""), - command: opt("") + label: opt("󱧶 Documents"), + command: opt("bash -c \"dolphin $HOME/Documents/\"") }, directory2: { - label: opt(""), - command: opt("") + label: opt("󰉏 Pictures"), + command: opt("bash -c \"dolphin $HOME/Pictures/\"") }, directory3: { - label: opt(""), - command: opt("") + label: opt("󱂵 Home"), + command: opt("bash -c \"dolphin $HOME/\"") }, } }, }, - network: { - status: opt(true), - }, - bluetooth: { - status: opt(true), - }, - battery: { - percentage: opt(true) - }, clock: { time: { military: opt(false), - seconds: opt(true) }, weather: { - hourly: opt(true), interval: opt(60_000), - unit: opt<"metric" | "imperial" | "standard">("metric"), + unit: opt<"metric" | "imperial">("metric"), key: opt( - JSON.parse(Utils.readFile(`${App.configDir}/.weather`) || "{}")?.key || "", + JSON.parse(Utils.readFile(`${App.configDir}/.weather.json`) || "{}")?.weather_api_key || "", ), } } }, - overview: { - scale: opt(9), - workspaces: opt(7), - monochromeIcon: opt(true), - }, - osd: { progress: { vertical: opt(true), @@ -724,10 +706,8 @@ const options = mkOptions(OPTIONS, { notifications: { position: opt>(["top", "right"]), - blacklist: opt(["Spotify"]), }, }) globalThis["options"] = options export default options - diff --git a/scss/style/menus/audiomenu.scss b/scss/style/menus/audiomenu.scss index d14a172..2aa7b02 100644 --- a/scss/style/menus/audiomenu.scss +++ b/scss/style/menus/audiomenu.scss @@ -132,6 +132,22 @@ .menu-label-container.input { border-radius: 0em; + background: if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-volume-card-color); +} +.menu-label-container.playback { + background: if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-volume-card-color); +} +.menu-items-section.input { + background: if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-volume-card-color); +} +.menu-items-section.playback { + background: if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-volume-card-color); +} +.menu-label-container.selected { + background: if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-volume-card-color); +} +.menu-items-section.selected { + background: if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-volume-card-color); } .menu-items-section.playback { diff --git a/scss/style/menus/bluetooth.scss b/scss/style/menus/bluetooth.scss index a6987f0..4f123fe 100644 --- a/scss/style/menus/bluetooth.scss +++ b/scss/style/menus/bluetooth.scss @@ -13,6 +13,7 @@ } .menu-label-container { + background: if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-bluetooth-card-color); .menu-label { color: if($bar-menus-monochrome, $bar-menus-label, $bar-menus-menu-bluetooth-label-color); } @@ -24,6 +25,7 @@ .menu-items-section { + background: if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-bluetooth-card-color); min-height: 20em; font-size: 1em; } diff --git a/scss/style/menus/calendar.scss b/scss/style/menus/calendar.scss index 5c78a47..3be2d14 100644 --- a/scss/style/menus/calendar.scss +++ b/scss/style/menus/calendar.scss @@ -31,16 +31,16 @@ color: if($bar-menus-monochrome, $bar-menus-text, $bar-menus-menu-clock-calendar-days); &:selected { - box-shadow: inset 0 -0.5em 0 0 if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-clock-calendar-currentday), + box-shadow: inset 0 -0.5em 0 0 if($bar-menus-monochrome, $bar-menus-label, $bar-menus-menu-clock-calendar-currentday), inset -0.4em -0.3em 0 0 if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-clock-card-color), inset 0.4em 0 0 0.01em if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-clock-card-color); - color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-clock-calendar-currentday); + color: if($bar-menus-monochrome, $bar-menus-label, $bar-menus-menu-clock-calendar-currentday); border-radius: 0em; } &.header { background-color: transparent; - color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-clock-calendar-yearmonth); + color: if($bar-menus-monochrome, $bar-menus-label, $bar-menus-menu-clock-calendar-yearmonth); } &.button { color: $text; @@ -66,13 +66,13 @@ .clock-content-time { font-size: 4em; - color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-clock-time-time); + color: if($bar-menus-monochrome, $bar-menus-label, $bar-menus-menu-clock-time-time); } .clock-content-period { font-size: 1.75em; margin-bottom: 1.35em; margin-right: -0.875em; - color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-clock-time-timeperiod); + color: if($bar-menus-monochrome, $bar-menus-label, $bar-menus-menu-clock-time-timeperiod); } } @@ -109,7 +109,7 @@ } .calendar-menu-weather.today.condition.label { - color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-clock-weather-status); + color: if($bar-menus-monochrome, $bar-menus-label, $bar-menus-menu-clock-weather-status); font-size: 1.5em; margin-bottom: 0.4em; } @@ -133,7 +133,7 @@ .calendar-menu-weather.today.stats.container { margin-bottom: 0.75em; - color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-clock-weather-stats); + color: if($bar-menus-monochrome, $bar-menus-label, $bar-menus-menu-clock-weather-stats); .weather.label { margin-left: 0.35em; @@ -145,7 +145,7 @@ } .hourly-weather-time { - color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-clock-weather-hourly-time); + color: if($bar-menus-monochrome, $bar-menus-label, $bar-menus-menu-clock-weather-hourly-time); margin-bottom: 0.5em; } @@ -155,5 +155,5 @@ } .hourly-weather-temp { - color: if($bar-menus-monochrome, $bar-menus-icons-active, $bar-menus-menu-clock-weather-hourly-temperature); + color: if($bar-menus-monochrome, $bar-menus-label, $bar-menus-menu-clock-weather-hourly-temperature); } diff --git a/scss/style/menus/energy.scss b/scss/style/menus/energy.scss index 793103d..15836df 100644 --- a/scss/style/menus/energy.scss +++ b/scss/style/menus/energy.scss @@ -10,6 +10,15 @@ color: if($bar-menus-monochrome, $bar-menus-label, $bar-menus-menu-battery-label-color); } + .menu-label-container { + background: if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-battery-card-color); + } + + + .menu-items-section { + background: if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-battery-card-color); + } + .power-profile-item { margin-bottom: 0.5em; diff --git a/scss/style/menus/menu.scss b/scss/style/menus/menu.scss index a9989f7..8c6e35c 100644 --- a/scss/style/menus/menu.scss +++ b/scss/style/menus/menu.scss @@ -94,8 +94,8 @@ tooltip label { .menu-items { background: $crust; - border: .13em solid $surface0; - border-radius: .7rem; + border: $bar-menus-border-size solid $bar-menus-border-color; + border-radius: $bar-menus-border-radius; min-width: 18em; color: $text; } @@ -117,7 +117,7 @@ tooltip label { .menu-label-container { background: $base; - border-radius: 0.4em; + border-radius: $bar-menus-card_radius; border-bottom-left-radius: 0em; border-bottom-right-radius: 0em; margin: 0em 1em ; @@ -138,7 +138,7 @@ tooltip label { .menu-items-section { background: $base; - border-radius: 0.4em; + border-radius: $bar-menus-card_radius; border-top-left-radius: 0em; border-top-right-radius: 0em; padding: 0.9em; diff --git a/scss/style/menus/network.scss b/scss/style/menus/network.scss index 1cc4465..474835f 100644 --- a/scss/style/menus/network.scss +++ b/scss/style/menus/network.scss @@ -118,4 +118,12 @@ color: if($bar-menus-monochrome, $bar-menus-text, $bar-menus-menu-network-text); opacity: 0.5; } + .menu-label-container { + background: if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-network-card-color); + } + + + .menu-items-section { + background: if($bar-menus-monochrome, $bar-menus-cards, $bar-menus-menu-network-card-color); + } } diff --git a/scss/style/notifications/popups.scss b/scss/style/notifications/popups.scss index 5a62da3..163a799 100644 --- a/scss/style/notifications/popups.scss +++ b/scss/style/notifications/popups.scss @@ -6,15 +6,11 @@ .notification-card { color: $notification-text; background: $notification-background; - margin-right: 0.45em; + margin: 0.45em; border: 0.15em solid transparentize($notification-border, 0.5); min-width: 26em; min-height: 6rem; border-radius: 0.6em; - - &:not(:first-child) { - margin-top: 0.85em; - } } .notification-card-container { @@ -77,7 +73,7 @@ } &:hover { - background: $notification-actions-hover; + background: transparentize($notification-actions-background, 0.6); } } diff --git a/scss/variables.scss b/scss/variables.scss index d691e92..873f9bb 100644 --- a/scss/variables.scss +++ b/scss/variables.scss @@ -2,8 +2,7 @@ $font-size: 1.2rem; $font-name: Ubuntu Nerd Font; $font-weight: 600; $notification-background: #181825; -$notification-actions-background: #313244; -$notification-actions-hover: #45475a; +$notification-actions-background: #b4befe; $notification-actions-text: #181825; $notification-label: #b4befe; $notification-border: #313244; @@ -64,12 +63,12 @@ $bar-buttons-notifications-background: #242438; $bar-buttons-notifications-hover: #45475a; $bar-buttons-notifications-icon: #b4befe; $bar-buttons-notifications-total: #b4befe; -$bar-menus-monochrome: true; +$bar-menus-monochrome: false; $bar-menus-background: #11111b; $bar-menus-cards: #1e1e2e; -$bar-menus-border-size: 0.13 em; -$bar-menus-border-radius: 0.7em; -$bar-menus-border-card_radius: 0.4em; +$bar-menus-card_radius: 0.4em; +$bar-menus-border-size: 0.13em; +$bar-menus-border-radius: 0.4em; $bar-menus-border-color: #313244; $bar-menus-text: #cdd6f4; $bar-menus-dimtext: #585b70;