Skip to content

Commit

Permalink
✨ Version 3.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
SenpaiHunters committed Nov 18, 2024
1 parent c3577bd commit 150eaed
Show file tree
Hide file tree
Showing 18 changed files with 538 additions and 602 deletions.
48 changes: 13 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,16 @@ Today, on March 18, 2024, this repository has undergone a significant update. Ev
<details>
<summary>Whats new!</summary>

## Changelog - 16/7/2024
## Changelog - 18/11/2024

### Version 3.1.0

- Added `removeMusicVids` toggle to remove all music video results from Spotify's update
- Fixed numerous CSS issues across the extension
- Removed the Translator feature due to low usage and recurring technical issues
- Further optimized the extension size

Note: Due to low user adoption, I'm evaluating whether to continue active development. Regardless of the decision, SpotOn will remain open-source and free forever. Development has slowed as I focus on macOS app development. I apologize for delayed updates.

### Version 3.0.6.2

Expand Down Expand Up @@ -249,8 +258,6 @@ Would you like to view SpotOn pictures without going through the whole repositor
65. Enable features in development
66. Enable features in development (CSS)
67. Scrollbar Customisation thing
68. Auto Translate
(at the bottom you can see images for each toggle section)

## Features

Expand All @@ -260,36 +267,7 @@ a. SpotOn (on by default) toggle one, this has your album art be made into your

![SpotOn Image](Resources/images/spoton.png)

b. Translation (disabled by default). Currently, you can translate the lyrics into the following languages:

1. Türkçe
2. English
3. Deutsch
4. Français
5. Español
6. Italiano
7. Русский
8. العربية
9. 中文
10. 日本語
11. 한국어
12. Português
13. हिन्दी
14. Nederlands
15. Svenska

If you want more languages added, please make a request.

You can also modify the Lyrics color!

**Image:**

![Translation Image](Resources/images/translate.png)

**Image two:**
![alt text](Resources/images/translate-settings.png)

c. Custom CSS
b. Custom CSS

Here, you can make whatever you want. I suggest turning off SpotOn before editing a theme or making it support SpotOn.

Expand All @@ -305,14 +283,14 @@ By default, we'll have a few themes you can pick from. These are the defaults. T

<br>

d. Non-codeable themes
c. Non-codeable themes
Here, you can change the lyrics color, lyrics font size, or (with SpotOn, which makes this feature actually useful), change the color of the navigation bar (NB), and now playing bar (NPB).

![non codedable themes](Resources/images/non-codetheme.png)

<br>

e. Hotkeys
d. Hotkeys
SpotOn comes with full customisable hotkeys, Play/Pause and Skip/Reverse with your Media Keys! All changeable at `chrome://extensions/shortcuts`

| Name | Hotkey | Defaults |
Expand Down
205 changes: 89 additions & 116 deletions SpotOn/background.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
// Utility functions
const openTab = (url, isActive = true) => chrome.tabs.create({ url, active: isActive });
const closeCurrentTab = () => chrome.tabs.query({ active: true, currentWindow: true }, tabs => chrome.tabs.remove(tabs[0].id));
const openSpotifyTab = () => {
chrome.tabs.query({ url: "https://open.spotify.com/*" }, tabs => {
tabs.length ? chrome.tabs.update(tabs[0].id, { active: true }) : openTab("https://open.spotify.com/");
});
};

// Hotkeys
const sendCommandToTab = async (command, tabId) => {
const findAndClick = (command) => {
Expand Down Expand Up @@ -58,27 +67,25 @@ const sendCommandToTab = async (command, tabId) => {
args: [command],
});
} catch (error) {
console.error(`[SpotOn Hotkeys] Error executing '${command}': ${error}`);
console.error(`[SpotOn Hotkeys] Error executing '${command}':`, error);
}
};

// Event Listeners
chrome.commands.onCommand.addListener(async (command) => {
try {
const tabs = await chrome.tabs.query({ url: "https://open.spotify.com/*" });
await Promise.all(tabs.map(tab => sendCommandToTab(command, tab.id)));
} catch (error) {
console.error(`[SpotOn Hotkeys] Error sending command '${command}': ${error}`);
console.error(`[SpotOn Hotkeys] Error sending command '${command}':`, error);
}
});
//

// On and off button initialization.
chrome.commands.onCommand.addListener((command) => {
if (command === "toggle_extension") {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
if (tabs.length === 0) return; // No active tab found
const currentTabId = tabs[0].id;
chrome.tabs.sendMessage(currentTabId, { action: "toggleExtension" });
if (tabs.length === 0) return;
chrome.tabs.sendMessage(tabs[0].id, { action: "toggleExtension" });
});
} else {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
Expand Down Expand Up @@ -106,7 +113,7 @@ const contextMenus = [
id: Command.OpenSpotify,
title: "🎧 Open Spotify In Tab",
contexts: ["page"],
handler: () => openSpotifyTab(),
handler: openSpotifyTab,
},
{
id: Command.CreatePlaylist,
Expand All @@ -118,29 +125,13 @@ const contextMenus = [
id: Command.CloseTab,
title: "❌ Close Current Tab",
contexts: ["page"],
handler: () => closeCurrentTab(),
handler: closeCurrentTab,
},
];

function openTab(url, isActive = true) {
chrome.tabs.create({ url, active: isActive });
}

function openSpotifyTab() {
chrome.tabs.query({ url: "https://open.spotify.com/*" }, tabs => {
tabs.length ? chrome.tabs.update(tabs[0].id, { active: true }) : openTab("https://open.spotify.com/");
});
}

function closeCurrentTab() {
chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
chrome.tabs.remove(tabs[0].id);
});
}

function initializeContextMenus() {
const initializeContextMenus = () => {
chrome.runtime.onInstalled.addListener(() => {
contextMenus.forEach(({ id, title, contexts, handler }) => {
contextMenus.forEach(({ id, title, contexts }) => {
chrome.contextMenus.create({ id, title, contexts }, () => {
if (chrome.runtime.lastError) console.error("Error creating context menu:", chrome.runtime.lastError);
});
Expand All @@ -151,7 +142,7 @@ function initializeContextMenus() {
const action = contextMenus.find(a => a.id === info.menuItemId);
if (action) action.handler(info);
});
}
};

initializeContextMenus();

Expand All @@ -165,7 +156,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
}
});

// Checkbox functions for the settings.html
// Default options and option handling
const defaultOptions = {
addLyricsButton: true, righter: true, roundAlbumArt: true, rainbowControls: true,
hiddenPIcon: false, hiddenPAlbum: false, hiddenPDate: false, hiddenPDura: false,
Expand All @@ -182,7 +173,7 @@ const defaultOptions = {
hiddenDevicePicker: false, removeAlbumArt: false, reducedTransparency: false,
lyricsColor: false, removeMerch: false, removeScroll: false, hiddenNPVcredits: false,
darkness: false, fontMain: true, removeLikedCover: false, hometopsel: false,
youwontlike: false, contextApp: false,
youwontlike: false, contextApp: false, removeMusicVids: false,
};

const optionScripts = {
Expand All @@ -191,7 +182,7 @@ const optionScripts = {
addLyricsButton: "addLyrics.js",
};

function handleOption(option, tabId, options) {
const handleOption = (option, tabId, options) => {
if (!options[option]) return;

const fileToInject = optionScripts[option] ? `./options/${optionScripts[option]}` : `./options/${option}.css`;
Expand All @@ -201,7 +192,7 @@ function handleOption(option, tabId, options) {
target: { tabId },
files: [fileToInject],
});
}
};

chrome.runtime.onInstalled.addListener(({ reason }) => {
if (reason === "install") {
Expand All @@ -221,102 +212,68 @@ chrome.tabs.onUpdated.addListener((tabId, { status }, tab) => {
}
});

// Custom options -- main popup
chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {
if (changeInfo.status === "complete") {
applyCustomizations(tabId);
// Custom options and CSS management
const generateLyricsCSS = (customLyrics) => `
.nw6rbs8R08fpPn7RWW2w.aeO5D7ulxy19q4qNBrkk {
color: ${customLyrics.color} !important;
font-size: ${customLyrics.fontSize}px !important;
}
});
`;

const generateColorCSS = (customColor) => `
.sqKERfoKl4KwrtHqcKOd,
.JG5J9NWJkaUO9fiKECMA,
.OTfMDdomT5S7B5dbYTT8,
.EhyK_jJzB2PcWXd5lg24,
#context-menu[aria-labelledby="device-picker-icon-button"]:has(#device-picker-header [data-testid="animated-now-playing"]),
.aCtCKL9BxAoHeVZS0uRs.bk509U3ZhZc9YBJAmoPB,
.uV8q95GGAb2VDtL3gpYa,
.lYpiKR_qEjl1jGGyEvsA,
div#Desktop_LeftSidebar_Id,
.AzO2ondhaHJntbGy_3_S,
div#Desktop_LeftSidebar_Id,
.Nw1INlIyra3LT1JjvoqH,
#main > div.Root.encore-dark-theme > div.ZQftYELq0aOsg6tPbVbV > div.JG5J9NWJkaUO9fiKECMA,
.pGU_qEtNT1qWKjrRbvan,
.EZFyDnuQnx5hw78phLqP {
background-color: ${customColor} !important;
background: ${customColor} !important;
background: var(${customColor}) !important;
background-image: url('${customColor}') !important;
background-image: var(${customColor}) !important;
background-image: ${customColor} !important;
background-size: cover !important;
background-attachment: fixed !important;
background-repeat: no-repeat !important;
background-blend-mode: soft-light !important;
overflow-x: none !important;
}
`;

async function applyCustomizations(tabId) {
const insertCSS = (tabId, css) => {
chrome.scripting.insertCSS({
target: { tabId },
css,
});
};

const applyCustomizations = async (tabId) => {
try {
const { customColor, customLyrics } = await chrome.storage.sync.get(["customColor", "customLyrics"]);
if (customColor) insertCSS(tabId, generateColorCSS(customColor));
if (customLyrics) insertCSS(tabId, generateLyricsCSS(customLyrics));
} catch (error) {
console.error("Error retrieving options:", error);
}
}

function generateLyricsCSS(customLyrics) {
return `
.nw6rbs8R08fpPn7RWW2w.aeO5D7ulxy19q4qNBrkk {
color: ${customLyrics.color} !important;
font-size: ${customLyrics.fontSize}px !important;
}
`;
}

function generateColorCSS(customColor) {
return `
.sqKERfoKl4KwrtHqcKOd,
.JG5J9NWJkaUO9fiKECMA,
.OTfMDdomT5S7B5dbYTT8,
.EhyK_jJzB2PcWXd5lg24,
#context-menu[aria-labelledby="device-picker-icon-button"]:has(#device-picker-header [data-testid="animated-now-playing"]),
.aCtCKL9BxAoHeVZS0uRs.bk509U3ZhZc9YBJAmoPB,
.uV8q95GGAb2VDtL3gpYa,
.lYpiKR_qEjl1jGGyEvsA,
div#Desktop_LeftSidebar_Id,
.AzO2ondhaHJntbGy_3_S,
div#Desktop_LeftSidebar_Id,
.Nw1INlIyra3LT1JjvoqH,
#main > div.Root.encore-dark-theme > div.ZQftYELq0aOsg6tPbVbV > div.JG5J9NWJkaUO9fiKECMA,
.pGU_qEtNT1qWKjrRbvan,
.EZFyDnuQnx5hw78phLqP {
background-color: ${customColor} !important;
background: ${customColor} !important;
background: var(${customColor}) !important;
background-image: url('${customColor}') !important;
background-image: var(${customColor}) !important;
background-image: ${customColor} !important;
background-size: cover !important;
background-attachment: fixed !important;
background-repeat: no-repeat !important;
background-blend-mode: soft-light !important;
overflow-x: none !important;
}
`;
}

function insertCSS(tabId, css) {
chrome.scripting.insertCSS({
target: { tabId: tabId },
css: css,
});
}

// Translator
const Actions = {
TranslateSonglyrics: "translate-song-lyrics",
};

chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
const tabId = tabs[0].id;

const executeScript = async (functionToExecute, args = []) => {
chrome.scripting.executeScript(
{
target: { tabId: tabId },
function: functionToExecute,
args: args,
},
() => {
sendResponse();
}
);
};

if (request.action === Actions.TranslateSonglyrics) {
executeScript(
async (targetLanguage) => await translateSongLyrics(targetLanguage),
[request.targetLanguage]
);
chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {
if (changeInfo.status === "complete") {
applyCustomizations(tabId);
}
});

// Custom CSS
// Custom CSS Manager
class CustomCSSManager {
constructor() {
this.css = '';
Expand Down Expand Up @@ -362,10 +319,26 @@ class CustomCSSManager {

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === "complete" && tab.url.startsWith("https://open.spotify.com/")) {
this.applyToTab(tabId);
this.injectContentScript(tabId);
}
});
}

async injectContentScript(tabId) {
try {
const response = await chrome.tabs.sendMessage(tabId, { action: "checkInit" });
if (!response || !response.initialized) {
await chrome.scripting.executeScript({
target: { tabId },
files: ["options/addLyrics.js"]
});
console.log("Content script injected successfully");
}
chrome.tabs.sendMessage(tabId, { action: "init" });
} catch (error) {
console.error("Error injecting content script:", error);
}
}
}

new CustomCSSManager();
new CustomCSSManager();
Loading

0 comments on commit 150eaed

Please sign in to comment.