Last active
August 19, 2021 11:22
-
-
Save Doliman100/0b7868cdc870f7ad70b9f871488049f6 to your computer and use it in GitHub Desktop.
Adds a volume control option to the duolingo.com settings page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @version 1.3 | |
| // @name Duolingo Volume Control | |
| // @namespace https://gist.github.com/Doliman100 | |
| // ==/UserScript== |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name Duolingo Volume Control | |
| // @namespace https://gist.github.com/Doliman100 | |
| // @version 1.3 | |
| // @description Adds a volume control option to the settings page. | |
| // @author Doliman100 | |
| // @icon https://d35aaqx5ub95lt.cloudfront.net/favicon.ico | |
| // @updateURL https://gist.githubusercontent.com/raw/0b7868cdc870f7ad70b9f871488049f6/script.meta.js | |
| // @downloadURL https://gist.githubusercontent.com/raw/0b7868cdc870f7ad70b9f871488049f6/script.user.js | |
| // @match https://www.duolingo.com/* | |
| // @grant none | |
| // ==/UserScript== | |
| "use strict"; | |
| let first = true; | |
| let layer = true; | |
| let style = true; | |
| let volume = localStorage.getItem("volume") || 1; | |
| Howler.volume(volume); | |
| window.addEventListener("storage", function(e) | |
| { | |
| if (e.key === "volume") | |
| { | |
| volume = e.newValue; | |
| Howler.volume(volume); | |
| } | |
| }); | |
| function inject() | |
| { | |
| if (first) | |
| { | |
| this.disconnect(); | |
| this.observe(document.querySelector("._1Xlh1"), { childList: true }); | |
| first = false; | |
| } | |
| if (location.pathname.substring(0, 9) !== "/settings") | |
| { | |
| layer = true; | |
| } | |
| else | |
| { | |
| if (layer) | |
| { | |
| this.observe(document.querySelector("._2PVaI"), { childList: true }); | |
| layer = false; | |
| } | |
| if (location.pathname === "/settings/account") | |
| { | |
| if (style) | |
| { | |
| document.head.insertAdjacentHTML("beforeend", | |
| `<style> | |
| #volume { | |
| display: flex; | |
| height: 24px; | |
| margin-top: 10px; | |
| } | |
| #volume input { | |
| -webkit-appearance: none; | |
| border-radius: 8px; | |
| background-color: #e5e5e5; | |
| width: 196px; | |
| height: 16px; | |
| margin-top: 4px; | |
| overflow: hidden; | |
| } | |
| #volume input::-webkit-slider-thumb { | |
| -webkit-appearance: none; | |
| box-shadow: -95px 0 0 87px #1cb0f6; | |
| box-sizing: content-box; | |
| border-radius: 50%; | |
| border: 2px solid #1cb0f6; | |
| background-color: #fff; | |
| width: 12px; | |
| height: 12px; | |
| } | |
| #volume input::-moz-range-thumb { | |
| box-shadow: -95px 0 0 87px #1cb0f6; | |
| box-sizing: content-box; | |
| border-radius: 50%; | |
| border: 2px solid #1cb0f6; | |
| background-color: #fff; | |
| width: 12px; | |
| height: 12px; | |
| } | |
| #volume div { | |
| margin: 2px 0 0 12px; | |
| } | |
| </style>` | |
| ); | |
| style = false; | |
| } | |
| const volume_pct = (volume * 100).toFixed(); | |
| document.querySelector('[name="enableSpeaker"]').closest("tr").insertAdjacentHTML("afterend", | |
| `<tr> | |
| <td class="_1CsoA _2cAA0">Volume</td> | |
| <td class="_1n58L _2cAA0 _2k8ad"> | |
| <div id="volume"> | |
| <input type="range" min="0" max="100" value="${volume_pct}" /> | |
| <div>${volume_pct}</div> | |
| </div> | |
| </td> | |
| </tr>` | |
| ); | |
| const volume_input = document.querySelector("#volume input"); | |
| const volume_output = document.querySelector("#volume div"); | |
| volume_input.oninput = function() | |
| { | |
| volume_output.textContent = this.value; | |
| } | |
| volume_input.onchange = function() | |
| { | |
| volume = this.value / 100; | |
| localStorage.setItem("volume", volume); | |
| Howler.volume(volume); | |
| } | |
| } | |
| } | |
| } | |
| new MutationObserver(inject).observe(document.getElementById("root"), { childList: true }); |
Author
It's strange. It looks like the script runs before the Howler object is initialized. What browser and script manager are you using? I have now tested it in Chrome with Tampermonkey and it works fine.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Is this still alive? Because it seems not to work for me…
It fails with
ReferenceError: Howler is not definedeventhough I can access Howler from the console.