디스코드 자동 스크롤

코드
// ==UserScript==
// @name         Discord Auto Scroll
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Discord Auto Scroll
// @author       codentalks
// @match        https://discordapp.com/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function () {
    "use strict";
    
    const DI = window.DiscordInternals;
    const hasLib = !!(DI && DI.versionCompare && DI.versionCompare(DI.version || "", "1.9") >= 0);
    const monkeyPatch = hasLib && DI.monkeyPatch || ((what, methodName, options) => {
        const {before, after, instead, once = false, silent = false} = options;
        const displayName = options.displayName || what.displayName || what.name || what.constructor.displayName || what.constructor.name;
        if (!silent) console.log('patch', methodName, 'of', displayName);
        const origMethod = what[methodName];
        const cancel = () => {
            if (!silent) console.log('unpatch', methodName, 'of', displayName);
            what[methodName] = origMethod;
        };
        what[methodName] = function() {
            const data = {
                thisObject: this,
                methodArguments: arguments,
                cancelPatch: cancel,
                originalMethod: origMethod,
                callOriginalMethod: () => data.returnValue = data.originalMethod.apply(data.thisObject, data.methodArguments)
            };
            if (instead) {
                const tempRet = instead(data);
                if (tempRet !== undefined)
                    data.returnValue = tempRet;
            }
            else {
                if (before) before(data);
                data.callOriginalMethod();
                if (after) after(data);
            }
            if (once) cancel();
            return data.returnValue;
        };
        what[methodName].__monkeyPatched = true;
        what[methodName].displayName = 'patched ' + (what[methodName].displayName || methodName);
        return cancel;
    });


    const WebpackModules = hasLib && DI.WebpackModules || (() => {

        const req = typeof(webpackJsonp) == "function" ? webpackJsonp([], {
                '__extra_id__': (module, exports, req) => exports.default = req
        }, ['__extra_id__']).default : webpackJsonp.push([[], {
                '__extra_id__': (module, exports, req) => module.exports = req
        }, [['__extra_id__']]]);
        delete req.m['__extra_id__'];
        delete req.c['__extra_id__'];
        const find = (filter, options = {}) => {
            const {cacheOnly = false} = options;
            for (let i in req.c) {
                if (req.c.hasOwnProperty(i)) {
                    let m = req.c[i].exports;
                    if (m && m.__esModule && m.default && filter(m.default))
                        return m.default;
                    if (m && filter(m))
                        return m;
                }
            }
            if (cacheOnly) {
                console.warn('Cannot find loaded module in cache');
                return null;
            }
            console.warn('Cannot find loaded module in cache. Loading all modules may have unexpected side effects');
            for (let i = 0; i < req.m.length; ++i) {
                let m = req(i);
                if (m && m.__esModule && m.default && filter(m.default))
                    return m.default;
                if (m && filter(m))
                    return m;
            }
            console.warn('Cannot find module');
            return null;
        };
        const findByUniqueProperties = (propNames, options) => find(module => propNames.every(prop => module[prop] !== undefined), options);
        const findByDisplayName = (displayName, options) => find(module => module.displayName === displayName, options);

        return {find, findByUniqueProperties, findByDisplayName};

    })();

    window.addEventListener('load', function() {
        
        var kb, onSwitch, cancels = [];
        kb = WebpackModules.findByUniqueProperties(["MARK_CHANNEL_READ"], {cacheOnly: false});
        
        onSwitch = (ev) => {
        if(("CHANNEL_SELECT" === ev.type || "GUILD_SELECT" === ev.type) && /^\/channels\/(?:@me|\d+)\/\d+$/.test(window.location.pathname))
            kb.MARK_CHANNEL_READ.action();
        };

        var _ = WebpackModules.findByUniqueProperties(["_orderedActionHandlers"], {cacheOnly: false});
        _.subscribe("CHANNEL_SELECT", onSwitch); cancels.push(_.unsubscribe.bind(_, "CHANNEL_SELECT", onSwitch));
        _.subscribe("GUILD_SELECT", onSwitch); cancels.push(_.unsubscribe.bind(_, "GUILD_SELECT", onSwitch));

    }, false);

})();

모바일에서 디스코드를 보고나서 컴퓨터에서 브라우저로 디스코드를 열었을 때 스크롤이 올라가 있어 불편한 경우가 많습니다. 이런 불편함을 해결하기 위해 자동으로 마지막 메시지가 있는 곳으로 스크롤 해주는 유저 스크립트를 작성하게 되었습니다.

기능

  • 채널의 마지막 ( 최신 ) 메시지로 자동 스크롤

사용 방법은 다음과 같습니다.

  1. TamperMonkey 확장을 브라우저에 설치 하신 후 여기를 클릭해 스크립트를 설치 해주세요.
    • 별도의 조작이 필요 없습니다.
1 Like