MediaWiki:DiscordCompact.js

From Support Wiki
Jump to navigation Jump to search

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)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/**
 * DiscordCompact.js
 * ----------------------
 * A very simple script to display a Discord widget.
 * Version 0.0.2
 * https://support.wiki.gg/wiki/DiscordCompact
 * ----------------------
 */

mw.hook('wikipage.content').add(function($content) {
	var widget = $content.find("#discord-compact-widget");

    // Bail out if we didn't find a widget.
    if (!widget.length) return;

	var id = widget.attr("data-id");
	
	// Ensure that the id is not blank.
	if (id === "") throw new Error("DiscordCompact has a blank server id!");
	// Ensure that the id consists only of numbers and is at least 17 characters long.
	if (!new RegExp("^[0-9]{17}[0-9]+$").test(id)) throw new Error("DiscordCompact has an invalid server id!");
	
	var apiBase = `https://discord.com/api/guilds/${id}`;
	// Get some information about the server, such as online member count and invite url.
	// This also tells us if the server exists or has widgets disabled, so we look out for that too.
	$.ajax(`${apiBase}/widget.json`).fail(function(req){
        if (!req.responseJSON) throw new Error(`DiscordCompact encountered an unknown error whilst fetching widget.json (status: ${req.status})`);
		switch (req.responseJSON.code) {
            case 10004:
                throw new Error("DiscordCompact has a valid server id, but no such server exists!");
            case 50004:
                throw new Error("DiscordCompact has a valid server id, but that server has widgets disabled!");
            default:
                throw new Error(`DiscordCompact encountered an unknown error whilst fetching widget.json (status: ${req.status}; code: ${req.responseJSON.code})`);
        }
	}).done(function(res){
		const inviteURL = res.instant_invite;

        // Warn if we can't get an invite URL.
        if (inviteURL == null) console.warn("DiscordCompact cannot get an invite URL; does this server have an invite channel set in Widget settings?");
        
        // Now get the widget image.
        $.ajax({url: `${apiBase}/widget.png?style=banner2`, xhrFields: {responseType: "blob"}}).fail(function(req){
            if (!req.responseJSON) throw new Error(`DiscordCompact encountered an unknown error whilst fetching widget.png! (status: ${req.status}`);
            throw new Error(`DiscordCompact encountered an unknown error whilst fetching widget.png! (status: ${req.status}; code: ${req.responseJSON.code})`);
        }).done(function(blob){
            // Convert the image data into base64. This prevents us having to make the client request it a second time.
            const imageReader = new FileReader();
            imageReader.readAsDataURL(blob);
            imageReader.onloadend = () => {
                const b64Data = imageReader.result;

                // Replace the widget with an <a> tag
                widget.replaceWith(function() {
                    return $("<a>", {
                        id: widget.attr("id"),
                        class: widget.attr("class"),
                        style: widget.attr("style"),
                        alt: "Discord server widget",
                        href: inviteURL
                    });
                });

                // We need to grab the widget again to update it.
                widget = $("#discord-compact-widget");

                // Setup the CSS so that the image is displayed.
                widget.css("display", "block");
                widget.css("max-height", "76px");
                widget.css("max-width", "320px");

                // Create the image.
                const widgetImage = document.createElement("img");
                widgetImage.src = b64Data;
                widgetImage.style.width = "100%";
                widgetImage.style.height = "100%";
                widgetImage.style.borderRadius = "5px";
                widget.append(widgetImage);

                // Prevent image dragging.
                widget.on("dragstart", function(e) { e.preventDefault(); });

                // We're done here.
                console.log("DiscordCompact loaded successfully!");
            }
        });
	});
});