Jeremy D commited on 2012-03-31 22:29:26
Showing 9 changed files, with 188 additions and 0 deletions.
... | ... |
@@ -0,0 +1,24 @@ |
1 |
+Copyright (c) 2012, SleePy (smf-mods-license@sleepycode.com) |
|
2 |
+All rights reserved. |
|
3 |
+ |
|
4 |
+Redistribution and use in source and binary forms, with or without |
|
5 |
+modification, are permitted provided that the following conditions are met: |
|
6 |
+ * Redistributions of source code must retain the above copyright |
|
7 |
+ notice, this list of conditions and the following disclaimer. |
|
8 |
+ * Redistributions in binary form must reproduce the above copyright |
|
9 |
+ notice, this list of conditions and the following disclaimer in the |
|
10 |
+ documentation and/or other materials provided with the distribution. |
|
11 |
+ * Neither the name of the <organization> nor the |
|
12 |
+ names of its contributors may be used to endorse or promote products |
|
13 |
+ derived from this software without specific prior written permission. |
|
14 |
+ |
|
15 |
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
|
16 |
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
17 |
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
18 |
+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY |
|
19 |
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
|
20 |
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
21 |
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
|
22 |
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
23 |
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
|
24 |
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
0 | 25 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,16 @@ |
1 |
+SMF 2.0+ Modification. I will not back support this mod to older versions. |
|
2 |
+ |
|
3 |
+This modification adds a unread PM counter to the favicon. In addition it continues to check for PMs at a specified interval. Setting this variable to lower can result in server degration/performance issues. Use with caution. The default timeout is 1 minute (60 seconds). |
|
4 |
+ |
|
5 |
+Prior to asking for support, check out the wiki: https://github.com/jdarwood007/smf-unreadPM_count/wiki |
|
6 |
+ |
|
7 |
+Credits for this ability go to Tom Moor for creating Tinycon: https://github.com/tommoor/tinycon |
|
8 |
+ |
|
9 |
+Browsers that support this: |
|
10 |
+Chrome 15+ |
|
11 |
+Firefox 9+ |
|
12 |
+Opera 11+ |
|
13 |
+ |
|
14 |
+The following browsers will fall back to changing the title due to lack of support for this: |
|
15 |
+Internet Explorer 9 |
|
16 |
+Safari 5 |
|
0 | 17 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,62 @@ |
1 |
+<?php |
|
2 |
+ |
|
3 |
+// This adds a hook to our action=. |
|
4 |
+function uPMs_hook_actionArray($actionArray) |
|
5 |
+{ |
|
6 |
+ global $modSettings; |
|
7 |
+ |
|
8 |
+ $actionArray['unreadpms'] = array('UnreadPMs.php', 'UnreadPMsXML'); |
|
9 |
+} |
|
10 |
+ |
|
11 |
+// Adds a hook to the end of loadTheme(); |
|
12 |
+function uPMs_hook_load_theme() |
|
13 |
+{ |
|
14 |
+ global $context, $settings, $modSettings; |
|
15 |
+ |
|
16 |
+ // Default the setting to 1 minute. |
|
17 |
+ if (!isset($modSettings['unreadPMstimeout'])) |
|
18 |
+ $modSettings['unreadPMstimeout'] = '60'; |
|
19 |
+ elseif (empty($modSettings['unreadPMstimeout']) || $context['user']['is_guest']) |
|
20 |
+ return; |
|
21 |
+ |
|
22 |
+ // Append the html headers. |
|
23 |
+ $context['html_headers'] .= ' |
|
24 |
+ <script type="text/javascript" src="' . $settings['default_theme_url'] . '/scripts/tinycon.min.js?fnl1"></script> |
|
25 |
+ <script type="text/javascript"><!-- // --><![CDATA[ |
|
26 |
+ var funreadPMs = function () |
|
27 |
+ { |
|
28 |
+ window.setTimeout(\'funreadPMs();\', ' . $modSettings['unreadPMstimeout'] * 600 . '); |
|
29 |
+ |
|
30 |
+ var oNewPms = getXMLDocument(smf_prepareScriptUrl(smf_scripturl) + \'action=unreadpms\'); |
|
31 |
+ |
|
32 |
+ if (oNewPms.responseXML) |
|
33 |
+ { |
|
34 |
+ var newCount = oNewPms.responseXML.getElementsByTagName(\'smf\')[0].getElementsByTagName(\'unreadpms\')[0].firstChild.nodeValue; |
|
35 |
+ Tinycon.setBubble(newCount); |
|
36 |
+ } |
|
37 |
+ } |
|
38 |
+ addLoadEvent(funreadPMs); |
|
39 |
+ // ]]></script>'; |
|
40 |
+} |
|
41 |
+ |
|
42 |
+ |
|
43 |
+// Adds a hook to the general mod settings so we can manage the setting. |
|
44 |
+function uPMs_hook_general_mod_settings($config_vars) |
|
45 |
+{ |
|
46 |
+ $config_vars[] = array('int', 'unreadPMstimeout', 'postinput' => $txt['unreadPMstimeout_post']); |
|
47 |
+} |
|
48 |
+ |
|
49 |
+// Provides the XML for our javascript to read. |
|
50 |
+function UnreadPMsXML() |
|
51 |
+{ |
|
52 |
+ global $user_info, $context; |
|
53 |
+ |
|
54 |
+ header('Content-Type: text/xml; charset=' . (empty($context['character_set']) ? 'ISO-8859-1' : $context['character_set'])); |
|
55 |
+ |
|
56 |
+ echo '<', '?xml version="1.0" encoding="', $context['character_set'], '"?', '> |
|
57 |
+<smf> |
|
58 |
+ <unreadpms>', $user_info['unread_messages'], '</unreadpms> |
|
59 |
+</smf>'; |
|
60 |
+ |
|
61 |
+ obExit(false, false, false); |
|
62 |
+} |
... | ... |
@@ -0,0 +1,19 @@ |
1 |
+<?php |
|
2 |
+error_reporting(E_ALL); |
|
3 |
+ |
|
4 |
+// Hopefully we have the goodies. |
|
5 |
+if (file_exists(dirname(__FILE__) . '/SSI.php') && !defined('SMF')) |
|
6 |
+{ |
|
7 |
+ $using_ssi = true; |
|
8 |
+ require_once(dirname(__FILE__) . '/SSI.php'); |
|
9 |
+} |
|
10 |
+elseif (!defined('SMF')) |
|
11 |
+ exit('<b>Error:</b> Cannot install - please verify you put this in the same place as SMF\'s index.php.'); |
|
12 |
+ |
|
13 |
+add_integration_function('integrate_pre_include', '$sourcedir/UnreadPMs.php'); |
|
14 |
+add_integration_function('integrate_actions', 'uPMs_hook_actionArray'); |
|
15 |
+add_integration_function('integrate_load_theme', 'uPMs_hook_load_theme'); |
|
16 |
+add_integration_function('integrate_general_mod_settings', 'uPMs_hook_general_mod_settings'); |
|
17 |
+ |
|
18 |
+if(!empty($using_ssi)) |
|
19 |
+ echo 'If no errors, Success!'; |
|
0 | 20 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,19 @@ |
1 |
+<?php |
|
2 |
+error_reporting(E_ALL); |
|
3 |
+ |
|
4 |
+// Hopefully we have the goodies. |
|
5 |
+if (file_exists(dirname(__FILE__) . '/SSI.php') && !defined('SMF')) |
|
6 |
+{ |
|
7 |
+ $using_ssi = true; |
|
8 |
+ require_once(dirname(__FILE__) . '/SSI.php'); |
|
9 |
+} |
|
10 |
+elseif (!defined('SMF')) |
|
11 |
+ exit('<b>Error:</b> Cannot uninstall - please verify you put this in the same place as SMF\'s index.php.'); |
|
12 |
+ |
|
13 |
+remove_integration_function('integrate_pre_include', '$sourcedir/UnreadPMs.php'); |
|
14 |
+remove_integration_function('integrate_actions', 'uPMs_hook_actionArray'); |
|
15 |
+remove_integration_function('integrate_load_theme', 'uPMs_hook_load_theme'); |
|
16 |
+remove_integration_function('integrate_general_mod_settings', 'uPMs_hook_general_mod_settings'); |
|
17 |
+ |
|
18 |
+if(!empty($using_ssi)) |
|
19 |
+ echo 'If no errors, Success!'; |
|
0 | 20 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,16 @@ |
1 |
+<?xml version="1.0"?> |
|
2 |
+<!DOCTYPE modification SYSTEM "http://www.simplemachines.org/xml/modification"> |
|
3 |
+<!-- This package was generated by SleePys Modification Maker at http://sleepycode.com --> |
|
4 |
+<modification xmlns="http://www.simplemachines.org/xml/modification" xmlns:smf="http://www.simplemachines.org/"> |
|
5 |
+ <id>sleepy:unreadpmfav</id> |
|
6 |
+ <version>1.0</version> |
|
7 |
+ |
|
8 |
+ <file name="$languagedir/Modifications.english.php"> |
|
9 |
+ <operation> |
|
10 |
+ <search position="end"/> |
|
11 |
+ <add><![CDATA[// Unread PMs strings. |
|
12 |
+$txt['unreadPMstimeout'] = 'Unread PMs Favicon Counter'; |
|
13 |
+$txt['unreadPMstimeout_post'] = 'seconds between checks (setting this to low may cause performance issues)';]]></add> |
|
14 |
+ </operation> |
|
15 |
+ </file> |
|
16 |
+</modification> |
|
0 | 17 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,23 @@ |
1 |
+<!DOCTYPE package-info SYSTEM "http://www.simplemachines.org/xml/package-info"> |
|
2 |
+<!-- This package was generated by SleePys Package Maker at http://sleepycode.com --> |
|
3 |
+<package-info xmlns="http://www.simplemachines.org/xml/package-info" xmlns:smf="http://www.simplemachines.org/"> |
|
4 |
+ <id>sleepy:unreadpmfav</id> |
|
5 |
+ <name>Unread PMs Favicon</name> |
|
6 |
+ <version>1.0</version> |
|
7 |
+ <type>modification</type> |
|
8 |
+ |
|
9 |
+ <install for="SMF 2.0-2.0.99"> |
|
10 |
+ <code>hooks_add.php</code> |
|
11 |
+ <move-file name="UnreadPMs.php" destination="$sourcedir/" /> |
|
12 |
+ <move-file name="tinycon.min.js" destination="$themedir/scripts/" /> |
|
13 |
+ <modification>language.xml</modification> |
|
14 |
+ </install> |
|
15 |
+ |
|
16 |
+ <uninstall for="SMF 2.0-2.0.99"> |
|
17 |
+ <code>hooks_remove.php</code> |
|
18 |
+ <remove-file name="$themedir/scripts/tinycon.min.js" /> |
|
19 |
+ <remove-file name="$sourcedir/UnreadPMs.php" /> |
|
20 |
+ <modification reverse="true">language.xml</modification> |
|
21 |
+ </uninstall> |
|
22 |
+ |
|
23 |
+</package-info> |
|
0 | 24 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,9 @@ |
1 |
+/* |
|
2 |
+ * Tinycon - A small library for manipulating the Favicon |
|
3 |
+ * Tom Moor, http://tommoor.com |
|
4 |
+ * Copyright (c) 2012 Tom Moor |
|
5 |
+ * MIT Licensed |
|
6 |
+ * @version 0.2.6 |
|
7 |
+*/ |
|
8 |
+ |
|
9 |
+(function(){var Tinycon={};var currentFavicon=null;var originalFavicon=null;var originalTitle=document.title;var faviconImage=null;var canvas=null;var options={};var defaults={width:7,height:9,font:'10px arial',colour:'#ffffff',background:'#F03D25',fallback:true};var ua=(function(){var agent=navigator.userAgent.toLowerCase();return function(browser){return agent.indexOf(browser)!==-1}}());var browser={chrome:ua('chrome'),webkit:ua('chrome')||ua('safari'),safari:ua('safari')&&!ua('chrome'),mozilla:ua('mozilla')&&!ua('chrome')&&!ua('safari')};var getFaviconTag=function(){var links=document.getElementsByTagName('link');for(var i=0,len=links.length;i<len;i++){if((links[i].getAttribute('rel')||'').match(/\bicon\b/)){return links[i]}}return false};var removeFaviconTag=function(){var links=document.getElementsByTagName('link');var head=document.getElementsByTagName('head')[0];for(var i=0,len=links.length;i<len;i++){var exists=(typeof(links[i])!=='undefined');if(exists&&links[i].getAttribute('rel')==='icon'){head.removeChild(links[i])}}};var getCurrentFavicon=function(){if(!originalFavicon||!currentFavicon){var tag=getFaviconTag();originalFavicon=currentFavicon=tag?tag.getAttribute('href'):'/favicon.ico'}return currentFavicon};var getCanvas=function(){if(!canvas){canvas=document.createElement("canvas");canvas.width=16;canvas.height=16}return canvas};var setFaviconTag=function(url){removeFaviconTag();var link=document.createElement('link');link.type='image/x-icon';link.rel='icon';link.href=url;document.getElementsByTagName('head')[0].appendChild(link)};var log=function(message){if(window.console)window.console.log(message)};var drawFavicon=function(num,colour){if(!getCanvas().getContext||browser.safari||options.fallback==='force'){return updateTitle(num)}var context=getCanvas().getContext("2d");var colour=colour||'#000000';var num=num||0;var src=getCurrentFavicon();faviconImage=new Image();faviconImage.onload=function(){context.clearRect(0,0,16,16);context.drawImage(faviconImage,0,0,faviconImage.width,faviconImage.height,0,0,16,16);if(num>0)drawBubble(context,num,colour);refreshFavicon()};if(!src.match(/^data/)){faviconImage.crossOrigin='anonymous'}faviconImage.src=src};var updateTitle=function(num){if(options.fallback){if(num>0){document.title='('+num+') '+originalTitle}else{document.title=originalTitle}}};var drawBubble=function(context,num,colour){var len=(num+"").length-1;var width=options.width+(6*len);var w=16-width;var h=16-options.height;context.font=(browser.webkit?'bold ':'')+options.font;context.fillStyle=options.background;context.strokeStyle=options.background;context.lineWidth=1;context.fillRect(w,h,width-1,options.height);context.beginPath();context.moveTo(w-0.5,h+1);context.lineTo(w-0.5,15);context.stroke();context.beginPath();context.moveTo(15.5,h+1);context.lineTo(15.5,15);context.stroke();context.beginPath();context.strokeStyle="rgba(0,0,0,0.3)";context.moveTo(w,16);context.lineTo(15,16);context.stroke();context.fillStyle=options.colour;context.textAlign="right";context.textBaseline="top";context.fillText(num,15,browser.mozilla?7:6)};var refreshFavicon=function(){if(!getCanvas().getContext)return;setFaviconTag(getCanvas().toDataURL())};Tinycon.setOptions=function(custom){options={};for(var key in defaults){options[key]=custom.hasOwnProperty(key)?custom[key]:defaults[key]}return this};Tinycon.setImage=function(url){currentFavicon=url;refreshFavicon();return this};Tinycon.setBubble=function(num,colour){if(isNaN(parseFloat(num))||!isFinite(num))return log('Bubble must be a number');drawFavicon(num,colour);return this};Tinycon.reset=function(){Tinycon.setImage(originalFavicon)};Tinycon.setOptions(defaults);window.Tinycon=Tinycon})(); |
|
0 | 10 |
\ No newline at end of file |
1 | 11 |