MediaWiki:Gadget-eventslist.js
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>
/**
* Interface for events
*
* @version 1.1
* @author JaydenKieran
* @author Elessar2
* @author ThePsionic
*
*/
/*global jQuery, mediaWiki, mw, gswiki, rs, OO, moment, ga */
'use strict';
// TODO: Add castaways?, circus city, Jewels of the Elid,
// TODO: Cache Vos as well
;(function($, mw, rs){
var portletLink,
$popup,
popup,
$content,
settingsForm,
notifsForm,
api,
et_events,
merchstock,
notiftimer,
notifpopup,
$notifs,
formConst = false,
formMade = false;
// localStorage key
var localKey = 'gsw-events-prefs',
localLast = 'gsw-events-last',
vosurl = 'https://chisel.weirdgloop.org/api/runescape/vos/history',
simplevosurl = 'https://chisel.weirdgloop.org/api/runescape/vos';
// Dailies
var simple_dailies = [
{ name:'Big Chinchompa', id:'bigchin', link:'/w/Big_Chinchompa', length:20, repeat:60, offset:30, from:'hour', img:'/images/6/63/Nyriki%27s_portal.png' },
{ name:'Guthixian Caches', id:'guthcache', link:'/w/Guthixian_Cache', length:10, repeat:60, offset:0, from:'hour', img:'/images/thumb/2/23/Player_automaton.png/600px-Player_automaton.png' },
{ name:'Guthixian Caches (boost)', id:'guthcacheb', link:'/w/Guthixian_Cache', length:10, repeat:(60*3), offset:0, from:'day', img:'/images/8/8e/Confused_automaton.png' },
{ name:'Sinkholes', id:'sinkhole', link:'/w/Sinkholes', length:25, repeat:60, offset:30, from:'hour', img:'/images/5/5c/Sinkhole_entrance.png' },
{ name:'Demon Flash Mob', id:'demonmob', link:'/w/Demon_Flash_Mob', length:5, repeat:60, offset:0, from:'hour', img:'/images/1/1f/Agrith_Naar_chathead.png' },
{ name:'Fish Flingers', id:'fishflin', link:'/w/Fish_Flingers', length:10, repeat:20, offset:0, from:'hour', img:'/images/thumb/c/cb/Fish_Flingers_logo.png/200px-Fish_Flingers_logo.png' },
{ name:'Supply Run', id:'goebiesup', link:'/w/Supply_run', length:25, repeat:(60 * 12), offset:0, from:'day', img:'/images/9/9e/Goebie_chathead.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 = {
// Settings
settings: {
daily_sort: 'by time',
notifs: false,
nobrownotifs: false,
notiftype: {},
raven: true,
et_events: false,
num_events: 3,
spots: true,
mg_spotlight: true,
dd_spotlight: true,
ed_spotlight: true,
show_next: false,
pvm: false,
//tms: false,
//pof: false,
merch: true,
farm: true,
//etlookup: '1970-01-01T01:00:00+00:00',
//events: []
dcache: '1970-01-01T01:00:00+00:00',
cache: {
events: [],
tms: {},
tmsTom: {}
}
},
// Using service worker notifications?
swnotif: false,
// Last times (for constant updating)
updatetimer: 0,
nextvos: '1970-01-01T01:00:00+00:00',
// Latest rotations (for notifications)
lastRot: {
time: '1970-01-01T01:00:00+00:00',
wreset: '1970-01-01T01:00:00+00:00',
mreset: '1970-01-01T01:00:00+00:00',
vos: '',
raven: '',
tms: '',
vorago: 99,
araxxor: 99,
rots: 99,
mgspot: 99,
edspot: 99,
ddspot: 99
},
/**
* Starts the events gadget
* @return {undefined}
*/
init: function () {
mw.log('Starting Events Interface');
api = new mw.Api();
// setup moment library
moment.locale('en-events', {
relativeTime : {
parentLocale: "en",
future: "in %s",
past: "%s ago",
s: "secs",
m: "1m",
mm: "%dm",
h: "1h",
hh: "%dh",
d: "1d",
dd: "%dd",
M: "1mth",
MM: "%dmths",
y: "1yr",
yy: "%dyr"
}
});
// Event team events
et_events = [];
// Travelling merchant stock
merchstock = { tod:[], tmr:[] };
// Check browser supports notifications
self.supportNotif = rs.canSendBrowserNotifs();
// TODO: Check if using service worker notifications
portletLink = mw.util.addPortletLink(
'p-personal',
'',
'',
'pt-events',
'Events',
null,
$('#pt-userpage, #pt-anonuserpage')
);
$(portletLink).find('a').addClass('oo-ui-icon-calendar').click(function(e) {
e.preventDefault();
var openPopup = function() {
mw.log('Open events popup');
self.loadSettings().then(self.loadEvents).then( self.updateAll(), self.updateAll() );
// Disable browser notifications settings if unavailable
// Done here to avoid a race condition where we disable it and save to localStorage
// before we actually load the settings
if (!self.supportNotif) {
notifsForm.browsnotif.setValue(true);
notifsForm.browsnotif.setDisabled(true);
}
// Google analytics tracker
if (typeof ga === 'function') {
ga('gtag_UA_126479006_1.send', 'event', 'Gadget-events', 'Open', 'Normal');
}
$('.gsw-events-popup .events-settings').removeClass('slideout').addClass('oo-ui-element-hidden');
popup.toggle();
};
if (!formMade && !formConst) {
mw.log('Initialise events popup');
formConst = true;
mw.loader.using(['oojs-ui-core', 'oojs-ui-windows', 'oojs-ui-widgets']).then(self.initInt).then(openPopup);
} else if (!formConst) {
openPopup();
} else {
mw.log('Waiting for initialisation to finish');
}
});
// Load settings and events from localStorage or via api on page load to handle notifs
self.loadSettings().then(self.loadEvents).then( function () {
if (self.settings.notifs && !self.swnotif) {
self.notifs();
notiftimer = setInterval(self.notifs, 300000);
}
}, function () {
console.warn('Error loading events settings!');
});
},
/**
* Initialises the interface (popup and forms)
* @return {Promise}
*/
initInt: function () {
mw.log('Initialising...');
return new Promise( function (resolve,reject) {
self.initPopup();
self.initSettingsForm();
self.initNotifsForm();
$popup = $('<div>').append(
$content,
settingsForm.$form
);
settingsForm.$form.find('.settings-container').append( notifsForm.$form );
popup = new OO.ui.PopupWidget({
$content: $popup,
$floatableContainer: $('#pt-events'),
autoClose: true,
classes: ['gsw-events-popup oo-ui-labelElement-invisible'],
hideWhenOutOfView: (rs.isUsingStickyHeader() ? true : false),
invisibleLabel: true,
label: 'Events',
width: 700
});
$('body').append(popup.$element);
popup.on('toggle', function (state) {
// Start constant update
clearInterval(self.updatetimer);
if (state) {
self.updatetimer = setInterval(self.update, 60000);
}
});
// For on wiki notifications
$('body').append($('<div>').attr('id', 'gsw-notifs-anchor'));
var notifclose = new OO.ui.ButtonWidget({
classes: ['oo-ui-labelElement-invisible'],
icon: 'close',
id:'gsw-eventsnotifs-close',
invisibleLabel: true,
label: 'Close',
framed: false
});
notifclose.on('click', function () {
notifpopup.toggle(false);
});
$notifs = $('<div>').addClass('event-notifs-container').append(
notifclose.$element,
$('<h3>').addClass('oo-ui-element-hidden').text('Event Notifications'),
$('<ul>').addClass('event-notifications')
);
notifpopup = new OO.ui.PopupWidget({
$content: $notifs,
$floatableContainer: $('#gsw-notifs-anchor'),
anchor: false,
autoClose: true,
classes: ['gsw-events-notifs oo-ui-labelElement-invisible'],
hideWhenOutOfView: false,
invisibleLabel: true,
label: 'Events Notifications',
width: 450
});
$('body').append(notifpopup.$element);
// Mark interface as initialised
formMade = true;
formConst = false;
resolve();
} );
},
/**
* Loads settings from browser localStorage
* @return {Promise}
*/
loadSettings: function () {
mw.log('Loading settings');
return new Promise( function (resolve, reject) {
if (!rs.hasLocalStorage()) {
console.warn('Browser does not support localStorage');
reject();
}
var prefs = {};
try {
prefs = JSON.parse(localStorage.getItem(localKey));
} catch (err) {
prefs = {};
console.warn('Error loading settings (events)');
}
for (var p in prefs) {
self.settings[p] = prefs[p];
}
resolve();
} );
},
/**
* 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
* @param {string} name Name (key) of setting to save
* @return {boolean} If save was successfull
*/
saveSetting: function (key, value) {
mw.log('Saving setting: ' + key);
if ( key.split('.')[0] == 'cache' ) {
self.settings.cache[key.split('.')[1]] = value;
} else {
self.settings[key] = value;
}
if (!rs.hasLocalStorage()) {
console.warn('Browser does not support localStorage');
return false;
}
var string = JSON.stringify(self.settings);
try {
localStorage.setItem(localKey, string);
} catch (err) {
console.warn('Error saving presets to localStorage');
return false;
}
return true;
},
/**
* Saves a notification setting to localStorage
* @param {string} key Name (key) of notification setting to save
* @param {boolean} value Send notifications?
* @return {boolean} If save was successfull
*/
saveNotif: function (key, value) {
mw.log('Saving notification setting: ' + key);
self.settings.notiftype[key] = value;
if (!rs.hasLocalStorage()) {
console.warn('Browser does not support localStorage');
return false;
}
var string = JSON.stringify(self.settings);
try {
localStorage.setItem(localKey, string);
} catch (err) {
console.warn('Error saving presets to localStorage');
return false;
}
return true;
},
/**
* Generates the events popup
* @return {undefined}
*/
initPopup: function () {
var closeButton = new OO.ui.ButtonWidget({
classes: ['oo-ui-labelElement-invisible'],
icon: 'close',
id:'gsw-events-close',
invisibleLabel: true,
label: 'Close',
framed: false
});
closeButton.on('click', function () {
popup.toggle(false);
});
var settingsButton = new OO.ui.ButtonWidget({
classes: ['oo-ui-labelElement-invisible'],
icon: 'advanced',
id:'gsw-events-setbut',
invisibleLabel: true,
label: 'Settings',
framed: false
});
settingsButton.on('click', function () {
self.openSettings();
});
// Current UTC time
var now = moment.utc();
$content = $('<div>');
$content
.addClass('events-popup')
.append(
$('<div>')
.addClass('header')
.append(
closeButton.$element,
$('<time>')
.addClass('cur-utc-time')
.attr({ 'title':now.format('HH:mm D/M/Y'), 'datetime':now.format() })
.text(now.format('HH:mm') + ' (UTC)'),
settingsButton.$element
),
$('<div>')
.addClass('top')
.append(
$('<div>')
.addClass('col col-l')
.append(
$('<div>')
.addClass('dailies section')
.append(
$('<h3>').text('Dailies'),
$('<ul>').addClass('events-list daily-list')
),
$('<div>')
.addClass('raven section')
),
$('<div>')
.addClass('col col-r')
.append(
$('<div>')
.addClass('resets section')
.append(
$('<h3>').text('Resets'),
$('<div>')
.addClass('event-boxes')
.append(
$('<div>')
.addClass('day event-box')
.append(
$('<label>').addClass('by-line').text('Day'),
$('<time>').addClass('event-name countdown-day').text('? hrs')
),
$('<div>')
.addClass('week event-box')
.append(
$('<label>').addClass('by-line').text('Week'),
$('<time>').addClass('event-name countdown-week').text('? days')
),
$('<div>')
.addClass('month event-box')
.append(
$('<label>').addClass('by-line').text('Month'),
$('<time>').addClass('event-name countdown-month').text('? days')
)
)
),
$('<div>')
.addClass('voice section')
.append(
$('<h3>').html('<a href="/w/Voice_of_Seren" title="Voice of Seren">Voice of Seren</a>'),
$('<div>')
.addClass('VoS-time by-line')
.text(
'There was an error loading the Voice of Seren. Please try again.<br/>If this issue persists, please <a href="/w/RS:AR">contact an administrator</a>.'
),
$('<div>')
.addClass('VoS-container event-boxes'),
$('<div>')
.addClass('by-line')
.append(
$('<span>').text('Last districts: '),
$('<span>').addClass('VoS-last').text('not found')
)
)
)
),
$('<div>')
.addClass('middle events-team'),
$('<div>')
.addClass('middle tms-pof'),
$('<div>')
.addClass('middle pvm'),
$('<div>')
.addClass('spotlights')
.append(
$('<div>')
.addClass('spotlight-spacer empty'),
$('<div>')
.addClass('spotlight mg-spotlight'),
$('<div>')
.addClass('spotlight-spacer empty'),
$('<div>')
.addClass('spotlight ed-spotlight'),
$('<div>')
.addClass('spotlight-spacer empty'),
$('<div>')
.addClass('spotlight dd-spotlight'),
$('<div>')
.addClass('spotlight-spacer')
)
);
},
/**
* Generates the settings popup
* @return {undefined}
*/
initSettingsForm: function () {
settingsForm = {};
// Back button
settingsForm.back = new OO.ui.ButtonWidget({
classes: ['oo-ui-labelElement-invisible'],
icon: 'close',
id: 'gsw-events-backbut',
invisibleLabel: true,
label: 'Back',
framed: false
});
var closeset = function () {
self.updateTimes();
self.updateVos();
self.updateSpots();
$('.gsw-events-popup .events-settings').addClass('slideout');
setTimeout( function () {
$('.gsw-events-popup .events-settings').removeClass('slideout').addClass('oo-ui-element-hidden');
}, 500);
};
settingsForm.back.on('click', closeset);
// Title
settingsForm.$title = $('<h3>').text('Options');
// Dailies sort selector
settingsForm.sort = new OO.ui.DropdownInputWidget({
classes: 'sort-selector',
options: [
{ data:'by time', label:'by time' },
{ data:'by name', label:'by name' }
],
});
settingsForm.sort.setValue(self.settings.daily_sort);
settingsForm.sortLay = new OO.ui.FieldLayout(settingsForm.sort, {
label: 'Sorting'
});
settingsForm.sort.on('change', self.saveSetting, ['daily_sort']);
// Show browser notifications
settingsForm.notifs = new OO.ui.ToggleSwitchWidget({
title: 'Recieve browser notifications',
value: self.settings.notifs
});
settingsForm.notifs.on('change', function (val) {
self.saveSetting('notifs', val);
if (val && !self.swnotif) {
window.clearInterval(notiftimer);
self.notifs();
notiftimer = setInterval(self.notifs, 300000);
} else {
window.clearInterval(notiftimer);
}
});
settingsForm.notifSets = new OO.ui.ButtonWidget({
classes: ['oo-ui-labelElement-invisible'],
icon: 'advanced',
invisibleLabel: true,
label: 'Notification Settings',
framed: false
});
settingsForm.notifSets.on('click', function () {
self.openNotifs();
});
settingsForm.notifsLay = new OO.ui.ActionFieldLayout(settingsForm.notifs, settingsForm.notifSets, {
label: 'Notifications',
help: 'Enable notifications for configured events. Currently in development.'
});
// Show events team events
settingsForm.events = new OO.ui.ToggleSwitchWidget({
title: 'Show events team events',
value: self.settings.et_events
});
settingsForm.eventsLay = new OO.ui.FieldLayout(settingsForm.events, { label: 'Events Team' });
settingsForm.events.on('change', function (val) {
self.saveSetting('et_events', val);
settingsForm.eventsNum.setDisabled(!val);
settingsForm.eventsNumLay.toggle(val);
});
// Number of events to display
settingsForm.eventsNum = new OO.ui.NumberInputWidget({
min: 0,
required: true,
step: 1,
validate: 'integer',
value: self.settings.num_events
});
settingsForm.eventsNumLay = new OO.ui.FieldLayout(settingsForm.eventsNum, {
label: 'Number of Events',
help: 'Number of Events Team events to display, use 0 for infinite'
});
settingsForm.eventsNum.on('change', function (val) {
val = parseInt(val, 10);
if (isNaN(val)) { val = 1; }
self.saveSetting('num_events', val);
});
// Disable if events turned off
if (!self.settings.et_events) {
settingsForm.eventsNum.setDisabled(true);
settingsForm.eventsNumLay.toggle(false);
}
// Show minigame spotlight
settingsForm.mg = new OO.ui.ToggleSwitchWidget({
title: 'Show minigame spotlight',
value: self.settings.mg_spotlight
});
settingsForm.mgLay = new OO.ui.FieldLayout(settingsForm.mg, { label: 'Minigame Spotlight' });
settingsForm.mg.on('change', self.saveSetting, ['mg_spotlight']);
// Show elite dungeon spotlight
settingsForm.ed = new OO.ui.ToggleSwitchWidget({
title: 'Show Elite Dungeon spotlight',
value: self.settings.ed_spotlight
});
settingsForm.edLay = new OO.ui.FieldLayout(settingsForm.ed, { label: 'Elite Dungeon Spotlight' });
settingsForm.ed.on('change', self.saveSetting, ['ed_spotlight']);
// Show next spotlight
settingsForm.next = new OO.ui.ToggleSwitchWidget({
title: 'Show next spotlight item',
value: self.settings.show_next
});
settingsForm.nextLay = new OO.ui.FieldLayout(settingsForm.next, {
label: 'Show next',
help: 'Show next item in spotlight rotations'
});
settingsForm.next.on('change', self.saveSetting, ['show_next']);
// Show PvM
settingsForm.pvm = new OO.ui.ToggleSwitchWidget({
title: 'Show PvM rotations',
value: self.settings.pvm
});
settingsForm.pvmLay = new OO.ui.FieldLayout(settingsForm.pvm, { label: 'PvM Rotations' });
settingsForm.pvm.on('change', self.saveSetting, ['pvm']);
// Settings form footer
settingsForm.$footer = $('<div>')
.addClass('footer')
.html('<a href="/w/Help_talk:Gadget-events" title="Events gadget discussion">Give us feedback on these timers!</a>');
var $setoverlay = $('<div>').addClass('settings-overlay');
$setoverlay.click( closeset );
// Complete form
settingsForm.$form = $('<div>')
.addClass('events-settings oo-ui-element-hidden')
.append(
$setoverlay,
$('<div>')
.addClass('settings-container')
.append(
settingsForm.back.$element,
settingsForm.$title,
settingsForm.form.$element,
settingsForm.$footer
)
);
},
/**
* Generates the notifications settings popup
* @return {undefined}
*/
initNotifsForm: function () {
notifsForm = {};
// Back button
notifsForm.back = new OO.ui.ButtonWidget({
classes: ['oo-ui-labelElement-invisible'],
icon: 'close',
id: 'gsw-notifs-backbut',
invisibleLabel: true,
label: 'Back',
framed: false
});
notifsForm.back.on('click', function () {
$('.gsw-events-popup .events-notifs').addClass('slideout');
setTimeout( function () {
$('.gsw-events-popup .events-notifs').removeClass('slideout').addClass('oo-ui-element-hidden');
}, 500);
});
// Title
notifsForm.$title = $('<h3>').text('Notifications');
// Disable browser notifications
notifsForm.browsnotif = new OO.ui.ToggleSwitchWidget({
title: 'Disable browser notifications',
value: self.settings.nobrownotifs
});
notifsForm.browsnotif.on('change', self.saveSetting, ['nobrownotifs']);
notifsForm.browsnotifLay = new OO.ui.FieldLayout(notifsForm.browsnotif, {
label: 'No Browser Notifs',
help: 'Disable native browser notifications. While disabled, notifications will instead be displayed in a popup at the top right of the wiki page.'
});
// All Dailies
notifsForm.dailies = new OO.ui.DropdownInputWidget({
options: [
{ data:'None', label:'None' },
{ data:'All', label:'All' },
{ data:'Some', label:'Selectively' }
],
title: 'Recieve notifications for dailies',
});
notifsForm.dailies.setValue(self.settings.notiftype.dailies);
notifsForm.dailiesLay = new OO.ui.FieldLayout(notifsForm.dailies, {
label: 'Dailies',
help: 'Recieve notifications for dailies such as Guthixian Caches or Sinkholes'
});
var toggledailies = function (val) {
self.saveNotif('dailies', val);
if (val == 'Some') {
notifsForm.dailiesselLay.toggle(true);
self.saveNotif('alldailies', false);
} else if (val == 'All') {
notifsForm.dailiesselLay.toggle(false);
self.saveNotif('alldailies', true);
} else {
notifsForm.dailiesselLay.toggle(false);
self.saveNotif('alldailies', false);
}
};
notifsForm.dailies.on('change', toggledailies);
// Individual Dailies
notifsForm.dailiessel = new OO.ui.CheckboxMultiselectWidget({ classes: ['notifs-group'] });
simple_dailies.forEach( function (dd) {
notifsForm[dd.id] = new OO.ui.CheckboxMultioptionWidget({
label: dd.name,
data: dd.name,
selected: self.settings.notiftype[dd.id]
});
notifsForm[dd.id].on('change', self.saveNotif, [dd.id]);
notifsForm.dailiessel.addItems([ notifsForm[dd.id] ]);
});
notifsForm.dailiesselLay = new OO.ui.FieldLayout(notifsForm.dailiessel, {
align: 'top',
label: 'Individual Dailies',
help: 'Choose individual dalies to be notified about'
});
if (self.settings.notiftype.dailies != 'Some') {
notifsForm.dailiesselLay.toggle(false);
}
// Resets
notifsForm.dreset = new OO.ui.ToggleSwitchWidget({
title: 'Daily reset notification',
value: self.settings.notiftype.dreset
});
notifsForm.dreset.on('change', self.saveNotif, ['dreset']);
notifsForm.dresetLay = new OO.ui.FieldLayout(notifsForm.dreset, {
label: 'Daily Reset'
});
notifsForm.wreset = new OO.ui.ToggleSwitchWidget({
title: 'Weekly reset notification',
value: self.settings.notiftype.wreset
});
notifsForm.wreset.on('change', self.saveNotif, ['wreset']);
notifsForm.wresetLay = new OO.ui.FieldLayout(notifsForm.wreset, {
label: 'Weekly Reset'
});
notifsForm.mreset = new OO.ui.ToggleSwitchWidget({
title: 'Monthly reset notification',
value: self.settings.notiftype.mreset
});
notifsForm.mreset.on('change', self.saveNotif, ['mreset']);
notifsForm.mresetLay = new OO.ui.FieldLayout(notifsForm.mreset, {
label: 'Monthly Reset'
});
// Events team events
notifsForm.etevents = new OO.ui.ToggleSwitchWidget({
title: 'Events team notifications',
value: self.settings.notiftype.etevents
});
notifsForm.etevents.on('change', self.saveNotif, ['etevents']);
notifsForm.eteventsLay = new OO.ui.FieldLayout(notifsForm.etevents, {
label: 'Events Team',
help: 'Receive notifications for RuneScape Wiki events team events'
});
// PVM
notifsForm.vorago = new OO.ui.ToggleSwitchWidget({
title: 'Vorago attack notifications',
value: self.settings.notiftype.vorago
});
notifsForm.vorago.on('change', self.saveNotif, ['vorago']);
notifsForm.voragoLay = new OO.ui.FieldLayout(notifsForm.vorago, {
label: 'Vorago',
help: 'Receive notifications about current Vorago attack'
});
notifsForm.araxxor = new OO.ui.ToggleSwitchWidget({
title: 'Araxxor path notifications',
value: self.settings.notiftype.araxxor
});
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
notifsForm.mg_spotlight = new OO.ui.ToggleSwitchWidget({
title: 'Minigame spotlight notifications',
value: self.settings.notiftype.mg_spotlight
});
notifsForm.mg_spotlight.on('change', self.saveNotif, ['mg_spotlight']);
notifsForm.mg_spotlightLay = new OO.ui.FieldLayout(notifsForm.mg_spotlight, {
label: 'Minigame Spotlight',
help: 'Receive notifications for current Minigame Spotlight'
});
notifsForm.ed_spotlight = new OO.ui.ToggleSwitchWidget({
title: 'Elite dungeon spotlight notifications',
value: self.settings.notiftype.ed_spotlight
});
notifsForm.ed_spotlight.on('change', self.saveNotif, ['ed_spotlight']);
notifsForm.ed_spotlightLay = new OO.ui.FieldLayout(notifsForm.ed_spotlight, {
label: 'Elite Dungeon Spotlight',
help: 'Receive notifications for current Elite dungeon spotlight'
});
notifsForm.dd_spotlight = new OO.ui.ToggleSwitchWidget({
title: 'Distraction and diversion of the week notifications',
value: self.settings.notiftype.dd_spotlight
});
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
]);
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);
});
// 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')
.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();
$content.find('.cur-utc-time')
.attr({ 'title':now.format('HH:mm D/M/Y'), 'datetime':now.format() })
.text(now.format('HH:mm') + ' (UTC)');
// Check if it's after a new hour, update VoS
if ( now.isAfter(moment(self.nextvos)) ) {
self.updateVos();
} 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');
}
var time_till = 'now!',
diff_secs = 0,
title = 'Going on now',
future = moment(next).add(dd.repeat, 'minutes'),
ntxt = future.fromNow(true),
ntitle = future.format('HH:mm') + ' game time, on ' + future.format('MMM D');
if (now.isBefore(next)) {
time_till = next.fromNow(true);
title = next.format('HH:mm') + ' game time, on ' + next.format('MMM D');
diff_secs = next.diff(now, 'seconds');
}
dailies_array.push( {name:dd.name, link:dd.link, txt:time_till, title:title, sort:diff_secs, time:next.format(), ntxt:ntxt, ntime:future.format(), ntitle:ntitle} );
});
// Sort Dailies
if ( self.settings.daily_sort == 'by time') {
dailies_array.sort( function (a,b) {
return a.sort - b.sort;
});
} else {
dailies_array.sort( function (a,b) {
if (a.name < b.name) {
return -1;
} else if (a.name > b.name) {
return 1;
} else {
return 0;
}
});
}
// Print Dailies
dailies_array.forEach( function (dd) {
var ddClass = 'daily';
if (dd.sort === 0) { ddClass += ' now'; }
$content.find('.daily-list').append(
$('<li>')
.addClass(ddClass)
.append(
$('<label>').addClass('daily-title').html('<a href="'+dd.link+'" title="'+dd.name+'">'+dd.name+'</a>'),
$('<time>').addClass('daily-timer').attr({'datetime':dd.time, 'title':dd.title}).text(dd.txt),
$('<time>').addClass('daily-next').attr({'datetime':dd.ntime, 'title':dd.ntitle}).text(dd.ntxt)
)
);
});
// Update resets
moment.relativeTimeThreshold('d', 31);
moment.relativeTimeThreshold('h', 24);
var dailyReset = moment(now).add(1, 'days').startOf('day'),
dailyTitle = dailyReset.format('MMM D') + ' at ' + dailyReset.format('HH:mm') + ' game time',
monthlyReset = moment(now).add(1, 'months').startOf('month'),
monthlyTitle = monthlyReset.format('MMM D') + ' at ' + monthlyReset.format('HH:mm') + ' game time',
weeklyReset = moment(now).day(3).startOf('day'); // reset is a wednesday
if (now.isAfter(weeklyReset)) {
weeklyReset.add(1, 'week');
}
var weeklyTitle = weeklyReset.format('MMM D') + ' at ' + weeklyReset.format('HH:mm') + ' game time';
$content.find('.countdown-day').attr({'datetime':dailyReset.format(), 'title':dailyTitle }).text( dailyReset.fromNow(true) );
$content.find('.countdown-week').attr({'datetime':weeklyReset.format(), 'title':weeklyTitle }).text( weeklyReset.fromNow(true) );
$content.find('.countdown-month').attr({'datetime':monthlyReset.format(), 'title':monthlyTitle }).text( monthlyReset.fromNow(true) );
moment.relativeTimeThreshold('h', 22);
moment.relativeTimeThreshold('d', 26);
// Events team events
$content.find('.events-team').empty();
if (self.settings.et_events) {
$content.find('.events-team').append(
$('<h3>').html('<a href="/w/RuneScape:Events_Team" title="Events Team events">Events Team</a>'),
$('<ul>')
.addClass('events-list etevents-list')
.append(
$('<li>').text('No upcoming events')
)
);
var events_array = [];
et_events.forEach( function (e) {
var emom = moment(e.date).utc(),
time = emom.fromNow(true),
sort = emom.diff(now, 'seconds'),
dtime = emom.format(),
title = emom.format('MMM D') + ' at ' + emom.format('HH:mm') + ' game time';
if (sort >= 0) {
if (sort < (e.length * 60)) {
sort = 0;
time = 'now!';
}
events_array.push( {name:e.name, txt:time, sort:sort, dtime:dtime, title:title} );
} else if (sort > -(e.length * 60)) {
sort = 0;
time = 'now!';
events_array.push( {name:e.name, txt:time, sort:sort, dtime:dtime, title:title} );
}
});
// Sort and trim
events_array.sort( function (a,b) {
return a.sort - b.sort;
});
if (self.settings.num_events > 0) {
events_array = events_array.slice(0,self.settings.num_events);
}
// Print Events
if (events_array.length > 0) {
$content.find('.etevents-list').empty();
events_array.forEach( function (e) {
var eClass = 'event';
if (e.sort === 0) { eClass += ' now'; }
$content.find('.etevents-list').append(
$('<li>')
.addClass(eClass)
.append(
$('<label>').addClass('event-title').text(e.name),
$('<time>').addClass('event-timer').attr({ 'datetime':e.dtime, 'title':e.title }).text(e.txt)
)
);
});
}
}
},
/**
* Update the Voice of Seren values in the Events popup
* @return {undefined}
*/
updateVos: function () {
// Current UTC time
var now = moment.utc();
// Append to content
$content.find('.pvm').append(
$('<div>')
.addClass('col col-l')
.append(
$('<h3>').html('<a href="/w/Vorago" title="Vorago">Vorago</a>'),
$vorago
),
$('<div>')
.addClass('col col-r')
.append(
$('<div>')
.addClass('section araxxor')
.append(
$('<h3>').html('<a href="/w/Araxxor" title="Araxxor">Araxxor</a>'),
$araxxor
),
$('<div>')
.addClass('section rots')
.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>'),
$rots
)
)
);
}
// Spotlights container empty?
if( !self.settings.dd_spotlight && !self.settings.mg_spotlight && !self.settings.ed_spotlight ) {
$content.addClass('spotlights-empty');
} else {
$content.removeClass('spotlights-empty');
}
$content.find('.spotlight-spacer').removeClass('first');
// Minigame Spotlight
$content.find('.mg-spotlight').empty().prev().addClass('empty');
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
$content.find('.ed-spotlight').empty().prev().addClass('empty');
if (self.settings.ed_spotlight) {
var ed_array = spotlights(ed_spotlights, 1, 0);
$content.find('.ed-spotlight').prev().removeClass('empty');
$content.find('.ed-spotlight').append(
$('<label>').text('Elite Dungeon Spotlight'),
$('<span>').addClass('spotlight-value').html('<a href="/w/' + ed_array[0] + '" title="' + ed_array[0] + '">' + ed_array[0] + '</a>')
);
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])
);
}
} else if (!self.settings.mg_spotlight) {
$content.find('.ed-spotlight').prev().removeClass('first');
$content.find('.ed-spotlight').next().addClass('first');
}
/**
* Sends notifications to the browser based on user prefs
* @return {undefined}
*/
notifs: function () {
mw.log('Running notifications');
// TODO: Check that still not using service worker notifs
if (self.swnotif) {
mw.log('Exiting notifications, using service worker instead');
window.clearInterval(notiftimer);
return;
}
// Notifications to send
var notifs = [];
// Latest rotations and settings from localStorage
if (rs.hasLocalStorage()) {
var last = {};
try {
last = JSON.parse(localStorage.getItem(localLast));
} catch (err) {
last = {};
console.warn('Error loading latest rotations from localStorage');
}
for (var l in last) {
self.lastRot[l] = last[l];
}
var prefs = {};
try {
prefs = JSON.parse(localStorage.getItem(localKey));
} catch (err) {
prefs = {};
console.warn('Error loading settings (events)');
}
for (var p in prefs) {
self.settings[p] = prefs[p];
}
}
// Exit if notifs turned off
if (!self.settings.notifs) {
mw.log('Exiting notifications, they\'ve been disabled');
return;
}
// Current UTC time
var now = moment.utc();
// Prevent multiple tabs from updating in short period of time
mw.log( now.diff(moment(self.lastRot.time), 'seconds') );
if ( now.diff(moment(self.lastRot.time), 'seconds') <= 255 ) {
return;
} else {
self.lastRot.time = now.format();
}
// VoS
if (now.isBefore( moment(now).startOf('hour').add(10,'minutes') )) {
var vosError = function (jqXHR, status, error) {
console.warn('Error loading VoS:\n' + status + ': ' + error);
};
var vosSucc = function (vosjson, status, jqXHR) {
if (!vosjson.districts) {
vosError({}, 'Missing districts', 'returned json did not contain a districts array');
return;
}
var vostext = vosjson.districts[0] + ',' + vosjson.districts[1];
if (vostext !== self.lastRot.vos) {
self.lastRot.vos = vostext;
var vosnotifs = [];
vosjson.districts.forEach( function (clan) {
if (self.settings.notiftype['vos' + clan] && self.settings.notiftype.vos == 'Some' || self.settings.notiftype.allvos) {
var img = rs.getFileURL(clan + ' Clan.png');
vosnotifs.push( { title:'VoS ' + clan, opts:{
badge: img,
body: 'Voice of Seren is now active in the ' + clan + ' district.',
tag: 'vos-' + clan,
icon: img,
image: img,
vibrate: true,
renotify: true,
requireInteraction: false
} } );
}
});
self.sendNotifs( vosnotifs, true );
// 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');
}
}
}
}
$.ajax({
dataType: 'json',
url: simplevosurl,
error: vosError,
success: vosSucc
});
}
// Dailies
simple_dailies.forEach( function (dd) {
if (self.settings.notiftype[dd.id] && self.settings.notiftype.dailies == 'Some' || self.settings.notiftype.alldailies) {
var next = moment(now).startOf(dd.from).add((dd.offset), 'minutes'),
nextEnd = moment(next).add(dd.length, 'minutes'),
text = dd.name + ' is going on now!';
while (!now.isBefore(nextEnd)) {
next.add(dd.repeat, 'minutes');
nextEnd.add(dd.repeat, 'minutes');
}
if (now.isBefore(next) && next.diff(now, 'seconds') <= 300) {
// Will happen soon
text = dd.name + ' is starting in ' + next.fromNow(true);
notifs.push( { title:dd.name, opts:{
badge: dd.img,
body: text,
tag: 'dd-' + dd.name,
icon: dd.img,
image: dd.img,
vibrate: true,
renotify: true,
requireInteraction: false
} } );
} else if (now.isAfter(next)) {
// Happening now
notifs.push( { title:dd.name, opts:{
badge: dd.img,
body: text,
tag: 'dd-on-' + dd.name,
icon: dd.img,
image: dd.img,
vibrate: true,
renotify: false,
requireInteraction: false
} } );
}
}
});
// 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) {
notifs.push( { title:'Daily Reset', opts:{
badge: img,
body: 'Daily reset in ' + dailyReset.fromNow(true),
tag: 'daily-reset',
icon: img,
image: img,
vibrate: true,
renotify: true,
requireInteraction: false
} } );
}
}
if (self.settings.notiftype.wreset) {
// Weekly
var weeklyReset = moment(now).day(3).startOf('day'),
img = '/images/4/47/D%26D_token_%28weekly%29_detail.png';
if (now.isAfter(weeklyReset)) {
weeklyReset.add(1, 'week');
}
if (weeklyReset.diff(now, 'minutes') <= 10 ) {
notifs.push( { title:'Weekly Reset', opts:{
badge: img,
body: 'Weekly reset in ' + weeklyReset.fromNow(true),
tag: 'weekly-reset-min',
icon: img,
image: img,
vibrate: true,
renotify: true,
requireInteraction: false
} } );
} else if (weeklyReset.diff(now, 'days') <= 1 && now.isAfter(moment(self.lastRot.wreset))) {
self.lastRot.wreset = weeklyReset.format();
notifs.push( { title:'Weekly Reset', opts:{
badge: img,
body: 'Weekly reset is tomorrow',
tag: 'weekly-reset',
icon: img,
image: img,
vibrate: true,
renotify: false,
requireInteraction: false
} } );
}
}
if (self.settings.notiftype.mreset) {
// Monthly
var monthlyReset = moment(now).add(1, 'months').startOf('month'),
img = '/images/thumb/a/a7/D%26D_token_%28monthly%29_detail.png/200px-D%26D_token_%28monthly%29_detail.png';
if (monthlyReset.diff(now, 'minutes') <= 10) {
notifs.push( { title:'Monthly Reset', opts:{
badge: img,
body: 'Monthly reset in ' + monthlyReset.fromNow(true),
tag: 'monthly-reset-min',
icon: img,
image: img,
vibrate: true,
renotify: true,
requireInteraction: false
} } );
} else if (monthlyReset.diff(now, 'days') <= 1 && now.isAfter(moment(self.lastRot.mreset))) {
self.lastRot.mreset = monthlyReset.format();
notifs.push( { title:'Monthly Reset', opts:{
badge: img,
body: 'Monthly reset is tomorrow',
tag: 'monthly-reset',
icon: img,
image: img,
vibrate: true,
renotify: false,
requireInteraction: false
} } );
}
}
// Daily cached
if (self.settings.notiftype.tms == 'All' || self.settings.notiftype.tms == 'Some' || self.settings.notiftype.etevents) {
self.loadEvents().then( function () {
var dnotifs = [];
// Events team events
if (self.settings.notiftype.etevents) {
var img = '/images/4/43/Apple-touch-icon.png';
et_events.forEach( function (e) {
var start = moment(e.date),
end = moment(start).add(e.length, 'minutes');
if (now.isBefore(start) && start.diff(now, 'seconds') <= 300) {
// Starting soon
dnotifs.push( { title:e.name, opts:{
badge: img,
body: 'Join the RS Wiki Events Team for ' + e.name + ' in ' + start.fromNow(true),
tag: 'et-' + e.name,
icon: img,
image: img,
vibrate: true,
renotify: false,
requireInteraction: false
} } );
} else if (now.isAfter(start) && now.isBefore(end)) {
// Going on
dnotifs.push( { title:e.name, opts:{
badge: img,
body: 'Join the RS Wiki Events Team for ' + e.name + ' going on now!',
tag: 'et-on-' + e.name,
icon: img,
image: img,
vibrate: true,
renotify: false,
requireInteraction: false
} } );
}
});
}
// 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];
};
// 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
} } );
}
}
// Send popup notifs
var popNotifs = function ( nl, noempty ) {
mw.log('Sending popup notifications');
// Google analytics tracker
if (typeof ga === 'function') {
ga('gtag_UA_126479006_1.send', 'event', 'Gadget-events', 'Send Notifactions', 'Popup', nl.length);
}
var createNotifs = function () {
var notiflist = $notifs.find('ul.event-notifications');
if ( !noempty ) {
notiflist.empty();
}
nl.forEach( function (n) {
mw.log('Sending ' + n.title);
notiflist.append(
$('<li>').addClass('event-notif').append(
$('<div>').addClass('notif-image').append(
$('<img>', {'src':n.opts.image, 'alt':n.title})
),
$('<label>').text(n.title),
$('<span>').text(n.opts.body)
)
);
});
notifpopup.toggle(true);
setTimeout(notifpopup.toggle, 180000, false);
};
if (!formMade) {
mw.log('Initialise interface');
mw.loader.using(['oojs-ui-core', 'oojs-ui-windows', 'oojs-ui-widgets']).then(self.initInt).then(createNotifs);
} else {
createNotifs();
}
};
// Check permissions
if (self.supportNotif && Notification.permission === 'granted' && !self.settings.nobrownotifs) {
mw.log('Notification permission granted');
// Send browser notifications
sendNotifs( notifs );
} else if (self.supportNotif && Notification.permission !== 'denied' && !self.settings.nobrownotifs) {
mw.log('Requesting permission');
// Request permissions
Notification.requestPermission().then( function (permission) {
if (permission === 'granted') {
mw.log('Notification permission granted');
// Send browser notifications
sendNotifs( notifs );
} else {
mw.log('Notification permission denied or dismissed');
// Send popup notifications
popNotifs( notifs, add );
}
}, function () {
console.warn('Error getting notification permissions');
// Send popup notifications
popNotifs( notifs, add );
});
} else {
mw.log('Notificationpermission denied');
// Send popup notifications
popNotifs( notifs, add );
}
}
};
mw.loader.using(['ext.gadget.gsw-util', 'moment', 'mediawiki.api', 'mediawiki.api.messages'], function () {
$(self.init);
});
}(jQuery, mediaWiki, gswiki));
//</nowiki>