Hangouts Design Theme for Google Chat Web

Use Google Chat Web with the old Hangouts Design Theme

当前为 2023-05-27 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Hangouts Design Theme for Google Chat Web
  3. // @name:de Hangouts Design Theme für Google Chat Web
  4. // @version 1.0.2
  5. // @description Use Google Chat Web with the old Hangouts Design Theme
  6. // @description:de Google Chat Web mit dem alten Hangouts-Design-Theme verwenden
  7. // @icon https://ssl.gstatic.com/ui/v1/icons/mail/images/favicon_chat_r2.ico
  8. // @author TalkLounge (https://github.com/TalkLounge)
  9. // @namespace https://github.com/TalkLounge/hangouts-design-theme-for-google-chat-web
  10. // @license MIT
  11. // @match https://mail.google.com/chat/*
  12. // @match https://chat.google.com/u/0/*
  13. // @require https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js
  14. // @grant GM.setValue
  15. // @grant GM.getValue
  16. // @grant GM.deleteValue
  17. // ==/UserScript==
  18.  
  19. (function ($, undefined) { // Safe jQuery import, Thanks to https://stackoverflow.com/a/29363547
  20. $(async function () {
  21. const BACKGROUNDS = [
  22. { // Bird
  23. src: "https://www.gstatic.com/chat/hangouts/bg/f466d78212377293b5b745200add730f-stclair.jpg",
  24. srcAlt: "",
  25. author: "Tim St. Clair",
  26. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/TimStClair.jpg",
  27. profileAlt: ""
  28. },
  29. { // Corn Field
  30. src: "https://www.gstatic.com/chat/hangouts/bg/8b5e7ba224b738d2230391a5a15802bb-davec.jpg",
  31. srcAlt: "",
  32. author: "Dave Cohen",
  33. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/DaveCohen.jpg",
  34. profileAlt: ""
  35. },
  36. { // Pink Flower with Bee
  37. src: "https://www.gstatic.com/chat/hangouts/bg/2f1c3d68387ec036b4e49469c3289dae-GregSpencerDude.jpg",
  38. srcAlt: "",
  39. author: "Greg Spencer",
  40. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/GregSpencer.jpg",
  41. profileAlt: ""
  42. },
  43. { // Green Plant with Dragonfly
  44. src: "https://www.gstatic.com/chat/hangouts/bg/1d1d6f6311e7950d18720796905a4cbd-AnushElangovan-02.jpg",
  45. srcAlt: "",
  46. author: "Anush Elangovan",
  47. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/AnushElangovan.jpg",
  48. profileAlt: ""
  49. },
  50. { // Mountains with Pink Sky
  51. src: "https://www.gstatic.com/chat/hangouts/bg/734d92065df4177a006d5438caa46ae1-AKrishnaswamy-01.jpg",
  52. srcAlt: "",
  53. author: "Aravind Krishnaswamy",
  54. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/AravindKrishnaswamy.jpg",
  55. profileAlt: ""
  56. },
  57. { // Sheep Flock with Dog
  58. src: "https://www.gstatic.com/chat/hangouts/bg/c08b5d898d4000793c509ed40f804e2a-Matiash-03.jpg",
  59. srcAlt: "",
  60. author: "Brian Matiash",
  61. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/BrianMatiash.jpg",
  62. profileAlt: ""
  63. },
  64. { // Tourist Spot: Moai
  65. src: "https://www.gstatic.com/chat/hangouts/bg/e4c50a95c0148bb14931a73c2ae80d35-AnushElangovan-01.jpg",
  66. srcAlt: "",
  67. author: "Anush Elangovan",
  68. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/AnushElangovan.jpg",
  69. profileAlt: ""
  70. },
  71. { // Lake with Dark Clouds
  72. src: "https://www.gstatic.com/chat/hangouts/bg/d737e8519d5e7d6e0fe5fec9e35b2e2c-echang.jpg",
  73. srcAlt: "",
  74. author: "Emily Chang",
  75. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/EmilyChang.jpg",
  76. profileAlt: ""
  77. },
  78. { // Orange Flower
  79. src: "https://www.gstatic.com/chat/hangouts/bg/74474c3fc567f4dd012954c96e58d8d6-ChristopherJohnson.jpg",
  80. srcAlt: "",
  81. author: "Christopher Johnson",
  82. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/ChristopherJohnson.jpg",
  83. profileAlt: ""
  84. },
  85. { // Mossy Tree with River
  86. src: "https://www.gstatic.com/chat/hangouts/bg/cbccbd84d54a52e3ba7b148f2711b629-Matiash-02.jpg",
  87. srcAlt: "",
  88. author: "Brian Matiash",
  89. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/BrianMatiash.jpg",
  90. profileAlt: ""
  91. },
  92. { // Two Lions
  93. src: "https://www.gstatic.com/chat/hangouts/bg/650ec88f5cc9e0c827fe6ac61117211d-VidyaNagarajan.jpg",
  94. srcAlt: "",
  95. author: "Vidya Nagarajan",
  96. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/VidyaNagarajan.jpg",
  97. profileAlt: ""
  98. },
  99. { // Nature Waterfall
  100. src: "https://www.gstatic.com/chat/hangouts/bg/bbafcf27dfe823a255e7fa549b5b6ba5-Matiash-01.jpg",
  101. srcAlt: "",
  102. author: "Brian Matiash",
  103. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/BrianMatiash.jpg",
  104. profileAlt: ""
  105. },
  106. { // Coast Line
  107. src: "https://www.gstatic.com/chat/hangouts/bg/a968e293d984aa05eee42df9a8d91dc2-AKrishnaswamy-03.jpg",
  108. srcAlt: "",
  109. author: "Aravind Krishnaswamy",
  110. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/AravindKrishnaswamy.jpg",
  111. profileAlt: ""
  112. },
  113. { // Snowy Valley
  114. src: "https://www.gstatic.com/chat/hangouts/bg/b4a063d93b237f1e21c1bd2ef77d2c45-PaulMoody.jpg",
  115. srcAlt: "",
  116. author: "Paul Moody",
  117. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/PaulMoody.jpg",
  118. profileAlt: ""
  119. },
  120. { // Three Light Aircrafts
  121. src: "https://www.gstatic.com/chat/hangouts/bg/47b6231b6b9171fefbdda2f4750f1fda-nbutko.jpg",
  122. srcAlt: "",
  123. author: "Nicholas Butko",
  124. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/NicholasButko.jpg",
  125. profileAlt: ""
  126. },
  127. { // Valley with big Lake
  128. src: "https://www.gstatic.com/chat/hangouts/bg/1cfdd2ae9f28d352d2853628cdb70659-TreyRatcliff.jpg",
  129. srcAlt: "",
  130. author: "Trey Ratcliff",
  131. profile: "https://www.gstatic.com/chat/hangouts/bg/photographer/TreyRatcliff.jpg",
  132. profileAlt: ""
  133. }
  134. ];
  135. const TRANSLATIONS = { en: "Photo by", de: "Foto von" };
  136. const LANG = navigator.language || navigator.userLanguage;
  137. const TRANSLATION = TRANSLATIONS[LANG] || TRANSLATIONS["en"];
  138. let interval;
  139.  
  140. function insertStyle(styles) {
  141. const html = `
  142. <style>
  143. ${styles.trim()}
  144. </style>
  145. `.trim();
  146.  
  147. const child = $.parseHTML(html);
  148. $("head").append(child);
  149. }
  150.  
  151. function insertBackground() {
  152. const ran = Math.floor(Math.random() * (BACKGROUNDS.length - 1));
  153. const html = `
  154. <div class="HDfGC-bg">
  155. <div class="HDfGC-bg-img"></div>
  156. <div class="HDfGC-bg-grad"></div>
  157. <div class="HDfGC-bg-author">
  158. <div class="HDfGC-bg-author-img"></div>
  159. <div class="HDfGC-bg-author-name-wrapper">
  160. <div class="HDfGC-bg-author-name">${TRANSLATION} ${BACKGROUNDS[ran].author}</div>
  161. </div>
  162. </div>
  163. </div>
  164. `.replace(/>\s+</g, '><').trim(); // Clean up formatted html, Thanks to https://stackoverflow.com/a/27841683
  165.  
  166. const child = $.parseHTML(html);
  167. $("body").prepend(child);
  168.  
  169. insertStyle(`
  170. .HDfGC-bg {
  171. position: fixed;
  172. width: 100%;
  173. height: 100%
  174. }
  175.  
  176. .HDfGC-bg-img {
  177. background-image: url("${BACKGROUNDS[ran].src}");
  178. background-size: cover;
  179. height: 100%
  180. }
  181.  
  182. .HDfGC-bg-grad {
  183. background-image: -moz-linear-gradient(rgba(0,0,0,.4) 0%,rgba(0,0,0,.6) 75%,rgba(0,0,0,.8) 100%);
  184. background-image: linear-gradient(rgba(0,0,0,.4) 0%,rgba(0,0,0,.6) 75%,rgba(0,0,0,.8) 100%);
  185. position: absolute;
  186. top: 0;
  187. left: 0;
  188. bottom: 0;
  189. right: 0
  190. }
  191.  
  192. .HDfGC-bg-author {
  193. right: 1.3vw;
  194. bottom: 1.3vw;
  195. position: absolute
  196. }
  197.  
  198. .HDfGC-bg-author-img {
  199. background-image: url("${BACKGROUNDS[ran].profile}");
  200. background-size: cover;
  201. display: inline-block;
  202. height: 32px;
  203. vertical-align: middle;
  204. width: 32px;
  205. border-radius: 50%
  206. }
  207.  
  208. .HDfGC-bg-author-name-wrapper {
  209. font-size: 13px;
  210. color: white;
  211. display: inline-block;
  212. margin-left: 16px;
  213. vertical-align: middle;
  214. }
  215.  
  216. .wl {
  217. background: inherit;
  218. }
  219.  
  220. #Layer_1 {
  221. display: none;
  222. }
  223. `);
  224.  
  225. $('[role="complementary"]').css("display", "none");
  226. }
  227.  
  228. function invertColors() {
  229. insertStyle(`
  230. .gb_Ia svg, .gb_Qc svg, .gb_cd .gb_ld, .gb_2c .gb_ld {
  231. color: white !important;
  232. }
  233.  
  234. .Yb.bax.bCd {
  235. background: none;
  236. }
  237.  
  238. .Yc.bax {
  239. color: white;
  240. }
  241. `);
  242.  
  243. $("a img").eq(0).attr("srcset", "https://ssl.gstatic.com/ui/v1/icons/mail/rfr/logo_chat_dark_2x.png 2x ,https://ssl.gstatic.com/ui/v1/icons/mail/rfr/logo_chat_dark_1x.png 1x")
  244. }
  245.  
  246. function changeDetails() {
  247. insertStyle(`
  248. .nH.bkK.nn {
  249. display: none;
  250. }
  251.  
  252. #aso_search_form_anchor {
  253. display: none;
  254. }
  255.  
  256. .aeN {
  257. max-width: none !important;
  258. }
  259. `);
  260.  
  261. $('[role="navigation"]').css("background-color", "white");
  262. $('[role="navigation"]').css("border-top-left-radius", "4px");
  263. $('[role="navigation"]').css("border-top-right-radius", "4px");
  264. $('[role="navigation"]').css("width", "20.83vw");
  265. $('[role="navigation"]').css("top", "3vh");
  266. $('[role="navigation"]').css("left", "3.5vw");
  267. }
  268.  
  269. function initMain() {
  270. if ($("#loading").is(":visible")) { // Stop when not completely loaded
  271. return;
  272. }
  273.  
  274. //console.log("--------------initMain()--------------");
  275.  
  276. window.clearInterval(interval);
  277.  
  278. insertBackground();
  279. invertColors();
  280. changeDetails();
  281.  
  282. $(".dw .no").empty();
  283. window.setInterval(() => {
  284. $(".dB").each(function () {
  285. $(this).css("width", "20.83vw");
  286. $(this).parent().parent().parent().parent().css("width", "21.33vw");
  287. $(this).css("height", "92.7vh");
  288. });
  289. }, 500);
  290. }
  291.  
  292. function initFrameUsers() {
  293. if (!$('[role="list"] [role="listitem"] div').length) { // Stop when not completely loaded
  294. return;
  295. }
  296.  
  297. //console.log("--------------initFrameUsers()--------------");
  298.  
  299. window.clearInterval(interval);
  300.  
  301. window.setInterval(() => {
  302. $('[role="list"] [role="listitem"]').each(function (index) {
  303. if ($(this).attr("jsaction")) {
  304. $(this).removeAttr("jsaction");
  305. const elem = $(this).find('div[role="button"][jsaction]').get(0);
  306. $(this).find('[role="link"]').eq(0).click(function (e) {
  307. elem.click();
  308. });
  309. }
  310. });
  311. }, 500);
  312. }
  313.  
  314. function initFrameGroups() {
  315. if (!$('[role="list"] [role="listitem"] div').length) { // Stop when not completely loaded
  316. return;
  317. }
  318.  
  319. //console.log("--------------initFrameGroups()--------------");
  320.  
  321. window.clearInterval(interval);
  322.  
  323. window.setInterval(() => {
  324. $('[role="list"] [role="listitem"]').each(function (index) {
  325. if ($(this).attr("jsaction")) {
  326. $(this).removeAttr("jsaction");
  327. const elem = $(this).find('div[role="button"][jsaction]').get(0);
  328. $(this).find('[role="link"]').eq(0).click(function (e) {
  329. elem.click();
  330. });
  331. }
  332. });
  333. }, 500);
  334. }
  335.  
  336. // Start injected function
  337. //console.log(window.location.href, window.top === window.self);
  338. if (window.location.href.startsWith("https://mail.google.com/chat/u/0/") && window.top == window.self) { // Main Page
  339. if (! await GM.getValue("reload") || new Date().getTime() - await GM.getValue("reload") > 10 * 1000) { // Must be loaded without Cache otherwise the IFrames will not be injected
  340. await GM.setValue("reload", new Date().getTime());
  341. window.setTimeout(() => {
  342. $.ajax({
  343. url: window.location.href,
  344. headers: {
  345. "Pragma": "no-cache",
  346. "Expires": -1,
  347. "Cache-Control": "no-cache"
  348. }
  349. }).done(function () {
  350. window.location.reload(true);
  351. });
  352. }, 500);
  353. } else {
  354. await GM.deleteValue("reload");
  355. interval = window.setInterval(initMain, 500);
  356. }
  357. } else if (window.location.href.startsWith("https://chat.google.com/u/0/mole/world") && window.top != window.self) { // IFrame Users
  358. interval = window.setInterval(initFrameUsers, 500);
  359. } else if (window.location.href.startsWith("https://chat.google.com/u/0/") && window.top != window.self && window.location.href.indexOf("id=rooms") != -1) { // IFrame Groups
  360. interval = window.setInterval(initFrameGroups, 500);
  361. }
  362. });
  363. })(window.jQuery.noConflict(true));