Google Voice Favicon Alerts

Alerts you to the number of unread items in Google Voice.

  1. // ==UserScript==
  2. // @name Google Voice Favicon Alerts
  3. // @description Alerts you to the number of unread items in Google Voice.
  4. // @version 1.0.14
  5. // @author Peter Wooley, Ben999_
  6. // @namespace http://peterwooley.com
  7. // @match *://voice.google.com/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. // Wait for the window to load to try and initialize
  12. window.addEventListener('load', function() {
  13. window.instance = new GVoiceFaviconAlerts;
  14. }, true);
  15. function GVoiceFaviconAlerts() {
  16. var self = this;
  17. this.construct = function() {
  18. this.head = document.getElementsByTagName("head")[0];
  19. this.pixelMaps = {
  20. icons: {
  21. 'unread':
  22. [["rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,255,0,0.00392)","rgba(63,191,63,0.01569)","rgba(0,127,127,0.00784)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(63,127,63,0.01569)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)"],["rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,127,127,0.00784)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(54,163,91,0.05490)","rgba(57,197,92,0.08627)","rgba(0,127,0,0.00784)","rgba(0,0,0,0.00000)","rgba(0,255,0,0.00392)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)"],["rgba(127,127,127,0.00784)","rgba(0,0,0,0.00000)","rgba(51,170,85,0.11765)","rgba(56,185,91,0.61961)","rgba(53,164,79,0.18824)","rgba(0,0,0,0.00000)","rgba(36,145,72,0.02745)","rgba(0,0,0,0.00000)","rgba(52,167,82,0.67059)","rgba(55,179,88,0.95294)","rgba(52,170,84,0.81961)","rgba(52,171,83,0.38431)","rgba(0,0,0,0.00000)","rgba(0,255,0,0.00392)","rgba(0,0,0,0.00392)","rgba(0,0,0,0.00000)"],["rgba(85,170,85,0.01176)","rgba(255,255,255,0.00392)","rgba(52,167,83,0.72941)","rgba(59,190,94,1.00000)","rgba(54,172,86,0.92549)","rgba(48,163,81,0.20784)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(53,170,85,0.76078)","rgba(58,181,90,1.00000)","rgba(53,171,85,1.00000)","rgba(57,184,91,1.00000)","rgba(51,167,82,0.60392)","rgba(85,170,85,0.01176)","rgba(0,255,127,0.00784)","rgba(0,0,0,0.00000)"],["rgba(0,0,0,0.00000)","rgba(34,144,59,0.11765)","rgba(51,168,82,0.98039)","rgba(52,168,83,0.98431)","rgba(53,172,85,1.00000)","rgba(54,173,85,0.92549)","rgba(51,165,85,0.21176)","rgba(0,0,0,0.00000)","rgba(34,142,66,0.74902)","rgba(42,158,75,0.99608)","rgba(52,167,82,0.98039)","rgba(52,168,82,0.97647)","rgba(57,184,91,1.00000)","rgba(51,166,83,0.37255)","rgba(0,0,0,0.00000)","rgba(63,191,63,0.01569)"],["rgba(0,0,0,0.00000)","rgba(20,121,52,0.24706)","rgba(32,144,65,0.98824)","rgba(52,168,83,0.99216)","rgba(52,167,82,0.97647)","rgba(59,190,93,1.00000)","rgba(50,167,81,0.53725)","rgba(0,0,0,0.00000)","rgba(22,126,54,0.75294)","rgba(22,131,56,0.98824)","rgba(31,139,63,0.97647)","rgba(52,167,82,0.98039)","rgba(54,174,86,0.98039)","rgba(52,167,82,0.83529)","rgba(42,212,85,0.02353)","rgba(127,127,127,0.00784)"],["rgba(0,0,0,0.00000)","rgba(26,134,67,0.07451)","rgba(22,124,53,0.95294)","rgba(31,139,63,1.00000)","rgba(52,171,84,0.99608)","rgba(52,171,83,0.77647)","rgba(49,166,78,0.10196)","rgba(0,0,0,0.00000)","rgba(23,128,56,0.79608)","rgba(28,143,63,1.00000)","rgba(22,130,56,1.00000)","rgba(42,159,75,1.00000)","rgba(57,182,90,1.00000)","rgba(52,171,85,1.00000)","rgba(53,170,85,0.09412)","rgba(0,0,0,0.00000)"],["rgba(0,85,85,0.01176)","rgba(0,170,85,0.01176)","rgba(25,129,56,0.79608)","rgba(21,128,55,0.99608)","rgba(38,151,70,0.96471)","rgba(58,174,94,0.13725)","rgba(0,0,0,0.00000)","rgba(127,255,127,0.00784)","rgba(24,127,56,0.49412)","rgba(25,136,59,0.74510)","rgba(22,125,54,0.74902)","rgba(34,142,65,0.74902)","rgba(55,175,86,0.74118)","rgba(51,170,83,0.65882)","rgba(45,165,75,0.06667)","rgba(0,255,0,0.00392)"],["rgba(0,127,63,0.01569)","rgba(0,0,0,0.00000)","rgba(21,123,55,0.38039)","rgba(33,147,67,1.00000)","rgba(51,168,82,0.99216)","rgba(53,172,85,0.78039)","rgba(40,161,80,0.07451)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)"],["rgba(0,1,0,0.00000)","rgba(0,255,127,0.00784)","rgba(42,127,42,0.02353)","rgba(50,166,82,0.81176)","rgba(55,177,88,1.00000)","rgba(55,176,87,1.00000)","rgba(53,172,85,0.79216)","rgba(45,165,75,0.06667)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(49,166,83,0.36078)","rgba(51,164,82,0.23137)","rgba(0,0,0,0.00000)","rgba(42,170,85,0.02353)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)"],["rgba(0,0,0,0.00000)","rgba(127,255,127,0.00784)","rgba(0,0,0,0.00000)","rgba(49,166,83,0.18039)","rgba(53,174,85,0.93333)","rgba(53,170,84,0.99216)","rgba(54,176,87,1.00000)","rgba(52,171,85,0.80000)","rgba(72,218,109,0.05490)","rgba(53,170,85,0.37647)","rgba(56,182,90,1.00000)","rgba(52,172,84,0.94510)","rgba(52,163,81,0.20784)","rgba(0,0,0,0.00000)","rgba(0,255,127,0.00784)","rgba(0,0,0,0.00000)"],["rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,255,127,0.00784)","rgba(0,0,0,0.00000)","rgba(48,163,81,0.20784)","rgba(53,174,85,0.93333)","rgba(54,173,86,1.00000)","rgba(55,175,87,1.00000)","rgba(40,152,72,0.86667)","rgba(50,165,80,0.98824)","rgba(53,171,85,0.98824)","rgba(53,172,85,1.00000)","rgba(54,172,85,0.92549)","rgba(51,170,85,0.21176)","rgba(0,255,0,0.00392)","rgba(0,127,127,0.00784)"],["rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(63,191,63,0.01569)","rgba(0,0,0,0.00000)","rgba(48,163,81,0.20784)","rgba(55,176,86,0.85098)","rgba(40,158,74,1.00000)","rgba(23,132,57,1.00000)","rgba(31,138,63,1.00000)","rgba(51,167,82,0.99216)","rgba(52,167,83,0.97255)","rgba(57,184,90,1.00000)","rgba(52,167,83,0.80000)","rgba(0,0,0,0.00000)","rgba(63,127,63,0.01569)"],["rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(85,170,85,0.01176)","rgba(0,0,0,0.00000)","rgba(34,136,68,0.05882)","rgba(23,132,57,0.50588)","rgba(25,132,57,0.83137)","rgba(23,129,56,1.00000)","rgba(32,144,65,1.00000)","rgba(53,175,86,1.00000)","rgba(54,176,87,0.91373)","rgba(50,167,82,0.37647)","rgba(0,255,0,0.00392)","rgba(85,170,85,0.01176)"],["rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,127,127,0.00784)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,85,85,0.01176)","rgba(24,137,58,0.20392)","rgba(19,123,51,0.25098)","rgba(43,159,75,0.25098)","rgba(60,170,85,0.08235)","rgba(0,0,0,0.00000)","rgba(0,255,0,0.00392)","rgba(0,0,0,0.00000)"],["rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,255,0,0.00392)","rgba(0,127,63,0.01569)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)","rgba(85,170,85,0.01176)","rgba(0,0,0,0.00000)","rgba(0,0,0,0.00000)"]]
  23. },
  24. numbers: {
  25. 0: [
  26. [1,1,1],
  27. [1,0,1],
  28. [1,0,1],
  29. [1,0,1],
  30. [1,1,1]
  31. ],
  32. 1: [
  33. [0,1,0],
  34. [1,1,0],
  35. [0,1,0],
  36. [0,1,0],
  37. [1,1,1]
  38. ],
  39. 2: [
  40. [1,1,1],
  41. [0,0,1],
  42. [1,1,1],
  43. [1,0,0],
  44. [1,1,1]
  45. ],
  46. 3: [
  47. [1,1,1],
  48. [0,0,1],
  49. [0,1,1],
  50. [0,0,1],
  51. [1,1,1]
  52. ],
  53. 4: [
  54. [0,0,1],
  55. [0,1,1],
  56. [1,0,1],
  57. [1,1,1],
  58. [0,0,1]
  59. ],
  60. 5: [
  61. [1,1,1],
  62. [1,0,0],
  63. [1,1,1],
  64. [0,0,1],
  65. [1,1,1]
  66. ],
  67. 6: [
  68. [0,1,1],
  69. [1,0,0],
  70. [1,1,1],
  71. [1,0,1],
  72. [1,1,1]
  73. ],
  74. 7: [
  75. [1,1,1],
  76. [0,0,1],
  77. [0,0,1],
  78. [0,1,0],
  79. [0,1,0]
  80. ],
  81. 8: [
  82. [1,1,1],
  83. [1,0,1],
  84. [1,1,1],
  85. [1,0,1],
  86. [1,1,1]
  87. ],
  88. 9: [
  89. [1,1,1],
  90. [1,0,1],
  91. [1,1,1],
  92. [0,0,1],
  93. [1,1,0]
  94. ],
  95. '+': [
  96. [0,0,0],
  97. [0,1,0],
  98. [1,1,1],
  99. [0,1,0],
  100. [0,0,0],
  101. ],
  102. 'k': [
  103. [1,0,1],
  104. [1,1,0],
  105. [1,1,0],
  106. [1,0,1],
  107. [1,0,1],
  108. ]
  109. }
  110. };
  111. this.timer = setInterval(this.poll, 500);
  112. this.poll();
  113. return true;
  114. }
  115. this.drawUnreadCount = function(unread) {
  116. if(!self.textedCanvas) {
  117. self.textedCanvas = [];
  118. }
  119. if(!self.textedCanvas[unread]) {
  120. var iconCanvas = self.getUnreadCanvas();
  121. var textedCanvas = document.createElement('canvas');
  122. textedCanvas.height = textedCanvas.width = iconCanvas.width;
  123. var ctx = textedCanvas.getContext('2d');
  124. ctx.drawImage(iconCanvas, 0, 0);
  125. ctx.fillStyle = "#fef4ac";
  126. ctx.strokeStyle = "#dabc5c";
  127. ctx.strokeWidth = 1;
  128. var count = unread.length;
  129. if(count > 4) {
  130. unread = "1k+";
  131. count = unread.length;
  132. }
  133. var bgHeight = self.pixelMaps.numbers[0].length;
  134. var bgWidth = 0;
  135. var padding = count < 4 ? 1 : 0;
  136. var topMargin = 7;
  137. for(var index = 0; index < count; index++) {
  138. bgWidth += self.pixelMaps.numbers[unread[index]][0].length;
  139. if(index < count-1) {
  140. bgWidth += padding;
  141. }
  142. }
  143. bgWidth = bgWidth > textedCanvas.width-4 ? textedCanvas.width-4 : bgWidth;
  144. ctx.fillRect(textedCanvas.width-bgWidth-4,topMargin,bgWidth+4,bgHeight+4);
  145. var digit;
  146. var digitsWidth = bgWidth;
  147. for(index = 0; index < count; index++) {
  148. digit = unread[index];
  149. if (self.pixelMaps.numbers[digit]) {
  150. var map = self.pixelMaps.numbers[digit];
  151. var height = map.length;
  152. var width = map[0].length;
  153. ctx.fillStyle = "#2c3323";
  154. for (var y = 0; y < height; y++) {
  155. for (var x = 0; x < width; x++) {
  156. if(map[y][x]) {
  157. ctx.fillRect(14- digitsWidth + x, y+topMargin+2, 1, 1);
  158. }
  159. }
  160. }
  161. digitsWidth -= width + padding;
  162. }
  163. }
  164. ctx.strokeRect(textedCanvas.width-bgWidth-3.5,topMargin+.5,bgWidth+3,bgHeight+3);
  165. self.textedCanvas[unread] = textedCanvas;
  166. }
  167. return self.textedCanvas[unread];
  168. }
  169. this.getIcon = function() {
  170. return self.getUnreadCanvas().toDataURL('image/png');
  171. }
  172. this.getUnreadCanvas = function() {
  173. if(!self.unreadCanvas) {
  174. self.unreadCanvas = document.createElement('canvas');
  175. self.unreadCanvas.height = self.unreadCanvas.width = 16;
  176. var ctx = self.unreadCanvas.getContext('2d');
  177. for (var y = 0; y < self.unreadCanvas.width; y++) {
  178. for (var x = 0; x < self.unreadCanvas.height; x++) {
  179. if (self.pixelMaps.icons.unread[y][x]) {
  180. ctx.fillStyle = self.pixelMaps.icons.unread[y][x];
  181. ctx.fillRect(x, y, 1, 1);
  182. }
  183. }
  184. }
  185. }
  186. return self.unreadCanvas;
  187. }
  188. this.getUnreadCountMessages = function() {
  189. var matches = self.getSearchTextMessages().match(/\d+/g); //parse numerics
  190. //console.log(matches + ' unread messages found');
  191. return matches ? matches[0] : false;
  192. }
  193. this.getUnreadCountCalls = function() {
  194. var matches = self.getSearchTextCalls().match(/\d+/g); //parse numerics
  195. //console.log(matches + ' unread calls found');
  196. return matches ? matches[0] : false;
  197. }
  198. this.getUnreadCountVoicemail = function() {
  199. var matches = self.getSearchTextVoicemail().match(/\d+/g); //parse numerics
  200. //console.log(matches + ' unread voicemails found');
  201. return matches ? matches[0] : false;
  202. }
  203. this.getUnreadCountArchived = function() {
  204. var matches = self.getSearchTextArchived().match(/\d+/g); //parse numerics
  205. //console.log(matches + ' unread archived items found');
  206. return matches ? matches[0] : false;
  207. }
  208. this.getUnreadCountIcon = function() {
  209. var unreadMessages = self.getUnreadCountMessages();
  210. var unreadCalls = self.getUnreadCountCalls();
  211. var unreadVoicemail = self.getUnreadCountVoicemail();
  212. var unreadArchived = self.getUnreadCountArchived();
  213. var totalUnread = 0;
  214. if (unreadMessages) {
  215. totalUnread += parseInt(unreadMessages);
  216. }
  217. if (unreadCalls) {
  218. totalUnread += parseInt(unreadCalls);
  219. }
  220. if (unreadVoicemail) {
  221. totalUnread += parseInt(unreadVoicemail);
  222. }
  223. if (unreadArchived) {
  224. totalUnread += parseInt(unreadArchived);
  225. }
  226. // 7/6/17 recent update seems to show twice as many unread in no particular order
  227. //totalUnread = totalUnread / 2;
  228. //if ((totalUnread < 1) && (totalUnread > 0)) {
  229. // totalUnread = 1;
  230. //}
  231. //console.log(totalUnread + ' unread items detected');
  232. return self.drawUnreadCount(totalUnread.toString()).toDataURL('image/png');
  233. }
  234. this.getSearchTextCalls = function() {
  235. var text = "";
  236. // calls = element 0
  237. if (document.getElementsByClassName('mdc-list-item__content')[0]) {
  238. text = top.document.getElementsByClassName('mdc-list-item__content')[0].textContent;
  239. }
  240. return text;
  241. }
  242. this.getSearchTextMessages = function() {
  243. var text = "";
  244. // messages = element 1
  245. if (document.getElementsByClassName('mdc-list-item__content')[1]) {
  246. text = top.document.getElementsByClassName('mdc-list-item__content')[1].textContent;
  247. }
  248. return text;
  249. }
  250. this.getSearchTextVoicemail = function() {
  251. var text = "";
  252. // voicemail = element 2
  253. if (document.getElementsByClassName('mdc-list-item__content')[2]) {
  254. text = top.document.getElementsByClassName('mdc-list-item__content')[2].textContent;
  255. }
  256. return text;
  257. }
  258. this.getSearchTextArchived = function() {
  259. var text = "";
  260. // archived = element 3
  261. if (document.getElementsByClassName('mdc-list-item__content')[3]) {
  262. text = top.document.getElementsByClassName('mdc-list-item__content')[3].textContent;
  263. }
  264. return text;
  265. }
  266. this.poll = function() {
  267. if (self.getUnreadCountMessages() || self.getUnreadCountCalls() || self.getUnreadCountVoicemail() || self.getUnreadCountArchived()) {
  268. self.setIcon(self.getUnreadCountIcon());
  269. } else {
  270. self.setIcon(self.getIcon());
  271. }
  272. }
  273. this.setIcon = function(icon) {
  274. var links = self.head.getElementsByTagName("link");
  275. for (var i = 0; i < links.length; i++)
  276. if (links[i].type == "image/x-icon" &&
  277. (links[i].rel.toLowerCase() == "shortcut icon" || links[i].rel.toLowerCase() == "icon") &&
  278. links[i].href != icon)
  279. self.head.removeChild(links[i]);
  280. else if(links[i].href == icon)
  281. return;
  282.  
  283. var newIcon = document.createElement("link");
  284. newIcon.type = "image/x-icon";
  285. newIcon.rel = "shortcut icon";
  286. newIcon.href = icon;
  287. self.head.appendChild(newIcon);
  288.  
  289. setTimeout(function() {
  290. var shim = document.createElement('iframe');
  291. shim.width = shim.height = 0;
  292. document.body.appendChild(shim);
  293. shim.src = "icon";
  294. document.body.removeChild(shim);
  295. }, 499);
  296.  
  297. }
  298. this.toString = function() { return '[object GVoiceFaviconAlerts]'; }
  299. return this.construct();
  300. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址