diff --git a/src/.config/ags/config.js b/src/.config/ags/config.js index aa12002..4d26a03 100644 --- a/src/.config/ags/config.js +++ b/src/.config/ags/config.js @@ -1,3 +1,4 @@ +import { LastfmWidget } from "./lastfm.js"; import { NotificationPopups } from "./notificationPopups.js"; import { StatusWidget } from "./status.js"; @@ -202,6 +203,7 @@ App.config({ style: "./style.css", windows: [ StatusWidget(1), + LastfmWidget(1), Bar(0), Bar(1), NotificationPopups(0), diff --git a/src/.config/ags/lastfm.js b/src/.config/ags/lastfm.js new file mode 100644 index 0000000..111ee1a --- /dev/null +++ b/src/.config/ags/lastfm.js @@ -0,0 +1,124 @@ +export function timeAgo(input) { + const date = input instanceof Date ? input : new Date(input); + const formatter = new Intl.RelativeTimeFormat("en"); + const ranges = [ + ["years", 3600 * 24 * 365], + ["months", 3600 * 24 * 30], + ["weeks", 3600 * 24 * 7], + ["days", 3600 * 24], + ["hours", 3600], + ["minutes", 60], + ["seconds", 1], + ]; + const secondsElapsed = (date.getTime() - Date.now()) / 1000; + + for (const [rangeType, rangeVal] of ranges) { + //@ts-expect-error + if (rangeVal < Math.abs(secondsElapsed)) { + //@ts-expect-error + const delta = secondsElapsed / rangeVal; + //@ts-expect-error + + return formatter.format(Math.round(delta), rangeType); + } + } +} + +const lastFM = { + apiKey: "816cfe50ddeeb73c9987b85de5c19e71", + constructUrl: (method, parameters) => { + const defaultParams = { + format: "json", + api_key: lastFM.apiKey, + method, + }; + + Object.assign(parameters, defaultParams); + + return ( + "https://ws.audioscrobbler.com/2.0/?" + + Object.entries(parameters) + .map((z) => z[0] + "=" + z[1]) + .join("&") + ); + }, + getRecentTracks: async (user) => { + const request = await Utils.fetch( + lastFM.constructUrl("User.getrecenttracks", { user, limit: 1 }) + ); + return await request.json(); + }, +}; + +export function LastfmWidget(monitor = 0) { + function generateCSS(image = "https://placehold.co/300x300") { + return ( + `background-image: url("${image}");` + + "background-size: contain;" + + "background-repeat: no-repeat;" + + "background-position: center;" + ); + } + + const imagebox = Widget.Box({ + widthRequest: 150, + heightRequest: 150, + css: generateCSS(), + }); + + const nowplayingLabel = Widget.Label({ + label: "Playing NOW!", + css: "font-size: 35px;", + }); + + const artistLabel = Widget.Label({ + label: "Loading Artist", + css: "font-size: 30px;", + }); + + const titleLabel = Widget.Label({ + label: "Loading Title", + css: "font-size: 25px;", + }); + + Utils.interval( + 2150, + () => { + lastFM.getRecentTracks("yourfriendoss").then((z) => { + const track = z.recenttracks.track[0]; + if (!track) return; + nowplayingLabel.set_label( + track["@attr"]?.nowplaying + ? "listening to Now" + : "listened to " + timeAgo(+track.date.uts * 1000) + ); + artistLabel.set_label(track.artist["#text"]); + titleLabel.set_label(track.name); + imagebox.setCss(generateCSS(track.image.at(-1)["#text"])); + }); + }, + imagebox + ); + + return Widget.Window({ + name: `lastfm-${monitor}`, + class_name: "lastfmjs", + monitor, + anchor: ["bottom", "right"], + exclusivity: "exclusive", + layer: "background", + margins: [6, 6, 6, 6], + child: Widget.Box({ + class_name: "lastfm", + children: [ + imagebox, + Widget.Box({ + margin: 6, + vertical: true, + vpack: "center", + children: [nowplayingLabel, titleLabel, artistLabel], + }), + ], + }), + }); +} diff --git a/src/.config/ags/status.js b/src/.config/ags/status.js index c1094c4..88e18ce 100644 --- a/src/.config/ags/status.js +++ b/src/.config/ags/status.js @@ -74,14 +74,14 @@ export function StatusWidget(monitor = 0) { }); const linuxLabel = Widget.Label({ label: "Linux " + unameR, - hpack: "start" + hpack: "start", }); const uptime = Widget.Box({ children: [ Widget.Label({ label: "Uptime: ", - class_name: "gray" + class_name: "gray", }), Widget.Label({ label: uptimeVar.bind(), @@ -96,7 +96,7 @@ export function StatusWidget(monitor = 0) { children: [ Widget.Label({ label: "RAM Usage: ", - class_name: "gray" + class_name: "gray", }), Widget.Label({ label: freeKBMemory.bind().as((freeKb) => { @@ -134,7 +134,7 @@ export function StatusWidget(monitor = 0) { children: [ Widget.Label({ label: "Average CPU load: ", - class_name: "gray" + class_name: "gray", }), Widget.Label({ label: loadAverage.bind(), @@ -146,7 +146,7 @@ export function StatusWidget(monitor = 0) { children: [ Widget.Label({ label: "Processes: ", - class_name: "gray" + class_name: "gray", }), Widget.Label({ label: processCount.bind().as((z) => z.toString()), @@ -163,7 +163,7 @@ export function StatusWidget(monitor = 0) { Widget.Label({ label: z.file, hpack: "start", - class_name: "gray" + class_name: "gray", }), Widget.Box({ vertical: true, @@ -202,8 +202,7 @@ export function StatusWidget(monitor = 0) { " ".repeat(7 - 3) + "%Mem " + "%Cpu ", - class_name: "gray" - + class_name: "gray", }), ...z.map((proc) => { return Widget.Box({ diff --git a/src/.config/ags/style.css b/src/.config/ags/style.css index a0371e5..ccdb4fc 100644 --- a/src/.config/ags/style.css +++ b/src/.config/ags/style.css @@ -90,7 +90,12 @@ window.notification-popups box.notifications { .gray { color: @theme_unfocused_fg_color; } - +.lastfm { + background-color: @theme_bg_color; + padding: 10px; + border-radius: 5px; + color: @theme_fg_color; +} levelbar trough { padding: 0; } diff --git a/src/.config/hypr/hyprland.conf b/src/.config/hypr/hyprland.conf index 12790f9..6204783 100644 --- a/src/.config/hypr/hyprland.conf +++ b/src/.config/hypr/hyprland.conf @@ -14,12 +14,13 @@ monitor=,highres,auto,auto exec-once=/usr/lib/polkit-kde-authentication-agent-1 exec-once=dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP exec-once=~/.config/hypr/portal.sh -exec-once=swww init && swww img ~/wallpaper.png exec-once=nm-applet exec-once=ags -exec-once=~/.config/hypr/setgtktheme.sh +exec-once=swww-daemon exec=~/.config/hypr/import-gsettings.sh +exec=swww img ~/wallpaper.png +exec=~/.config/hypr/setgtktheme.sh env = XCURSOR_SIZE,24 diff --git a/src/wallpaper.png b/src/wallpaper.png index 00046de..e4f9391 100644 Binary files a/src/wallpaper.png and b/src/wallpaper.png differ