MediaWiki:Gadget-eventslist.js: Difference between revisions

Created page with "//<nowiki> * * Interface for events * * @version 1.1 * @author JaydenKieran * @author Elessar2 * @author ThePsionic *: /*global jQuery, mediaWiki, mw, gswiki, rs..."
 
No edit summary
Line 49: Line 49:
{ name:'Wilderness Warbands', id:'wildwar', link:'/w/Wilderness_Warbands', length:10, repeat:(60 * 7), offset:(60 * 2), from:'isoWeek', img:'/images/5/57/Wilderness_Warbands_emblem.png' },
{ name:'Wilderness Warbands', id:'wildwar', link:'/w/Wilderness_Warbands', length:10, repeat:(60 * 7), offset:(60 * 2), from:'isoWeek', img:'/images/5/57/Wilderness_Warbands_emblem.png' },
];
];
 
var self = {
// VoS Locations
var voslocs = { 'Amlodd':['WNW','West-north-west'], 'Crwys':['ENE','East-north-east'], 'Cadarn':['ESE','East-south-east'], 'Hefin':['NNW','North-north-west'],
'Iorwerth':['SSW','South-south-west'], 'Ithell':['WSW','West-south-west'], 'Meilyr':['NNE','North-north-east'], 'Trahaearn':['SSE','South-south-east'] };
// Spotlight lists
var dd_spotlights = ['Shooting Star', 'Penguin Hide and Seek', 'Circus', 'Evil Tree'],
mg_spotlights = ['Pest Control', 'Soul Wars', 'Fist of Guthix', 'Barbarian Assault', 'Conquest', 'Fishing Trawler', 'The Great Orb Project', 'Flash Powder Factory', 'Castle Wars', 'Stealing Creation', 'Cabbage Facepunch Bonanza', 'Heist', 'Soul Wars', 'Barbarian Assault',
'Conquest', 'Fist of Guthix', 'Castle Wars', 'Pest Control', 'Soul Wars', 'Fishing Trawler', 'The Great Orb Project', 'Flash Powder Factory', 'Stealing Creation', 'Cabbage Facepunch Bonanza', 'Heist', 'Trouble Brewing', 'Castle Wars'],
ed_spotlights = ['Temple of Aminishi', 'Dragonkin Laboratory', 'The Shadow Reef'];
var self = {
// Settings
// Settings
settings: {
settings: {
Line 294: Line 304:
} );
} );
},
},
 
/**
/**
* Loads events team events, travelling merchant stock
* @return {Promise}
*/
loadEvents: function ( force ) {
mw.log('Loading events, travelling merchant stock');
if ( moment().isBefore( moment(self.settings.dcache).utc().add(1, 'days').startOf('day') ) && !force ) {
mw.log('Less than a day since last lookup');
et_events = self.settings.cache.events;
merchstock = {
tod: self.settings.cache.tms,
tmr: self.settings.cache.tmsTom
};
return Promise.resolve();
}
 
// ET events
var etapi = api.get({
action: 'ask',
query: '[[RuneScape:Events Team]]|?Events JSON',
maxage: '7200',
smaxage: '7200'
}).then( function (ret) {
mw.log('Events team api return:');
mw.log(ret);
if (ret.query.results && ret.query.results['RuneScape:Events Team'].printouts['Events JSON']) {
ret.query.results['RuneScape:Events Team'].printouts['Events JSON'].forEach( function (ev) {
ev = JSON.parse(ev);
et_events.push( { name:mw.html.escape(ev.name), date:ev.time, length:Number(ev.length) } );
});
} else {
mw.log('No events team events');
}
self.saveSetting('cache.events', et_events);
}, function (err) {
console.warn('Error getting Events team events');
throw err;
});
 
// Resolve/reject all
return Promise.all([ etapi, tmsapi, tmsTomapi ]).then( function () {
// Success, resolve promise
self.saveSetting('dcache', moment().format());
}, function (err) {
// Error, reject promise
throw err;
});
},
 
/**
* Saves a setting to localStorage
* Saves a setting to localStorage
* @param  {string} name Name (key) of setting to save
* @param  {string} name Name (key) of setting to save
Line 643: Line 604:
settingsForm.eventsNumLay.toggle(false);
settingsForm.eventsNumLay.toggle(false);
}
}
// Show spotlights (combined)
settingsForm.spots = new OO.ui.ToggleSwitchWidget({
title: 'Show D&D, Minigame and ED spotlights',
value: self.settings.spots
});
settingsForm.spotsLay = new OO.ui.FieldLayout(settingsForm.spots, {
label: 'Spotlights',
help: 'Show Minigame Spotlight, Featured D&D and Elite Dungeon Spotlight'
});
settingsForm.spots.on('change', function (val) {
self.saveSetting('mg_spotlight', val);
self.saveSetting('dd_spotlight', val);
self.saveSetting('ed_spotlight', val);
});
// Show minigame spotlight
// Show minigame spotlight
settingsForm.mg = new OO.ui.ToggleSwitchWidget({
settingsForm.mg = new OO.ui.ToggleSwitchWidget({
Line 650: Line 627:
settingsForm.mgLay = new OO.ui.FieldLayout(settingsForm.mg, { label: 'Minigame Spotlight' });
settingsForm.mgLay = new OO.ui.FieldLayout(settingsForm.mg, { label: 'Minigame Spotlight' });
settingsForm.mg.on('change', self.saveSetting, ['mg_spotlight']);
settingsForm.mg.on('change', self.saveSetting, ['mg_spotlight']);
// Show featured D&D spotlight
settingsForm.dd = new OO.ui.ToggleSwitchWidget({
title: 'Show featured D&D',
value: self.settings.dd_spotlight
});
settingsForm.ddLay = new OO.ui.FieldLayout(settingsForm.dd, { label: 'Featured D&D' });
settingsForm.dd.on('change', self.saveSetting, ['dd_spotlight']);
// Show elite dungeon spotlight
// Show elite dungeon spotlight
settingsForm.ed = new OO.ui.ToggleSwitchWidget({
settingsForm.ed = new OO.ui.ToggleSwitchWidget({
Line 676: Line 662:
settingsForm.pvmLay = new OO.ui.FieldLayout(settingsForm.pvm, { label: 'PvM Rotations' });
settingsForm.pvmLay = new OO.ui.FieldLayout(settingsForm.pvm, { label: 'PvM Rotations' });
settingsForm.pvm.on('change', self.saveSetting, ['pvm']);
settingsForm.pvm.on('change', self.saveSetting, ['pvm']);
 
// Settings form footer
// Force update events and travelling merchant stock
settingsForm.fupdate = new OO.ui.ButtonWidget({
label: 'Refresh',
icon: 'reload',
title: 'Force refresh of travelling merchant stock and events'
});
settingsForm.fupdateLay = new OO.ui.FieldLayout(settingsForm.fupdate, {
label: 'Force TMS Update',
help: 'Force the travelling merchant stock and events team events to update regardless of the last update time.'
});
settingsForm.fupdate.on('click', function () {
self.loadEvents(true).then(self.updateAll(), self.updateAll());
});
 
settingsForm.form =  new OO.ui.FieldsetLayout({ classes:'settings-form' });
settingsForm.form.addItems([
settingsForm.sortLay,
settingsForm.notifsLay,
settingsForm.ravenLay,
settingsForm.eventsLay,
settingsForm.eventsNumLay,
settingsForm.tmsLay,
settingsForm.pofLay,
settingsForm.spotsLay,
settingsForm.nextLay,
settingsForm.pvmLay,
settingsForm.fupdateLay
]);
 
// Settings form footer
settingsForm.$footer = $('<div>')
settingsForm.$footer = $('<div>')
.addClass('footer')
.addClass('footer')
Line 815: Line 830:
label: 'Monthly Reset'
label: 'Monthly Reset'
});
});
 
// Events team events
// All Voice of Seren
notifsForm.etevents = new OO.ui.ToggleSwitchWidget({
notifsForm.vos = new OO.ui.DropdownInputWidget({
title: 'Events team notifications',
options: [
value: self.settings.notiftype.etevents
{ data:'None', label:'None' },
{ data:'All', label:'All' },
{ data:'Some', label:'Some' }
],
title: 'Receive notifications for Voice of Seren',
});
});
notifsForm.etevents.on('change', self.saveNotif, ['etevents']);
notifsForm.vos.setValue(self.settings.notiftype.vos);
notifsForm.eteventsLay = new OO.ui.FieldLayout(notifsForm.etevents, {
notifsForm.vosLay = new OO.ui.FieldLayout(notifsForm.vos, {
label: 'Events Team',
label: 'Voice of Seren',
help: 'Receive notifications for RuneScape Wiki events team events'
help: 'Receive notifications for Voice of Seren'
});
});
var togglevos = function (val) {
self.saveNotif('vos', val);


// PVM
if (val == 'Some') {
notifsForm.vorago = new OO.ui.ToggleSwitchWidget({
notifsForm.vosselLay.toggle(true);
title: 'Vorago attack notifications',
self.saveNotif('allvos', false);
value: self.settings.notiftype.vorago
} else if (val == 'All') {
notifsForm.vosselLay.toggle(false);
self.saveNotif('allvos', true);
} else {
notifsForm.vosselLay.toggle(false);
self.saveNotif('allvos', false);
}
};
notifsForm.vos.on('change', togglevos);
// Individual VoS
notifsForm.vossel = new OO.ui.CheckboxMultiselectWidget({ classes: ['notifs-group'] });
for (var clan in voslocs) {
notifsForm[clan] = new OO.ui.CheckboxMultioptionWidget({
label: clan,
data: clan,
selected: self.settings.notiftype['vos' + clan]
});
 
notifsForm[clan].on('change', self.saveNotif, ['vos' + clan]);
 
notifsForm.vossel.addItems([ notifsForm[clan] ]);
}
notifsForm.vosselLay = new OO.ui.FieldLayout(notifsForm.vossel, {
align: 'top',
label: 'Individual Clan Districts',
help: 'Choose the Prifddinas clan districts you wish to be notified about when a Voice of Seren is active.'
});
});
notifsForm.vorago.on('change', self.saveNotif, ['vorago']);
if (self.settings.notiftype.vos != 'Some') {
notifsForm.voragoLay = new OO.ui.FieldLayout(notifsForm.vorago, {
notifsForm.vosselLay.toggle(false);
label: 'Vorago',
}
help: 'Receive notifications about current Vorago attack'
 
// Events team events
notifsForm.etevents = new OO.ui.ToggleSwitchWidget({
title: 'Events team notifications',
value: self.settings.notiftype.etevents
});
});
notifsForm.araxxor = new OO.ui.ToggleSwitchWidget({
notifsForm.etevents.on('change', self.saveNotif, ['etevents']);
title: 'Araxxor path notifications',
notifsForm.eteventsLay = new OO.ui.FieldLayout(notifsForm.etevents, {
value: self.settings.notiftype.araxxor
label: 'Events Team',
});
help: 'Receive notifications for RuneScape Wiki events team events'
notifsForm.araxxor.on('change', self.saveNotif, ['araxxor']);
notifsForm.araxxorLay = new OO.ui.FieldLayout(notifsForm.araxxor, {
label: 'Araxxor',
help: 'Receive notifications about open Araxxor paths'
});
notifsForm.rots = new OO.ui.ToggleSwitchWidget({
title: 'Rise of the Six notifications',
value: self.settings.notiftype.rots
});
notifsForm.rots.on('change', self.saveNotif, ['rots']);
notifsForm.rotsLay = new OO.ui.FieldLayout(notifsForm.rots, {
label: 'RotS',
title: 'Rise of the Six',
help: 'Receive notifications for Rise of the Six rotations'
});
});


// Spotlights
// All PoF Resets
notifsForm.mg_spotlight = new OO.ui.ToggleSwitchWidget({
notifsForm.pof = new OO.ui.DropdownInputWidget({
title: 'Minigame spotlight notifications',
options: [
value: self.settings.notiftype.mg_spotlight
{ data:'None', label:'None' },
{ data:'All', label:'All' },
{ data:'Some', label:'Some' }
],
title: 'Receive notifications for player-owned farm resets',
});
});
notifsForm.mg_spotlight.on('change', self.saveNotif, ['mg_spotlight']);
notifsForm.pof.setValue(self.settings.notiftype.pof);
notifsForm.mg_spotlightLay = new OO.ui.FieldLayout(notifsForm.mg_spotlight, {
notifsForm.pofLay = new OO.ui.FieldLayout(notifsForm.pof, {
label: 'Minigame Spotlight',
label: 'Player-owned Farm',
help: 'Receive notifications for current Minigame Spotlight'
help: 'Receive notifications for player-owned farm resets'
});
});
notifsForm.ed_spotlight = new OO.ui.ToggleSwitchWidget({
var togglepof = function (val) {
title: 'Elite dungeon spotlight notifications',
self.saveNotif('pof', val);
value: self.settings.notiftype.ed_spotlight
 
if (val == 'Some') {
notifsForm.pofselLay.toggle(true);
self.saveNotif('allpof', false);
} else if (val == 'All') {
notifsForm.pofselLay.toggle(false);
self.saveNotif('allpof', true);
} else {
notifsForm.pofselLay.toggle(false);
self.saveNotif('allpof', false);
}
};
notifsForm.pof.on('change', togglepof);
// Individual PoF resets
notifsForm.pofsel = new OO.ui.CheckboxMultiselectWidget({ classes: ['notifs-group'] });
pofresets.forEach( function (res) {
notifsForm[res] = new OO.ui.CheckboxMultioptionWidget({
label: res,
data: res,
selected: self.settings.notiftype['pof' + res]
});
 
notifsForm[res].on('change', self.saveNotif, ['pof' + res]);
 
notifsForm.pofsel.addItems([ notifsForm[res] ]);
});
});
notifsForm.ed_spotlight.on('change', self.saveNotif, ['ed_spotlight']);
notifsForm.pofselLay = new OO.ui.FieldLayout(notifsForm.pofsel, {
notifsForm.ed_spotlightLay = new OO.ui.FieldLayout(notifsForm.ed_spotlight, {
align: 'top',
label: 'Elite Dungeon Spotlight',
label: 'Individual PoF resets',
help: 'Receive notifications for current Elite dungeon spotlight'
help: 'Choose the player-owned farm resets you wish to be notified about'
});
});
notifsForm.dd_spotlight = new OO.ui.ToggleSwitchWidget({
if (self.settings.notiftype.pof != 'Some') {
title: 'Distraction and diversion of the week notifications',
notifsForm.vosselLay.toggle(false);
value: self.settings.notiftype.dd_spotlight
}
 
// PVM
notifsForm.vorago = new OO.ui.ToggleSwitchWidget({
title: 'Vorago attack notifications',
value: self.settings.notiftype.vorago
});
});
notifsForm.dd_spotlight.on('change', self.saveNotif, ['dd_spotlight']);
notifsForm.vorago.on('change', self.saveNotif, ['vorago']);
notifsForm.dd_spotlightLay = new OO.ui.FieldLayout(notifsForm.dd_spotlight, {
notifsForm.voragoLay = new OO.ui.FieldLayout(notifsForm.vorago, {
label: 'Distraction & Diversions',
label: 'Vorago',
help: 'Receive notifications for Distraction and Diversion of the week'
help: 'Receive notifications about current Vorago attack'
});
});
 
notifsForm.form = new OO.ui.FieldsetLayout({ classes:'notifs-form' });
// Spotlights
notifsForm.form.addItems([
notifsForm.mg_spotlight = new OO.ui.ToggleSwitchWidget({
notifsForm.browsnotifLay,
title: 'Minigame spotlight notifications',
notifsForm.dailiesLay,
value: self.settings.notiftype.mg_spotlight
notifsForm.dailiesselLay,
});
notifsForm.ravenLay,
notifsForm.mg_spotlight.on('change', self.saveNotif, ['mg_spotlight']);
notifsForm.dresetLay,
notifsForm.mg_spotlightLay = new OO.ui.FieldLayout(notifsForm.mg_spotlight, {
notifsForm.wresetLay,
label: 'Minigame Spotlight',
notifsForm.mresetLay,
help: 'Receive notifications for current Minigame Spotlight'
notifsForm.vosLay,
});
notifsForm.vosselLay,
notifsForm.ed_spotlight = new OO.ui.ToggleSwitchWidget({
notifsForm.tmsLay,
title: 'Elite dungeon spotlight notifications',
notifsForm.tmsselLay,
value: self.settings.notiftype.ed_spotlight
notifsForm.pofLay,
});
notifsForm.pofselLay,
notifsForm.ed_spotlight.on('change', self.saveNotif, ['ed_spotlight']);
notifsForm.eteventsLay,
notifsForm.ed_spotlightLay = new OO.ui.FieldLayout(notifsForm.ed_spotlight, {
notifsForm.voragoLay,
label: 'Elite Dungeon Spotlight',
notifsForm.araxxorLay,
help: 'Receive notifications for current Elite dungeon spotlight'
notifsForm.rotsLay,
});
notifsForm.mg_spotlightLay,
notifsForm.dd_spotlight = new OO.ui.ToggleSwitchWidget({
notifsForm.ed_spotlightLay,
title: 'Distraction and diversion of the week notifications',
notifsForm.dd_spotlightLay
value: self.settings.notiftype.dd_spotlight
]);
 
var $notifoverlay = $('<div>').addClass('notifs-overlay');
$notifoverlay.click( function () {
$('.gsw-events-popup .events-notifs').addClass('slideout');
setTimeout( function () {
$('.gsw-events-popup .events-notifs').removeClass('slideout').addClass('oo-ui-element-hidden');
}, 500);
});
});
notifsForm.dd_spotlight.on('change', self.saveNotif, ['dd_spotlight']);
notifsForm.dd_spotlightLay = new OO.ui.FieldLayout(notifsForm.dd_spotlight, {
label: 'Distraction & Diversions',
help: 'Receive notifications for Distraction and Diversion of the week'
});
notifsForm.form = new OO.ui.FieldsetLayout({ classes:'notifs-form' });
notifsForm.form.addItems([
notifsForm.browsnotifLay,
notifsForm.dailiesLay,
notifsForm.dailiesselLay,
notifsForm.ravenLay,
notifsForm.dresetLay,
notifsForm.wresetLay,
notifsForm.mresetLay,
notifsForm.vosLay,
notifsForm.vosselLay,
notifsForm.tmsLay,
notifsForm.tmsselLay,
notifsForm.pofLay,
notifsForm.pofselLay,
notifsForm.eteventsLay,
notifsForm.voragoLay,
notifsForm.araxxorLay,
notifsForm.rotsLay,
notifsForm.mg_spotlightLay,
notifsForm.ed_spotlightLay,
notifsForm.dd_spotlightLay
]);


// Complete form
var $notifoverlay = $('<div>').addClass('notifs-overlay');
notifsForm.$form = $('<div>')
$notifoverlay.click( function () {
.addClass('events-notifs oo-ui-element-hidden')
$('.gsw-events-popup .events-notifs').addClass('slideout');
.append(
setTimeout( function () {
$notifoverlay,
$('.gsw-events-popup .events-notifs').removeClass('slideout').addClass('oo-ui-element-hidden');
$('<div>')
}, 500);
.addClass('notifs-container')
});
.append(
notifsForm.back.$element,
notifsForm.$title,
notifsForm.form.$element
)
);
},
 
/**
* Updates all events dropdown values (used on  opening)
* @return {undefined}
*/
updateAll: function () {
var now = moment.utc();
$content.find('.cur-utc-time')
.attr({ 'title':now.format('HH:mm D/M/Y'), 'datetime':now.format() })
.text(now.format('HH:mm') + ' (UTC)');
self.updateTimes();
self.updateSpots();
if ( now.isAfter(moment(self.nextvos)) ) {
self.updateVos();
} else {
self.updateVostime();
}
},
 
/**
* Continuously updates the values in Events dropdown
* @return {undefined}
*/
update: function () {
self.updateTimes();
 
// Current UTC time
var now = moment.utc();


// Complete form
notifsForm.$form = $('<div>')
.addClass('events-notifs oo-ui-element-hidden')
.append(
$notifoverlay,
$('<div>')
.addClass('notifs-container')
.append(
notifsForm.back.$element,
notifsForm.$title,
notifsForm.form.$element
)
);
},
/**
* Updates all events dropdown values (used on  opening)
* @return {undefined}
*/
updateAll: function () {
var now = moment.utc();
$content.find('.cur-utc-time')
$content.find('.cur-utc-time')
.attr({ 'title':now.format('HH:mm D/M/Y'), 'datetime':now.format() })
.attr({ 'title':now.format('HH:mm D/M/Y'), 'datetime':now.format() })
.text(now.format('HH:mm') + ' (UTC)');
.text(now.format('HH:mm') + ' (UTC)');
 
self.updateTimes();
// Check if it's after a new hour, update VoS
self.updateSpots();
if ( now.isAfter(moment(self.nextvos)) ) {
if ( now.isAfter(moment(self.nextvos)) ) {
self.updateVos();
self.updateVos();
} else {
} else {
self.updateVostime();
self.updateVostime();
}
// Check if it's after a new day, update PVM etc
if ( now.isBetween(moment(now).startOf('day'), moment(now).startOf('day').add(1, 'minutes'), null, '[]') ) {
self.updateSpots();
}
}
},
},


/**
/**
* Update time based events in the Events popup
* Continuously updates the values in Events dropdown
* Dailies, Resets, Events team events
* @return {undefined}
* @return {[type]} [description]
*/
*/
updateTimes: function () {
update: function () {
self.updateTimes();
 
// Current UTC time
// Current UTC time
var now = moment.utc();
var now = moment.utc();


// Dailies
$content.find('.cur-utc-time')
$content.find('.daily-list').empty();
.attr({ 'title':now.format('HH:mm D/M/Y'), 'datetime':now.format() })
var dailies_array = [];
.text(now.format('HH:mm') + ' (UTC)');
simple_dailies.forEach( function (dd) {
 
var next = moment(now).startOf(dd.from).add((dd.offset), 'minutes'),
// Check if it's after a new hour, update VoS
nextEnd = moment(next).add(dd.length, 'minutes');
if ( now.isAfter(moment(self.nextvos)) ) {
while (!now.isBefore(nextEnd)) {
self.updateVos();
next.add(dd.repeat, 'minutes');
} else {
self.updateVostime();
}
 
// Check if it's after a new day, update PVM etc
if ( now.isBetween(moment(now).startOf('day'), moment(now).startOf('day').add(1, 'minutes'), null, '[]') ) {
self.updateSpots();
}
},
 
/**
* Update time based events in the Events popup
* Dailies, Resets, Events team events
* @return {[type]} [description]
*/
updateTimes: function () {
// Current UTC time
var now = moment.utc();
 
// Dailies
$content.find('.daily-list').empty();
var dailies_array = [];
simple_dailies.forEach( function (dd) {
var next = moment(now).startOf(dd.from).add((dd.offset), 'minutes'),
nextEnd = moment(next).add(dd.length, 'minutes');
while (!now.isBefore(nextEnd)) {
next.add(dd.repeat, 'minutes');
nextEnd.add(dd.repeat, 'minutes');
nextEnd.add(dd.repeat, 'minutes');
}
}
Line 1,123: Line 1,221:
var now = moment.utc();
var now = moment.utc();


// Append to content
// Error updating VoS
$content.find('.pvm').append(
var vosError = function (jqXHR, status, error) {
$('<div>')
console.warn('Error loading VoS:\n' + status + ': ' + error);
.addClass('col col-l')
$content.find('.VoS-time').empty().append('There was an error loading the Voice of Seren. Please try again later.<br/>If this issue persists, please <a href="/w/RS:AR">contact an administrator</a>.');
.append(
$content.find('.VoS-container').empty();
$('<h3>').html('<a href="/w/Vorago" title="Vorago">Vorago</a>'),
$content.find('.VoS-last').empty().append('not found');
$vorago
};
),
// Update Voice of Seren (VoS)
$('<div>')
var vosSucc = function (vosjson, status, jqXHR) {
.addClass('col col-r')
mw.log(vosjson);
.append(
if (!(vosjson.data && vosjson.data[0] && vosjson.data[0].districts)) {
$('<div>')
vosError({}, 'Missing districts', 'returned json did not contain a districts array');
.addClass('section araxxor')
return;
.append(
}
$('<h3>').html('<a href="/w/Araxxor" title="Araxxor">Araxxor</a>'),
 
$araxxor
var voschng = moment(now).add(1, 'hours').startOf('hour'),
),
chngtitle = voschng.format('MMM D') + ' at ' + voschng.format('HH:mm') + ' game time',
$('<div>')
currvos = vosjson.data[0].districts,
.addClass('section rots')
lastvos = vosjson.data[1].districts;
.append(
$('<h3>').attr('title', 'Barrows: Rise of the Six').html('<a href="/w/Barrows:_Rise_of_the_Six" title="Barrows: Rise of the Six">Rise of the Six</a>'),
$content.find('.VoS-time').empty().append(
$rots
$('<time>').addClass('time').attr({ 'datetime':voschng.format(), 'title':chngtitle }).text(voschng.fromNow(true)),
)
' until new districts are active.'
);
$content.find('.VoS-container').empty().append(
$('<div>').addClass('event-box VoS-district').append(
$('<div>').addClass('VoS-image VoS-'+currvos[0]),
$('<div>').addClass('VoS-text').append(
$('<span>').addClass('by-line').attr('title', voslocs[currvos[0]][1]).text(voslocs[currvos[0]][0]),
$('<label>').addClass('event-name').html('<a href="/w/' + currvos[0] + '_Clan" title="' + currvos[0] + ' Clan">' + currvos[0] + '</a>')
)
),
$('<div>').addClass('event-box VoS-district').append(
$('<div>').addClass('VoS-image VoS-'+currvos[1]),
$('<div>').addClass('VoS-text').append(
$('<span>').addClass('by-line').attr('title', voslocs[currvos[1]][1]).text(voslocs[currvos[1]][0]),
$('<label>').addClass('event-name').html('<a href="/w/' + currvos[1] + '_Clan" title="' + currvos[1] + ' Clan">' + currvos[1] + '</a>')
)
)
)
);
);
}


// Spotlights container empty?
$content.find('.VoS-last').empty();
if( !self.settings.dd_spotlight && !self.settings.mg_spotlight && !self.settings.ed_spotlight ) {
$content.find('.VoS-last').append(lastvos[0] + ', ' + lastvos[1]);
$content.addClass('spotlights-empty');
} else {
$content.removeClass('spotlights-empty');
}
$content.find('.spotlight-spacer').removeClass('first');


// Minigame Spotlight
// Set time for next check
$content.find('.mg-spotlight').empty().prev().addClass('empty');
self.nextvos = moment(now).startOf('hour').add(61, 'minutes').format();
if (self.settings.mg_spotlight) {
};
var mg_array = spotlights(mg_spotlights, 3, 49);
$content.find('.mg-spotlight').prev().removeClass('empty');
$content.find('.mg-spotlight').append(
$('<label>').text('Minigame Spotlight'),
$('<span>').addClass('spotlight-value').html('<a href="/w/' + mg_array[0] + '" title="' + mg_array[0] + '">' + mg_array[0] + '</a>')
);
if (self.settings.show_next) {
$content.find('.mg-spotlight').append(
$('<label>').addClass('sl-next').text('Next:'),
$('<span>').addClass('sl-next mg-spotlight-next').text(mg_array[2] + ' in '),
$('<time>').addClass('sl-next mg-spotlight-in').attr({ 'datetime':mg_array[3], 'title':mg_array[4] }).text(mg_array[1])
);
}
} else {
$content.find('.mg-spotlight').next().addClass('first');
}


// Elite dungeon spotlight
// Make api Call
$content.find('.ed-spotlight').empty().prev().addClass('empty');
$content.find('.VoS-time').empty().append('Loading current VoS...');
if (self.settings.ed_spotlight) {
$content.find('.VoS-container').empty();
var ed_array = spotlights(ed_spotlights, 1, 0);
$content.find('.VoS-last').empty().append('Loading last VoS...');
$content.find('.ed-spotlight').prev().removeClass('empty');
$.ajax({
$content.find('.ed-spotlight').append(
dataType: 'json',
$('<label>').text('Elite Dungeon Spotlight'),
url: vosurl,
$('<span>').addClass('spotlight-value').html('<a href="/w/' + ed_array[0] + '" title="' + ed_array[0] + '">' + ed_array[0] + '</a>')
error: vosError,
);
success: vosSucc
if (self.settings.show_next) {
});
$content.find('.ed-spotlight').append(
},
$('<label>').addClass('sl-next').text('Next:'),
 
$('<span>').addClass('sl-next ed-spotlight-next').text(ed_array[2] + ' in '),
/**
$('<time>').addClass('sl-next ed-spotlight-in').attr({ 'datetime':ed_array[3], 'title':ed_array[4] }).text(ed_array[1])
* Update the Voice of Seren time display only
);
* @return {undefined}
*/
updateVostime: function () {
// Next change
var voschng = moment.utc().add(1, 'hours').startOf('hour'),
chngtitle = voschng.format('MMM D') + ' at ' + voschng.format('HH:mm') + ' game time';
// Update time display
$content.find('.VoS-time').empty().append(
$('<time>').addClass('time').attr({ 'datetime':voschng.format(), 'title':chngtitle }).text(voschng.fromNow(true)),
' until new districts are active.'
);
},
/**
* Opens the settings form
* @return {undefined}
*/
openSettings: function () {
// Update settings, switch window
var switchWind = function () {
// Update form elements
settingsForm.sort.setValue(self.settings.daily_sort);
settingsForm.notifs.setValue(self.settings.notifs);
// Disable if notifications disabled
if (self.supportNotif) {
settingsForm.notifs.setDisabled(false);
} else {
settingsForm.notifs.setDisabled(true);
}
}
} else if (!self.settings.mg_spotlight) {
settingsForm.raven.setValue(self.settings.raven);
$content.find('.ed-spotlight').prev().removeClass('first');
settingsForm.events.setValue(self.settings.et_events);
$content.find('.ed-spotlight').next().addClass('first');
settingsForm.eventsNum.setValue(self.settings.num_events);
}
settingsForm.eventsNum.setDisabled(!self.settings.et_events);
settingsForm.eventsNumLay.toggle(self.settings.et_events);
/**
settingsForm.tms.setValue(self.settings.merch);
* Sends notifications to the browser based on user prefs
settingsForm.pof.setValue(self.settings.farm);
settingsForm.spots.setValue(self.settings.spots);
//settingsForm.mg.setValue(self.settings.mg_spotlight);
//settingsForm.dd.setValue(self.settings.dd_spotlight);
//settingsForm.ed.setValue(self.settings.ed_spotlight);
settingsForm.next.setValue(self.settings.show_next);
settingsForm.pvm.setValue(self.settings.pvm);
$('.gsw-events-popup .events-settings').removeClass('oo-ui-element-hidden');
$('.gsw-events-popup .events-settings').addClass('slideout');
setTimeout( function () {
$('.gsw-events-popup .events-settings').removeClass('slideout');
}, 5);
};
self.loadSettings().then(switchWind(), switchWind());
},
 
/**
* Opens the notifications form
* @return {undefined}
* @return {undefined}
*/
*/
notifs: function () {
openNotifs: function () {
var switchWind = function () {
// Update form elements
notifsForm.browsnotif.setValue(self.settings.nobrownotifs);
notifsForm.dailies.setValue(self.settings.notiftype.dailies);
simple_dailies.forEach( function (dd) {
notifsForm[dd.id].setSelected(self.settings.notiftype[dd.id]);
});
notifsForm.raven.setValue(self.settings.notiftype.raven);
notifsForm.dreset.setValue(self.settings.notiftype.dreset);
notifsForm.wreset.setValue(self.settings.notiftype.wreset);
notifsForm.mreset.setValue(self.settings.notiftype.mreset);
notifsForm.vos.setValue(self.settings.notiftype.vos);
for (var clan in voslocs) {
notifsForm[clan].setSelected(self.settings.notiftype['vos' + clan]);
}
notifsForm.etevents.setValue(self.settings.notiftype.etevents);
notifsForm.tms.setValue(self.settings.notiftype.tms);
if (self.settings.notiftype.tmsitems) {
var tmsitems = self.settings.notiftype.tmsitems;
notifsForm.tmssel.clearItems();
tmsitems.forEach( function (item) {
notifsForm.tmssel.addTag(item, item);
});
} else {
notifsForm.tmssel.clearItems();
}
notifsForm.pof.setValue(self.settings.notiftype.pof);
pofresets.forEach( function (fres) {
notifsForm[fres].setSelected(self.settings.notiftype['pof' + fres]);
});
notifsForm.vorago.setValue(self.settings.notiftype.vorago);
notifsForm.araxxor.setValue(self.settings.notiftype.araxxor);
notifsForm.rots.setValue(self.settings.notiftype.rots);
notifsForm.mg_spotlight.setValue(self.settings.notiftype.mg_spotlight);
notifsForm.ed_spotlight.setValue(self.settings.notiftype.ed_spotlight);
notifsForm.dd_spotlight.setValue(self.settings.notiftype.dd_spotlight);
 
$('.gsw-events-popup .events-notifs').removeClass('oo-ui-element-hidden');
$('.gsw-events-popup .events-notifs').addClass('slideout');
setTimeout( function () {
$('.gsw-events-popup .events-notifs').removeClass('slideout');
}, 5);
};
self.loadSettings().then(switchWind(), switchWind());
},
 
/**
* Sends notifications to the browser based on user prefs
* @return {undefined}
*/
notifs: function () {
mw.log('Running notifications');
mw.log('Running notifications');
// TODO: Check that still not using service worker notifs
// TODO: Check that still not using service worker notifs
Line 1,350: Line 1,537:
});
});


// Resets
// Raven
if (self.settings.notiftype.dreset) {
if (self.settings.notiftype.raven) {
// Daily
var days_into = -( moment('0', 'X').utc().add(6, 'days').diff(now, 'days') ) % 13,
var dailyReset = moment(now).add(1, 'days').startOf('day'),
text = 'Raven is currently spawned in Prifddinas',
img = '/images/thumb/0/08/D%26D_token_%28daily%29_detail.png/200px-D%26D_token_%28daily%29_detail.png';
tag = 'raven',
img = '/images/d/d5/Raven_%28Prifddinas%29.png';
if (days_into >= 11) {
var tospawn = 13 - days_into;
if (tospawn > 1) {
text = 'Raven spawns in Prifddinas in ' + tospawn + 'days';
} else {
text = 'Raven spawns in Prifddinas tomorrow';
}
tag = 'raven-' + tospawn;
}
if (days_into < 1 || days_into >= 11) {
if (self.lastRot.raven != tag) {
notifs.push( { title:'Raven (Prif)', opts:{
badge: img,
body: text,
tag: tag,
icon: img,
image: img,
vibrate: true,
renotify: false,
requireInteraction: false
} } );
self.lastRot.raven = tag;
}
}
}
 
// Resets
if (self.settings.notiftype.dreset) {
// Daily
var dailyReset = moment(now).add(1, 'days').startOf('day'),
img = '/images/thumb/0/08/D%26D_token_%28daily%29_detail.png/200px-D%26D_token_%28daily%29_detail.png';
if (dailyReset.diff(now, 'minutes') <= 10) {
if (dailyReset.diff(now, 'minutes') <= 10) {
notifs.push( { title:'Daily Reset', opts:{
notifs.push( { title:'Daily Reset', opts:{
Line 1,470: Line 1,689:
}
}


// For spotlights
self.sendNotifs( dnotifs );
var curspotlight = function(items, duration, offset) {
// Save the last rotations to localstorage if possible
var days_passed = -( moment('0', 'X').utc().add(offset, 'days').diff(now, 'days') ),
if (rs.hasLocalStorage()) {
days_into = days_passed % (duration * items.length),
var string = JSON.stringify(self.lastRot);
rotation = Math.floor(days_into / duration),
try {
days_till = duration - (days_into % duration);
localStorage.setItem(localLast, string);
 
} catch (err) {
return [rotation, items[rotation], days_till];
console.warn('Error saving latest rotations to localStorage');
}
}
}, function (err) {
console.warn('Error loading events and merchant stock');
console.warn(err);
});
}
 
// For spotlights
var curspotlight = function(items, duration, offset) {
var days_passed = -( moment('0', 'X').utc().add(offset, 'days').diff(now, 'days') ),
days_into = days_passed % (duration * items.length),
rotation = Math.floor(days_into / duration),
days_till = duration - (days_into % duration);
 
return [rotation, items[rotation], days_till];
};
 
// Player-owned farm notifications
if (self.settings.notiftype.pof == 'All' || self.settings.notiftype.pof == 'Some') {
var pofnots = [];
// Is less 10 minutes before reset
if ( moment(now).add(1, 'days').startOf('day').diff(now, 'minutes') <= 10 ) {
// Small buyer, easy request
if (self.settings.notiftype.pof == 'All' || self.settings.notiftype['pofSmall Buyer']) {
pofnots.push( 'small buyer' );
}
if (self.settings.notiftype.pof == 'All' || self.settings.notiftype['pofEasy Request']) {
pofnots.push( 'easy request' );
}
// Medium buyer
if (self.settings.notiftype.pof == 'All' || self.settings.notiftype['pofMedium Buyer']) {
if ( curspotlight(['med'], 2, 1)[2] == 1 ) {
pofnots.push( 'medium buyer' );
}
}
// Medium request
if (self.settings.notiftype.pof == 'All' || self.settings.notiftype['pofMedium Request']) {
if ( curspotlight(['med'], 3, 0)[2] == 1 ) {
pofnots.push( 'medium request' );
}
}
// Large buyer
if (self.settings.notiftype.pof == 'All' || self.settings.notiftype['pofLarge Buyer']) {
if ( curspotlight(['large'], 3, 0)[2] == 1 ) {
pofnots.push( 'large buyer' );
}
}
}
// Generate notification
if (pofnots.length > 0) {
var img = '/images/1/18/Farming.png',
nbod = 'Spawning soon:',
len = pofnots.length,
i = 1;
 
pofnots.forEach( function (npc) {
if (i == 1) {
nbod = nbod + ' ' + npc;
} else if (i == len) {
nbod =  nbod + ' and ' + npc;
} else {
nbod = nbod + ', ' + npc;
}
i ++;
});
nbod = nbod + '.';
 
notifs.push( { title:'POF Spawns', opts:{
badge: img,
body: nbod,
tag: 'pofresets',
icon: img,
image: img,
vibrate: true,
renotify: false,
requireInteraction: false
} } );
}
}
// Minigame Spotlight
if (self.settings.notiftype.mg_spotlight) {
var spot = curspotlight(mg_spotlights, 3, 49);
if (spot[0] != self.lastRot.mgspot) {
self.lastRot.mgspot = spot[0];
var img = '/images/c/c8/Current_spotlight_icon.png';
 
notifs.push( { title:'Minigame Spotlight', opts:{
badge: img,
body: 'The currently spotlighted minigame is ' + spot[1],
tag: 'mgspot',
icon: img,
image: img,
vibrate: true,
renotify: true,
requireInteraction: false
} } );
}
}
 
// Elite dungeon spotlight
if (self.settings.notiftype.ed_spotlight) {
var spot = curspotlight(ed_spotlights, 1, 0);
if (spot[0] != self.lastRot.edspot) {
self.lastRot.edspot = spot[0];
var imgs = {
'Temple of Aminishi':'/images/thumb/f/fd/Relic_of_aminishi_%28rare%29_detail.png/200px-Relic_of_aminishi_%28rare%29_detail.png',
'Dragonkin Laboratory':'/images/thumb/d/d4/Laboratory_relic_%28uncommon%29_detail.png/180px-Laboratory_relic_%28uncommon%29_detail.png',
'The Shadow Reef':'/images/thumb/e/e5/Umbral_urn_detail.png/160px-Umbral_urn_detail.png'
},
img = imgs[spot[1]];
 
notifs.push( { title:'Elite Dungeon Spotlight', opts:{
badge: img,
body: 'The currently spotlighted elite dungeon is ' + spot[1],
tag: 'edspot',
icon: img,
image: img,
vibrate: true,
renotify: true,
requireInteraction: false
} } );
}
}
// Save the last rotations to localstorage if possible
if (rs.hasLocalStorage()) {
var string = JSON.stringify(self.lastRot);
try {
localStorage.setItem(localLast, string);
} catch (err) {
console.warn('Error saving latest rotations to localStorage');
}
}
},
/**
* Sends notifications (on site or browser)
* @param  {array} notifs Array of notifcation objects to be sent
* @param  {boolean} add    (optional) Whether to replace or add to current notifications
* @return {undefined}
*/
sendNotifs: function ( notifs, add ) {
// Send browser notifications
var sendNotifs = function ( nl ) {
mw.log('Sending browser notifications');
// Google analytics tracker
if (typeof ga === 'function') {
ga('gtag_UA_126479006_1.send', 'event', 'Gadget-events', 'Send Notifactions', 'Browser', nl.length);
}
 
var interval = 200;
nl.forEach( function (n,i) {
mw.log('Sending ' + n.title);
// Some browser block them if to many sent in a short time
setTimeout(function() {
var bn = new Notification(n.title, n.opts);
bn.onclick = function () {
popup.toggle(true);
bn.close.bind(bn);
};
}, interval * i);
});
};
};
// Minigame Spotlight
if (self.settings.notiftype.mg_spotlight) {
var spot = curspotlight(mg_spotlights, 3, 49);
if (spot[0] != self.lastRot.mgspot) {
self.lastRot.mgspot = spot[0];
var img = '/images/c/c8/Current_spotlight_icon.png';
notifs.push( { title:'Minigame Spotlight', opts:{
badge: img,
body: 'The currently spotlighted minigame is ' + spot[1],
tag: 'mgspot',
icon: img,
image: img,
vibrate: true,
renotify: true,
requireInteraction: false
} } );
}
}
// Elite dungeon spotlight
if (self.settings.notiftype.ed_spotlight) {
var spot = curspotlight(ed_spotlights, 1, 0);
if (spot[0] != self.lastRot.edspot) {
self.lastRot.edspot = spot[0];
var imgs = {
'Temple of Aminishi':'/images/thumb/f/fd/Relic_of_aminishi_%28rare%29_detail.png/200px-Relic_of_aminishi_%28rare%29_detail.png',
'Dragonkin Laboratory':'/images/thumb/d/d4/Laboratory_relic_%28uncommon%29_detail.png/180px-Laboratory_relic_%28uncommon%29_detail.png',
'The Shadow Reef':'/images/thumb/e/e5/Umbral_urn_detail.png/160px-Umbral_urn_detail.png'
},
img = imgs[spot[1]];


notifs.push( { title:'Elite Dungeon Spotlight', opts:{
// Send popup notifs
badge: img,
body: 'The currently spotlighted elite dungeon is ' + spot[1],
tag: 'edspot',
icon: img,
image: img,
vibrate: true,
renotify: true,
requireInteraction: false
} } );
}
}
// Send popup notifs
var popNotifs = function ( nl, noempty ) {
var popNotifs = function ( nl, noempty ) {
mw.log('Sending popup notifications');
mw.log('Sending popup notifications');