MediaWiki:CustomItemTracker.js: Difference between revisions

From Roat Pkz
Jump to navigation Jump to search
No edit summary
No edit summary
 
(8 intermediate revisions by the same user not shown)
Line 1: Line 1:
mw.hook('wikipage.content').add(function () {
mw.hook('wikipage.content').add(function () {


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


     if (!container) return;
     if (!container) return;
    const infoBox =
        document.getElementById(
            "customItemTrackerInfo"
        );




Line 20: Line 13:


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




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




     function loadData(){
    let images = {};
 
    let searchValue = "";
 
 
 
     function loadData() {
 


         $.getJSON(
         $.getJSON(
             mw.util.wikiScript('api'),
             mw.util.wikiScript("api"),
             {
             {
                 action:'query',
                 action: "query",
                 titles:'Module:CustomItemTracker/data.json',
                 titles: "Module:CustomItemTracker/data.json",
                 prop:'revisions',
                 prop: "revisions",
                 rvprop:'content',
                 rvprop: "content",
                 format:'json',
                 format: "json",
                 formatversion:2
                 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;


             }
             }


        ).done(function(data){




             let page =
             loadImages();
            data.query.pages[0];
 
 
        });
 
 
    }
 
 
 
 
 
    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");
        $.post(
            "/api.php",
            {
                action: "parse",
                text: templates,
                format: "json"
            }
        ).done(function(data) {
            if (!data.parse) {
                console.warn(
                    "Image parse failed",
                    data
                );
                images = {};
                render();


            if(!page.revisions)
                 return;
                 return;


            }
            const wrapper =
                document.createElement("div");
            wrapper.innerHTML =
                data.parse.text["*"];
            const parsedImages =
                Array.from(
                    wrapper.querySelectorAll("img")
                );
            images = {};
            allItems.forEach(function(item, index) {
                if (parsedImages[index]) {
                    images[item.name] =
                        parsedImages[index];
                }
            });


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




Line 64: Line 189:


         });
         });


     }
     }
Line 69: Line 195:




    function render(){




         container.innerHTML="";
    function render(searchTerm = "") {
 
 
         container.innerHTML = "";
 
 
 
        let total = 0;
 
 
        trackerData.tiers.forEach(function(tier) {
 
            total += tier.items.length;
 
        });
 
 
 
        let completed = 0;




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




         let total =
         });
        trackerData.items.length;






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




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




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


Line 106: Line 256:




         let grid =
         const searchBox =
        document.createElement("div");
            document.createElement("input");
 
 
        searchBox.type =
            "text";
 
 
        searchBox.placeholder =
            "Search items...";
 
 
        searchBox.className =
            "trackerSearch";




         grid.className=
         searchBox.value =
        "trackerGrid";
            searchTerm;




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






         trackerData.items.forEach(
         searchBox.addEventListener(
        function(item,index){
            "input",
            function() {


                searchValue =
                    this.value.toLowerCase();


            let tile =
                render(searchValue);
            document.createElement("div");
 
 
                setTimeout(function() {
 
                    const newSearch =
                        container.querySelector(".trackerSearch");
 
 
                    if (newSearch) {
 
                        newSearch.focus();
 
                        newSearch.setSelectionRange(
                            newSearch.value.length,
                            newSearch.value.length
                        );


                    }


            tile.className=
                }, 0);
            "trackerTile";




            if(
            trackerData.completed[index]
            )
            {
                tile.classList.add(
                    "completed"
                );
             }
             }
        );
                let globalIndex = 0;
        trackerData.tiers.forEach(function(tier) {
            const filteredItems =
                tier.items.filter(function(item) {
                    if (!searchTerm)
                        return true;
                    return item.name
                        .toLowerCase()
                        .includes(searchTerm);
                });
            if (filteredItems.length === 0)
                return;


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




             tile.innerHTML=
             heading.className =
            `
                "trackerTierHeading";
            <div class="itemImage">
            </div>


            <div class="itemName">
            ${item.name}
            </div>
            `;


            heading.textContent =
                tier.name;




             tile.onclick=function(){
             container.appendChild(heading);




                showInfo(item);


            const grid =
                document.createElement("div");
            grid.className =
                "trackerGrid";
            container.appendChild(grid);
            tier.items.forEach(function(item) {
const index =
    trackerData.tiers
    .flatMap(t => t.items)
    .indexOf(item);
                if (
                    searchTerm &&
                    !item.name
                    .toLowerCase()
                    .includes(searchTerm)
                ) {


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




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




                saveData();


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


            };


                tile.className =
                    "trackerTile";




            grid.appendChild(tile);


                if (
                    trackerData.completed[index]
                ) {


                    tile.classList.add(
                        "completed"
                    );
                }
                const imageBox =
                    document.createElement("div");
                imageBox.className =
                    "itemImage";
                if (
                    images[item.name]
                ) {
                    const img =
                        images[item.name]
                        .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);
                }


            getImage(
                item.name,
                tile.querySelector(".itemImage")
            );




        });
                tile.appendChild(imageBox);




    }






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




    function getImage(name,target){
                name.className =
                    "itemName";




        let text =
                name.textContent =
        "{{plinkp|" +
                    item.name;
        name +
        "}}";




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


        .done(function(data){
                tile.appendChild(name);




            if(!data.parse)
                return;




            let div =
            document.createElement("div");


                tile.onclick =
                function() {


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




            let img =
                    if (
            div.querySelector("img");
                        !allowedUsers.includes(
                            currentUser
                        )
                    ) {


                        return;


if(img)
                    }
{
    img.style.width = "50px";
    img.style.height = "50px";
    img.style.objectFit = "contain";
    img.style.display = "block";
    img.style.margin = "0 auto";


    target.appendChild(img);
}




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




    }


                    saveData();




                };




    function showInfo(item){


                grid.appendChild(tile);


        infoBox.innerHTML=
        `
        <h3>${item.name}</h3>


        <b>Category:</b>
            });
        ${item.category}


        <br><br>


         ${item.info.replaceAll(
         });
            "%%",
            "<br>"
        )}


        `;


     }
     }
Line 280: Line 533:




     function saveData(){
 
     function saveData() {




         $.post(
         $.post(
        mw.util.wikiScript('api'),
            mw.util.wikiScript("api"),
        {
            {
 
                action: "edit",
 
                title:
                "Module:CustomItemTracker/data.json",


            action:'edit',


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


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


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


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


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


         .done(function(){
            }
 
         ).done(function() {
 
 
            render(searchValue);
 
 
            console.log(
                "Custom Item Tracker updated"
            );


            render();


         });
         });
Line 316: Line 580:


     }
     }





Latest revision as of 17:12, 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 = {};

    let searchValue = "";



    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");



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

        ).done(function(data) {



            if (!data.parse) {

                console.warn(
                    "Image parse failed",
                    data
                );

                images = {};

                render();

                return;

            }



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



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



            const parsedImages =
                Array.from(
                    wrapper.querySelectorAll("img")
                );



            images = {};



            allItems.forEach(function(item, index) {


                if (parsedImages[index]) {

                    images[item.name] =
                        parsedImages[index];

                }


            });



            render();


        });


    }





    function render(searchTerm = "") {


        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);



        const searchBox =
            document.createElement("input");


        searchBox.type =
            "text";


        searchBox.placeholder =
            "Search items...";


        searchBox.className =
            "trackerSearch";


        searchBox.value =
            searchTerm;


        container.appendChild(searchBox);



        searchBox.addEventListener(
            "input",
            function() {

                searchValue =
                    this.value.toLowerCase();

                render(searchValue);


                setTimeout(function() {

                    const newSearch =
                        container.querySelector(".trackerSearch");


                    if (newSearch) {

                        newSearch.focus();

                        newSearch.setSelectionRange(
                            newSearch.value.length,
                            newSearch.value.length
                        );

                    }

                }, 0);


            }
        );
                let globalIndex = 0;


        trackerData.tiers.forEach(function(tier) {


            const filteredItems =
                tier.items.filter(function(item) {


                    if (!searchTerm)
                        return true;


                    return item.name
                        .toLowerCase()
                        .includes(searchTerm);


                });



            if (filteredItems.length === 0)
                return;



            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 =
    trackerData.tiers
    .flatMap(t => t.items)
    .indexOf(item);



                if (
                    searchTerm &&
                    !item.name
                    .toLowerCase()
                    .includes(searchTerm)
                ) {

                    return;

                }





                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[item.name]
                ) {


                    const img =
                        images[item.name]
                        .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(searchValue);


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


        });


    }





    loadData();


});