MediaWiki:Gadget-events.js/sandbox

De RuneScape Wiki
Ir para: navegação, pesquisa

// /** * Interface for events * * @version 1.1 * @author JaydenKieran * @author Elessar2 * @author ThePsionic * */ /*global jQuery, mediaWiki, mw, rswiki, 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 = 'rsw-events-prefs', localLast = 'rsw-events-last', vosurl = 'https://chisel.weirdgloop.org/api/runescape/vos/history', simplevosurl = 'https://chisel.weirdgloop.org/api/runescape/vos'; // Dailies var simple_dailies = [ { name:'Grande Chinchompa', id:'bigchin', link:'/w/Grande_Chinchompa', length:20, repeat:60, offset:30, from:'hour', img:'/images/6/63/Nyriki%27s_portal.png' }, { name:'Depósitos Guthixianos', id:'guthcache', link:'/w/Depósitos_Guthixianos', length:10, repeat:60, offset:0, from:'hour', img:'/images/thumb/2/23/Player_automaton.png/600px-Player_automaton.png' }, { name:'Depósitos Guthixianos (impulso)', id:'guthcacheb', link:'/w/Depósitos_Guthixianos', length:10, repeat:(60*3), offset:0, from:'day', img:'/images/8/8e/Confused_automaton.png' }, { name:'Dolinas', id:'sinkhole', link:'/w/Dolinas', length:25, repeat:60, offset:30, from:'hour', img:'/images/5/5c/Sinkhole_entrance.png' }, { name:'Invasões de Demônios', id:'demonmob', link:'/w/Invasão_de_Demônios', length:5, repeat:60, offset:0, from:'hour', img:'/images/1/1f/Agrith_Naar_chathead.png' }, { name:'Traineira de pesca', id:'fishflin', link:'/w/Traineira de pesca', length:10, repeat:20, offset:0, from:'hour', img:'/images/thumb/c/cb/Fish_Flingers_logo.png/200px-Fish_Flingers_logo.png' }, { name:'Escolta de Suprimentos', id:'goebiesup', link:'/w/Escolta_de_Suprimentos', length:25, repeat:(60 * 12), offset:0, from:'day', img:'/images/9/9e/Goebie_chathead.png' }, { name:'Bandos de Guerra da Terra Selvagem', id:'wildwar', link:'/w/Bandos de Guerra da Terra Selvagem', length:10, repeat:(60 * 7), offset:(60 * 2), from:'isoWeek', img:'/images/5/57/Wilderness_Warbands_emblem.png' }, ]; // VoS Locations var voslocs = { 'Amlodd':['ONO','Oés-noroeste'], 'Crwys':['ENE','És-nordeste'], 'Cadarn':['ESE','És-sudeste'], 'Hefin':['NNE','Nor-nordeste'], 'Iorwerth':['SSO','Su-sudoeste'], 'Ithell':['OSO','Oés-sudoeste'], 'Meilyr':['NNE','Nor-nordeste'], 'Trahaearn':['SSE','Su-sudeste'] }; // TM stock items var tmsStock = [ {data:'Barril de iscas', label:'Barril de iscas'}, {data:'Aquário Emaranhado', label:'Aquário Emaranhado'}, {data:'Vara de pescar quebrada', label:'Vara de pescar quebrada'}, {data:'Talismã funerário goebie pq.', label:'Talismã funerário goebie pq.'}, {data:'Talismã funerário goebie', label:'Talismã funerário goebie'}, {data:'Presente Menaphita (pq)', label:'Presente Menaphita (pq)'}, {data:'Presente Menaphita (M)', label:'Presente Menaphita (M)'}, {data:'Runa do ar instável', label:'Runa do ar instável'}, {data:'Cristal de anima', label:'Cristal de anima'}, {data:'Cupom Vip de Extermínio', label:'Cupom Vip de Extermínio'}, {data:'Ficha D&D (Diária)', label:'Ficha D&D (Diária)'}, {data:'Melhorador dano não sintoniz.', label:'Melhorador dano não sintoniz.'}, {data:'Argila sagrada', label:'Argila sagrada'}, {data:'Anima Fragmentada', label:'Anima Fragmentada'}, {data:'Núcleo de pulsação avançada', label:'Núcleo de pulsação avançada'}, {data:'Planta Vil', label:'Planta Vil'}, {data:'Presente do Ceifador', label:'Presente do Ceifador'}, {data:'Plumas de Falcão de Prata', label:'Plumas de Falcão de Prata'}, {data:'Talismã Funerário Goebie (G)', label:'Talismã Funerário Goebie (G)'}, {data:'Mensagem na garrafa', label:'Mensagem na garrafa'}, {data:'Lâmpada de Dragonkin', label:'Lâmpada de Dragonkin'}, {data:'Carta Curinga de Dungeon', label:'Carta Curinga de Dungeon'}, {data:'Presente menaphita (G)', label:'Presente menaphita (G)'}, {data:'Taijitu', label:'Taijitu'}, {data:'Ficha de D&D (semanal)', label:'Ficha de D&D (semanal)'}, {data:'Ficha de D&D (mensal)', label:'Ficha de D&D (mensal)'}, {data:'Antiga efígie faminta', label:'Antiga efígie faminta'}, {data:' Poeira harmônica', label:' Poeira harmônica'}, {data:'Tríscele de Cristal', label:'Tríscele de Cristal'}, {data:'Dardo mata-tudo', label:'Dardo mata-tudo'}, {data:'Melhorador recompensa não sintoniz.', label:'Melhorador recompensa não sintoniz.'} ]; // Player-owned farm resets var pofresets = ['Comprador Pequeno', 'Comprador Médio', 'Comprador Grande', 'Pedido Fácil', 'Pedido Médio', 'Pedido Difícil']; // Spotlight lists var dd_spotlights = ['Estrela Cadente', 'Esconde-Esconde de Pinguim', 'Circo', 'Árvore Sinistra'], mg_spotlights = ['Controle da Praga', 'Guerra das Almas', 'Punho de Guthix', 'Assalto Bárbaro', 'Conquista', 'Traineira de Pesca', 'O Grande Projeto Orbe', 'Fábrica de Pó Luminoso', 'Guerra das Cidadelas', 'Criações Profanas', 'Festival de Socos de Repolhos', 'Pega Ladrão', 'Guerra das Almas', 'Assalto Bárbaro, 'Conquista', 'Punho de Guthix', 'Guerra das Cidadelas', 'Controle da Praga', 'Guerra das Almas', 'Traineira de Pesca', 'O Grande Projeto Orbe', 'Fábrica de Pó Luminoso', 'Criações Profanas', 'Festival de Socos de Repolhos', 'Pega Ladrão', 'Me dá um Refresco', 'Guerra das Cidadelas'], ed_spotlights = ['Templo de Aminishi', 'Laboratório Dragonkin', 'O Recife das Sombras']; // PvM tables var rax_array = [ 'Servos', 'Ácido', 'Escuridão' ], vorago_rotations = ['Ceiling collapse', 'Scopulus', 'Vitalis', 'Green bomb', 'TeamSplit', 'The End'], vorago_hm = { 'Ceiling collapse':{pathTen:'TeamSplit / Green bomb', pathElev:'TeamSplit / Vitalis', unlock:'Torso of Omens'}, 'Scopulus':{pathTen:'Purple bomb / TeamSplit', pathElev:'Purple bomb / Vitalis', unlock:'Helm of Omens'}, 'Vitalis':{pathTen:'Vitalis / Purple bomb', pathElev:'Vitalis / Bleeds', unlock:'Legs of Omens'}, 'Green bomb':{pathTen:'Green bomb / Vitalis', pathElev:'Green bomb / TeamSplit', unlock:'Boots of Omens'}, 'TeamSplit':{pathTen:'TeamSplit / TeamSplit', pathElev:'TeamSplit / Purple bomb', unlock:'Maul of Omens'}, 'The End':{pathTen:'Purple bomb / Bleeds', pathElev:'Purple bomb / Vitalis', unlock:'Gloves of Omens'} }, rn = { A:'Ahrim', D:'Dharok', G:'Guthan', K:'Karil', T:'Torag', V:'Verac'}, rots_rotations = [ [[rn.D,rn.T,rn.V], [rn.K,rn.A,rn.G]], [[rn.K,rn.T,rn.G], [rn.A,rn.D,rn.V]], [[rn.K,rn.G,rn.V], [rn.A,rn.T,rn.D]], [[rn.G,rn.T,rn.V], [rn.K,rn.A,rn.D]], [[rn.K,rn.T,rn.V], [rn.A,rn.G,rn.D]], [[rn.A,rn.G,rn.D], [rn.K,rn.T,rn.V]], [[rn.K,rn.A,rn.D], [rn.G,rn.T,rn.V]], [[rn.A,rn.T,rn.D], [rn.K,rn.G,rn.V]], [[rn.A,rn.D,rn.V], [rn.K,rn.T,rn.G]], [[rn.K,rn.A,rn.G], [rn.T,rn.D,rn.V]], [[rn.A,rn.T,rn.G], [rn.K,rn.D,rn.V]], [[rn.A,rn.G,rn.V], [rn.K,rn.T,rn.D]], [[rn.K,rn.A,rn.T], [rn.G,rn.D,rn.V]], [[rn.K,rn.A,rn.V], [rn.D,rn.T,rn.G]], [[rn.A,rn.T,rn.V], [rn.K,rn.D,rn.G]], [[rn.K,rn.D,rn.G], [rn.A,rn.T,rn.V]], [[rn.D,rn.T,rn.G], [rn.K,rn.A,rn.V]], [[rn.G,rn.D,rn.V], [rn.K,rn.A,rn.T]], [[rn.K,rn.T,rn.D], [rn.A,rn.G,rn.V]], [[rn.K,rn.D,rn.V], [rn.A,rn.T,rn.G]] ]; 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'); } $('.rsw-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: ['rsw-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', 'rsw-notifs-anchor')); var notifclose = new OO.ui.ButtonWidget({ classes: ['oo-ui-labelElement-invisible'], icon: 'close', id:'rsw-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: $('#rsw-notifs-anchor'), anchor: false, autoClose: true, classes: ['rsw-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; }); // Travelling merchant stock var tmsapi = api.get({ action:'parse', prop:'text', disablelimitreport:1, contentmodel:'wikitext', text:'{{Travelling_Merchant/api|format=json}}', }).then( function (ret) { mw.log('Todays travelling merchant stock from api'); mw.log(ret); if (ret.parse && ret.parse.text) { var string = ret.parse.text['*'].replace('<div class=\"mw-parser-output\"><p>', '').replace('</p></div>', ''); var obj = JSON.parse(string); mw.log(obj); merchstock.tod = obj.items; self.saveSetting('cache.tms', obj.items); } else { throw 'Could not parse tm data for today'; } }, function (err) { console.warn('Error getting todays travelling merchant stock'); console.warn(err); throw err; }); // Travelling merchant stock var tmsTomapi = api.get({ action:'parse', prop:'text', disablelimitreport:1, contentmodel:'wikitext', text:'{{Travelling_Merchant/api|offset=1|format=json}}', }).then( function (ret) { mw.log('Tomorrows travelling merchant stock from api'); mw.log(ret); if (ret.parse && ret.parse.text) { var string = ret.parse.text['*'].replace('<div class=\"mw-parser-output\"><p>', '').replace('</p></div>', ''); var obj = JSON.parse(string); mw.log(obj); merchstock.tmr = obj.items; self.saveSetting('cache.tmsTom', obj.items); } else { throw 'Could not parse tm data for tomorrow'; } }, function (err) { console.warn('Error getting tomorrows travelling merchant stock'); console.warn(err); 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:'rsw-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:'rsw-events-setbut', invisibleLabel: true, label: 'Configurações', 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('Diárias'), $('<ul>').addClass('events-list daily-list') ), $('<div>') .addClass('raven section') ), $('<div>') .addClass('col col-r') .append( $('<div>') .addClass('resets section') .append( $('<h3>').text('Reinícios'), $('<div>') .addClass('event-boxes') .append( $('<div>') .addClass('day event-box') .append( $('<label>').addClass('by-line').text('Dia'), $('<time>').addClass('event-name countdown-day').text('? hrs') ), $('<div>') .addClass('week event-box') .append( $('<label>').addClass('by-line').text('Semana'), $('<time>').addClass('event-name countdown-week').text('? days') ), $('<div>') .addClass('month event-box') .append( $('<label>').addClass('by-line').text('Mês'), $('<time>').addClass('event-name countdown-month').text('? days') ) ) ), $('<div>') .addClass('voice section') .append( $('<h3>').html('<a href="/w/Voz_de_Seren" title="Voz de Seren">Voz de Seren</a>'), $('<div>') .addClass('VoS-time by-line') .text( 'Houve um erro ao carregar a Voz de Seren. Por favor, tente novamente.<br/>Se este erro persistir, por favor, <a href="/w/en:RS:AR">contate um administrador</a>.' ), $('<div>') .addClass('VoS-container event-boxes'), $('<div>') .addClass('by-line') .append( $('<span>').text('Últimos distritos: '), $('<span>').addClass('VoS-last').text('não encontrado') ) ) ) ), $('<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: 'rsw-events-backbut', invisibleLabel: true, label: 'Voltar', framed: false }); var closeset = function () { self.updateTimes(); self.updateVos(); self.updateSpots(); $('.rsw-events-popup .events-settings').addClass('slideout'); setTimeout( function () { $('.rsw-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:'por tempo' }, { data:'by name', label:'por nome' } ], }); settingsForm.sort.setValue(self.settings.daily_sort); settingsForm.sortLay = new OO.ui.FieldLayout(settingsForm.sort, { label: 'Ordenação' }); settingsForm.sort.on('change', self.saveSetting, ['daily_sort']); // Show browser notifications settingsForm.notifs = new OO.ui.ToggleSwitchWidget({ title: 'Receber notificações pelo navegador', 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: 'Configurações de Notificação', framed: false }); settingsForm.notifSets.on('click', function () { self.openNotifs(); }); settingsForm.notifsLay = new OO.ui.ActionFieldLayout(settingsForm.notifs, settingsForm.notifSets, { label: 'Notifications', help: 'Permite notificações para os eventos configurados. Atualmente em desenvolvimento.' }); // Show raven spawn settingsForm.raven = new OO.ui.ToggleSwitchWidget({ title: 'Prifddinas Raven', value: self.settings.raven }); settingsForm.ravenLay = new OO.ui.FieldLayout(settingsForm.raven, { label: 'Raven' }); settingsForm.raven.on('change', self.saveSetting, ['raven']); // Show events team events settingsForm.events = new OO.ui.ToggleSwitchWidget({ title: 'Mostrar eventos', 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: 'Número de Eventos', help: 'Número de eventos a serem mostrados. Use 0 para infinitos.' }); 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 travelling merchant stock settingsForm.tms = new OO.ui.ToggleSwitchWidget({ title: 'Show Travelling Merchant stock', value: self.settings.merch }); settingsForm.tmsLay = new OO.ui.FieldLayout(settingsForm.tms, { label: 'Mercador Viajante', help: 'Mostrar a loja de hoje e amanhã do estoque do Mercador Viajante' }); settingsForm.tms.on('change', self.saveSetting, ['merch']); // Show player-owned farm resets settingsForm.pof = new OO.ui.ToggleSwitchWidget({ title: 'Mostrar reinícios do Projeto de Obra Rural', value: self.settings.farm }); settingsForm.pofLay = new OO.ui.FieldLayout(settingsForm.pof, { label: 'Projeto de Obra Rural', help: 'Mostrar o tempo para o próximo reinício dos compradores do projeto de obra rural e os pedidos' }); settingsForm.pof.on('change', self.saveSetting, ['farm']); // 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: 'Minijogo da Vez', help: 'Mostrar o Minijogo da Vez, D&D em destaque e a Masmorra de Elite em destaque' }); settingsForm.spots.on('change', function (val) { self.saveSetting('mg_spotlight', val); self.saveSetting('dd_spotlight', val); self.saveSetting('ed_spotlight', val); }); // 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 featured D&D spotlight settingsForm.dd = new OO.ui.ToggleSwitchWidget({ title: 'Mostrar D&D em destaque', 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 settingsForm.ed = new OO.ui.ToggleSwitchWidget({ title: 'Mostrar Masmorra de Elite em Destaque', 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: 'Mostrar próximo item da cez', value: self.settings.show_next }); settingsForm.nextLay = new OO.ui.FieldLayout(settingsForm.next, { label: 'Mostrar próximo', help: 'Motrar próximo item na rotação' }); settingsForm.next.on('change', self.saveSetting, ['show_next']); // Show PvM settingsForm.pvm = new OO.ui.ToggleSwitchWidget({ title: 'Mostrar rotações de PvM', value: self.settings.pvm }); settingsForm.pvmLay = new OO.ui.FieldLayout(settingsForm.pvm, { label: 'PvM Rotations' }); settingsForm.pvm.on('change', self.saveSetting, ['pvm']); // Force update events and travelling merchant stock settingsForm.fupdate = new OO.ui.ButtonWidget({ label: 'Recarregar', icon: 'reload', title: 'Força a atualização do estoque do mercador viajante e dos eventos' }); settingsForm.fupdateLay = new OO.ui.FieldLayout(settingsForm.fupdate, { label: 'Forçar atualição do MV', help: 'Força a atualização do estoque do mercador viajante e dos eventos independentemente da última atualização.' }); 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>') .addClass('footer') .html('<a href="/w/en:Help_talk:Gadget-events" title="Discussão do Gadget">Nos dê feedback!</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: 'rsw-notifs-backbut', invisibleLabel: true, label: 'Voltar', framed: false }); notifsForm.back.on('click', function () { $('.rsw-events-popup .events-notifs').addClass('slideout'); setTimeout( function () { $('.rsw-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: 'Destivar notificações pelo navegador', 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); } // Raven notifsForm.raven = new OO.ui.ToggleSwitchWidget({ title: 'Prifddinas raven notifications', value: self.settings.notiftype.raven }); notifsForm.raven.on('change', self.saveNotif, ['raven']); notifsForm.ravenLay = new OO.ui.FieldLayout(notifsForm.raven, { label: 'Raven' }); // 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' }); // All Voice of Seren notifsForm.vos = new OO.ui.DropdownInputWidget({ options: [ { data:'None', label:'None' }, { data:'All', label:'All' }, { data:'Some', label:'Some' } ], title: 'Receive notifications for Voice of Seren', }); notifsForm.vos.setValue(self.settings.notiftype.vos); notifsForm.vosLay = new OO.ui.FieldLayout(notifsForm.vos, { label: 'Voice of Seren', help: 'Receive notifications for Voice of Seren' }); var togglevos = function (val) { self.saveNotif('vos', val); if (val == 'Some') { notifsForm.vosselLay.toggle(true); self.saveNotif('allvos', false); } 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.' }); if (self.settings.notiftype.vos != 'Some') { notifsForm.vosselLay.toggle(false); } // 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' }); // All travelling merchant stock notifsForm.tms = new OO.ui.DropdownInputWidget({ options: [ { data:'None', label:'None' }, { data:'All', label:'All' }, { data:'Some', label:'Some' } ], title: 'Receive notifications for Travelling Merchant stock', }); notifsForm.tms.setValue(self.settings.notiftype.tms); notifsForm.tmsLay = new OO.ui.FieldLayout(notifsForm.tms, { label: 'Travelling Merchant', help: 'Receive notifications for Travelling Merchant stock' }); var toggletms = function (val) { self.saveNotif('tms', val); if (val == 'Some') { notifsForm.tmsselLay.toggle(true); self.saveNotif('alltms', false); } else if (val == 'All') { notifsForm.tmsselLay.toggle(false); self.saveNotif('alltms', true); } else { notifsForm.tmsselLay.toggle(false); self.saveNotif('alltms', false); } }; notifsForm.tms.on('change', toggletms); // Specific traveling merchant stock notifsForm.tmssel = new OO.ui.MenuTagMultiselectWidget({ allowArbitrary: false, classes: ['notifs-group'], options: tmsStock }); var seltms = function (vals) { var items = []; vals.forEach( function (i) { items.push(i.data); }); self.saveNotif('tmsitems', items); }; notifsForm.tmssel.on('change', seltms); notifsForm.tmsselLay = new OO.ui.FieldLayout(notifsForm.tmssel, { align: 'top', label: 'Travelling Merchant stock', help: 'Choose the Travelling Merchant stock items you would like to be notified about' }); if (self.settings.notiftype.tmsitems) { self.settings.notiftype.tmsitems.forEach( function (item) { notifsForm.tmssel.addTag(item, item); }); } if (self.settings.notiftype.tms != 'Some') { notifsForm.tmsselLay.toggle(false); } // All PoF Resets notifsForm.pof = new OO.ui.DropdownInputWidget({ options: [ { data:'None', label:'None' }, { data:'All', label:'All' }, { data:'Some', label:'Some' } ], title: 'Receive notifications for player-owned farm resets', }); notifsForm.pof.setValue(self.settings.notiftype.pof); notifsForm.pofLay = new OO.ui.FieldLayout(notifsForm.pof, { label: 'Player-owned Farm', help: 'Receive notifications for player-owned farm resets' }); var togglepof = function (val) { self.saveNotif('pof', val); 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.pofselLay = new OO.ui.FieldLayout(notifsForm.pofsel, { align: 'top', label: 'Individual PoF resets', help: 'Choose the player-owned farm resets you wish to be notified about' }); if (self.settings.notiftype.pof != 'Some') { notifsForm.vosselLay.toggle(false); } // 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 () { $('.rsw-events-popup .events-notifs').addClass('slideout'); setTimeout( function () { $('.rsw-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('Nenhum evento previsto') ) ); 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(); // Error updating VoS var vosError = function (jqXHR, status, error) { console.warn('Error loading VoS:\n' + status + ': ' + error); $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>.'); $content.find('.VoS-container').empty(); $content.find('.VoS-last').empty().append('not found'); }; // Update Voice of Seren (VoS) var vosSucc = function (vosjson, status, jqXHR) { mw.log(vosjson); if (!(vosjson.data && vosjson.data[0] && vosjson.data[0].districts)) { vosError({}, 'Missing districts', 'returned json did not contain a districts array'); return; } var voschng = moment(now).add(1, 'hours').startOf('hour'), chngtitle = voschng.format('MMM D') + ' at ' + voschng.format('HH:mm') + ' game time', currvos = vosjson.data[0].districts, lastvos = vosjson.data[1].districts; $content.find('.VoS-time').empty().append( $('<time>').addClass('time').attr({ 'datetime':voschng.format(), 'title':chngtitle }).text(voschng.fromNow(true)), ' até que novos distritos estejam ativos.' ); $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>') ) ) ); $content.find('.VoS-last').empty(); $content.find('.VoS-last').append(lastvos[0] + ', ' + lastvos[1]); // Set time for next check self.nextvos = moment(now).startOf('hour').add(61, 'minutes').format(); }; // Make api Call $content.find('.VoS-time').empty().append('Loading current VoS...'); $content.find('.VoS-container').empty(); $content.find('.VoS-last').empty().append('Loading last VoS...'); $.ajax({ dataType: 'json', url: vosurl, error: vosError, success: vosSucc }); }, /** * 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)), ' até que novos distritos estejam ativos.' ); }, /** * Updates the values that are per day in the Events popup * Raven, spotlights (D&D, ED, MiniGame), PVM, Travelling Merchant * @return {undefined} */ updateSpots: function () { // Current UTC time var now = moment.utc(); // Update raven $content.find('.raven').empty(); if (self.settings.raven) { var $raven = $('<div>').addClass('raven-status by-line now').text('There is a raven currently spawned in Prifddinas.'), days_passed = -( moment('0', 'X').utc().add(6, 'days').diff(now, 'days') ), days_into = days_passed % 13; if (days_into > 0) { var when = moment(now).add((13 - days_into), 'days').startOf('day'), whenttl = when.format('MMM D') + ' at ' + when.format('HH:mm') + ' game time'; $raven = $('<div>').addClass('raven-status by-line').append( $('<time>').addClass('time').attr({ 'datetime':when.format(), 'title':whenttl }).text( when.fromNow(true) ), ' até o corvo aparecer em Prifddinas.' ); } $content.find('.raven').append( $('<h3>').html('<a href="/w/Corvo_(Prifddinas)" title="Corvo de Prifddinas">Corvo</a>'), $raven ); } // Travelling Merchant Stock var tmsimg = function (item) { if (item == 'uim') { return '<a href="/w/Mapa_da_ilha_inexplorada_(Pesca_em_Alto_Mar) title="Mapa da ilha inexplorada (Pesca em Alto Mar)"><img alt="Mapa da ilha inexplorada (Pesca em Alto Mar).png" src="/images/0/0d/Uncharted_island_map_%28Deep_Sea_Fishing%29.png?93a55"></a>'; } else if (item == 'Plumas de Falcão de Prata') { return '<a href="/w/' + item + '" title="' + item + '"><img alt="' + item +' 5.png" src="' + rs.getFileURL(item + ' 5.png') + '?1234"></a>'; } else { return '<a href="/w/' + item + '" title="' + item + '"><img alt="' + item +'.png" src="' + rs.getFileURL(item + '.png') + '?1234"></a>'; } }; $content.find('.tms-pof .tms').remove(); if (self.settings.merch) { var $tms = $('<div>').addClass('tms'); // Stock for today and tomorrow $tms.append( $('<h3>').html('<a href="/w/Loja_do_Mercador_Viajante" title="Loja do Mercador Viajante">Loja do Mercador Viajante</a>'), $('<div>').addClass('tms-pof-cols').append( $('<div>').addClass('tms-today').append( $('<div>').addClass('by-line').text('Estoque de hoje'), $('<div>').addClass('event-boxes inventory-image').append( $('<div>') .addClass('event-box') .html( tmsimg('uim') ) ) ), $('<div>').addClass('tms-tomorrow').append( $('<div>').addClass('by-line').text('Estoque de amanhã'), $('<div>').addClass('event-boxes inventory-image').append( $('<div>') .addClass('event-box') .html( tmsimg('uim') ) ) ) ) ); merchstock.tod.forEach( function (i) { var name = i.name.replace(/&/g, '&'); $tms.find('.tms-today .event-boxes').append( $('<div>') .addClass('event-box') .html( tmsimg(name) ) ); }); merchstock.tmr.forEach( function (i) { var name = i.name.replace(/&/g, '&'); $tms.find('.tms-tomorrow .event-boxes').append( $('<div>') .addClass('event-box') .html( tmsimg(name) ) ); }); if (self.settings.farm) { $tms.addClass('col col-l'); $content.find('.tms-pof').addClass('usecols'); } else { $tms.find('.tms-pof-cols').addClass('usecols'); $content.find('.tms-pof').removeClass('usecols'); } $content.find('.tms-pof').append( $tms ); } /** * Gets the current spotlight item, the next one, and time till next * @param {Array.<string>} items Array of the possible spotlights in the correct order * @param {number} duration Duration in days of a spotlight item * @param {number} offset Offset from 0 Unix time that rotation started in days * @return {Array.<string>} An array containing the current item, time till next, and next item */ var spotlights = function (items, duration, offset) { // Start rotation from Tuesday 1 January 1970, with an 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), when = moment(now).add(days_till, 'days').startOf('day'), whenttl = when.format('MMM D') + ' at ' + when.format('HH:mm') + ' game time', next = rotation + 1; if (next >= items.length) { next -= items.length; } mw.log(items); mw.log(days_into); mw.log(rotation); mw.log(items[rotation]); mw.log(days_till); mw.log(when.format()); mw.log(when.fromNow(true)); mw.log(items[next]); return [items[rotation], when.fromNow(true), items[next], when.format(), whenttl]; }; // Player-owned farm $content.find('.tms-pof .pof').remove(); if (self.settings.farm) { var small = moment(now).add(1, 'days').startOf('day'), smallttl = small.format('MMM D') + ' at ' + small.format('HH:mm') + ' game time', med_array = spotlights(['med'], 2, 1), large_array = spotlights(['large'], 3, 0), medr_array = spotlights(['med'], 3, 0), hardreq = moment(now).day(3).startOf('day'); if (now.isAfter(hardreq)) { hardreq.add(1, 'week'); } var hardreqttl = hardreq.format('MMM D') + ' at ' + hardreq.format('HH:mm') + ' game time'; var $pof = $('<div>').addClass('pof').append( $('<h3>').html('<a href="/w/Player-owned_farm" title="Player-owned farm">Player-owned farm</a>'), $('<div>').addClass('tms-pof-cols').append( $('<div>').addClass('buyers').append( $('<div>').addClass('by-line').text('Animal buyers'), $('<div>').addClass('event-boxes').append( $('<div>').addClass('event-box').append( $('<label>').addClass('by-line').text('Small'), $('<time>').addClass('event-name').attr({'datetime':small.format(), 'title':smallttl}).text( small.fromNow(true) ) ), $('<div>').addClass('event-box').append( $('<label>').addClass('by-line').text('Medium'), $('<time>').addClass('event-name').attr({'datetime':med_array[3], 'title':med_array[4]}).text( med_array[1] ) ), $('<div>').addClass('event-box').append( $('<label>').addClass('by-line').text('Large'), $('<time>').addClass('event-name').attr({'datetime':large_array[3], 'title':large_array[4]}).text( large_array[1] ) ) ) ), $('<div>').addClass('requests').append( $('<div>').addClass('by-line').text('Requests'), $('<div>').addClass('event-boxes').append( $('<div>').addClass('event-box').append( $('<label>').addClass('by-line').text('Easy'), $('<time>').addClass('event-name').attr({'datetime':small.format(), 'title':smallttl}).text( small.fromNow(true) ) ), $('<div>').addClass('event-box').append( $('<label>').addClass('by-line').text('Medium'), $('<time>').addClass('event-name').attr({'datetime':medr_array[3], 'title':medr_array[4]}).text( medr_array[1] ) ), $('<div>').addClass('event-box').append( $('<label>').addClass('by-line').text('Hard'), $('<time>').addClass('event-name').attr({'datetime':hardreq.format(), 'title':hardreqttl}).text( hardreq.fromNow(true) ) ) ) ) ) ); if (self.settings.merch) { $pof.addClass('col col-r'); $content.find('.tms-pof').addClass('usecols'); } else { $pof.find('.tms-pof-cols').addClass('usecols'); $content.find('.tms-pof').removeClass('usecols'); } $content.find('.tms-pof').append( $pof ); } // PvM $content.find('.pvm').empty(); if (self.settings.pvm) { var $vorago = $('<div>').addClass('pvm-value vorago-value'), $araxxor = $('<div>').addClass('pvm-value araxxor-value'), $rots = $('<div>').addClass('pvm-value rots-value'); // Vorago var vorago_array = spotlights( vorago_rotations, 7, 48), hm = vorago_hm[vorago_array[0]]; $vorago.append( $('<time>').attr({ 'datetime':vorago_array[3], 'title':vorago_array[4] }).text(vorago_array[1]).addClass('by-line'), $('<label>').text(' until next attack rotation.').addClass('by-line'), $('<div>').addClass('event-boxes').append( $('<div>').addClass('event-box').append( $('<div>').text(vorago_rotations[0]) ), $('<div>').addClass('event-box').append( $('<div>').text(vorago_rotations[1]) ), $('<div>').addClass('event-box').append( $('<div>').text(vorago_rotations[2]) ) ), $('<div>').addClass('event-boxes').append( $('<div>').addClass('event-box').append( $('<div>').text(vorago_rotations[3]) ), $('<div>').addClass('event-box').append( $('<div>').text(vorago_rotations[4]) ), $('<div>').addClass('event-box').append( $('<div>').text(vorago_rotations[5]) ) ), $('<ul>') .addClass('events-list') .append( $('<li>').append( $('<label>').html('Phase 10'), $('<span>').html(hm.pathTen) ), $('<li>').append( $('<label>').html('Phase 11'), $('<span>').html(hm.pathElev) ), $('<li>').append( $('<label>').text('Outfit of Omens unlock'), $('<span>').text(hm.unlock) ) ) ); $vorago.find(".event-box div:contains('" + vorago_array[0] + "')").parent().addClass('now'); if (self.settings.show_next) { $vorago.find('ul').append( $('<li>').append( $('<label>').addClass('sl-next-label').text('Next'), $('<span>').addClass('sl-next').text(vorago_array[2]) ) ); } // Araxxor var rax_inact = spotlights( rax_array, 4, 9); $araxxor.append( $('<time>').attr({ 'datetime':rax_inact[3], 'title':rax_inact[4] }).text(rax_inact[1]).addClass('by-line'), $('<label>').text(' until next path rotation.').addClass('by-line'), $('<div>').addClass('event-boxes') ); rax_array.forEach( function (path, num) { if (path == rax_inact[0]) { $araxxor.find('.event-boxes').append( $('<div>').addClass('event-box').append( $('<label>').addClass('by-line').append( 'Caminho ' + (num + 1) ), $('<label>').addClass('event-name').append(path) ) ); } else { $araxxor.find('.event-boxes').append( $('<div>').addClass('event-box now').append( $('<label>').addClass('by-line').append( 'Caminho ' + (num + 1) ), $('<label>').addClass('event-name').append(path) ) ); } }); if (self.settings.show_next) { $araxxor.append( $('<ul>').addClass('events-list').append( $('<li>').append( $('<label>').text('Próximo a fechar'), $('<span>').text(rax_inact[2]) ) ) ); } // Rise of the Six (RotS) var rots_array = spotlights( rots_rotations, 1, 0), cur = rots_array[0], nex = rots_array[2]; if (self.settings.show_next) { $rots.append( $('<div>').addClass('event-boxes').append( $('<div>').addClass('box-title by-line').text('Atual'), $('<div>').addClass('box-title by-line').text('Próximo') ), $('<div>').addClass('event-boxes').append( $('<div>').addClass('box-title by-line').text('Oeste'), $('<div>').addClass('box-title by-line').text('Leste'), $('<div>').addClass('box-title by-line').text('Oeste'), $('<div>').addClass('box-title by-line').text('Leste') ), $('<div>').addClass('event-boxes').append( $('<div>').addClass('event-box').append( $('<label>').addClass('event-title').text(cur[0][0]), $('<label>').addClass('event-title').text(cur[0][1]), $('<label>').addClass('event-title').text(cur[0][2]) ), $('<div>').addClass('event-box').append( $('<label>').addClass('event-title').text(cur[1][0]), $('<label>').addClass('event-title').text(cur[1][1]), $('<label>').addClass('event-title').text(cur[1][2]) ), $('<div>').addClass('event-box').append( $('<label>').addClass('event-title').text(nex[0][0]), $('<label>').addClass('event-title').text(nex[0][1]), $('<label>').addClass('event-title').text(nex[0][2]) ), $('<div>').addClass('event-box').append( $('<label>').addClass('event-title').text(nex[1][0]), $('<label>').addClass('event-title').text(nex[1][1]), $('<label>').addClass('event-title').text(nex[1][2]) ) ) ); } else { $rots.append( $('<div>').addClass('event-boxes').append( $('<div>').addClass('box-title by-line').text('Oeste'), $('<div>').addClass('box-title by-line').text('Leste') ), $('<div>').addClass('event-boxes').append( $('<div>').addClass('event-box').append( $('<label>').addClass('event-title').text(cur[0][0]), $('<label>').addClass('event-title').text(cur[0][1]), $('<label>').addClass('event-title').text(cur[0][2]) ), $('<div>').addClass('event-box').append( $('<label>').addClass('event-title').text(cur[1][0]), $('<label>').addClass('event-title').text(cur[1][1]), $('<label>').addClass('event-title').text(cur[1][2]) ) ) ); } // 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', 'Catacumbas: Despertar dos Seis').html('<a href="/w/Catacumbas:_Despertar_dos_Seis" title="Catacumbas: Despertar dos Seis">Despertar dos Seis</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('Minijogo da Vez'), $('<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('Masmorra de Elite em destaque'), $('<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'); } // D&D Spotlight $content.find('.dd-spotlight').empty().prev().addClass('empty'); if (self.settings.dd_spotlight) { var dd_array = spotlights(dd_spotlights, 7, 6); $content.find('.dd-spotlight').prev().removeClass('empty'); $content.find('.dd-spotlight').append( $('<label>').text('D&D em destaque'), $('<span>').addClass('dd-spotlight-value').html('<a href="/w/' + dd_array[0] + '" title="' + dd_array[0] + '">' + dd_array[0] + '</a>') ); if (self.settings.show_next) { $content.find('.dd-spotlight').append( $('<label>').addClass('sl-next').text('Próxima:'), $('<span>').addClass('sl-next dd-spotlight-next').text(dd_array[2] + ' in '), $('<time>').addClass('sl-next dd-spotlight-in').attr({ 'datetime':dd_array[3], 'title':dd_array[4] }).text(dd_array[1]) ); } } }, /** * 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); } settingsForm.raven.setValue(self.settings.raven); settingsForm.events.setValue(self.settings.et_events); 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); 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); $('.rsw-events-popup .events-settings').removeClass('oo-ui-element-hidden'); $('.rsw-events-popup .events-settings').addClass('slideout'); setTimeout( function () { $('.rsw-events-popup .events-settings').removeClass('slideout'); }, 5); }; self.loadSettings().then(switchWind(), switchWind()); }, /** * Opens the notifications form * @return {undefined} */ 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); $('.rsw-events-popup .events-notifs').removeClass('oo-ui-element-hidden'); $('.rsw-events-popup .events-notifs').addClass('slideout'); setTimeout( function () { $('.rsw-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'); // 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 }); } // Diárias simple_dailies.forEach( function (dd) { if (self.settings.notiftype[dd.id] && self.settings.notiftype.dailies == 'Alguns' || self.settings.notiftype.alldailies) { var next = moment(now).startOf(dd.from).add((dd.offset), 'minutos'), nextEnd = moment(next).add(dd.length, 'minutos'), text = dd.name + ' está acontecendo!'; while (!now.isBefore(nextEnd)) { next.add(dd.repeat, 'minutos'); nextEnd.add(dd.repeat, 'minutos'); } if (now.isBefore(next) && next.diff(now, 'segundos') <= 300) { // Will happen soon text = dd.name + ' vai começar em ' + 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 } } ); } } }); // Corvo if (self.settings.notiftype.raven) { var days_into = -( moment('0', 'X').utc().add(6, 'days').diff(now, 'days') ) % 13, text = 'O corvo está agora em Prifddinas', tag = 'raven', img = '/images/d/d5/Corvo_%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; } } } // Reiniícios 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:'Reinício Diário', opts:{ badge: img, body: 'Reinício diário em ' + 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:'Reinício Semanal', opts:{ badge: img, body: 'Reinício semanal em ' + 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:'Reinício Semanal', opts:{ badge: img, body: 'O reinício semanal é amanhã', 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:'Reinício Mensal', opts:{ badge: img, body: 'Reinício mensal em ' + 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:'Reinício Mensal', opts:{ badge: img, body: 'O reinício mensal é amanhã', 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: 'Entre para o time de eventos da Comu Pt-Br ' + e.name + ' em ' + 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: 'Entre para o time de eventos da Comu Pt-Br ' + e.name + ' está acontecendo agora!', tag: 'et-on-' + e.name, icon: img, image: img, vibrate: true, renotify: false, requireInteraction: false } } ); } }); } // Loja do Mercador Viajante if (self.settings.notiftype.tms == 'All' || self.settings.notiftype.tms == 'Some') { var tmsArray = merchstock.tod.map(function (i) { return i.name; }), tmsString = tmsArray.toString(); if (self.settings.notiftype.tms == 'All' && tmsString !== self.lastRot.tms) { // All items notification dnotifs.push( { title:'Mercador Viajante', opts:{ badge: '/images/e/e5/Travelling_merchant.png', body: 'Stock: '+tmsArray[0]+', '+tmsArray[1]+' and '+tmsArray[2], tag: 'tm-stock', icon: '/images/e/e5/Travelling_merchant.png', image: '/images/e/e5/Travelling_merchant.png', vibrate: true, renotify: true, requireInteraction: false } } ); self.lastRot.tms = tmsString; } else if (self.settings.notiftype.tms == 'Some' && tmsString !== self.lastRot.tms) { // Inidividual item notifications tmsArray.forEach( function (item, num) { item = item.replace(/&/g, '&'); if (self.settings.notiftype.tmsitems.indexOf(item) >= 0) { dnotifs.push( { title:'Mercador Viajante', opts:{ badge: '/images/e/e5/Travelling_merchant.png', body: item+' está disponível na Loja do Mercador Viajante hoje', tag: 'tm-item'+num, icon: '/images/e/e5/Travelling_merchant.png', image: '/images/e/e5/Travelling_merchant.png', vibrate: true, renotify: true, requireInteraction: false } } ); } }); self.lastRot.tms = tmsString; } } self.sendNotifs( dnotifs ); // 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'); } } }, 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' ); } } } // Hard request if (self.settings.notiftype.pof == 'All' || self.settings.notiftype['pofHard Request']) { var hrtime = moment(now).day(3).startOf('day'); if ( now.isAfter(hrtime) ) { hrtime.add(1, 'week'); } if ( hrtime.diff(now, 'minutes') <= 10 ) { pofnots.push( 'hard request' ); } } // 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 } } ); } } // Vorago if (self.settings.notiftype.vorago) { var rotation = curspotlight(vorago_rotations, 7, 48); if (rotation[0] != self.lastRot.vorago) { self.lastRot.vorago = rotation[0]; var img = '/images/1/18/Vorago_chathead.png'; notifs.push( { title:'Vorago', opts:{ badge: img, body: 'O ataque atual de Vorago é ' + rotation[1], tag: 'vorago', icon: img, image: img, vibrate: true, renotify: true, requireInteraction: false } } ); } } // Araxxor if (self.settings.notiftype.araxxor) { var rotation = curspotlight(rax_array, 4, 9); if (rotation[0] != self.lastRot.araxxor) { self.lastRot.araxxor = rotation[0]; var img = '/images/thumb/f/f2/Araxxor.png/500px-Araxxor.png', openpaths = []; rax_array.forEach( function (path, num) { if (path != rotation[1]) { num += 1; openpaths.push( path + ' (path ' + num + ')' ); } }); notifs.push( { title:'Araxxor', opts:{ badge: img, body: 'Os caminhos do Araxxor abertos são ' + openpaths[0] + ' e ' + openpaths[1], tag: 'araxxor', icon: img, image: img, vibrate: true, renotify: true, requireInteraction: false } } ); } } // Rise of the Six if (self.settings.notiftype.rots) { var rotation = curspotlight(rots_rotations, 1, 0); if (rotation[0] != self.lastRot.rots) { self.lastRot.rots = rotation[0]; var img = '/images/thumb/6/69/Barrows_totem_detail.png/150px-Barrows_totem_detail.png', curr = rotation[1], text = 'Current rotation, West: ' + curr[0][0] +' '+ curr[0][1] +' '+ curr[0][2] + ' and East: ' + curr[1][0] +' '+ curr[1][1] +' '+ curr[1][2]; notifs.push( { title:'Despertar dos Seis', opts:{ badge: img, body: text, tag: 'rots', icon: img, image: img, vibrate: true, renotify: true, 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:'Minijogo da Vez', opts:{ badge: img, body: 'O Minijogo da Vez é ' + 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 = { 'Templo de Aminishi':'/images/thumb/f/fd/Relic_of_aminishi_%28rare%29_detail.png/200px-Relic_of_aminishi_%28rare%29_detail.png', 'Laboratório Dragonkin':'/images/thumb/d/d4/Laboratory_relic_%28uncommon%29_detail.png/180px-Laboratory_relic_%28uncommon%29_detail.png', 'O Recife das Sombras':'/images/thumb/e/e5/Umbral_urn_detail.png/160px-Umbral_urn_detail.png' }, img = imgs[spot[1]]; notifs.push( { title:'Masmorra de Elite em destaque', opts:{ badge: img, body: 'A Masmorra de Elite em destaque é ' + spot[1], tag: 'edspot', icon: img, image: img, vibrate: true, renotify: true, requireInteraction: false } } ); } } // Distraction and Diversion of the week if (self.settings.notiftype.dd_spotlight) { var spot = curspotlight(dd_spotlights, 3, 49); if (spot[0] != self.lastRot.ddspot) { self.lastRot.ddspot = spot[0]; var img = '/images/6/62/D%26D_icon.png'; notifs.push( { title:'D&D da Semana', opts:{ badge: img, body: 'A Distração & Diversão da semana é ' + spot[1], tag: 'ddspot', icon: img, image: img, vibrate: true, renotify: true, requireInteraction: false } } ); } } self.sendNotifs( notifs ); // 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); }); }; // 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.rsw-util', 'moment', 'mediawiki.api', 'mediawiki.api.messages'], function () { $(self.init); }); }(jQuery, mediaWiki, rswiki)); //