MediaWiki:DiscordModule/code.js

/* Name:  DiscordModule 1.0.51 * Author: Сибирский Смотритель (Siberian Specules) * Idea:  Your Own Waifu

/*global require */ require(['jquery', 'mw', 'wikia.ui.factory', 'BannerNotification', 'wikia.window'], function ($, mw, uiFactory, BannerNotification, window) { 'use strict'; var cfg = mw.config.get([ 'skin', 'wgPageName', 'wgUserLanguage', 'wgUserName', 'wgUserGroups' ]); if ( (!$('#WikiaRail').length && cfg.skin !== "wikia" && cfg.skin !== "oasis") && !$('.discord-container').length && cfg.wgPageName !== "MediaWiki:Custom-Discord-Module-Settings" ) {   return; }

// Translations function translate(text) { var i18n = { en: { description: "Discord is a free application for public discussions outside Fandom. " + "Get more in Wikipedia", online: "Online:", join: "Join", onlinelist: "Users online", instruction: "To get server ID you need to go this path (need administrator rights): " + "Server settings > Widget > Server ID " + "Also here you need to turn on widget and choose the channel to invite if you want users to be coming on your server.", descriptionForm: "Module description", supportsWikitext: "supports wikitext", placeholder: "Information about Discord by default", useSvg: "Use custom image (CSS change required)", flags: "Other parameters", showGuideline: "Do not show custom description", showForAnonym: "Do not show for anonyms", showServerName: "Do not show server name", railPosition: "Position below the rail", generateHTML: "Generate HTML", saveSettings: "Save", reset: "Reset", successChange: 'Successfully saved', errorChange: 'An error occurred' },       ru: { description: "Discord – бесплатное приложение для публичного общения вне Фэндома. " + "Подробнее в Википедии", online: "В сети:", join: "Войти", onlinelist: "Пользователи онлайн", instruction: "Чтобы получить ID сервера, нужно пройти: " + "Настройки сервера > Виджет > ID Сервера " + "Там же надо включить виджет и выбрать канал, если хотите, чтобы люди приходили на сервер.", descriptionForm: "Описание", supportsWikitext: "поддерживает викитекст", placeholder: "По умолчанию будут выведена информация о Дискорде", useSvg: "Использовать собственное изображение (требуются изменения CSS)", flags: "Другие параметры", showForAnonym: "Не показывать анонимам", showServerName: "Не показывать имя сервера", showGuideline: "Не показывать описание", railPosition: "Позиционировать снизу рельсы", generateHTML: "Сгенерировать HTML", saveSettings: "Сохранить", reset: "Сбросить", successChange: 'Изменения сохранены', errorChange: 'Ошибка сохранения' }   };    var lang = cfg.wgUserLanguage; var translateList = typeof i18n[lang] !== 'undefined' ? i18n[lang] : i18n.en; for (var k in translateList) { text = text.replace(new RegExp("\\(" + k + "\\)", "gi"), translateList[k] || i18n.en[k]); }   return text; } var defaultSettings = { id: '', customDescription: "", railPosition: "prepend", showGuideline: true, showForAnonym: true, showServerName: true, useSvg: true };

// Settings from MediaWiki function init(callback) { var settings = {}; $.ajax({       url: '/index.php',        type: 'GET',        data: {            action: "raw",            title: "MediaWiki:Custom-Discord-Module-Settings",        },        success: function(settings) {            if (typeof settings.missing === 'undefined')                settings = JSON.parse(settings);            else                settings = window.DiscordModuleSettings || {};            callback(settings);        }    }); }

// Discord Guild Data function getData(settings, container) { var id = typeof container.selector.data("id") !== 'undefined' ? container.selector.data("id") : settings.id; var discordJSON = "https://discordapp.com/api/servers/" + id + "/embed.json"; var request = new XMLHttpRequest; request.onreadystatechange = function { if (request.readyState == 4 && request.status == 200) { try { var data = JSON.parse(request.responseText); if (typeof data.name === undefined) container.showError("Configuration Error: wrong server ID"); buildModule(data, settings, container); } catch (e) { container.showError(e); }       } else if (request.readyState == 4) { container.showError("Configuration Error"); }   };    request.open("GET", discordJSON, true); request.send; }

// Generate block with guild info and join link function buildModule(data, settings, container) { settings = $.extend({}, defaultSettings, settings, container.getData); if (       typeof settings.showForAnonym !== "boolean" ||         typeof settings.showServerName !== "boolean" ||         typeof settings.showGuideline !== "boolean" ||         typeof settings.useSvg !== "boolean" ||         typeof settings.customDescription !== "string"    ) { return container.showError("Configuration Error: wrong type"); }   if (settings.showForAnonym && typeof cfg.wgUserName === 'undefined') return; function loadModule(description) { var image = !settings.useSvg ? ' ' :        '' + '' + '<path d="M189.5 20h-134C44.2 20 35 29.2 35 40.6v135.2c0 11.4 9.2 20.6 20.5 20.6h113.4l-5.3-18.5 12.8 11.9 12.1 11.2 21.5 19V40.6c0-11.4-9.2-20.6-20.5-20.6zm-38.6 130.6s-3.6-4.3-6.6-8.1c13.1-3.7 18.1-11.9 18.1-11.9-4.1 2.7-8 4.6-11.5 5.9-5 2.1-9.8 3.5-14.5 4.3-9.6 1.8-18.4 1.3-25.9-.1-5.7-1.1-10.6-2.7-14.7-4.3-2.3-.9-4.8-2-7.3-3.4-.3-.2-.6-.3-.9-.5-.2-.1-.3-.2-.4-.3-1.8-1-2.8-1.7-2.8-1.7s4.8 8 17.5 11.8c-3 3.8-6.7 8.3-6.7 8.3-22.1-.7-30.5-15.2-30.5-15.2 0-32.2 14.4-58.3 14.4-58.3 14.4-10.8 28.1-10.5 28.1-10.5l1 1.2c-18 5.2-26.3 13.1-26.3 13.1s2.2-1.2 5.9-2.9c10.7-4.7 19.2-6 22.7-6.3.6-.1 1.1-.2 1.7-.2 6.1-.8 13-1 20.2-.2 9.5 1.1 19.7 3.9 30.1 9.6 0 0-7.9-7.5-24.9-12.7l1.4-1.6s13.7-.3 28.1 10.5c0 0 14.4 26.1 14.4 58.3 0 0-8.5 14.5-30.6 15.2z"/>' + ' ';       var $module = $(' ' +            '' +                image +                 (settings.showServerName ? data.name : 'Discord') +            ' ' +            (description || '') +            ' ' +                (data.instant_invite ? '(join)' : '') +               '(online) ? ' +            ' ' +        ' '); $module.find('.discord-join').attr('onclick', "window.open('" + data.instant_invite + "','_blank')"); $module.find('.discord-counter').text(data.members.length); $module.html(translate( $module[0].innerHTML )); var $members = $(''); data.members.forEach(function (v) {           var $member = $('' + ' ' +                   ' ' +                ' ' +            '');            $member.append(v.username + (v.bot ? ' BOT ' : ''));            $member.find('.discord-avatar').addClass("discord-" + v.status);            $member.find('img').attr("src", v.avatar_url);            $members.append($member);        }); $module.find('.discord-online').click(function(e) {           e.preventDefault;            uiFactory.init(['modal']).then(function(uiModal) { uiModal.createComponent({                   type: 'default',                    vars: {                        id: 'discord-list-modal',                        title: translate('(onlinelist)'),                        content: $members.html,                        size: 'small'                    }                }, function(modal) {                    modal.$element.keydown(function(e) { if (e.which == 27) { e.preventDefault; modal.trigger("close"); }                   });                    modal.bind("reset", function(e) { e.preventDefault; modal.trigger("close"); });                   modal.show;                }); });       });        container.fill($module, settings.railPosition); }   if (settings.showGuideline) { var description = '' + (settings.customDescription || translate("(description)")) + ' ';       parseWikitext(description, loadModule); } else { loadModule(false); } }

// Settings form function visualSettings(settings) { var $form = $(translate(' ' + '' + 'ID: ' + '' + ' (instruction) ' + ' ' +       '' + ' (descriptionForm) ((supportsWikitext)) ' + '<textarea id="ds-description-input" name="customDescription" placeholder="(placeholder)"> ' + ' ' +       '<form id="ds-flags">' + ' (flags) ' + '<label class="ds-flag">' + '<input type="checkbox" name="useSvg"/>' + ' (useSvg) ' + ' ' +           '<label class="ds-flag">' + '<input type="checkbox" name="showForAnonym"/>' + ' (showForAnonym) ' + ' ' +           '<label class="ds-flag">' + '<input type="checkbox" name="showServerName"/>' + ' (showServerName) ' + ' ' +           '<label class="ds-flag">' + '<input type="checkbox" name="showGuideline"/>' + ' (showGuideline) ' + ' ' +       ' ' +        '<form id="ds-buttons">' + (cfg.wgUserGroups.indexOf('sysop') !== 0 ?            '<a class="wds-button wds-is-squished ds-save">(saveSettings)</a>' :             '') + '<a class="wds-is-secondary wds-button wds-is-squished ds-reset">(reset)</a>' + '<a class="wds-is-secondary wds-button wds-is-squished ds-html">(generateHTML)</a>' + ' ' +       '<textarea class="ds-generated" style="display: none;"> ' + ' '));   s2v(settings, $form); $form.find('.ds-save').click(function {        $.ajax({ url: '/api.php', type: 'POST', data: { action: "edit", title: "MediaWiki:Custom-Discord-Module-Settings", token: mw.user.tokens.get('editToken'), text: JSON.stringify(v2s($form)), summary: "Editing settings", recreate: true },           success: function { new BannerNotification(translate('(successChange)'), 'confirm').show; },           error: function(e) { new BannerNotification(translate('(errorChange)'), 'error').show; console.error(e); }       });    });    $form.find('.ds-reset').click(function {        s2v(settings, $form);    }); $form.find('.ds-html').click(function {        var data = v2s($form);        Object.keys(data).map(function(key) { data["data-" + key.replace(/([A-Z])/g, '-$1')] = data[key]; delete data[key]; });       $form.find('.ds-generated').val( $(' ').append(               $(' ').attr( data )            ).html ).show;   }); $('#mw-content-text').before($form); }

// Settings to visual function s2v(settings, selector) { selector.find('#ds-form-id').val( getAttr("id") ); selector.find('#ds-description-input').val( getAttr("customDescription") ); ["showForAnonym", "showGuideline", "useSvg", "showServerName"] .forEach(function(v) {       checkIf( !getAttr(v), v );    }); function getAttr(attr) { return settings[attr] || defaultSettings[attr]; }   function checkIf(condition, checkbox) { var $checkbox = selector.find('[name="' + checkbox + '"]'); if (condition) $checkbox.prop('checked', true); else $checkbox.prop('checked', false); } }

// Visual to settings function v2s(selector) { return _.object(       selector.find("#ds-id, #ds-description, #ds-flags")        .serializeArray        .map(function(v) { if (               v.value === "on" &&                ["showForAnonym", "showGuideline", "useSvg", "showServerName"]                .indexOf(v.name) != -1            ) { v.value = false; }           return [v.name, v.value]; })   ); }

// Container's object: rail section or block in content function Container(type, selector) { this.type = type; if (type == "box") { this.selector = $(selector).addClass("rail-module"); } else { var newSelector = $(' '); $(selector).prepend(newSelector); this.selector = newSelector; }   this.fill(this.preload); } Container.prototype.preload = $( ' ' +    '<svg xmlns="http://www.w3.org/2000/svg" class="wds-spinner wds-spinner__block" width="45" height="45" viewBox="0 0 45 45">' +        '<g transform="translate(22.5, 22.5)">' +		            '<circle class="wds-spinner__stroke" fill="none" stroke-linecap="round" stroke-width="5" stroke-dasharray="125.66370614359172" stroke-dashoffset="125.66370614359172" r="20"> ' +        '</g>' +    ' ' + ' '); Container.prototype.getData = function { if (this.type === "rail") return {}; return this.selector.data; }; Container.prototype.fill = function(content) { this.selector.html(content); }; Container.prototype.showError = function(text) { this.fill(' ' + text + ' ', 'prepend'); };

// Wikitext parser function parseWikitext(text, callback) { $.ajax({       url: '/api.php',        type: 'GET',        data: {            action: "parse",            contentmodel: "wikitext",            text: text,            format: 'json'        },        success: function(data) {            callback(data.parse.text['*']);        }    }); }

// Run init(function(settings) {   window.importArticle({ type: 'style', article: 'u:dev:MediaWiki:DiscordModule/style.css' });

if ( $('#WikiaRail').length ) { getData( settings, new Container('rail', '#WikiaRail') ); }   if ( $('.discord-container').length ) { $('.discord-container').each(function {           getData( settings, new Container('box', $(this)) );        }); }   if ( cfg.wgPageName === "MediaWiki:Custom-Discord-Module-Settings" ) { visualSettings(settings); } }); });