MediaWiki:Gadget-armory-core.js

From [N8]
Revision as of 15:07, 18 August 2020 by Banri (talk | contribs) (Created page with "//<nowiki> 'use strict'; var queryDefaults = { slot: 'armor', tradeable: 'any', cbclass: 'any', restriction: 'surface', hiderecolour: true, tier_min: 100, tier_max: 50...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
//<nowiki>
'use strict';

var queryDefaults = {
	slot: 'armor',
	tradeable: 'any',
	cbclass: 'any',
	restriction: 'surface',
	hiderecolour: true,
	tier_min: 100,
	tier_max: 500,
	tier_min_enabled: true,
	tier_max_enabled: false,
	page: 0
},
queryMap = {
	slot: [ 'Armor', 'Shields',  'Weapons', 'Sensors', 'Engines', 'Utility' ],
	tradeable: [ 'any', 'yes', 'no' ],
	cbclass: [ 'any', 'melee', 'magic', 'ranged', 'hybrid' ],
	restriction: [ 'any', 'surface', 'dungeoneering', 'quest', 'minigame', 'limited', 'microtransaction', 'removed' ],
	augmented: [ 'any', 'able', 'yes' ],
	hiderecolour: [ false, true ],
},
currentQuery,
api = new mw.Api(),
loadingGif;

var form, fieldset, slotDropdown, membersSelect, tradeableSelect, classSelect, restrictionSelect, augmentedSelect, recolourCheck, tierMinCheck, tierMaxCheck, tierMinSelect, tierMaxSelect, submitButton, resetButton, toggleAdvButton, copyPermalinkButton, pageButtons, pageFirstButton, pagePrevButton, pageNextButton, resultsLabel;

var $messages, $results, $selector;

var offset=0, limit=500, currentPage=0, maxResThisPage=500, morePages=false;


function makeShortLink(q) {
	var link = new mw.Uri(), query = [];
	query.push('s');
	query.push(Math.max(0,queryMap.slot.indexOf(q.slot)));
	query.push('c');
	query.push(Math.max(0,queryMap.cbclass.indexOf(q.cbclass)));
	query.push('m');
	query.push(Math.max(0,queryMap.members.indexOf(q.members)));
	query.push('t');
	query.push(Math.max(0,queryMap.tradeable.indexOf(q.tradeable)));
	query.push('r');
	query.push(Math.max(0,queryMap.restriction.indexOf(q.restriction)));
	//query.push('a');
	//query.push(Math.max(0,queryMap.augmented.indexOf(q.augmented)));
	query.push('o');
	query.push(Math.max(0,queryMap.hiderecolour.indexOf(q.hiderecolour)));
	if (q.tier_min_enabled) {
		query.push('l');
		query.push(q.tier_min);
	}
	if (q.tier_max_enabled) {
		query.push('u');
		query.push(q.tier_max);
	}
	link.query = { l: query.join('') };
	return link.toString();
}

function makeForm(params) {
	
	// dropdown for slot
	slotDropdown = new OO.ui.DropdownInputWidget({
		options: [
			{ data: 'armor' , label: 'Armor' },
			{ data: 'shields' , label: 'Shields' },
			{ data: 'weapons' , label: 'Weapons' },
			{ data: 'sensors' , label: 'Sensors' },
			{ data: 'engines' , label: 'Engines' },
			{ data: 'utility' , label: 'Utility' },
		],
		value: params.slot,
		align: 'left'
	});
	
	//tradeable
	
	tradeableSelect = new OO.ui.ButtonSelectWidget({
		items: [
			new OO.ui.ButtonOptionWidget({ data: 'any', label: 'Any', title: 'No tradeable restriction' }),
			new OO.ui.ButtonOptionWidget({ data: 'yes', label: 'Tradeable' }),
			new OO.ui.ButtonOptionWidget({ data: 'no', label: 'Untradeable' }),
			],
			align: 'left'
	});
	tradeableSelect.selectItemByData(params.tradeable);
	
	
	//class
	classSelect = new OO.ui.ButtonSelectWidget({
		items: [
			new OO.ui.ButtonOptionWidget({ data: 'any', label: 'Any', title: 'Any class' }),
			new OO.ui.ButtonOptionWidget({ data: 'melee', label: 'Melee' }),
			new OO.ui.ButtonOptionWidget({ data: 'magic', label: 'Magic' }),
			new OO.ui.ButtonOptionWidget({ data: 'ranged', label: 'Ranged' }),
			new OO.ui.ButtonOptionWidget({ data: 'hybrid', label: 'Hybrid', title: 'Hybrid and all-class' }),
		],
		align: 'left'
	});
	classSelect.selectItemByData(params.cbclass);
	
	//TODO surface
	//restriction
	restrictionSelect = new OO.ui.ButtonSelectWidget({
		items: [
			new OO.ui.ButtonOptionWidget({ data: 'any', label: 'Any', title: 'Everything' }),
			new OO.ui.ButtonOptionWidget({ data: 'surface', label: 'Unrestricted', title: 'Items that are not restricted' }),
			new OO.ui.ButtonOptionWidget({ data: 'dungeoneering', label: 'Dungeoneering', title: 'Items only available in Daemonheim' }),
			new OO.ui.ButtonOptionWidget({ data: 'quest', label: 'Quest', title: 'Items only available during quests' }),
			new OO.ui.ButtonOptionWidget({ data: 'minigame', label: 'Minigame', title: 'Items only available during minigames' }),
			new OO.ui.ButtonOptionWidget({ data: 'limited', label: 'Limited', title: 'Items only available for a limited amount of time' }),
			new OO.ui.ButtonOptionWidget({ data: 'microtransaction', label: 'MTX', title: 'Items only (reasonably) obtainable via Treasure Hunter, Squeal of Fortune, or Solomon\' General Store' }),
			]
	});
	restrictionSelect.selectItemByData(params.restriction);

	recolourCheck = new OO.ui.CheckboxInputWidget({
		selected: params.hiderecolour
	});
	//Augmentation
	/*
	augmentedSelect = new OO.ui.ButtonSelectWidget({
		items: [
			new OO.ui.ButtonOptionWidget({ data: 'any', label: 'Any' }),
			new OO.ui.ButtonOptionWidget({ data: 'able', label: 'Augmentable' }),
			new OO.ui.ButtonOptionWidget({ data: 'yes', label: 'Augmented' }),
			]
	});
	augmentedSelect.selectItemByData(params.augmented);*/
	
	tierMinCheck = new OO.ui.CheckboxInputWidget({
		selected: params.tier_min_enabled
	});
	tierMaxCheck = new OO.ui.CheckboxInputWidget({
		selected: params.tier_max_enabled
	});
	
	tierMinCheck.on('change', function(){
		tierMinSelect.setDisabled(!tierMinCheck.isSelected());
	});
	tierMaxCheck.on('change', function(){
		tierMaxSelect.setDisabled(!tierMaxCheck.isSelected());
	});
	
	//tierMin
	tierMinSelect = new OO.ui.NumberInputWidget({
		min: 100,
		max: 500,
		value: params.tier_min,
		align: 'left',
		disabled: !params.tier_min_enabled
	});
	//tierMax
	tierMaxSelect = new OO.ui.NumberInputWidget({
		min: 100,
		max: 500,
		value: params.tier_max,
		align: 'left',
		disabled: !params.tier_max_enabled
	});
	
	//submit
	submitButton = new OO.ui.ButtonInputWidget({
		label: 'Search',
		flags: [ 'primary', 'progressive' ],
		align: 'left',
		icon: 'search'
	});
	
	submitButton.on('click', submitForm);
	
	//reset
	resetButton = new OO.ui.ButtonInputWidget({
		label: 'Reset form',
		title: 'Reset the form to default values',
		align: 'left',
		icon: 'clear'
	});
	
	resetButton.on('click', function(){
		//don't reset slot
		tradeableSelect.selectItemByData(queryDefaults.tradeable);
		membersSelect.selectItemByData(queryDefaults.members);
		classSelect.selectItemByData(queryDefaults.cbclass);
		restrictionSelect.selectItemByData(queryDefaults.restriction);
		//augmentedSelect.selectItemByData(queryDefaults.augmented);
		tierMinSelect.setValue(queryDefaults.tier_min);
		tierMaxSelect.setValue(queryDefaults.tier_max);
		tierMinCheck.setValue(queryDefaults.tier_min_enabled);
		tierMaxCheck.setValue(queryDefaults.tier_max_enabled);
	});
	
	//copy link
	copyPermalinkButton = new OO.ui.ButtonInputWidget({
		label: 'Copy short link',
		title: 'Copy the a permalink to the current results set to the clipboard. This is shortened link for easy sharing.',
		align: 'left',
		icon: 'link'
	});
	
	//clipboard api pls arrive sooner
	copyPermalinkButton.on('click', function(){
		var txt = document.createElement('textarea'), $txt = $(txt);
		$txt.text(makeShortLink(currentQuery)).css({
			position: 'fixed',
			top: 0,
			left: 0,
			width: '2em',
			heigh: '2em',
			padding: 0,
			border: 'none',
			outline: 'none',
			boxShadow: 'none',
			background: 'transparent'
		}).appendTo('body');
		txt.select();
		try {
			document.execCommand('copy');
			mw.notify('Copied short link to the clipboard', {tag: 'equipmentTableCopyLink'});
		} catch (err) {}
		$txt.remove();
	});
	
	//pagination
    pageFirstButton = new OO.ui.ButtonWidget({
        label: 'First page',
        align: 'left',
        icon: 'first',
        data: -10000,
    });
    pagePrevButton = new OO.ui.ButtonWidget({
        label: 'Previous',
        align: 'left',
        icon: 'previous',
        data: -1,
    });
    pageNextButton = new OO.ui.ButtonWidget({
        label: 'Next',
        align: 'left',
        icon: 'next',
        data: 1,
    });
    
	var onClickPages = function (button) {
		currentQuery.page = Math.max(0, currentQuery.page + button.getData());
		doSearch(currentQuery);
	};
	pageFirstButton.on('click', function(){ onClickPages(pageFirstButton)});
	pagePrevButton.on('click', function(){ onClickPages(pagePrevButton)});
	pageNextButton.on('click', function(){ onClickPages(pageNextButton)});
    
    pageButtons = new OO.ui.ButtonGroupWidget({
        items: [ pageFirstButton, pagePrevButton, pageNextButton ],
        align: 'left'
    });
    
    resultsLabel = new OO.ui.LabelWidget({
    	label: '',
    });
    
    resultsLabel.toggle(false);
    pageFirstButton.toggle(false);
    pagePrevButton.toggle(false);
    pageNextButton.toggle(false);
	
	//fieldset
	fieldset = new OO.ui.FieldsetLayout({
		label: 'Armoury search',
		id: 'armouryFilterSelector'
	});
	
	var buttons = [ resetButton, copyPermalinkButton ];
	fieldset.addItems([
		new OO.ui.FieldLayout(slotDropdown, { label: 'Slot', align: 'left' }),
		new OO.ui.FieldLayout(classSelect, { label: 'Class', align: 'left' }),
		new OO.ui.FieldLayout(membersSelect, { label: 'Membership', align: 'left' }),
		new OO.ui.FieldLayout(tradeableSelect, { label: 'Tradeability', align: 'left' }),
		new OO.ui.FieldLayout(restrictionSelect, { label: 'Restriction', align: 'left' }),
		//new OO.ui.FieldLayout(augmentedSelect, { label: 'Augmentation', align: 'left' }),
		new OO.ui.FieldLayout(recolourCheck, { label: 'Hide recolours and dyes?', align: 'left' }),
		new OO.ui.LabelWidget({label: 'Tier filters', classes: ['armoury-tier-label']}),
		new OO.ui.HorizontalLayout({
			items: [
				new OO.ui.FieldLayout(tierMinCheck, { label: 'Enable minimum tier filter', align: 'inline' }),
				new OO.ui.FieldLayout(tierMinSelect, { label: 'Minimum tier', align: 'top' })
			]
		}),
		new OO.ui.HorizontalLayout({
			items: [
				new OO.ui.FieldLayout(tierMaxCheck, { label: 'Enable maximum tier filter', align: 'inline' }),
				new OO.ui.FieldLayout(tierMaxSelect, { label: 'Maximum tier', align: 'top' })
			]
		}),
		new OO.ui.FieldLayout(submitButton),
		new OO.ui.FieldLayout(new OO.ui.ButtonGroupWidget({ items: buttons })),
		new OO.ui.FieldLayout(resultsLabel),
			new OO.ui.FieldLayout(pageButtons)
	]);
    
}

function submitForm() {
	var values = {
		page: 0
	}, val;
	val = slotDropdown.getValue();
	if (val !== null) {
		values.slot = val;
	}
	
	val = classSelect.findSelectedItem();
	if (val !== null) {
		values.cbclass = val.getData();
	}
	
	val = membersSelect.findSelectedItem();
	if (val !== null) {
		values.members = val.getData();
	}
	
	val = tradeableSelect.findSelectedItem();
	if (val !== null) {
		values.tradeable = val.getData();
	}
	
	val = restrictionSelect.findSelectedItem();
	if (val !== null) {
		values.restriction = val.getData();
	}
	/*
	val = augmentedSelect.findSelectedItem();
	if (val !== null) {
		values.augmented = val.getData();
	}*/
	values.hiderecolour = recolourCheck.isSelected();
	
	values.tier_min_enabled = tierMinCheck.isSelected();
	values.tier_max_enabled = tierMinCheck.isSelected();
	values.tier_min = tierMinSelect.getNumericValue();
	values.tier_max = tierMaxSelect.getNumericValue();
	
	doSearch(values);
}

function parseShortLink(l) {
	var retest = /^([scmtroalu]\d{1,3})+$/i;
	if (!retest.test(l)) {
		return null;
	}
	var query = {}, regex = /([scomtralu])(\d{1,3})/ig, res;
	
	function assignTo(p, n) {
		var val = queryMap[p][n];
		if (val === undefined || val === null) {
			val = queryDefaults[p];
		}
		query[p] = val;
	}
	
	while ((res = regex.exec(l)) !== null) {
		var letter = res[1].toLowerCase(), number = parseInt(res[2], 10);
		if (isNaN(number)) {
			continue;
		}
		switch (letter) {
			case 's': assignTo('slot', number); break;
			case 'c': assignTo('cbclass', number); break;
			case 'm': assignTo('members', number); break;
			case 't': assignTo('tradeable', number); break;
			case 'r': assignTo('restriction', number); break;
			//case 'a': assignTo('augmented', number); break;
			case 'o':
				query.hiderecolour = (number == 1);
				break;
			case 'l':
				query.tier_min = number;
				query.tier_min_enabled = true;
				break;
			case 'u':
				query.tier_max = number;
				query.tier_max_enabled = true;
				break;
		}
	}
	if (query.slot === undefined || query.slot === null) query.slot = queryMap.slot[0];
	return $.extend({}, queryDefaults, query);
}

function doSearch(params) {
	var tierMin = -1, tierMax = 1000;
	if (params.tier_min_enabled) {
		tierMin = params.tier_min;
	}
	if (params.tier_max_enabled) {
		tierMax = params.tier_max;
	}
	var template = [
		'{{Armoury',
		'|slot='+params.slot,
		'|cbclass='+params.cbclass,
		'|members='+params.members,
		'|tradeable='+params.tradeable,
		'|restriction='+params.restriction,
		//'|augmented='+params.augmented,
		'|hiderecolour='+params.hiderecolour,
		'|tier_min='+tierMin,
		'|tier_max='+tierMax,
		'|enable_tier_min='+params.tier_min_enabled,
		'|enable_tier_max='+params.tier_max_enabled,
		'|page='+params.page,
		'}}'
	];
	
	console.log(template.join('\n'));
	
	submitButton.setDisabled(true);
    pageFirstButton.setDisabled(true);
    pagePrevButton.setDisabled(true);
    pageNextButton.setDisabled(true);
    
    if (Math.floor(Math.random()*50) === 0) {
    	var msg = '🦀';
    	switch (Math.floor(Math.random()*5)) {
    		case 0:
    			msg = 'The best-in-slot gear is crab helm, crab claw, and rock-shell armour.'; break;
    		case 1:
    			msg = 'I\'m searching all of the items by claw, just for you.'; break;
    		case 2:
    			msg = 'Do you like this search? Hit me up with some feedback.'; break;
    		case 3:
    			msg = 'You can enable me on every page in preferences, if you have an account :)'; break;
    		case 4:
    			msg = 'Hey how you doin\'?'; break;
    	}
        $messages.append(
        	$('<strong>').text('Loading...'),
        	$('<br />'),
        	$('<div style="color: black; z-index: 999999999;" id="crob"><div style="background-color: #FFFDCC;width: 175px;border: 1px solid black;border-radius: 7px;" id="crob-speech"><div id="crob-speech-text" style="margin: 7px 10px;font-family: Arial;font-size: 13px;">'+msg+'</div></div><div style="width: 0; position: relative; bottom: 3px; left: 110px; border-top: 15px solid #FFFDCC; border-left: 0 solid transparent; border-right: 10px solid transparent; filter: drop-shadow(-1px 1px 0 #000) drop-shadow(0 1px 0 #000);" id="crob-speech-arrow"></div><div id="crob-img"></div></div>')
        );
    
    } else {
        $messages.append(
        	$('<strong>').text('Loading...'),
        	$('<br />'),
        	loadingGif
        );
    }
    
    currentQuery = params;
	api.get({
		action: 'parse',
		title: mw.config.get('wgPageName'),
		prop: 'text',
		text: template.join('\n'),
		maxage: 3600,
		smaxage: 3600
	}).done(displayResults);
}

function displayResults(data){
	$results.empty().append($(data.parse.text['*']));
	var info = {
		offset: 0,
		count: 0,
		limit: 0,
		page: 0
	},
	table = $results.find('table.armoury');
	
	resultsLabel.setLabel('');
	
	if (!$('.no-results-found').length && table.length) {
		info = {
    		offset: parseInt(table.attr('data-offset'), 10),
    		count: parseInt(table.attr('data-count'), 10),
    		page: parseInt(table.attr('data-page'), 10),
    		limit: parseInt(table.attr('data-limit'), 10)
    	};
		resultsLabel.toggle(true).setLabel(new OO.ui.HtmlSnippet('<strong>Showing pages '+(info.offset+1)+' – '+(info.offset+info.count)+'</strong> (may be more or less rows)'));
		if (mw.config.get('skin') !== 'minerva') {
			mw.loader.using('jquery.tablesorter', function(){
				$results.find('table.armoury.sortable').tablesorter();
			});
		}
	}
    pageFirstButton.toggle(true).setDisabled(info.page < 1);
    pagePrevButton.toggle(true).setDisabled(info.page < 1).setLabel('Previous '+info.limit);
    pageNextButton.toggle(true).setDisabled(info.count < info.limit).setLabel('Next '+info.limit);
	
	submitButton.setDisabled(false);
	$messages.empty();
}

function init() {
	var uri = new mw.Uri();
	var search = false, parsed;
	loadingGif = $('#armourySelector #armouryLoadingGif img').clone();
	if (typeof(uri.query.l) === 'string') {
		parsed = parseShortLink(uri.query.l);
		makeForm(parsed);
		search = true;
	} else {
    	makeForm(queryDefaults);
	}
    $selector = $('#armourySelector');
    $messages = $('<div id="armouryMessages">');
    $results = $('<div id="armouryResults">');
    $selector.empty().append(fieldset.$element).after($results).after($messages);
    if (search) {
    	doSearch(parsed);
    }
}

$(init);

// </nowiki>