diff --git a/README.md b/README.md index 3262cb5..de909e1 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,8 @@ # Steam Janitor -_A userscript that makes browsing through thousands of mods viable_ +_A userscript that makes browsing mods viable_ -## [Install 0.0.2](https://github.com/Jetsparrow/steam-janitor/raw/main/steam-janitor.user.js) -_Requires a userscript extension for your browser, like [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=en)_ +[Demo, install links](https://jetsparrow.github.io/steam-janitor/) -**N.B.: this is a very crude alpha. Developed and tested in Google Chrome** - -## Filter mods - -Adds a little "hide" button to any workshop browse page. Use it, and you will no longer see the hundreds of miscellaneous translations to laguages you don't know, obsolete mods, or gachimuchi memes. - -The userscripts adds a "filter" checkbox to the top paging controls, allowing you to switch between the filtered and unfiltered view. - -## Endless scrolling - -After the filter runs its course, you will be left with barely any mods. Endless scrolling fixes that. +* Adds a "hide" button to all items on the workshop browse page. Hides item forever, until unhidden. +* Adds a "filter" checkbox to the top paging controls, allowing to switch between filtered and unfiltered view. +* Adds endless scrolling to workshop browse pages. \ No newline at end of file diff --git a/index.md b/index.md index 95eee62..8dbb118 100644 --- a/index.md +++ b/index.md @@ -1,13 +1,17 @@ -## [Install 0.0.2](https://github.com/Jetsparrow/steam-janitor/raw/main/steam-janitor.user.js) -_Requires a userscript extension for your browser, like [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=en)_ +https://user-images.githubusercontent.com/37241560/153673942-b35b53e9-4c88-4695-8631-855243251740.mp4 -**N.B.: this is a very crude alpha. Developed and tested in Google Chrome** +## [Steam Janitor v0.0.3-alpha - install](https://github.com/Jetsparrow/steam-janitor/raw/main/steam-janitor.user.js) +_Requires a userscript extension for your browser, e.g. [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=en)_ -## Filter mods +**N.B.: this is an early alpha. Tested only in Tampermonkey on Google Chrome** -Adds a little "hide" button to any workshop browse page. Use it, and you will no longer see the hundreds of miscellaneous translations to laguages you don't know, obsolete mods, or gachimuchi memes. +## Filter unwanted items -The userscripts adds a "filter" checkbox to the top paging controls, allowing you to switch between the filtered and unfiltered view. +A "hide" button is added to every item on a workshop browse page. +Clicking it will hide the item forever - until you turn off the filter and unhide it. +Translations to laguages you don't know, obsolete mods, gachimuchi memes, and mods that are just not quite your cup of tea - hide once and never see them again. + +The "filter" checkbox at the top paging controls allows you to switch between the filtered and unfiltered view. ## Endless scrolling diff --git a/steam-janitor.user.js b/steam-janitor.user.js index ea09c88..0602f20 100644 --- a/steam-janitor.user.js +++ b/steam-janitor.user.js @@ -1,14 +1,14 @@ // ==UserScript== // @name Steam Janitor +// @namespace jetsparrow-steam-janitor +// @author Jetsparrow // @description Hide unwanted user content in browse view, endless scrolling // @match *://*.steamcommunity.com/workshop/browse/* // @run-at document-end -// @version 0.0.2 +// @version 0.0.3 // @grant GM_setValue // @grant GM_getValue -// @grant GM_listValues -// @updateURL https://raw.githubusercontent.com/Jetsparrow/steam-janitor/main/steam-janitor.js -// @downloadURL https://raw.githubusercontent.com/Jetsparrow/steam-janitor/main/steam-janitor.js +// @downloadURL https://jetsparrow.github.io/steam-janitor/steam-janitor.user.js // ==/UserScript== const addGlobalStyle = (doc, css) => { @@ -42,31 +42,60 @@ const onVisible = (element, callback) => { observer.observe(element); }; -const selectors = { +const selector = { PAGING_INFO: ".workshopBrowsePagingWithBG", ITEM_CONTAINER: ".workshopBrowseItems .workshopItemPreviewHolder", ITEMS_CONTAINER: ".workshopBrowseItems", ITEMS_HOVERS: ".workshopBrowseItems script", NEXT_BUTTON: ".workshopBrowsePagingControls .pagebtn:last-child", PAGINATOR: ".workshopBrowsePagingControls", - FOOTER: ".workshopBrowsePaging" + PAGE_INFO: ".workshopBrowsePagingInfo", + FOOTER: ".workshopBrowsePaging", }; -const unhiddenClass = "janitorItem"; -const hiddenFilteredClass = "janitorItemHidden"; -const hiddenUnfilteredClass = "janitorItemHiddenUnfiltered"; -const hideButtonClass = "janitorHideButton"; -const showButtonClass = "janitorShowButton"; +const elemId = { + scrollTarget: "footer", + filterToggleCheckbox: "janitorFilterToggleCheckbox", + filterToggleOn: "janitorFilterOnIcon", + filterToggleOff: "janitorFilterOffIcon", +}; + +const cssClass = { + unhidden: "janitorItem", + hiddenFiltered: "janitorItemHidden", + hiddenUnfiltered: "janitorItemHiddenUnfiltered", + hideButton: "janitorHideButton", + showButton: "janitorShowButton", + filterToggle: "janitorFilterToggle", + hideButton: "janitorhideButton" +}; + +const resource = { + iconEyeOpen:"https://jetsparrow.github.io/steam-janitor/res/filter_toggle_open.png", + iconEyeClosed:"https://jetsparrow.github.io/steam-janitor/res/filter_toggle_closed.png", + btnHide:"https://jetsparrow.github.io/steam-janitor/res/janitor_hide.png", + btnHideHover:"https://jetsparrow.github.io/steam-janitor/res/janitor_hide_hover.png", + btnUnhide:"https://jetsparrow.github.io/steam-janitor/res/janitor_unhide.png", + btnUnhideHover:"https://jetsparrow.github.io/steam-janitor/res/janitor_unhide_hover.png", +}; const janitorCss = ` -.${hiddenFilteredClass} { display:none !important; } -.${hiddenUnfilteredClass} {opacity: 0.25;} -.${hiddenUnfilteredClass} .${showButtonClass} { display:inline !important; } -.${hiddenUnfilteredClass} .${hideButtonClass} { display:none !important; } -.${unhiddenClass} .${showButtonClass} { display:none !important; } -.${unhiddenClass} .${hideButtonClass} { display:inline !important; } +.${cssClass.hiddenFiltered} {display:none !important; } +.${cssClass.hiddenUnfiltered} img {opacity: 0.25;} +.${cssClass.hideButton} {width:25px; height:25px;} +.${cssClass.hiddenUnfiltered} .${cssClass.hideButton}:hover {background-image:url("${resource.btnUnhideHover}")} +.${cssClass.hiddenUnfiltered} .${cssClass.hideButton} {background-image:url("${resource.btnUnhide}")} +.${cssClass.unhidden} .${cssClass.hideButton}:hover {background-image:url("${resource.btnHideHover}")} +.${cssClass.unhidden} .${cssClass.hideButton} {background-image:url("${resource.btnHide}")} +.${cssClass.filterToggle} * { vertical-align: middle; } +.workshopItem .${cssClass.hideButton} { visibility: hidden; position: absolute; top: 4px; right: 6px; } +.workshopItem:hover .${cssClass.hideButton} { visibility: visible; position: absolute; top: 4px; right: 6px;} `; +const setting = { + filterEnabled: "janitorFilterEnabled" +}; + const defaultModData = () => { let d = new Object(); d.hide = false; @@ -78,41 +107,42 @@ const loadModData = (modId) => { } const saveModData = (modId, data) => GM_setValue("modid:" + modId, JSON.stringify(data)); -const updateHiddenClass = (doc, modId) => { +const updateHiddenClass = (doc, modId, filterOn) => { var container = doc.getElementById(modId)?.parentElement?.parentElement; if (!container) return; const d = loadModData(modId); - container.classList.remove(unhiddenClass); - container.classList.remove(hiddenFilteredClass); - container.classList.remove(hiddenUnfilteredClass); + container.classList.remove(cssClass.unhidden); + container.classList.remove(cssClass.hiddenFiltered); + container.classList.remove(cssClass.hiddenUnfiltered); - if (!d.hide) container.classList.add(unhiddenClass); - else if (window.janitorFilterEnabled) container.classList.add(hiddenFilteredClass); - else container.classList.add(hiddenUnfilteredClass); + if (!d.hide) container.classList.add(cssClass.unhidden); + else if (filterOn) container.classList.add(cssClass.hiddenFiltered); + else container.classList.add(cssClass.hiddenUnfiltered); } -const setHidden = (doc, modId, isHidden) => { +const toggleHidden = (doc, modId) => { var d = loadModData(modId); - d.hide = isHidden; + d.hide = !d.hide; saveModData(modId, d); - updateHiddenClass(doc, modId); + const filterOn = GM_getValue(setting.filterEnabled); + updateHiddenClass(doc, modId, filterOn); } const addHideButtons = (doc, container, id) => { - const hide = htmlToElement(doc, `hide`) - hide.onclick = () => {setHidden(document, id, true);}; - container.prepend(hide); - - const show = htmlToElement(doc, `show`) - show.onclick = () => {setHidden(document, id, false);}; - container.prepend(show); + const controls = htmlToElement(doc, `