From e01821f527fb4efd79a1325d7a98c038fbc35e39 Mon Sep 17 00:00:00 2001 From: Markus Stefanko Date: Wed, 18 Jan 2017 00:43:13 +0700 Subject: [PATCH 01/14] Moved Refresh to own function --- src/main/Refresh.js | 10 ++++++++++ src/main/tabs/playing.js | 11 +---------- 2 files changed, 11 insertions(+), 10 deletions(-) create mode 100644 src/main/Refresh.js diff --git a/src/main/Refresh.js b/src/main/Refresh.js new file mode 100644 index 0000000..d543b1a --- /dev/null +++ b/src/main/Refresh.js @@ -0,0 +1,10 @@ +Main.k.refreshAll = function() { + // TODO: loading screen -- Optimize + + Main.refreshChat(); + Main.acListMaintainer.refresh(true); + Main.syncInvOffset(null,true); + Main.doChatPacks(); + Main.topChat(); + Main.onChanDone(ChatType.Local[1],true) +} \ No newline at end of file diff --git a/src/main/tabs/playing.js b/src/main/tabs/playing.js index b13151c..844b9b2 100644 --- a/src/main/tabs/playing.js +++ b/src/main/tabs/playing.js @@ -4403,16 +4403,7 @@ Main.k.tabs.playing = function() { // Page reloader Main.k.MakeButton(" "+ Main.k.text.gettext("Actualiser"), null, null, Main.k.text.gettext("Actualiser"), Main.k.text.gettext("Actualiser la page sans tout recharger. Fonctionnalité en cours d'optimisation.")) - .appendTo(leftbar).find("a").on("mousedown", function() { - // TODO: loading screen -- Optimize - - Main.refreshChat(); - Main.acListMaintainer.refresh(true); - Main.syncInvOffset(null,true); - Main.doChatPacks(); - Main.topChat(); - Main.onChanDone(ChatType.Local[1],true) - }); + .appendTo(leftbar).find("a").on("mousedown", Main.k.refreshAll); Main.k.MakeButton(Main.k.text.gettext("Nouvelle partie ?"), null, null, Main.k.text.gettext("Nouvelle partie"), Main.k.text.gettext("Vous venez de commencer une nouvelle partie ? Utilisez ce bouton pour supprimer les informations de votre ancienne partie")) From df21aa98acf41272f628b134848ec29d2ef689e5 Mon Sep 17 00:00:00 2001 From: Markus Stefanko Date: Wed, 18 Jan 2017 00:43:36 +0700 Subject: [PATCH 02/14] Added var to see if window is active or hidden --- src/globalVariable.js | 1 + src/main/init.js | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/globalVariable.js b/src/globalVariable.js index 6e7d2bb..3918442 100644 --- a/src/globalVariable.js +++ b/src/globalVariable.js @@ -47,6 +47,7 @@ Main.k.domain = document.domain; Main.k.mushurl = 'http://' + document.domain; Main.k.debug = true; Main.k.errorList = []; +Main.k.windowFocus = true; if(Main.k.debug){ var console = unsafeWindow.console; }else{ diff --git a/src/main/init.js b/src/main/init.js index eb4924b..1278daa 100644 --- a/src/main/init.js +++ b/src/main/init.js @@ -5,6 +5,14 @@ Main.k.init = function(){ Main.k.Game.init(); Main.k.initData(); Main.k.displayMainMenu(); + + //Check if tab is focused + $( window ).focus(function() { + Main.k.windowFocus = true; + }).blur(function() { + Main.k.windowFocus = false; + }); + //Integration with others scripts $( window ).load(function() { From c553e477a89acb8c3c906418a7bfe1b3ae66aeca Mon Sep 17 00:00:00 2001 From: Markus Stefanko Date: Wed, 18 Jan 2017 00:44:02 +0700 Subject: [PATCH 03/14] Send notifications via browser API if window inactive --- src/main/BrowserNotice.js | 52 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/main/BrowserNotice.js diff --git a/src/main/BrowserNotice.js b/src/main/BrowserNotice.js new file mode 100644 index 0000000..5477460 --- /dev/null +++ b/src/main/BrowserNotice.js @@ -0,0 +1,52 @@ +Main.k.browserNotice = function(msg){ + + // Let's check if the browser supports notifications + if (!("Notification" in window)) { + Main.k.quickNoticeError("This browser does not support desktop notifications"); + } + + // Let's check if the user is okay to get some notification + else if (Notification.permission === "granted") { + // If it's okay let's create a notification + // If window currently in focus, don't notify + if ( Main.k.windowFocus ) return; + Main.k.browserNotify(msg); + } + + // Otherwise, we need to ask the user for permission + // Note, Chrome does not implement the permission static property + // So we have to check for NOT 'denied' instead of 'default' + else if (Notification.permission !== 'denied') { + Notification.requestPermission(function (permission) { + + // Whatever the user answers, we make sure we store the information + if(!('permission' in Notification)) { + Notification.permission = permission; + } + + // If the user is okay, let's create a notification + if (permission === "granted") { + // If window currently in focus, don't notify + if ( Main.k.windowFocus ) return; + Main.k.browserNotify(msg); + } + }); + } + + // At last, if the user already denied any notification, and you + // want to be respectful there is no need to bother him any more. +}; + +Main.k.browserNotify = function(msg) { + var options = { + body: msg, + icon: Main.k.servurl + "/img/icons/ui/mush.png" + } + + var notification = new Notification("Mush", options); + notification.onclick = function() { + window.focus(); + this.close(); + } + +} \ No newline at end of file From b5a1eed9bdd8f8525f016389b9009e70b48f4639 Mon Sep 17 00:00:00 2001 From: Markus Stefanko Date: Wed, 18 Jan 2017 00:50:38 +0700 Subject: [PATCH 04/14] StatusCheck Refreshes game every minute if tab active, and every 5 minutes if tab is not active Counts unread messages Sends a browser notification if tab inactive when : - You have X unread messages - Cycle change about to happen - Cycle change just happened --- src/main/StatusCheck.js | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/main/StatusCheck.js diff --git a/src/main/StatusCheck.js b/src/main/StatusCheck.js new file mode 100644 index 0000000..cc8dfbd --- /dev/null +++ b/src/main/StatusCheck.js @@ -0,0 +1,41 @@ +Main.k.statusCheck = function(){ + + Main.k.refreshAll(); + + var _now = new Date(); + var _elapsed = _now.getTime() - Main.tData.clientNow.getTime(); + var _timeToGo = (Main.tData.timeToCycle - _elapsed) / 1000.0 | 0; + + var _diffHI = parseInt(_timeToGo / 3600.0 | 0); + var _diffMI = parseInt(Math.abs(_timeToGo / 60.0 % 60.0)); + var _diffSI = parseInt(Math.abs(_timeToGo % 60)); + + var _unreads = 0; + + $('.cdNbNotRead').each(function(i, notReadEl ) { + _unreads += parseInt( $( notReadEl ).text() ); + }); + + if(_unreads > 0) { + Main.k.browserNotice("You have " + _unreads + " unread messages"); + } + + if(_diffHI == 0 && _diffMI < 3) { + Main.k.browserNotice("Cycle change about to happen"); + } + + if(_diffHI == 2 && _diffMI > 55) { + Main.k.browserNotice("Cycle change just happened"); + } + + // TODO : Make this configurable? + // TODO : Increase timer if long time in inactive tab + + // Check every minute + var timeout = 60000; + // If in hidden tab, check every 5 minutes + if(!Main.k.windowFocus) timeout = 300000; + + setTimeout(Main.k.statusCheck, timeout); + +} \ No newline at end of file From 5db415e13e6455b0f65be2712832ec69778d4990 Mon Sep 17 00:00:00 2001 From: Markus Stefanko Date: Wed, 18 Jan 2017 00:50:52 +0700 Subject: [PATCH 05/14] Start statusCheck on init() --- src/main/init.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/init.js b/src/main/init.js index 1278daa..64cd5a7 100644 --- a/src/main/init.js +++ b/src/main/init.js @@ -22,6 +22,9 @@ Main.k.init = function(){ $(this).removeAttr('data-async_src'); }); + //Start notification check and reloads + Main.k.statusCheck(); + }); }; Main.k.getFullName = function(dev_surname) { From c5812e43187fb1bf5b52884ef79b7f54f28cd7ac Mon Sep 17 00:00:00 2001 From: Markus Stefanko Date: Wed, 18 Jan 2017 00:52:04 +0700 Subject: [PATCH 06/14] Compiled changes --- CTRLW.user.js | 172 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 139 insertions(+), 33 deletions(-) diff --git a/CTRLW.user.js b/CTRLW.user.js index ae3763c..12dff43 100644 --- a/CTRLW.user.js +++ b/CTRLW.user.js @@ -69,6 +69,7 @@ Main.k.domain = document.domain; Main.k.mushurl = 'http://' + document.domain; Main.k.debug = true; Main.k.errorList = []; +Main.k.windowFocus = true; if(Main.k.debug){ var console = unsafeWindow.console; }else{ @@ -403,6 +404,14 @@ Main.k.init = function(){ Main.k.Game.init(); Main.k.initData(); Main.k.displayMainMenu(); + + //Check if tab is focused + $( window ).focus(function() { + Main.k.windowFocus = true; + }).blur(function() { + Main.k.windowFocus = false; + }); + //Integration with others scripts $( window ).load(function() { @@ -412,6 +421,9 @@ Main.k.init = function(){ $(this).removeAttr('data-async_src'); }); + //Start notification check and reloads + Main.k.statusCheck(); + }); }; Main.k.getFullName = function(dev_surname) { @@ -427,6 +439,58 @@ Main.k.getHeroBySurname = function(dev_surname) { } return null; }; +Main.k.browserNotice = function(msg){ + + // Let's check if the browser supports notifications + if (!("Notification" in window)) { + Main.k.quickNoticeError("This browser does not support desktop notifications"); + } + + // Let's check if the user is okay to get some notification + else if (Notification.permission === "granted") { + // If it's okay let's create a notification + // If window currently in focus, don't notify + if ( Main.k.windowFocus ) return; + Main.k.browserNotify(msg); + } + + // Otherwise, we need to ask the user for permission + // Note, Chrome does not implement the permission static property + // So we have to check for NOT 'denied' instead of 'default' + else if (Notification.permission !== 'denied') { + Notification.requestPermission(function (permission) { + + // Whatever the user answers, we make sure we store the information + if(!('permission' in Notification)) { + Notification.permission = permission; + } + + // If the user is okay, let's create a notification + if (permission === "granted") { + // If window currently in focus, don't notify + if ( Main.k.windowFocus ) return; + Main.k.browserNotify(msg); + } + }); + } + + // At last, if the user already denied any notification, and you + // want to be respectful there is no need to bother him any more. +}; + +Main.k.browserNotify = function(msg) { + var options = { + body: msg, + icon: Main.k.servurl + "/img/icons/ui/mush.png" + } + + var notification = new Notification("Mush", options); + notification.onclick = function() { + window.focus(); + this.close(); + } + +} Main.k.MakeButton = function(content, href, onclick, tiptitle, tipdesc) { var but = $("
").addClass("action but"); var butbr = $("
").addClass("butright").appendTo(but); @@ -456,25 +520,6 @@ Main.k.clearCache = function(){ localStorage.removeItem('ctrlw_remaining_cycles'); window.location.reload(); }; -Main.k.countdownTimer = {}; -Main.k.countdownTimer.counters = {}; -Main.k.countdownTimer.go = function(seconds, id, callback){ - var count = seconds; - var $this = this; - this.counters[id] = setInterval(function(){ - count--; - callback(count); - if(count <= 0){ - clearInterval($this.counters[id]); - } - }, 1000); //1000 will run it every 1 second -}; - -Main.k.countdownTimer.stop = function (id){ - if(typeof(this.counters[id]) != "undefined"){ - clearInterval(this.counters[id]); - } -}; // BUG Main.k.treatingBug = function(e){ Main.k.errorList += e; @@ -717,6 +762,57 @@ Main.k.ClosePopup = function() { } }; exportFunction(Main.k.ClosePopup, unsafeWindow.Main.k, {defineAs: "ClosePopup"}); +Main.k.refreshAll = function() { + // TODO: loading screen -- Optimize + + Main.refreshChat(); + Main.acListMaintainer.refresh(true); + Main.syncInvOffset(null,true); + Main.doChatPacks(); + Main.topChat(); + Main.onChanDone(ChatType.Local[1],true) +} +Main.k.statusCheck = function(){ + + Main.k.refreshAll(); + + var _now = new Date(); + var _elapsed = _now.getTime() - Main.tData.clientNow.getTime(); + var _timeToGo = (Main.tData.timeToCycle - _elapsed) / 1000.0 | 0; + + var _diffHI = parseInt(_timeToGo / 3600.0 | 0); + var _diffMI = parseInt(Math.abs(_timeToGo / 60.0 % 60.0)); + var _diffSI = parseInt(Math.abs(_timeToGo % 60)); + + var _unreads = 0; + + $('.cdNbNotRead').each(function(i, notReadEl ) { + _unreads += parseInt( $( notReadEl ).text() ); + }); + + if(_unreads > 0) { + Main.k.browserNotice("You have " + _unreads + " unread messages"); + } + + if(_diffHI == 0 && _diffMI < 3) { + Main.k.browserNotice("Cycle change about to happen"); + } + + if(_diffHI == 2 && _diffMI > 55) { + Main.k.browserNotice("Cycle change just happened"); + } + + // TODO : Make this configurable? + // TODO : Increase timer if long time in inactive tab + + // Check every minute + var timeout = 60000; + // If in hidden tab, check every 5 minutes + if(!Main.k.windowFocus) timeout = 300000; + + setTimeout(Main.k.statusCheck, timeout); + +} Main.k.SyncAstropad = function(tgt){ if(typeof(Main.AstroPad) != 'undefined'){ Main.AstroPad.updateInventory(false, Main.k.SyncAstropadNotice); @@ -837,6 +933,25 @@ Main.k.InvertObject = function(obj){ } return new_obj; }; +Main.k.countdownTimer = {}; +Main.k.countdownTimer.counters = {}; +Main.k.countdownTimer.go = function(seconds, id, callback){ + var count = seconds; + var $this = this; + this.counters[id] = setInterval(function(){ + count--; + callback(count); + if(count <= 0){ + clearInterval($this.counters[id]); + } + }, 1000); //1000 will run it every 1 second +}; + +Main.k.countdownTimer.stop = function (id){ + if(typeof(this.counters[id]) != "undefined"){ + clearInterval(this.counters[id]); + } +}; Main.k.css = {}; @@ -1909,10 +2024,6 @@ Main.k.Game.init = function() { } Main.k.Game.data = JSON.parse(ctrlw_game); }; -Main.k.Game.clear = function(){ - Main.k.Game.data.day = 0; - this.save(); -}; // Shows the actual number of remaining cycles Main.k.displayRemainingCyclesToNextLevel = function (){ $('.levelingame').each(function(){ @@ -1964,6 +2075,10 @@ Main.k.onCycleChange = function(){ localStorage.removeItem('ctrlw_remaining_cycles',0); // ----------------------------------- // }; +Main.k.Game.clear = function(){ + Main.k.Game.data.day = 0; + this.save(); +}; Main.k.Game.save = function() { localStorage.setItem("ctrlw_game",JSON.stringify(Main.k.Game.data)); }; @@ -6785,16 +6900,7 @@ Main.k.tabs.playing = function() { // Page reloader Main.k.MakeButton(" "+ Main.k.text.gettext("Actualiser"), null, null, Main.k.text.gettext("Actualiser"), Main.k.text.gettext("Actualiser la page sans tout recharger. Fonctionnalité en cours d'optimisation.")) - .appendTo(leftbar).find("a").on("mousedown", function() { - // TODO: loading screen -- Optimize - - Main.refreshChat(); - Main.acListMaintainer.refresh(true); - Main.syncInvOffset(null,true); - Main.doChatPacks(); - Main.topChat(); - Main.onChanDone(ChatType.Local[1],true) - }); + .appendTo(leftbar).find("a").on("mousedown", Main.k.refreshAll); Main.k.MakeButton(Main.k.text.gettext("Nouvelle partie ?"), null, null, Main.k.text.gettext("Nouvelle partie"), Main.k.text.gettext("Vous venez de commencer une nouvelle partie ? Utilisez ce bouton pour supprimer les informations de votre ancienne partie")) From 97bd5e7b2f21399c0a18a715618879b21dfb780c Mon Sep 17 00:00:00 2001 From: Markus Stefanko Date: Wed, 18 Jan 2017 00:52:14 +0700 Subject: [PATCH 07/14] Updated README with install and dev instructions --- README.md | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2c2e507..dcb8ef6 100644 --- a/README.md +++ b/README.md @@ -8,19 +8,46 @@ Mush (Spanish) : http://mush.twinoid.es Initially created by kill0u, now maintained by badconker. -Download +How to install ====== + +CTRL+W works with Firefox(GreaseMonkey) or Chrome(TamperMonkey). + + - In Firefox, install the [GreaseMonkey](https://addons.mozilla.org/firefox/addon/greasemonkey/) Add-On + - In Chrome, install the [TamperMonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo) extension + +After you've added the script, you can install CTRL+W by opening one of the following files : + +Enjoy! Translators ====== I you want to help me to translate the script in English and Spanish, you have only to edit the .po file in translations directory with .po editor (like poedit : http://www.poedit.net/) -Thank you. :) \ No newline at end of file +Thank you. :) + + + +Developers +====== + +First make sure you have gulp installed - you can install it by running the following commands from the root directory ( provided you have `npm` installed ) +``` +npm install +npm install gulp-cli -g +``` + +After making your changes in the `src` folder, build the latest CTRLW.user.js with : +``` +gulp +``` + +Finally submit your PR requests to the `dev` branch. \ No newline at end of file From ec982dfa09c7228cf4d5b889599939d4b653d677 Mon Sep 17 00:00:00 2001 From: Markus Stefanko Date: Wed, 18 Jan 2017 01:00:01 +0700 Subject: [PATCH 08/14] Wrong image URL fixed --- CTRLW.user.js | 2 +- src/main/BrowserNotice.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CTRLW.user.js b/CTRLW.user.js index 12dff43..e5a3be4 100644 --- a/CTRLW.user.js +++ b/CTRLW.user.js @@ -481,7 +481,7 @@ Main.k.browserNotice = function(msg){ Main.k.browserNotify = function(msg) { var options = { body: msg, - icon: Main.k.servurl + "/img/icons/ui/mush.png" + icon: "/img/icons/ui/mush.png" } var notification = new Notification("Mush", options); diff --git a/src/main/BrowserNotice.js b/src/main/BrowserNotice.js index 5477460..8545f8b 100644 --- a/src/main/BrowserNotice.js +++ b/src/main/BrowserNotice.js @@ -40,7 +40,7 @@ Main.k.browserNotice = function(msg){ Main.k.browserNotify = function(msg) { var options = { body: msg, - icon: Main.k.servurl + "/img/icons/ui/mush.png" + icon: "/img/icons/ui/mush.png" } var notification = new Notification("Mush", options); From efd9d519d606b53c0fbaa6f246b4663a53fb755b Mon Sep 17 00:00:00 2001 From: Markus Stefanko Date: Wed, 18 Jan 2017 01:46:35 +0700 Subject: [PATCH 09/14] Translations --- ctrl-w.pot | 12 ++++++++++++ src/main/StatusCheck.js | 7 ++++--- translations/en/LC_MESSAGES/ctrl-w.po | 12 ++++++++++++ translations/es/LC_MESSAGES/ctrl-w.po | 12 ++++++++++++ translations/fr/LC_MESSAGES/ctrl-w.po | 12 ++++++++++++ 5 files changed, 52 insertions(+), 3 deletions(-) diff --git a/ctrl-w.pot b/ctrl-w.pot index d4e421f..e071b58 100644 --- a/ctrl-w.pot +++ b/ctrl-w.pot @@ -1080,3 +1080,15 @@ msgstr "" msgid "Canal privé" msgstr "" + +msgid "You have %1 unread message" +msgstr "" + +msgid "You have %1 unread messages" +msgstr "" + +msgid "Cycle change about to happen" +msgstr "" + +msgid "Cycle change just happened" +msgstr "" \ No newline at end of file diff --git a/src/main/StatusCheck.js b/src/main/StatusCheck.js index cc8dfbd..c31efb9 100644 --- a/src/main/StatusCheck.js +++ b/src/main/StatusCheck.js @@ -17,15 +17,16 @@ Main.k.statusCheck = function(){ }); if(_unreads > 0) { - Main.k.browserNotice("You have " + _unreads + " unread messages"); + var _unreadMSG = Main.k.text.strargs(Main.k.text.ngettext("You have %1 unread message","You have %1 unread messages",_unreads),[_unreads]); + Main.k.browserNotice(_unreadMSG); } if(_diffHI == 0 && _diffMI < 3) { - Main.k.browserNotice("Cycle change about to happen"); + Main.k.browserNotice(Main.k.text.gettext('Cycle change about to happen')); } if(_diffHI == 2 && _diffMI > 55) { - Main.k.browserNotice("Cycle change just happened"); + Main.k.browserNotice(Main.k.text.gettext('Cycle change just happened')); } // TODO : Make this configurable? diff --git a/translations/en/LC_MESSAGES/ctrl-w.po b/translations/en/LC_MESSAGES/ctrl-w.po index 593a863..7910b16 100644 --- a/translations/en/LC_MESSAGES/ctrl-w.po +++ b/translations/en/LC_MESSAGES/ctrl-w.po @@ -1128,3 +1128,15 @@ msgstr "connected" msgid "Canal privé" msgstr "Private channel" + +msgid "You have %1 unread message" +msgstr "You have %1 unread message" + +msgid "You have %1 unread messages" +msgstr "You have %1 unread messages" + +msgid "Cycle change about to happen" +msgstr "Cycle change about to happen" + +msgid "Cycle change just happened" +msgstr "Cycle change just happened" \ No newline at end of file diff --git a/translations/es/LC_MESSAGES/ctrl-w.po b/translations/es/LC_MESSAGES/ctrl-w.po index dc4e517..4bc3b9a 100644 --- a/translations/es/LC_MESSAGES/ctrl-w.po +++ b/translations/es/LC_MESSAGES/ctrl-w.po @@ -1097,6 +1097,18 @@ msgstr "conectado(a)" msgid "Canal privé" msgstr "Canal privado" +msgid "You have %1 unread message" +msgstr "" + +msgid "You have %1 unread messages" +msgstr "" + +msgid "Cycle change about to happen" +msgstr "" + +msgid "Cycle change just happened" +msgstr "" + #~ msgid "Description inactif" #~ msgstr "Si tus barras de \"pa\" están llenas, eres considerado como inactivo y te vuelves un blanco fácil. No queremos imaginar lo que pasará..." diff --git a/translations/fr/LC_MESSAGES/ctrl-w.po b/translations/fr/LC_MESSAGES/ctrl-w.po index 9cab3ed..f0e79e6 100644 --- a/translations/fr/LC_MESSAGES/ctrl-w.po +++ b/translations/fr/LC_MESSAGES/ctrl-w.po @@ -1079,3 +1079,15 @@ msgstr "" msgid "Canal privé" msgstr "" + +msgid "You have %1 unread message" +msgstr "" + +msgid "You have %1 unread messages" +msgstr "" + +msgid "Cycle change about to happen" +msgstr "" + +msgid "Cycle change just happened" +msgstr "" \ No newline at end of file From 46bb3310fe9bdd5cfb5917c9fc82edabce09e60d Mon Sep 17 00:00:00 2001 From: Markus Stefanko Date: Wed, 18 Jan 2017 03:14:02 +0700 Subject: [PATCH 10/14] Timeout var, and cancel timeout on restart ( needed for options ) --- src/main/StatusCheck.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/StatusCheck.js b/src/main/StatusCheck.js index c31efb9..59dc03c 100644 --- a/src/main/StatusCheck.js +++ b/src/main/StatusCheck.js @@ -1,5 +1,6 @@ Main.k.statusCheck = function(){ + if (!!Main.k.statusTimeout) clearTimeout(Main.k.statusTimeout); Main.k.refreshAll(); var _now = new Date(); @@ -33,10 +34,10 @@ Main.k.statusCheck = function(){ // TODO : Increase timer if long time in inactive tab // Check every minute - var timeout = 60000; + var _timeout = 60000; // If in hidden tab, check every 5 minutes - if(!Main.k.windowFocus) timeout = 300000; + if(!Main.k.windowFocus) _timeout = 300000; - setTimeout(Main.k.statusCheck, timeout); + Main.k.statusTimeout = setTimeout(Main.k.statusCheck, _timeout); } \ No newline at end of file From b4eb24a663971ab2a29e3eec1e092d4ac2ba8ca7 Mon Sep 17 00:00:00 2001 From: Markus Stefanko Date: Wed, 18 Jan 2017 03:20:39 +0700 Subject: [PATCH 11/14] Refactored options to objects with keys Numeric indexes with disabled options were started to be messy. E.g. option 4 is disabled, and next option 5 doesn't exist, as it's the "new" 4. Changed this by switching over to option names as keys. It also makes the template a bit more readable, as values are adressed with their keys and not indexes. ( opt[2] -> opt.refresh ) Compatible with existing cookies. --- src/main/options/init.js | 54 +++++++++++++++++++++++++++----- src/main/options/initData.js | 2 +- src/main/options/open.js | 17 +++++----- src/main/options/update.js | 4 +-- src/main/options/updateCookie.js | 10 +++--- src/main/options/updateOpt.js | 10 +++--- 6 files changed, 68 insertions(+), 29 deletions(-) diff --git a/src/main/options/init.js b/src/main/options/init.js index f914db2..416aa5a 100644 --- a/src/main/options/init.js +++ b/src/main/options/init.js @@ -1,12 +1,50 @@ Main.k.Options.init = function() { - Main.k.Options.options = [ - // Option Name, Option Object, Need refresh, After(), Desc - ["cbubbles", Main.k.Options.cbubbles, false, Main.k.customBubbles, Main.k.text.gettext("Activer la mise en forme personnalisée des messages (bordure + couleur nom + image de fond).")], - ["cbubblesNB", Main.k.Options.cbubblesNB, false, Main.k.customBubbles, Main.k.text.gettext("Simplifier la mise en forme personnalisée des messages (suppression de l'image de fond).")], - ["dlogo", Main.k.Options.dlogo, true, null, Main.k.text.gettext("Afficher le logo Mush au dessus des onglets.")], - ["splitpjt", Main.k.Options.splitpjt, false, Main.k.updateBottom, Main.k.text.gettext("Séparer les projets / recherches / pilgred sous la zone de jeu.")] - //["altpa", Main.k.Options.altpa, true, null, "Utiliser des images alternatives pour les pa / pm."] - ]; + + Main.k.Options.options = {}; + + /** + + Option format : + + Main.k.Options.options.OPTIONNAME = { + option: Main.k.Options.OPTIONNAME, // Option value to change + text: Main.k.text.gettext("description"), // Description text + after: callback, // (Optional) After option changed, call this function + refresh: true, // (Optional) Page refresh needed after option change? + }; + + */ + + Main.k.Options.options.cbubbles = { + option: Main.k.Options.cbubbles, + after: Main.k.customBubbles, + text: Main.k.text.gettext("Activer la mise en forme personnalisée des messages (bordure + couleur nom + image de fond)."), + }; + + Main.k.Options.options.cbubblesNB = { + option: Main.k.Options.cbubblesNB, + after: Main.k.customBubbles, + text: Main.k.text.gettext("Simplifier la mise en forme personnalisée des messages (suppression de l'image de fond)."), + }; + + Main.k.Options.options.dlogo = { + option: Main.k.Options.dlogo, + refresh: true, + text: Main.k.text.gettext("Afficher le logo Mush au dessus des onglets."), + }; + + Main.k.Options.options.splitpjt = { + option: Main.k.Options.splitpjt, + after: Main.k.updateBottom, + text: Main.k.text.gettext("Séparer les projets / recherches / pilgred sous la zone de jeu."), + }; + + // Main.k.Options.options.altpa = { + // option: Main.k.Options.altpa, + // refresh: true, + // text: "Utiliser des images alternatives pour les pa / pm." + // }; + var cook = js.Cookie.get("ctrlwoptions"); if (!cook) return; diff --git a/src/main/options/initData.js b/src/main/options/initData.js index 6274334..ca4a834 100644 --- a/src/main/options/initData.js +++ b/src/main/options/initData.js @@ -9,4 +9,4 @@ Main.k.Options.dlogo = false; Main.k.Options.splitpjt = true; Main.k.Options.altpa = false; Main.k.Options.mushNoConf = false; -Main.k.Options.options = []; +Main.k.Options.options = {}; diff --git a/src/main/options/open.js b/src/main/options/open.js index 986eab3..a1ff14d 100644 --- a/src/main/options/open.js +++ b/src/main/options/open.js @@ -17,10 +17,10 @@ Main.k.Options.open = function() { $("

").addClass("warning").text(Main.k.text.gettext("Plus d'options disponibles prochainement.")).appendTo(td); - for (var i=0; i").css({ color: "#EEE", @@ -30,19 +30,18 @@ Main.k.Options.open = function() { margin: "10px 20px", clear: "both" }) - .html('') + .html('') .appendTo(td); var chk = $("").css({ "float": "left" }) .attr("type", "checkbox") - .attr("optname", opt[0]) - .attr("id", 'ctrlw_'+opt[0]) - .attr("opti", i) + .attr("optname", optname) + .attr("id", 'ctrlw_'+optname) .on("change", Main.k.Options.update) .prependTo(p); - if (opt[1]) chk.attr("checked", "checked"); + if (opt.option) chk.attr("checked", "checked"); } Main.k.MakeButton(" "+ Main.k.text.gettext("Vider le cache du script"), null, null, Main.k.text.gettext("Vider le cache du script"), diff --git a/src/main/options/update.js b/src/main/options/update.js index 07c1a4e..90b92f1 100644 --- a/src/main/options/update.js +++ b/src/main/options/update.js @@ -2,9 +2,9 @@ Main.k.Options.update = function(e) { var tgt = $(e.target); var key = $(tgt).attr("optname"); var val = $(tgt).is(":checked") ? "y" : "n"; - var i = $(tgt).attr("opti"); + var optname = $(tgt).attr("optname"); Main.k.Options.updateOpt(key,val); Main.k.Options.updateCookie(); - if (Main.k.Options.options[i][3]) Main.k.Options.options[i][3](); + if (!!Main.k.Options.options[optname].after) Main.k.Options.options[optname].after(); }; \ No newline at end of file diff --git a/src/main/options/updateCookie.js b/src/main/options/updateCookie.js index 597e2d3..1dbde25 100644 --- a/src/main/options/updateCookie.js +++ b/src/main/options/updateCookie.js @@ -1,9 +1,11 @@ Main.k.Options.updateCookie = function() { var cook = ""; - for (var i=0; i0) cook += "|"; - cook += Main.k.Options.options[i][0] + ":"; - cook += Main.k.Options.options[i][1] ? "y" : "n"; + for (var optname in Main.k.Options.options) { + if (cook != "") cook += "|"; + + cook += optname + ":"; + cook += Main.k.Options.options[optname].option ? "y" : "n"; + } js.Cookie.set("ctrlwoptions",cook,420000000); diff --git a/src/main/options/updateOpt.js b/src/main/options/updateOpt.js index d83838b..83056e9 100644 --- a/src/main/options/updateOpt.js +++ b/src/main/options/updateOpt.js @@ -3,25 +3,25 @@ Main.k.Options.updateOpt = function(key, val) { case "custombubbles": case "cbubbles": Main.k.Options.cbubbles = (val == "y"); - Main.k.Options.options[0][1] = (val == "y"); + Main.k.Options.options.cbubbles.option = (val == "y"); break; case "custombubbles_nobackground": case "cbubblesNB": Main.k.Options.cbubblesNB = (val == "y"); - Main.k.Options.options[1][1] = (val == "y"); + Main.k.Options.options.cbubblesNB.option = (val == "y"); break; case "displaylogo": case "dlogo": Main.k.Options.dlogo = (val == "y"); - Main.k.Options.options[2][1] = (val == "y"); + Main.k.Options.options.dlogo.option = (val == "y"); break; case "splitpjt": Main.k.Options.splitpjt = (val == "y"); - Main.k.Options.options[3][1] = (val == "y"); + Main.k.Options.options.splitpjt.option = (val == "y"); break; //case "altpa": // Main.k.Options.altpa = (val == "y"); - // Main.k.Options.options[4][1] = (val == "y"); + // Main.k.Options.options.altpa.option = (val == "y"); // break; } }; \ No newline at end of file From f63e9349f6854039c6ee2930fcd0ed44d22014fd Mon Sep 17 00:00:00 2001 From: Markus Stefanko Date: Wed, 18 Jan 2017 03:22:03 +0700 Subject: [PATCH 12/14] Option to enable/disable mush browser notifications --- src/main/StatusCheck.js | 2 ++ src/main/options/init.js | 5 +++++ src/main/options/initData.js | 1 + src/main/options/updateOpt.js | 4 ++++ 4 files changed, 12 insertions(+) diff --git a/src/main/StatusCheck.js b/src/main/StatusCheck.js index 59dc03c..0e49628 100644 --- a/src/main/StatusCheck.js +++ b/src/main/StatusCheck.js @@ -1,6 +1,8 @@ Main.k.statusCheck = function(){ if (!!Main.k.statusTimeout) clearTimeout(Main.k.statusTimeout); + if (!Main.k.Options.browserNot) return; + Main.k.refreshAll(); var _now = new Date(); diff --git a/src/main/options/init.js b/src/main/options/init.js index 416aa5a..b9e4fe7 100644 --- a/src/main/options/init.js +++ b/src/main/options/init.js @@ -45,6 +45,11 @@ Main.k.Options.init = function() { // text: "Utiliser des images alternatives pour les pa / pm." // }; + Main.k.Options.options.browserNot = { + option: Main.k.Options.browserNot, + after: Main.k.statusCheck, + text: Main.k.text.gettext("Show browser notifications when tab is inactive.") + }; var cook = js.Cookie.get("ctrlwoptions"); if (!cook) return; diff --git a/src/main/options/initData.js b/src/main/options/initData.js index ca4a834..6823c3e 100644 --- a/src/main/options/initData.js +++ b/src/main/options/initData.js @@ -9,4 +9,5 @@ Main.k.Options.dlogo = false; Main.k.Options.splitpjt = true; Main.k.Options.altpa = false; Main.k.Options.mushNoConf = false; +Main.k.Options.browserNot = true; Main.k.Options.options = {}; diff --git a/src/main/options/updateOpt.js b/src/main/options/updateOpt.js index 83056e9..1d6ce5a 100644 --- a/src/main/options/updateOpt.js +++ b/src/main/options/updateOpt.js @@ -23,5 +23,9 @@ Main.k.Options.updateOpt = function(key, val) { // Main.k.Options.altpa = (val == "y"); // Main.k.Options.options.altpa.option = (val == "y"); // break; + case "browserNot": + Main.k.Options.browserNot = (val == "y"); + Main.k.Options.options.browserNot.option = (val == "y"); + break; } }; \ No newline at end of file From 67ce1a0092bdb499ac57777c341f869624bf3ec9 Mon Sep 17 00:00:00 2001 From: Markus Stefanko Date: Wed, 18 Jan 2017 03:23:06 +0700 Subject: [PATCH 13/14] gettext for browser option --- ctrl-w.pot | 3 +++ translations/en/LC_MESSAGES/ctrl-w.po | 5 ++++- translations/es/LC_MESSAGES/ctrl-w.po | 3 +++ translations/fr/LC_MESSAGES/ctrl-w.po | 3 +++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ctrl-w.pot b/ctrl-w.pot index e071b58..033acee 100644 --- a/ctrl-w.pot +++ b/ctrl-w.pot @@ -1091,4 +1091,7 @@ msgid "Cycle change about to happen" msgstr "" msgid "Cycle change just happened" +msgstr "" + +msgid "Show browser notifications when tab is inactive." msgstr "" \ No newline at end of file diff --git a/translations/en/LC_MESSAGES/ctrl-w.po b/translations/en/LC_MESSAGES/ctrl-w.po index 7910b16..bc0fbaf 100644 --- a/translations/en/LC_MESSAGES/ctrl-w.po +++ b/translations/en/LC_MESSAGES/ctrl-w.po @@ -1139,4 +1139,7 @@ msgid "Cycle change about to happen" msgstr "Cycle change about to happen" msgid "Cycle change just happened" -msgstr "Cycle change just happened" \ No newline at end of file +msgstr "Cycle change just happened" + +msgid "Show browser notifications when tab is inactive." +msgstr "Show browser notifications when tab is inactive." \ No newline at end of file diff --git a/translations/es/LC_MESSAGES/ctrl-w.po b/translations/es/LC_MESSAGES/ctrl-w.po index 4bc3b9a..dbbe1d9 100644 --- a/translations/es/LC_MESSAGES/ctrl-w.po +++ b/translations/es/LC_MESSAGES/ctrl-w.po @@ -1109,6 +1109,9 @@ msgstr "" msgid "Cycle change just happened" msgstr "" +msgid "Show browser notifications when tab is inactive." +msgstr "" + #~ msgid "Description inactif" #~ msgstr "Si tus barras de \"pa\" están llenas, eres considerado como inactivo y te vuelves un blanco fácil. No queremos imaginar lo que pasará..." diff --git a/translations/fr/LC_MESSAGES/ctrl-w.po b/translations/fr/LC_MESSAGES/ctrl-w.po index f0e79e6..8cc17ce 100644 --- a/translations/fr/LC_MESSAGES/ctrl-w.po +++ b/translations/fr/LC_MESSAGES/ctrl-w.po @@ -1090,4 +1090,7 @@ msgid "Cycle change about to happen" msgstr "" msgid "Cycle change just happened" +msgstr "" + +msgid "Show browser notifications when tab is inactive." msgstr "" \ No newline at end of file From f54d366e9b7719cbc40dad4ca57763cb5778fd6e Mon Sep 17 00:00:00 2001 From: Markus Stefanko Date: Wed, 18 Jan 2017 03:23:37 +0700 Subject: [PATCH 14/14] gulped user.js --- CTRLW.user.js | 123 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 88 insertions(+), 35 deletions(-) diff --git a/CTRLW.user.js b/CTRLW.user.js index e5a3be4..d517a46 100644 --- a/CTRLW.user.js +++ b/CTRLW.user.js @@ -774,6 +774,9 @@ Main.k.refreshAll = function() { } Main.k.statusCheck = function(){ + if (!!Main.k.statusTimeout) clearTimeout(Main.k.statusTimeout); + if (!Main.k.Options.browserNot) return; + Main.k.refreshAll(); var _now = new Date(); @@ -791,26 +794,27 @@ Main.k.statusCheck = function(){ }); if(_unreads > 0) { - Main.k.browserNotice("You have " + _unreads + " unread messages"); + var _unreadMSG = Main.k.text.strargs(Main.k.text.ngettext("You have %1 unread message","You have %1 unread messages",_unreads),[_unreads]); + Main.k.browserNotice(_unreadMSG); } if(_diffHI == 0 && _diffMI < 3) { - Main.k.browserNotice("Cycle change about to happen"); + Main.k.browserNotice(Main.k.text.gettext('Cycle change about to happen')); } if(_diffHI == 2 && _diffMI > 55) { - Main.k.browserNotice("Cycle change just happened"); + Main.k.browserNotice(Main.k.text.gettext('Cycle change just happened')); } // TODO : Make this configurable? // TODO : Increase timer if long time in inactive tab // Check every minute - var timeout = 60000; + var _timeout = 60000; // If in hidden tab, check every 5 minutes - if(!Main.k.windowFocus) timeout = 300000; + if(!Main.k.windowFocus) _timeout = 300000; - setTimeout(Main.k.statusCheck, timeout); + Main.k.statusTimeout = setTimeout(Main.k.statusCheck, _timeout); } Main.k.SyncAstropad = function(tgt){ @@ -2145,17 +2149,61 @@ Main.k.Options.dlogo = false; Main.k.Options.splitpjt = true; Main.k.Options.altpa = false; Main.k.Options.mushNoConf = false; -Main.k.Options.options = []; +Main.k.Options.browserNot = true; +Main.k.Options.options = {}; Main.k.Options.init = function() { - Main.k.Options.options = [ - // Option Name, Option Object, Need refresh, After(), Desc - ["cbubbles", Main.k.Options.cbubbles, false, Main.k.customBubbles, Main.k.text.gettext("Activer la mise en forme personnalisée des messages (bordure + couleur nom + image de fond).")], - ["cbubblesNB", Main.k.Options.cbubblesNB, false, Main.k.customBubbles, Main.k.text.gettext("Simplifier la mise en forme personnalisée des messages (suppression de l'image de fond).")], - ["dlogo", Main.k.Options.dlogo, true, null, Main.k.text.gettext("Afficher le logo Mush au dessus des onglets.")], - ["splitpjt", Main.k.Options.splitpjt, false, Main.k.updateBottom, Main.k.text.gettext("Séparer les projets / recherches / pilgred sous la zone de jeu.")] - //["altpa", Main.k.Options.altpa, true, null, "Utiliser des images alternatives pour les pa / pm."] - ]; + + Main.k.Options.options = {}; + + /** + + Option format : + + Main.k.Options.options.OPTIONNAME = { + option: Main.k.Options.OPTIONNAME, // Option value to change + text: Main.k.text.gettext("description"), // Description text + after: callback, // (Optional) After option changed, call this function + refresh: true, // (Optional) Page refresh needed after option change? + }; + + */ + + Main.k.Options.options.cbubbles = { + option: Main.k.Options.cbubbles, + after: Main.k.customBubbles, + text: Main.k.text.gettext("Activer la mise en forme personnalisée des messages (bordure + couleur nom + image de fond)."), + }; + + Main.k.Options.options.cbubblesNB = { + option: Main.k.Options.cbubblesNB, + after: Main.k.customBubbles, + text: Main.k.text.gettext("Simplifier la mise en forme personnalisée des messages (suppression de l'image de fond)."), + }; + + Main.k.Options.options.dlogo = { + option: Main.k.Options.dlogo, + refresh: true, + text: Main.k.text.gettext("Afficher le logo Mush au dessus des onglets."), + }; + + Main.k.Options.options.splitpjt = { + option: Main.k.Options.splitpjt, + after: Main.k.updateBottom, + text: Main.k.text.gettext("Séparer les projets / recherches / pilgred sous la zone de jeu."), + }; + + // Main.k.Options.options.altpa = { + // option: Main.k.Options.altpa, + // refresh: true, + // text: "Utiliser des images alternatives pour les pa / pm." + // }; + + Main.k.Options.options.browserNot = { + option: Main.k.Options.browserNot, + after: Main.k.statusCheck, + text: Main.k.text.gettext("Show browser notifications when tab is inactive.") + }; var cook = js.Cookie.get("ctrlwoptions"); if (!cook) return; @@ -2189,10 +2237,10 @@ Main.k.Options.open = function() { $("

").addClass("warning").text(Main.k.text.gettext("Plus d'options disponibles prochainement.")).appendTo(td); - for (var i=0; i").css({ color: "#EEE", @@ -2202,19 +2250,18 @@ Main.k.Options.open = function() { margin: "10px 20px", clear: "both" }) - .html('') + .html('') .appendTo(td); var chk = $("").css({ "float": "left" }) .attr("type", "checkbox") - .attr("optname", opt[0]) - .attr("id", 'ctrlw_'+opt[0]) - .attr("opti", i) + .attr("optname", optname) + .attr("id", 'ctrlw_'+optname) .on("change", Main.k.Options.update) .prependTo(p); - if (opt[1]) chk.attr("checked", "checked"); + if (opt.option) chk.attr("checked", "checked"); } Main.k.MakeButton(" "+ Main.k.text.gettext("Vider le cache du script"), null, null, Main.k.text.gettext("Vider le cache du script"), @@ -2230,18 +2277,20 @@ Main.k.Options.update = function(e) { var tgt = $(e.target); var key = $(tgt).attr("optname"); var val = $(tgt).is(":checked") ? "y" : "n"; - var i = $(tgt).attr("opti"); + var optname = $(tgt).attr("optname"); Main.k.Options.updateOpt(key,val); Main.k.Options.updateCookie(); - if (Main.k.Options.options[i][3]) Main.k.Options.options[i][3](); + if (!!Main.k.Options.options[optname].after) Main.k.Options.options[optname].after(); }; Main.k.Options.updateCookie = function() { var cook = ""; - for (var i=0; i0) cook += "|"; - cook += Main.k.Options.options[i][0] + ":"; - cook += Main.k.Options.options[i][1] ? "y" : "n"; + for (var optname in Main.k.Options.options) { + if (cook != "") cook += "|"; + + cook += optname + ":"; + cook += Main.k.Options.options[optname].option ? "y" : "n"; + } js.Cookie.set("ctrlwoptions",cook,420000000); @@ -2251,26 +2300,30 @@ Main.k.Options.updateOpt = function(key, val) { case "custombubbles": case "cbubbles": Main.k.Options.cbubbles = (val == "y"); - Main.k.Options.options[0][1] = (val == "y"); + Main.k.Options.options.cbubbles.option = (val == "y"); break; case "custombubbles_nobackground": case "cbubblesNB": Main.k.Options.cbubblesNB = (val == "y"); - Main.k.Options.options[1][1] = (val == "y"); + Main.k.Options.options.cbubblesNB.option = (val == "y"); break; case "displaylogo": case "dlogo": Main.k.Options.dlogo = (val == "y"); - Main.k.Options.options[2][1] = (val == "y"); + Main.k.Options.options.dlogo.option = (val == "y"); break; case "splitpjt": Main.k.Options.splitpjt = (val == "y"); - Main.k.Options.options[3][1] = (val == "y"); + Main.k.Options.options.splitpjt.option = (val == "y"); break; //case "altpa": // Main.k.Options.altpa = (val == "y"); - // Main.k.Options.options[4][1] = (val == "y"); + // Main.k.Options.options.altpa.option = (val == "y"); // break; + case "browserNot": + Main.k.Options.browserNot = (val == "y"); + Main.k.Options.options.browserNot.option = (val == "y"); + break; } };