Better Player

QoL improvements for the Deezer player(bar)

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

You will need to install an extension such as Tampermonkey to install this script.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name        Better Player
// @description QoL improvements for the Deezer player(bar)
// @author      bertigert
// @version     1.0.3
// @icon        https://www.google.com/s2/favicons?sz=64&domain=deezer.com
// @namespace   Violentmonkey Scripts
// @match       https://www.deezer.com/*
// @grant       none
// ==/UserScript==


(function() {
    "use strict";

    class Logger {
        constructor(prefix, debug=false) {
            this.prefix = prefix;
            this.should_debug = debug;
        }

        debug(...args) {if (this.should_debug) console.debug(this.prefix, ...args);}
        log(...args) {console.log(this.prefix, ...args);}
        warn(...args) {console.warn(this.prefix, ...args);}
        error(...args) {console.error(this.prefix, ...args);}
    }

    class WebpackPatch {
        PATCHES = [
            {
                find: ["getStorageKey:e=>`ALERT_DISMISSED_${e}"],
                replacements: [
                    // remaining time
                    {
                        match: /(_renderCurrentValue.*?)this._formatValue\(([a-z])\)(.*?"data-testid":"elapsed_time")/, //(.*?"data-testid":"remaining_time"},[a-z])/,
                        replace: (_, $1, $2, $3, $4) => `${$1}(${WebpackPatcher.ph.data}.altMode?"-":"")+this._formatValue(${WebpackPatcher.ph.data}.altMode?this.props.max-${$2}:${$2})${$3},onMouseUp:()=>${WebpackPatcher.ph.functions}.toggle()` //${$4}`+(${WebpackPatcher.placeholders.data}.altMode?" / "+this._formatValue(dzPlayer.getTrackListDuration()):"")`
                    },
                    // better play previous
                    {
                        match: /(isDisabled:)![a-zA-Z]\|\|(!n.prev,onClick:\(\)=>{\$[a-zA-Z]\.[a-zA-Z]+\.control\.prevSong\(\)})/,
                        replace: (_, $1, $2) => `${$1}${$2}`
                    }
                ]
            }
        ]
        data = {
            altMode: false,
        }
        functions = {
            toggle: () => {
                this.data.altMode = !this.data.altMode;
            }
        }

        constructor() {
            this.wait_for_webpack_patcher_and_patch = this.wait_for_webpack_patcher_and_patch.bind(this);
            this.wait_for_webpack_patcher_and_patch();
        }

        wait_for_webpack_patcher_and_patch() {
            if (window.WebpackPatcher) {
                logger.log("Registering webpack patches");
                window.WebpackPatcher.register({
                    name: "BetterPlayer",
                    data: this.data,
                    functions: this.functions
                }, this.PATCHES);
            } else if (!window.webpackJsonpDeezer) {
                setTimeout(this.wait_for_webpack_patcher_and_patch, 0);
            } else {
                logger.warn("Webpack array found, but not patcher, stopping");
            }
        }
    }

    class DzPlayerPatch {
        static REPEAT_MODES = {
            NO_REPEAT: 0,
            REPEAT_ALL: 1,
            REPEAT_ONE: 2,
        }

        constructor() {
            this.patch_play_previous();
        }

        patch_play_previous() {
            const patch_play_previous = () => {
                logger.log("Hooking dzPlayer.control.prevSong");
                const orig_play_previous = window.dzPlayer.control.prevSong;
                window.dzPlayer.control.prevSong = async function() {
                    if (
                        window.dzPlayer.getPosition() > 5 ||
                        window.dzPlayer.getRepeat() !== DzPlayerPatch.REPEAT_MODES.REPEAT_ALL && window.dzPlayer.getTrackListIndex() === 0
                    ) {
                        window.dzPlayer.control.seek(0);
                    } else {
                        orig_play_previous.call(window);
                    }
                }
            }

            const wait_for_dzplayer = setInterval(() => {
                if (window?.dzPlayer?.control?.prevSong) {
                    clearInterval(wait_for_dzplayer);
                    patch_play_previous();
                }
            }, 100);
        }
    }


    const logger = new Logger("[Better Player]", false);

    new WebpackPatch();
    new DzPlayerPatch();
})();