Compare commits
No commits in common. "eb3e73f69071d3176c4bf7d80a1f3276841530cf" and "b44c6bd073d6cbe328c5bc8877a179060b1f7b15" have entirely different histories.
eb3e73f690
...
b44c6bd073
30
src/build.ts
30
src/build.ts
|
@ -1,30 +0,0 @@
|
||||||
import fs from "fs";
|
|
||||||
|
|
||||||
const outDir = "dist";
|
|
||||||
|
|
||||||
// Removes old files
|
|
||||||
fs.rmdirSync("dist", { recursive: true });
|
|
||||||
|
|
||||||
await Bun.build({
|
|
||||||
entrypoints: [
|
|
||||||
"src/extension/typescript/content.ts",
|
|
||||||
"src/extension/typescript/background.ts",
|
|
||||||
],
|
|
||||||
outdir: outDir,
|
|
||||||
});
|
|
||||||
|
|
||||||
const glob = new Bun.Glob("!.ts");
|
|
||||||
|
|
||||||
const extensionPath = "src/extension";
|
|
||||||
|
|
||||||
// TODO: Update script to preserve folders (not necessary for this extension, as of now)
|
|
||||||
// TODO: Setup directory watch (bun build --watch works, but only for TS files)
|
|
||||||
|
|
||||||
for await (const node of glob.scan(extensionPath)) {
|
|
||||||
const file = Bun.file(`${extensionPath}/${node}`);
|
|
||||||
|
|
||||||
// console.log(`${outDir}/${node}`);
|
|
||||||
|
|
||||||
Bun.write(`${outDir}/${node}`, file);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Spotify Web Notifications",
|
|
||||||
"description": "Spotify Web Notifications",
|
|
||||||
"version": "0.1",
|
|
||||||
"homepage_url": "https://code.violetmillie.me/Millie/spotify-web-notifications",
|
|
||||||
|
|
||||||
"manifest_version": 2,
|
|
||||||
|
|
||||||
"permissions": ["notifications"],
|
|
||||||
|
|
||||||
"browser_specific_settings": {
|
|
||||||
"gecko": {
|
|
||||||
"id": "spotifywebextension@violet.millie.me",
|
|
||||||
"strict_min_version": "42.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"background": {
|
|
||||||
"scripts": ["background.js"]
|
|
||||||
},
|
|
||||||
|
|
||||||
"content_scripts": [
|
|
||||||
{
|
|
||||||
"exclude_matches": ["*://developer.mozilla.org/*"],
|
|
||||||
"matches": ["*://open.spotify.com/*"],
|
|
||||||
"js": ["content.js"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
function onRuntimeMessage(message: any) {}
|
|
||||||
|
|
||||||
browser.runtime.onMessage.addListener(onRuntimeMessage);
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
import SpotifyAPI from "./modules/SpotifyAPI";
|
|
||||||
|
|
||||||
const API = new SpotifyAPI();
|
|
||||||
|
|
||||||
// use the API
|
|
||||||
|
|
||||||
API.getCurrentTrack();
|
|
|
@ -1,70 +0,0 @@
|
||||||
import SpotifyScraper from "./SpotifyScraper";
|
|
||||||
|
|
||||||
export type Artist = {
|
|
||||||
name: string;
|
|
||||||
URL: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Track = {
|
|
||||||
track: {
|
|
||||||
title: string;
|
|
||||||
URL: string;
|
|
||||||
coverArt: string;
|
|
||||||
|
|
||||||
artist: Artist | Artist[];
|
|
||||||
};
|
|
||||||
|
|
||||||
playing: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Playstate = {
|
|
||||||
track: Track;
|
|
||||||
|
|
||||||
isPlaying: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class SpotifyAPI {
|
|
||||||
currentPlaystate = {};
|
|
||||||
private scraper: SpotifyScraper;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.scraper = new SpotifyScraper();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates the full URL from a relative Spotify URL
|
|
||||||
* @example `/album/` -> `https://open.spotify.com/album/`
|
|
||||||
*/
|
|
||||||
private generateFullURL(relativeURL: string) {
|
|
||||||
return `${window.location.host}${relativeURL}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
getCurrentTrack() {
|
|
||||||
const titleElement = this.scraper.getBarElement("title")!;
|
|
||||||
const trackURL = `${titleElement.getAttribute("href")}`;
|
|
||||||
|
|
||||||
const artistElement = this.scraper.getBarElement("artist")!;
|
|
||||||
const artistName = artistElement.textContent;
|
|
||||||
const artistURL = artistElement.getAttribute("href");
|
|
||||||
|
|
||||||
// console.log(trackElement.textContent);
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
`Now playing: ${
|
|
||||||
titleElement.textContent
|
|
||||||
} by ${artistName} (${this.generateFullURL(trackURL)})`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
getPlaystate() {}
|
|
||||||
|
|
||||||
// TODO: Implement events: onPlay, onPause (?), trackChanged, playstateChanged
|
|
||||||
|
|
||||||
// trackChanged: fire on track changes
|
|
||||||
// onPlay: fired when playback resumes
|
|
||||||
|
|
||||||
// onPause: fired when playback is paused
|
|
||||||
|
|
||||||
// playStateChagned: fired whenever the playstate changes (any of the above)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
type BarElement = {
|
|
||||||
name: string;
|
|
||||||
selector: string;
|
|
||||||
element?: HTMLElement | null | undefined;
|
|
||||||
|
|
||||||
// isPersisent?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class SpotifyScraper {
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
barElements: BarElement[] = [
|
|
||||||
{
|
|
||||||
name: "playbackControlButton",
|
|
||||||
selector: "button[data-testid=control-button-playpause]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "title",
|
|
||||||
selector: "a[data-testid=context-item-link]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "artist",
|
|
||||||
selector: "a[data-testid=context-item-info-artist]",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "coverArtImage",
|
|
||||||
selector: "img[data-testid=cover-art-image]",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
getBarElement(name: string) {
|
|
||||||
const barElementData = this.barElements.find(
|
|
||||||
(element) => element.name === name
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!barElementData) {
|
|
||||||
// Raise some error
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return document.querySelector(barElementData.selector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"lib": ["ESNext", "DOM"],
|
"lib": ["ESNext"],
|
||||||
"target": "ESNext",
|
"target": "ESNext",
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"moduleDetection": "force",
|
"moduleDetection": "force",
|
||||||
|
@ -20,4 +20,3 @@
|
||||||
"forceConsistentCasingInFileNames": true
|
"forceConsistentCasingInFileNames": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue