Skip to content

Commit

Permalink
Release 3.0.3.5 - 2/4/2024
Browse files Browse the repository at this point in the history
  • Loading branch information
SenpaiHunters committed Apr 1, 2024
1 parent 9d192ef commit 9372f79
Show file tree
Hide file tree
Showing 16 changed files with 314 additions and 352 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,23 @@ Today, on March 18, 2024, this repository has undergone a significant update. Ev
<details>
<summary>Whats new!</summary>

## Changelog - 2/4/2024
Significant optimizations and bug fixes have been implemented. Detailed changes are as follows:

- Manifest updated to version 3.0.3.5.
- JavaScript file structure and codebase streamlined:
- The `options` folder has been removed; `settingsDown.js` is now located in the `settings` folder.
- Consolidated `toggle.js` and contents of the `shared` folder into a single file `themeToggles.js` within the `settings` folder.
- Enhanced theme settings functionality, particularly the 'Auto' feature, and resolved related bugs.
- Refined the extension's enabled state logic for improved performance.
- Resolved an issue in `import.js` to ensure reliable importing of user settings.
- Conducted code optimization for `settingsOptions.js`, `settings.js`, `search.js`, `locals.js`, and `background.js`.
- Corrected a defect affecting the lyrics color display.
- Improved code formatting across several files for better readability and maintenance.
- Addressed various minor bugs to enhance overall stability.


---

28/3/2024: Removed `declarativeContent` as indicated in the below email (thanks, Chrome); fixed some minor padding issues and corrected some minor coloring issues as well.

Expand Down
47 changes: 17 additions & 30 deletions SpotOn/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
sendResponse({ status: themeLocked ? "theme_locked" : "theme_unlocked" });
}
});
//

// Checkbox functions for the settings.html
const defaultOptions = {
Expand Down Expand Up @@ -244,40 +243,27 @@ function handleOption(option, tabId, options) {
addLyricsButton: "addLyrics.js",
};

if (optionScripts[option]) {
if (options[option]) {
chrome.scripting.executeScript({
target: { tabId: tabId },
files: [`./options/${optionScripts[option]}`],
});
}
} else {
const fileName = `./options/${option}.css`;
if (options[option]) {
chrome.scripting.insertCSS({
target: { tabId: tabId },
files: [fileName],
});
}
const fileToInject = optionScripts[option] ? `./options/${optionScripts[option]}` : `./options/${option}.css`;
const method = optionScripts[option] ? 'executeScript' : 'insertCSS';

if (options[option]) {
chrome.scripting[method]({
target: { tabId },
files: [fileToInject],
});
}
}

chrome.runtime.onInstalled.addListener((details) => {
if (details.reason === "install") {
chrome.storage.sync.set({
...defaultOptions,
extensionEnabled: true,
}, () => console.log("Default options and extensionEnabled set."));
// chrome.tabs.create({ url: "SITE-HERE" });
chrome.runtime.onInstalled.addListener(({ reason }) => {
if (reason === "install") {
chrome.storage.sync.set({ ...defaultOptions, extensionEnabled: true });
}
});

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === "complete" && tab.url.startsWith("https://open.spotify.com/")) {
chrome.storage.sync.get(null, (options) => {
for (const option of Object.keys(options)) {
handleOption(option, tabId, options);
}
chrome.tabs.onUpdated.addListener((tabId, { status }, tab) => {
if (status === "complete" && tab.url.startsWith("https://open.spotify.com/")) {
chrome.storage.sync.get(null, options => {
Object.keys(options).forEach(option => handleOption(option, tabId, options));
});
}
});
Expand Down Expand Up @@ -320,7 +306,8 @@ function generateColorCSS(customColor) {
.AzO2ondhaHJntbGy_3_S,
.Nw1INlIyra3LT1JjvoqH,
#main > div.Root.encore-dark-theme > div.ZQftYELq0aOsg6tPbVbV > div.JG5J9NWJkaUO9fiKECMA,
.pGU_qEtNT1qWKjrRbvan {
.pGU_qEtNT1qWKjrRbvan,
.EZFyDnuQnx5hw78phLqP {
background-color: ${customColor} !important;
background: ${customColor} !important;
background: var(${customColor}) !important;
Expand Down
37 changes: 20 additions & 17 deletions SpotOn/js/settings/import.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
function triggerDownload(dataURL, filename) {
function triggerDownload(jsonData, filename) {
const blob = new Blob([jsonData], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = dataURL;
a.href = url;
a.download = filename;
a.style.display = 'none';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url); // Clean up the object URL
}

async function exportOptions() {
Expand All @@ -15,8 +17,7 @@ async function exportOptions() {
chrome.storage.local.get()
]);
const allOptions = { sync: syncOptions, local: localOptions };
const dataStr = `data:text/json;charset=utf-8,${encodeURIComponent(JSON.stringify(allOptions))}`;
triggerDownload(dataStr, "SpotOn_Options.json");
triggerDownload(JSON.stringify(allOptions), "SpotOn_Options.json");
} catch (error) {
console.error("Error during export:", error);
alert("Error exporting options.");
Expand All @@ -33,22 +34,24 @@ async function importOptions(event) {
try {
const text = await file.text();
const importedOptions = JSON.parse(text);
await Promise.all([
importedOptions.sync ? chrome.storage.sync.set(importedOptions.sync) : null,
importedOptions.local ? chrome.storage.local.set(importedOptions.local) : null
]);
const promises = [];
if (importedOptions.sync) {
promises.push(chrome.storage.sync.set(importedOptions.sync));
}
if (importedOptions.local) {
promises.push(chrome.storage.local.set(importedOptions.local));
}
await Promise.all(promises);
alert("All options imported successfully!");
window.location.reload();
} catch (error) {
console.error("Error during import:", error);
alert("Error importing options. Please ensure the selected file is a valid JSON file.");
alert("Error importing options. Please check the console for more details.");
}
}

document.getElementById('exportOptionsButton')?.addEventListener('click', exportOptions);
document.getElementById('importOptionsButton')?.addEventListener('click', () => {
const importInput = document.getElementById('importOptionsInput');
if (importInput) {
importInput.click();
}
document.getElementById('exportOptionsButton').addEventListener('click', exportOptions);
document.getElementById('importOptionsButton').addEventListener('click', () => {
document.getElementById('importOptionsInput').click();
});
document.getElementById('importOptionsInput')?.addEventListener('change', importOptions);
document.getElementById('importOptionsInput').addEventListener('change', importOptions);
88 changes: 38 additions & 50 deletions SpotOn/js/settings/search.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,63 @@
const addHighlightClass = () => {
const style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = '.highlight { background-color: var(--highlight); }';
document.head.appendChild(style);
};

const hideOptionGroups = () => {
const optionGroups = document.querySelectorAll(".option-group:not(#default-content)");
optionGroups.forEach(group => group.style.display = "none");
};

const highlightMatchingText = (option, searchInput) => {
const regex = new RegExp(`(${searchInput})`, 'gi');
option.innerHTML = option.textContent.replace(regex, "<span class='highlight'>$1</span>");
};

const searchInput = document.getElementById("search-input");
const defaultContent = document.getElementById("default-content");
const matchCountElement = document.getElementById('match-count');

const handleNoResultsFound = () => {
searchInput.placeholder = "Try another word";
defaultContent.style.display = "block";
};

const displayMatchCount = matchCount => {
matchCountElement.textContent = `Matches found: ${matchCount}`;
const toggleDisplay = (element, show) => {
element.style.display = show ? "block" : "none";
};

const resetSearchInput = () => {
searchInput.placeholder = "Search...";
const createHighlightStyle = () => {
if (!document.querySelector('#highlight-style')) {
const style = document.createElement('style');
style.id = 'highlight-style';
style.type = 'text/css';
style.textContent = '.highlight { background-color: var(--highlight); }';
document.head.appendChild(style);
}
};

const removeExistingHighlights = () => {
const highlighted = document.querySelectorAll(".highlight");
highlighted.forEach(highlight => highlight.outerHTML = highlight.innerHTML);
const updatePlaceholder = (placeholder) => {
searchInput.placeholder = placeholder;
};

const showDefaultContent = () => {
defaultContent.style.display = "block";
const updateMatchCount = (count) => {
matchCountElement.textContent = count ? `Matches found: ${count}` : "";
};

const removeMatchCount = () => {
matchCountElement.textContent = "";
const highlightMatchingText = (text, term) => {
const regex = new RegExp(`(${term})`, 'gi');
return text.replace(regex, "<span class='highlight'>$1</span>");
};

searchInput.addEventListener("input", () => {
const searchInputValue = searchInput.value.toLowerCase();
const term = searchInput.value.trim().toLowerCase();
let matchCount = 0;

hideOptionGroups();

if (searchInputValue.trim() !== "") {
const options = document.querySelectorAll(".option label");
options.forEach(option => {
if (option.textContent.toLowerCase().includes(searchInputValue)) {
option.closest(".option-group").style.display = "block";
highlightMatchingText(option, searchInputValue);
document.querySelectorAll(".option-group").forEach(group => {
toggleDisplay(group, group.id === "default-content");
});

if (term) {
document.querySelectorAll(".option label").forEach(label => {
const text = label.textContent.toLowerCase();
if (text.includes(term)) {
const optionGroup = label.closest(".option-group");
toggleDisplay(optionGroup, true);
label.innerHTML = highlightMatchingText(label.textContent, term);
matchCount++;
} else {
label.innerHTML = label.textContent; // Remove any previous highlights
}
});

const visibleGroups = document.querySelectorAll('.option-group[style="display: block;"]');
visibleGroups.length === 0 ? handleNoResultsFound() : null;
displayMatchCount(matchCount);
updatePlaceholder("Try another word");
updateMatchCount(matchCount);
toggleDisplay(defaultContent, matchCount === 0);
} else {
resetSearchInput();
removeExistingHighlights();
showDefaultContent();
removeMatchCount();
updatePlaceholder("Search...");
updateMatchCount();
toggleDisplay(defaultContent, true);
}
});

addHighlightClass();
createHighlightStyle();
73 changes: 38 additions & 35 deletions SpotOn/js/settings/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

const saveButton = document.getElementById("save");
const settingsButton = document.getElementById("settingsButton");
const checkboxElements = {};
const countElements = {
onCount: document.getElementById("on-count"),
offCount: document.getElementById("off-count"),
Expand Down Expand Up @@ -76,55 +75,59 @@
youwontlike: false,
};

const defaultOptionsKeys = Object.keys(defaultOptions);
const totalCount = defaultOptionsKeys.length;
countElements.totalCount.textContent = totalCount;

const checkboxElements = defaultOptionsKeys.reduce((elements, id) => {
elements[id] = document.getElementById(id);
return elements;
}, {});

function updateToggleCounts() {
const onCount = Object.values(checkboxElements).filter(el => el.checked).length;
const totalCount = Object.keys(defaultOptions).length;
const onCount = defaultOptionsKeys.reduce((count, id) => count + (checkboxElements[id].checked ? 1 : 0), 0);
const offCount = totalCount - onCount;

countElements.onCount.textContent = onCount;
countElements.offCount.textContent = offCount;
countElements.totalCount.textContent = totalCount;
countElements.onPercentage.textContent = calculatePercentage(onCount, totalCount) + '%';
countElements.offPercentage.textContent = calculatePercentage(offCount, totalCount) + '%';
countElements.onPercentage.textContent = `${calculatePercentage(onCount)}%`;
countElements.offPercentage.textContent = `${calculatePercentage(offCount)}%`;
}

function calculatePercentage(part, total) {
return ((part / total) * 100).toFixed(2);
function calculatePercentage(part) {
return ((part / totalCount) * 100).toFixed(2);
}

async function saveOptions() {
try {
const options = gatherOptions();
await chrome.storage.sync.set(options);
await restoreOptions();
updateToggleCounts();
openSpotifyTab();
} catch (error) {
console.error('Error saving options:', error);
}
function saveOptions() {
const options = gatherOptions();
chrome.storage.sync.set(options, () => {
if (chrome.runtime.lastError) {
console.error('Error saving options:', chrome.runtime.lastError);
} else {
updateToggleCounts();
openSpotifyTab();
}
});
}

function gatherOptions() {
return Object.keys(defaultOptions).reduce((acc, id) => {
acc[id] = checkboxElements[id].checked;
return acc;
return defaultOptionsKeys.reduce((options, id) => {
options[id] = checkboxElements[id].checked;
return options;
}, {});
}

async function restoreOptions() {
try {
const items = await chrome.storage.sync.get(defaultOptions);
for (const [id, value] of Object.entries(items)) {
const checkbox = checkboxElements[id] || document.getElementById(id);
if (checkbox) {
checkboxElements[id] = checkbox;
checkbox.checked = value;
}
function restoreAndUpdateOptions() {
chrome.storage.sync.get(defaultOptions, (items) => {
if (chrome.runtime.lastError) {
console.error('Error restoring options:', chrome.runtime.lastError);
} else {
defaultOptionsKeys.forEach(id => {
checkboxElements[id].checked = items[id];
});
updateToggleCounts();
}
updateToggleCounts();
} catch (error) {
console.error('Error restoring options:', error);
}
});
}

function openSpotifyTab() {
Expand All @@ -137,7 +140,7 @@
});
}

document.addEventListener("DOMContentLoaded", restoreOptions);
document.addEventListener("DOMContentLoaded", restoreAndUpdateOptions);
saveButton.addEventListener("click", saveOptions);
settingsButton.addEventListener("click", openSpotifyTab);
})();
File renamed without changes.
Loading

0 comments on commit 9372f79

Please sign in to comment.