Udemy Progress Control

The script can automatically check or uncheck off completed lessons of courses or sections, saving users time and effort in manually marking them as completed.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

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

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

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

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्क्रिप्ट व्यवस्थापक एक्स्टेंशन इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्क्रिप्ट व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्टाईल व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

// ==UserScript==
// @name         Udemy Progress Control
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  The script can automatically check or uncheck off completed lessons of courses or sections, saving users time and effort in manually marking them as completed.
// @author       realzam
// @match        https://www.udemy.com/course/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=udemy.com
// @grant        none
// @license MIT
// ==/UserScript==


function awaitToElement(element){
    return new Promise((resolve) => {
        let nIntervId = setInterval(()=>{
            const isReady=document.querySelectorAll(element).length != 0
            if(isReady){
                resolve()
                clearInterval(nIntervId)
            }
        },100)
        });
}

function seccionCollapse(seccion,action){
    return new Promise(async(resolve) => {
        const seccionButtonCollapse =seccion.querySelector('button[type="button"]')
        const isChecked = seccion.querySelector('span[data-checked]').getAttribute('data-checked') === 'checked'
        console.log(seccion.getAttribute('data-purpose'),isChecked)
        if(isChecked!=action){
            seccionButtonCollapse.click()
            if(action){
                await awaitToElement('ul.ud-unstyled-list')
            }
        }
        resolve()
    });
}

const isPageLoaded = async()=> awaitToElement('div[data-purpose="curriculum-section-container"]')

async function actioSeccion(seccion,action){
    await seccionCollapse(seccion,true)
    const leccions=seccion.childNodes[2].childNodes[0].childNodes[0].childNodes
    for(const leccion of leccions)
    {
        if(leccion.querySelector('input').checked !=action)
        {
            leccion.querySelector('input').click()
        }
    }
    await seccionCollapse(seccion,false)

}

async function actionCourse(seccions,action){
    for(const seccion of seccions)
    {
        await actioSeccion(seccion,action)
    }
}


async function main() {
    await isPageLoaded();
    const seccions = document.querySelector('#ct-sidebar-scroll-container > div > div').childNodes;
    const courseActions = document.querySelector('section[data-purpose="sidebar"]').childNodes[0];

    let completeAllCourseBtn = document.createElement("div");
    completeAllCourseBtn.tabIndex=0
    completeAllCourseBtn.role="button"
    completeAllCourseBtn.className = "item-link ud-btn ud-btn-small ud-btn-primary ud-heading-sm";
    completeAllCourseBtn.innerHTML ='<span>Complete</span>'
    completeAllCourseBtn.onclick = ()=>{actionCourse(seccions,true)};

    let resetCourseBtn = document.createElement("div");
    resetCourseBtn.tabIndex=0
    resetCourseBtn.role="button"
    resetCourseBtn.className = "item-link ud-btn ud-btn-small ud-btn-secondary ud-heading-sm";
    resetCourseBtn.innerHTML ='<span>Reset</span>'
    resetCourseBtn.onclick = ()=>{actionCourse(seccions,false)};

    courseActions.appendChild(completeAllCourseBtn)
    courseActions.appendChild(resetCourseBtn)

    for(const seccion of seccions)
    {
        let checkAllSeccionnBtn = document.createElement("div");
        checkAllSeccionnBtn.tabIndex=0
        checkAllSeccionnBtn.role="button"
        checkAllSeccionnBtn.className = "item-link ud-btn ud-btn-small ud-btn-primary ud-heading-sm";
        checkAllSeccionnBtn.innerHTML ='<span>Check All</span>'
        checkAllSeccionnBtn.style.margin='5px'
        checkAllSeccionnBtn.onclick = ()=>{actioSeccion(seccion,true)}

        let uncheckAllSeccionnBtn = document.createElement("div");
        uncheckAllSeccionnBtn.tabIndex=0
        uncheckAllSeccionnBtn.role="button"
        uncheckAllSeccionnBtn.className = "item-link ud-btn ud-btn-small ud-btn-secondary ud-heading-sm";
        uncheckAllSeccionnBtn.innerHTML ='<span>Uncheck All</span';
        uncheckAllSeccionnBtn.style.margin='5px'
        uncheckAllSeccionnBtn.onclick = ()=>{actioSeccion(seccion,false)};

        seccion.appendChild(checkAllSeccionnBtn)
        seccion.appendChild(uncheckAllSeccionnBtn)
    }

}

main()