MediaWiki:Gadget-CargoHelper.js

From Angelina Jordan Wiki
Revision as of 11:33, 14 November 2025 by Most2dot0 (talk | contribs) (bugfix)

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
mw.loader.using(['mediawiki.api', 'ext.cargo.main']).then(function () {

    const api = new mw.Api();
    const page = mw.config.get('wgPageName');

    // Sanitize page name the same way the Lua module does (compatible)
    function sanitizeForPerfID(title) {
        title = title.replace(/&[#\w]+;/g, "_");
        title = title.replace(/[^A-Za-z0-9_.-]/g, "_");
        return title;
    }

    // Compute next available local ID
    function nextLocalId(perfIDs, sanitizedPage) {
        let max = 0;
        perfIDs.forEach(id => {
            if (!id.startsWith(sanitizedPage + "_")) return;
            const local = id.slice(sanitizedPage.length + 1);
            const m = local.match(/^(\d+)/);
            if (m) {
                const n = parseInt(m[1], 10);
                if (n > max) max = n;
            }
        });
        return String(max + 1);
    }

    // Query existing performances for this page
	function queryPerformances() {
	    const apiUrl = new URL(mw.util.wikiScript('api'), location.origin);
	
	    apiUrl.searchParams.set('action', 'cargoquery');
	    apiUrl.searchParams.set('format', 'json');
	
	    apiUrl.searchParams.set('tables', 'Performances');
	    apiUrl.searchParams.set('fields', 'perfID,event,date,type,context');
	    apiUrl.searchParams.set('where', 'song="' + page + '"');
	
	    return $.getJSON(apiUrl.toString()).then(data => {
	        if (data && data.cargoquery) {
	            return data.cargoquery.map(e => e.title);
	        }
	        return [];
	    });
	}

    // Redirect to preload editor
    function buildAndRedirect(perfBlock, videoBlock) {
        const url = mw.util.getUrl(page, {
            action: "edit",
            section: "new",
            preload: "Template:CargoAddVideoPreload",
            "preloadparams[]": [perfBlock, videoBlock]
        });
        window.location.href = url;
    }

    // Main driver
    function openMinimalPrompt() {

        queryPerformances().then(rows => {

            const sanitized = sanitizeForPerfID(page);
            const perfIds = rows.map(r => r.perfID);
            const suggestedLocal = nextLocalId(perfIds, sanitized);
            const suggestedPerfID = sanitized + "_" + suggestedLocal;

            const chooseExisting = confirm(
                "Select OK to attach video to an existing Performance.\n" +
                "Select Cancel to create a new Performance."
            );

            // ------------------------------------------------------------
            // EXISTING PERFORMANCE PATH (no new performance creation)
            // ------------------------------------------------------------
            if (chooseExisting) {

                if (rows.length === 0) {
                    alert("No existing performances found. A new performance must be created.");
                    return;
                }

                const list = rows.map((r, i) =>
                    (i + 1) + ". " + r.perfID + " — " + r.event + " (" + r.date + ")"
                ).join("\n");

                const index = prompt(
                    "Choose performance by number:\n\n" + list
                );
                const i = parseInt(index, 10) - 1;
                if (isNaN(i) || i < 0 || i >= rows.length)
                    return;

                const perfID = rows[i].perfID;

                // --- Video prompts ---
                const videoUrl = prompt("Video URL (mandatory):");
                if (!videoUrl) return;

                const videoDuration = prompt("Duration (full/short/fragment) optional:", "");
                const videoQuality  = prompt("Quality (best/good/acceptable/poor) optional:", "");
                const videoComment  = prompt("Comment (optional):", "");
                const videoRating   = prompt("Rating (optional integer):", "");

                // --- Video-only block ---
                const videoBlock =
`{{#cargo_store: _table=Videos
 |perfID=${perfID}
 |url=${videoUrl}
 |duration=${videoDuration || ""}
 |quality=${videoQuality || ""}
 |comment=${videoComment || ""}
 |rating=${videoRating || ""}
}}`;

                // Preload only the video block
                buildAndRedirect("", videoBlock);
                return;
            }

            // ------------------------------------------------------------
            // NEW PERFORMANCE PATH
            // ------------------------------------------------------------

            const event = prompt("Performance event (mandatory):");
            const date = prompt("Performance date (mandatory, YYYY…):");
            const type = prompt("Performance type (recording/track/music-video/live/...):");

            if (!event || !date || !type) return;

            // --- Video prompts ---
            const videoUrl = prompt("Video URL (mandatory):");
            if (!videoUrl) return;

            const videoDuration = prompt("Duration (full/short/fragment) optional:", "");
            const videoQuality  = prompt("Quality (best/good/acceptable/poor) optional:", "");
            const videoComment  = prompt("Comment (optional):", "");
            const videoRating   = prompt("Rating (optional integer):", "");

            // --- Performance block ---
            const perfBlock =
`{{#cargo_store: _table=Performances
 |song=${page}
 |event=${event}
 |context=
 |date=${date}
 |type=${type}
 |perfID=${suggestedPerfID}
 |page=${page}
}}`;

            // --- Video block ---
            const videoBlock =
`{{#cargo_store: _table=Videos
 |perfID=${suggestedPerfID}
 |url=${videoUrl}
 |duration=${videoDuration || ""}
 |quality=${videoQuality || ""}
 |comment=${videoComment || ""}
 |rating=${videoRating || ""}
}}`;

            buildAndRedirect(perfBlock, videoBlock);
        });
    }

    // Add portlet link
    function addButton() {
        mw.util.addPortletLink(
            "p-cactions",
            "#",
            "Add Video",
            "cargo-add-video",
            "Add Video / Performance"
        ).addEventListener("click", function (e) {
            e.preventDefault();
            openMinimalPrompt();
        });
    }

    if (mw.config.get('wgNamespaceNumber') === 0) {
        addButton();
    }

});