diff options
author | Ajay Ramachandran <[email protected]> | 2021-07-31 01:02:41 -0400 |
---|---|---|
committer | Ajay Ramachandran <[email protected]> | 2021-07-31 01:02:41 -0400 |
commit | 9c54d141e9e8d50c5c9f67d537e132ef1159ee24 (patch) | |
tree | 7ba4a628f828905b1e7adfea666e17ba9d7caf94 /src/utils.ts | |
parent | 8c9424b6c5177b678bfb3cd65f03e4fa79d3d266 (diff) | |
parent | 2a3a04a504029be0f544d4c4523c4dd6e37ad2b1 (diff) | |
download | SponsorBlock-9c54d141e9e8d50c5c9f67d537e132ef1159ee24.tar.gz SponsorBlock-9c54d141e9e8d50c5c9f67d537e132ef1159ee24.zip |
Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into improvements
Diffstat (limited to 'src/utils.ts')
-rw-r--r-- | src/utils.ts | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/src/utils.ts b/src/utils.ts index af685a18..6d7e6e89 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -168,6 +168,31 @@ export default class Utils { } /** + * Starts a spinning animation and returns a function to be called when it should be stopped + * The callback will be called when the animation is finished + * It waits until a full rotation is complete + */ + applyLoadingAnimation(element: HTMLElement, time: number, callback?: () => void): () => void { + element.style.animation = `rotate ${time}s 0s infinite`; + + return () => { + // Make the animation finite + element.style.animation = `rotate ${time}s`; + + // When the animation is over, hide the button + const animationEndListener = () => { + if (callback) callback(); + + element.style.animation = "none"; + + element.removeEventListener("animationend", animationEndListener); + }; + + element.addEventListener("animationend", animationEndListener); + } + } + + /** * Merges any overlapping timestamp ranges into single segments and returns them as a new array. */ getMergedTimestamps(timestamps: number[][]): [number, number][] { @@ -253,7 +278,8 @@ export default class Utils { getLocalizedMessage(text: string): string | false { const valNewH = text.replace(/__MSG_(\w+)__/g, function(match, v1) { - return v1 ? chrome.i18n.getMessage(v1).replace("\n", "<br/>") : ""; + return v1 ? chrome.i18n.getMessage(v1).replace(/</g, "<") + .replace(/"/g, """).replace(/\n/g, "<br/>") : ""; }); if(valNewH != text) { @@ -398,6 +424,19 @@ export default class Utils { return referenceNode; } + objectToURI<T>(url: string, data: T, includeQuestionMark: boolean): string { + let counter = 0; + for (const key in data) { + const seperator = (url.includes("?") || counter > 0) ? "&" : (includeQuestionMark ? "?" : ""); + const value = (typeof(data[key]) === "string") ? data[key] as unknown as string : JSON.stringify(data[key]); + url += seperator + encodeURIComponent(key) + "=" + encodeURIComponent(value); + + counter++; + } + + return url; + } + getFormattedTime(seconds: number, precise?: boolean): string { const hours = Math.floor(seconds / 60 / 60); const minutes = Math.floor(seconds / 60) % 60; @@ -462,14 +501,13 @@ export default class Utils { async getHash(value: string, times = 5000): Promise<string> { if (times <= 0) return ""; - let hashBuffer = new TextEncoder().encode(value).buffer; - + let hashHex = value; for (let i = 0; i < times; i++) { - hashBuffer = await crypto.subtle.digest('SHA-256', hashBuffer); - } + const hashBuffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(hashHex).buffer); - const hashArray = Array.from(new Uint8Array(hashBuffer)); - const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); + const hashArray = Array.from(new Uint8Array(hashBuffer)); + hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); + } return hashHex; } |