diff --git a/css/content.css b/css/content.css
index 1093543..9780047 100644
--- a/css/content.css
+++ b/css/content.css
@@ -36,18 +36,20 @@
gap: 10px;
z-index: 9999;
border-top: 1px solid #000;
+ height: 30px;
+ overflow-x: scroll;
}
.swi-toolbar-section {
display: flex;
align-items: center;
- gap: 5px;
- padding: 0 10px;
- border-right: 1px solid #2a475e;
+ gap: 10px;
}
-.swi-toolbar-section:last-child {
- border-right: none;
+.filter-container {
+ display: flex;
+ align-items: center;
+ gap: 10px;
}
.swi-toolbar button {
@@ -57,6 +59,7 @@
padding: 5px 10px;
border-radius: 2px;
cursor: pointer;
+ white-space: nowrap;
}
.swi-toolbar button:hover {
@@ -65,23 +68,52 @@
.swi-toolbar .icon-filter {
cursor: pointer;
- opacity: 1;
+ opacity: 0.25;
transition: opacity 0.2s;
+ line-height: 1.5;
}
.swi-toolbar .icon-filter.filtered {
- opacity: 0.5;
+ opacity: 0.25;
}
.swi-toolbar .depth-slider {
width: 100px;
}
+.swi-hidden {
+ display: none !important;
+}
+
+.swi-toolbar-divider {
+ width: 1px;
+ background: #2a475e;
+ height: 100%;
+ z-index: 1;
+}
+
+.swi-toolbar .filter-mode {
+ background: #2a475e;
+ border: none;
+ color: #c7d5e0;
+ padding: 4px 8px;
+ border-radius: 2px;
+ cursor: pointer;
+}
+
+
.swi-toolbar .close-button {
margin-left: auto;
- font-weight: bold;
}
-.swi-hidden {
- display: none !important;
+.swi-toolbar.hide-mode .icon-filter {
+ opacity: 1;
+}
+
+.swi-toolbar.hide-mode .icon-filter.filtered {
+ opacity: 0.25;
+}
+
+.swi-toolbar.only-mode .icon-filter.filtered {
+ opacity: 1;
}
\ No newline at end of file
diff --git a/scripts/background.js b/scripts/background.js
index 2dff18f..f42a888 100644
--- a/scripts/background.js
+++ b/scripts/background.js
@@ -75,7 +75,7 @@ async function addToBlacklist(url) {
),
].join("\n");
- await chrome.storage.local.set({ "swi_settings": settings });
+ await chrome.runtime.sendMessage({ "action": "setSettings", settings });
}
function arrayToObject(array, key) {
@@ -258,6 +258,9 @@ function onMessage(message, sender, sendResponse) {
case "getSettings":
getSettings().then((settings) => sendResponse(settings));
break;
+ case "setSettings":
+ chrome.storage.local.set({ "swi_settings": message.settings }).then(() => sendResponse(true));
+ break;
case "runSWI":
case "reloadSWI":
case "clearSWI":
diff --git a/scripts/content.js b/scripts/content.js
index fc4806f..c5382fa 100644
--- a/scripts/content.js
+++ b/scripts/content.js
@@ -1,5 +1,10 @@
let boxNode;
+let settings = {};
+chrome.runtime.sendMessage({ "action": "getSettings" }).then((newSettings) => {
+ settings = newSettings;
+});
+
function createBoxNode(boxed) {
let div = document.createElement("div");
div.classList.add("swi-block");
@@ -50,7 +55,7 @@ function getBoxNode(html, iconsEncoding, appID, subID, boxDynamicColor) {
return node;
}
-function doApp(settings, elem, wishlist, ownedApps, ignoredApps, followedApps, decommissioned, limited, cards, bundles, dlc, lcs, dlcs, dlclcs, llcs, clcs, blcs) {
+function doApp(elem, wishlist, ownedApps, ignoredApps, followedApps, decommissioned, limited, cards, bundles, dlc, lcs, dlcs, dlclcs, llcs, clcs, blcs) {
elem.classList.add("swi");
/* Example detectable links:
@@ -149,7 +154,7 @@ function doApp(settings, elem, wishlist, ownedApps, ignoredApps, followedApps, d
}, 0);
}
-function doSub(settings, elem, ownedPackages, bundles, lcs, blcs) {
+function doSub(elem, ownedPackages, bundles, lcs, blcs) {
elem.classList.add("swi");
/* Example detectable links:
@@ -196,7 +201,7 @@ function doSub(settings, elem, ownedPackages, bundles, lcs, blcs) {
}, 0);
}
-function integrate(settings, userdata, decommissioned, cards, bundles, limited, dlcs, lastCached) {
+function integrate(userdata, decommissioned, cards, bundles, limited, dlcs, lastCached) {
const { ignoredApps, ownedApps, ownedPackages, followedApps, wishlist } = userdata;
const lcstr = new Date(lastCached.userdata).toLocaleString(settings.dateOverride ? "sv-SE" : undefined);
@@ -239,9 +244,9 @@ function integrate(settings, userdata, decommissioned, cards, bundles, limited,
clearTimeout(delaySWI);
[...document.body.querySelectorAll(appSelector)]
- .forEach((elem) => doApp(settings, elem, wishlist, ownedApps, ignoredApps, followedApps, decommissioned, limited, cards, bundles, dlcs, lcstr, dlcstr, dlclcstr, llcstr, clcstr, blcstr));
+ .forEach((elem) => doApp(elem, wishlist, ownedApps, ignoredApps, followedApps, decommissioned, limited, cards, bundles, dlcs, lcstr, dlcstr, dlclcstr, llcstr, clcstr, blcstr));
[...document.body.querySelectorAll(subSelector)]
- .forEach((elem) => doSub(settings, elem, ownedPackages, bundles, lcstr, blcstr), 0);
+ .forEach((elem) => doSub(elem, ownedPackages, bundles, lcstr, blcstr), 0);
}, delay);
};
@@ -249,7 +254,7 @@ function integrate(settings, userdata, decommissioned, cards, bundles, limited,
const clearSWI = () => {
console.log("[Steam Web Integration] Clearing");
[...document.body.querySelectorAll(".swi-block")].forEach((e) => e.remove());
- [...document.body.querySelectorAll(".swi")].forEach((e) => e.classList.remove("swi"));
+ [...document.body.querySelectorAll(".swi:not(.swi-toolbar .swi)")].forEach((e) => e.classList.remove("swi"));
if (pinger) {
clearInterval(pinger);
pinger = null;
@@ -335,7 +340,7 @@ function addStyle(css) {
}
async function init() {
- let settings = await chrome.runtime.sendMessage({ "action": "getSettings" });
+ settings = await chrome.runtime.sendMessage({ "action": "getSettings" });
let css = `:root {
--swi-font-size: ${settings.iconsScale}em;
--swi-font-weight: ${settings.iconsBold ? "bold" : "normal"};
@@ -351,22 +356,28 @@ async function init() {
addStylesheet("/css/content.css");
addStylesheet("/css/fontawesome.min.css");
addStylesheet("/css/solid.min.css");
- integrate(settings, userdata, decommissioned, cards, bundles, limited, dlcs, lastCached);
+ integrate(userdata, decommissioned, cards, bundles, limited, dlcs, lastCached);
}
}
-function applyFilters(activeFilters, depth) {
+function applyFilters(activeFilters, depth, mode) {
document.querySelectorAll(".swi-hidden").forEach((node) => node.classList.remove("swi-hidden"));
+
document.querySelectorAll(".swi-block").forEach((block) => {
- const shouldHide = [...block.childNodes].some((node) => {
- const classes = node.querySelector(".swi").classList;
- return [...activeFilters].some((filter) => classes.contains(`fa-${filter}`));
- });
+ const blockIcons = [...block.childNodes].map((node) => node.querySelector(".swi").getAttribute("class")).join(" ");
+
+ const shouldHide = mode === "hide"
+ ? [...activeFilters].some((filter) => blockIcons.includes(`fa-${filter}`))
+ : ![...activeFilters].every((filter) => blockIcons.includes(`fa-${filter}`));
let target = block;
for (let i = 0; i < depth; i++) {
- if (target.parentNode) {
+ if (target.parentNode
+ && target.parentNode !== document.body
+ && ![...document.body.childNodes].includes(target.parentNode)) {
target = target.parentNode;
+ } else {
+ break;
}
}
@@ -376,14 +387,44 @@ function applyFilters(activeFilters, depth) {
});
}
-function createToolbar(settings) {
+function createToolbar() {
const toolbar = document.createElement("div");
- toolbar.className = "swi-toolbar";
+ toolbar.className = "swi-toolbar hide-mode";
+
+ const activeFilters = new Set();
+
+ // Depth slider
+ const depthSlider = document.createElement("input");
+ depthSlider.type = "range";
+ depthSlider.min = "0";
+ depthSlider.max = "10";
+ depthSlider.value = "0";
+ depthSlider.className = "depth-slider";
+ depthSlider.title = "Filter Depth";
// Filter section
const filterSection = document.createElement("div");
filterSection.className = "swi-toolbar-section";
+ const filterMode = document.createElement("select");
+ filterMode.className = "filter-mode";
+ filterMode.innerHTML = `
+
+
+ `;
+
+ filterMode.addEventListener("change", () => {
+ toolbar.className = `swi-toolbar ${filterMode.value}-mode`;
+ applyFilters(activeFilters, depthSlider.value, filterMode.value);
+ });
+
+ depthSlider.addEventListener("input", () => {
+ applyFilters(activeFilters, depthSlider.value, filterMode.value);
+ });
+
+ const filterContainer = document.createElement("div");
+ filterContainer.className = "filter-container";
+
// Create icon filters
const iconConfigs = [
{ "name": "Owned", "color": settings.ownedColor, "icon": settings.ownedIcon },
@@ -398,24 +439,6 @@ function createToolbar(settings) {
{ "name": "Bundle", "color": settings.bundleColor, "icon": settings.bundleIcon },
];
- const activeFilters = new Set();
-
- // Depth slider
- const depthSlider = document.createElement("input");
- depthSlider.type = "range";
- depthSlider.min = "0";
- depthSlider.max = "10";
- depthSlider.value = "0";
- depthSlider.className = "depth-slider";
- depthSlider.title = "Filter Depth";
-
- depthSlider.addEventListener("input", () => {
- applyFilters(activeFilters, depthSlider.value);
- });
-
- filterSection.appendChild(depthSlider);
- toolbar.appendChild(filterSection);
-
iconConfigs.forEach(({ name, color, icon }) => {
const iconSpan = document.createElement("span");
iconSpan.className = "icon-filter";
@@ -429,78 +452,103 @@ function createToolbar(settings) {
} else {
activeFilters.delete(icon);
}
- applyFilters(activeFilters, depthSlider.value);
+ applyFilters(activeFilters, depthSlider.value, filterMode.value);
});
- filterSection.appendChild(iconSpan);
+ filterContainer.appendChild(iconSpan);
});
+ filterSection.appendChild(filterMode);
+ filterSection.appendChild(depthSlider);
+ filterSection.appendChild(filterContainer);
+
// Blacklist section
const blacklistSection = document.createElement("div");
blacklistSection.className = "swi-toolbar-section";
const blacklistButton = document.createElement("button");
- blacklistButton.textContent = settings.whiteListMode ? "Add/Remove from Whitelist" : "Add/Remove from Blacklist";
+ const isBlacklisted = () => settings.blackList.split("\n").some((url) => location.href.includes(url.trim()));
+ const setButtonText = () => {
+ if (settings.whiteListMode) {
+ blacklistButton.innerHTML = isBlacklisted()
+ ? " Whitelist"
+ : " Whitelist";
+ } else {
+ blacklistButton.innerHTML = isBlacklisted()
+ ? " Blacklist"
+ : " Blacklist";
+ }
+ };
+
+ setButtonText();
blacklistButton.addEventListener("click", async() => {
- const isBlacklisted = settings.blackList.split("\n").some((url) => location.href.includes(url.trim()));
- if (isBlacklisted) {
+ if (isBlacklisted()) {
settings.blackList = settings.blackList.split("\n")
.filter((url) => !location.href.includes(url.trim()))
.join("\n");
- console.log({ settings });
- await chrome.storage.local.set({ "swi_settings": settings });
- chrome.runtime.sendMessage({ "action": "runSWI" });
+ await chrome.runtime.sendMessage({ "action": "setSettings", settings });
+ setButtonText();
+ await chrome.runtime.sendMessage({ "action": "runSWI" });
} else {
settings.blackList += `\n${location.href}`;
- console.log({ settings });
- await chrome.storage.local.set({ "swi_settings": settings });
- chrome.runtime.sendMessage({ "action": "clearSWI" });
+ await chrome.runtime.sendMessage({ "action": "setSettings", settings });
+ setButtonText();
+ await chrome.runtime.sendMessage({ "action": "clearSWI" });
}
});
blacklistSection.appendChild(blacklistButton);
- toolbar.appendChild(blacklistSection);
// Copy section
const copySection = document.createElement("div");
copySection.className = "swi-toolbar-section";
const copyAppsButton = document.createElement("button");
- copyAppsButton.textContent = "Copy Apps";
+ copyAppsButton.innerHTML = " Apps";
copyAppsButton.addEventListener("click", () => {
const appIds = [...document.querySelectorAll("[data-appid]")]
+ .filter((el) => !el.closest(".swi-hidden"))
.map((el) => el.dataset.appid)
.join(",");
navigator.clipboard.writeText(appIds);
- copyAppsButton.textContent = "Copied!";
+ copyAppsButton.innerHTML = " Copied";
setTimeout(() => {
- copyAppsButton.textContent = "Copy Apps";
+ copyAppsButton.innerHTML = " Apps";
}, 1000);
});
const copySubsButton = document.createElement("button");
- copySubsButton.textContent = "Copy Subs";
+ copySubsButton.innerHTML = " Subs";
copySubsButton.addEventListener("click", () => {
const subIds = [...document.querySelectorAll("[data-subid]")]
+ .filter((el) => !el.closest(".swi-hidden"))
.map((el) => el.dataset.subid)
.join(",");
navigator.clipboard.writeText(subIds);
- copySubsButton.textContent = "Copied!";
+ copySubsButton.innerHTML = " Copied";
setTimeout(() => {
- copySubsButton.textContent = "Copy Subs";
+ copySubsButton.innerHTML = " Subs";
}, 1000);
});
-
copySection.appendChild(copyAppsButton);
copySection.appendChild(copySubsButton);
- toolbar.appendChild(copySection);
// Close button
const closeButton = document.createElement("button");
- closeButton.textContent = "X";
+ closeButton.innerHTML = "";
closeButton.className = "close-button";
closeButton.addEventListener("click", () => toolbar.remove());
+ // Divider
+ const divider = document.createElement("div");
+ divider.className = "swi-toolbar-divider";
+
+ toolbar.appendChild(filterSection);
+ toolbar.appendChild(divider.cloneNode(false));
+ toolbar.appendChild(blacklistSection);
+ toolbar.appendChild(divider.cloneNode(false));
+ toolbar.appendChild(copySection);
+ toolbar.appendChild(divider.cloneNode(false));
toolbar.appendChild(closeButton);
return toolbar;
@@ -513,9 +561,7 @@ chrome.runtime.onMessage.addListener((message) => {
if (existingToolbar) {
existingToolbar.remove();
} else {
- chrome.runtime.sendMessage({ "action": "getSettings" }).then((settings) => {
- document.body.appendChild(createToolbar(settings));
- });
+ document.body.appendChild(createToolbar());
}
}
});
diff --git a/scripts/popup.js b/scripts/popup.js
index bad3d08..07980fb 100644
--- a/scripts/popup.js
+++ b/scripts/popup.js
@@ -8,7 +8,7 @@ function factoryReset() {
async function setSettings(newSettings) {
let settings = await chrome.runtime.sendMessage({ "action": "getSettings" });
settings = { ...settings, ...newSettings };
- await chrome.storage.local.set({ "swi_settings": settings });
+ await chrome.runtime.sendMessage({ "action": "setSettings", settings });
return true;
}