MediaWiki:CustomItemTracker.js: Difference between revisions

From Roat Pkz
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
mw.hook('wikipage.content').add(function () {
mw.hook('wikipage.content').add(function () {


     const container = document.getElementById("customItemTracker");
     const container =
        document.getElementById("customItemTracker");


     if (!container) return;
     if (!container) return;


     const allowedUsers = [
     const allowedUsers = [
Line 9: Line 11:
     ];
     ];


     const currentUser = mw.config.get("wgUserName");
 
     const currentUser =
        mw.config.get("wgUserName");
 


     let trackerData = {
     let trackerData = {
Line 15: Line 20:
         completed: {}
         completed: {}
     };
     };
    let images = [];


     function loadData() {
     function loadData() {


         $.getJSON(
         $.getJSON(
Line 29: Line 40:
             }
             }


         ).done(function (data) {
         ).done(function(data) {
 
 
            const page =
                data.query.pages[0];


            const page = data.query.pages[0];


             if (!page.revisions)
             if (!page.revisions)
                 return;
                 return;


             try {
             try {
Line 43: Line 59:
                     );
                     );


                render();


             } catch (e) {
             } catch(e) {
 
                console.error(
                    "Invalid tracker JSON",
                    e
                );
 
                return;
 
            }
 
 
 
            loadImages();
 
 
        });
 
 
    }
 
 
 
 
 
    function loadImages() {
 
 
        const allItems = [];
 
 
        trackerData.tiers.forEach(function(tier) {
 
 
            tier.items.forEach(function(item) {
 
 
                allItems.push(item);
 
 
            });
 
 
        });
 
 
 
        const templates =
            allItems
            .map(function(item) {
 
                return "{{plinkp|" +
                    item.name +
                    "}}";
 
            })
            .join("\n");
 


                console.error(e);


        $.getJSON(
            "/api.php",
            {
                action: "parse",
                text: templates,
                format: "json"
             }
             }
        ).done(function(data) {
            if (!data.parse)
                return;
            const wrapper =
                document.createElement("div");
            wrapper.innerHTML =
                data.parse.text["*"];
            images =
                Array.from(
                    wrapper.querySelectorAll("img")
                );
            render();


         });
         });


     }
     }


     function render() {
     function render() {


         container.innerHTML = "";
         container.innerHTML = "";


        let totalItems = 0;


         trackerData.tiers.forEach(function (tier) {
 
             totalItems += tier.items.length;
        let total = 0;
 
 
         trackerData.tiers.forEach(function(tier) {
 
             total += tier.items.length;
 
         });
         });


         let completed = 0;
         let completed = 0;


        Object.keys(trackerData.completed).forEach(function (key) {


             if (trackerData.completed[key])
        Object.keys(
            trackerData.completed
        ).forEach(function(key) {
 
 
             if (
                trackerData.completed[key]
            )
            {
                 completed++;
                 completed++;
            }


         });
         });


         const progress =
         const progress =
             document.createElement("div");
             document.createElement("div");


         progress.className = "trackerProgress";
 
         progress.className =
            "trackerProgress";
 


         progress.innerHTML =
         progress.innerHTML =
            `Completed: <strong>${completed}/${totalItems}</strong> (${Math.floor((completed / totalItems) * 100) || 0}%)`;
        `
        Completed:
        <strong>${completed}/${total}</strong>
        (${total ? Math.floor((completed / total) * 100) : 0}%)
        `;
 


         container.appendChild(progress);
         container.appendChild(progress);


         let globalIndex = 0;
         let globalIndex = 0;
       
        trackerData.tiers.forEach(function(tier) {


        trackerData.tiers.forEach(function (tier) {
            const heading =
                document.createElement("div");


const heading =
    document.createElement("div");


heading.className = "trackerTierHeading";
            heading.className =
                "trackerTierHeading";
 
 
            heading.textContent =
                tier.name;


heading.textContent = tier.name;


             container.appendChild(heading);
             container.appendChild(heading);


             const grid =
             const grid =
                 document.createElement("div");
                 document.createElement("div");


             grid.className = "trackerGrid";
 
             grid.className =
                "trackerGrid";
 


             container.appendChild(grid);
             container.appendChild(grid);


            tier.items.forEach(function (item) {


                 const currentIndex = globalIndex++;
 
 
 
            tier.items.forEach(function(item) {
 
 
                 const index =
                    globalIndex++;
 
 


                 const tile =
                 const tile =
                     document.createElement("div");
                     document.createElement("div");


                tile.className = "trackerTile";


                 if (trackerData.completed[currentIndex])
                tile.className =
                     tile.classList.add("completed");
                    "trackerTile";
 
 
 
                 if (
                    trackerData.completed[index]
                ) {
 
                     tile.classList.add(
                        "completed"
                    );
 
                }
 
 
 
 


                 const image =
                 const imageBox =
                     document.createElement("div");
                     document.createElement("div");


                image.className = "itemImage";


                 tile.appendChild(image);
                imageBox.className =
                    "itemImage";
 
 
 
                if (
                    images[index]
                ) {
 
                    const img =
                        images[index]
                        .cloneNode(true);
 
 
 
                    img.style.maxWidth =
                        "50px";
 
 
                    img.style.maxHeight =
                        "50px";
 
 
                    img.style.width =
                        "auto";
 
 
                    img.style.height =
                        "auto";
 
 
                    img.style.objectFit =
                        "contain";
 
 
 
                    imageBox.appendChild(img);
 
                }
 
 
 
                 tile.appendChild(imageBox);
 
 
 
 


                 const name =
                 const name =
                     document.createElement("div");
                     document.createElement("div");


                 name.className = "itemName";
 
                 name.textContent = item.name;
                 name.className =
                    "itemName";
 
 
                 name.textContent =
                    item.name;
 
 


                 tile.appendChild(name);
                 tile.appendChild(name);


                loadImage(item.name, image);


                tile.onclick = function () {


                    if (!allowedUsers.includes(currentUser))
                        return;


                    trackerData.completed[currentIndex] =
                        !trackerData.completed[currentIndex];


                     saveData();
                tile.onclick = function() {
 
 
 
                     if (
                        !allowedUsers.includes(
                            currentUser
                        )
                    ) {
 
                        return;


                };
                    }


                grid.appendChild(tile);


            });


        });
                    trackerData.completed[index] =
                        !trackerData.completed[index];


    }
        function loadImage(itemName, target) {


        const template = "{{plinkp|" + itemName + "}}";


        $.getJSON("/api.php", {
                    saveData();
            action: "parse",
            text: template,
            format: "json"
        }).done(function (data) {


            if (!data.parse)
                return;


            const wrapper =
                 };
                 document.createElement("div");


            wrapper.innerHTML =
                data.parse.text["*"];


            const img =
                wrapper.querySelector("img");


            if (img) {
                grid.appendChild(tile);


                img.style.maxWidth = "50px";
                img.style.maxHeight = "50px";
                img.style.width = "auto";
                img.style.height = "auto";
                img.style.objectFit = "contain";


                target.appendChild(img);
            });


            }


         });
         });


     }
     }


     function saveData() {
     function saveData() {


         $.post(
         $.post(
Line 198: Line 413:
                 action: "edit",
                 action: "edit",


                 title: "Module:CustomItemTracker/data.json",
                 title:
                "Module:CustomItemTracker/data.json",
 
 
                token:
                mw.user.tokens.get(
                    "csrfToken"
                ),


                token: mw.user.tokens.get("csrfToken"),


                 format: "json",
                 format: "json",


                 text: JSON.stringify(
 
                 text:
                JSON.stringify(
                     trackerData,
                     trackerData,
                     null,
                     null,
Line 212: Line 435:
             }
             }


         ).done(function () {
         ).done(function() {
 


             render();
             render();


             console.log(
             console.log(
                 "Tracker updated."
                 "Custom Item Tracker updated"
             );
             );


         });
         });


     }
     }


     loadData();
     loadData();


});
});

Revision as of 16:28, 30 July 2026

mw.hook('wikipage.content').add(function () {

    const container =
        document.getElementById("customItemTracker");

    if (!container) return;


    const allowedUsers = [
        "Hefner"
    ];


    const currentUser =
        mw.config.get("wgUserName");


    let trackerData = {
        tiers: [],
        completed: {}
    };


    let images = [];



    function loadData() {


        $.getJSON(
            mw.util.wikiScript("api"),
            {
                action: "query",
                titles: "Module:CustomItemTracker/data.json",
                prop: "revisions",
                rvprop: "content",
                format: "json",
                formatversion: 2
            }

        ).done(function(data) {


            const page =
                data.query.pages[0];


            if (!page.revisions)
                return;



            try {

                trackerData =
                    JSON.parse(
                        page.revisions[0].content
                    );


            } catch(e) {

                console.error(
                    "Invalid tracker JSON",
                    e
                );

                return;

            }



            loadImages();


        });


    }





    function loadImages() {


        const allItems = [];


        trackerData.tiers.forEach(function(tier) {


            tier.items.forEach(function(item) {


                allItems.push(item);


            });


        });



        const templates =
            allItems
            .map(function(item) {

                return "{{plinkp|" +
                    item.name +
                    "}}";

            })
            .join("\n");



        $.getJSON(
            "/api.php",
            {
                action: "parse",
                text: templates,
                format: "json"
            }

        ).done(function(data) {



            if (!data.parse)
                return;



            const wrapper =
                document.createElement("div");



            wrapper.innerHTML =
                data.parse.text["*"];



            images =
                Array.from(
                    wrapper.querySelectorAll("img")
                );



            render();


        });


    }





    function render() {


        container.innerHTML = "";



        let total = 0;


        trackerData.tiers.forEach(function(tier) {

            total += tier.items.length;

        });



        let completed = 0;


        Object.keys(
            trackerData.completed
        ).forEach(function(key) {


            if (
                trackerData.completed[key]
            )
            {
                completed++;
            }


        });



        const progress =
            document.createElement("div");


        progress.className =
            "trackerProgress";


        progress.innerHTML =
        `
        Completed:
        <strong>${completed}/${total}</strong>
        (${total ? Math.floor((completed / total) * 100) : 0}%)
        `;


        container.appendChild(progress);



        let globalIndex = 0;
        
        trackerData.tiers.forEach(function(tier) {


            const heading =
                document.createElement("div");


            heading.className =
                "trackerTierHeading";


            heading.textContent =
                tier.name;


            container.appendChild(heading);



            const grid =
                document.createElement("div");


            grid.className =
                "trackerGrid";


            container.appendChild(grid);





            tier.items.forEach(function(item) {


                const index =
                    globalIndex++;



                const tile =
                    document.createElement("div");


                tile.className =
                    "trackerTile";



                if (
                    trackerData.completed[index]
                ) {

                    tile.classList.add(
                        "completed"
                    );

                }





                const imageBox =
                    document.createElement("div");


                imageBox.className =
                    "itemImage";



                if (
                    images[index]
                ) {

                    const img =
                        images[index]
                        .cloneNode(true);



                    img.style.maxWidth =
                        "50px";


                    img.style.maxHeight =
                        "50px";


                    img.style.width =
                        "auto";


                    img.style.height =
                        "auto";


                    img.style.objectFit =
                        "contain";



                    imageBox.appendChild(img);

                }



                tile.appendChild(imageBox);





                const name =
                    document.createElement("div");


                name.className =
                    "itemName";


                name.textContent =
                    item.name;



                tile.appendChild(name);





                tile.onclick = function() {



                    if (
                        !allowedUsers.includes(
                            currentUser
                        )
                    ) {

                        return;

                    }



                    trackerData.completed[index] =
                        !trackerData.completed[index];



                    saveData();


                };



                grid.appendChild(tile);


            });


        });


    }





    function saveData() {


        $.post(
            mw.util.wikiScript("api"),
            {

                action: "edit",

                title:
                "Module:CustomItemTracker/data.json",


                token:
                mw.user.tokens.get(
                    "csrfToken"
                ),


                format: "json",


                text:
                JSON.stringify(
                    trackerData,
                    null,
                    4
                )

            }

        ).done(function() {


            render();


            console.log(
                "Custom Item Tracker updated"
            );


        });


    }





    loadData();


});