Skip to content

Instantly share code, notes, and snippets.

@giu1io
Last active October 20, 2023 08:06
Show Gist options
  • Save giu1io/03a3ded6658baf697dd1ded7ee4c50fd to your computer and use it in GitHub Desktop.
Save giu1io/03a3ded6658baf697dd1ded7ee4c50fd to your computer and use it in GitHub Desktop.
Tampermonkey Script to Cleanup the Google Chat UI so it can run in a smaller PWA window
// ==UserScript==
// @name Google Chat Style Cleanup
// @namespace http://tampermonkey.net/
// @version 0.13
// @description Tampermonkey Script to Cleanup the Google Chat UI so it can run in a smaller PWA window
// @author Giulio Montagner
// @match https://mail.google.com/chat/*
// @match https://chat.google.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=google.com
// @updateURL https://gist.githubusercontent.com/giu1io/03a3ded6658baf697dd1ded7ee4c50fd/raw/cleanup_google_chat_ui.js
// @downloadURL https://gist.githubusercontent.com/giu1io/03a3ded6658baf697dd1ded7ee4c50fd/raw/cleanup_google_chat_ui.js
// @grant GM_addStyle
// ==/UserScript==
(function() {
'use strict';
/*
***********************
* PART1: THE ÆSTETICS *
***********************
*/
let topBar = null
function hideTopBar() {
topBar = GM_addStyle(`
/* Top Bar */
div.w-asV.bbg.aiw {
position: absolute;
top: -100px !important;
}
/* IFrame Chat */
#\\:1 iframe, #\\:3 {
height: 100vh !important;
}
`)
}
function showTopBar() {
if(topBar){
topBar.remove()
}
}
function decorateTopBar(){
const containers = document.getElementsByClassName("gb_he gb_fe")
if(containers.length !== 1) {
return
}
const container = containers[0]
const button = document.createElement("div");
button.className = "zo"
const link = document.createElement("a");
link.className = "gb_ke gb_ie gb_le t6"
link.text = "⬆️"
link.href = "#"
link.style = "height: 10px; width: 16px"
link.addEventListener("click", (event) => {
event.preventDefault()
hideTopBar()
})
button.append(link)
container.prepend(button)
}
hideTopBar()
setTimeout(decorateTopBar, 5000)
GM_addStyle(`
/* Right Side Bar */
div.nH.bAw.nn {
display: none !important;
}
/* Padding Bottom Text Input */
div.XganBc.eLNT1d {
padding-bottom: 20px !important;
}
/* Move typing indicator */
div.bNfiFb.qs41qe {
top: -10px;
}
`)
window.addEventListener("message", (event) => {
if(event.data === "sbox.df") {
showTopBar()
}
}, false);
/*
***********************
* PART2: THE FEATURES *
***********************
*/
// Options for the observer (which mutations to observe)
const config = { childList: true };
let messageInput = null
function onNewMessage(message) {
message.addEventListener("dblclick", () => {
const elements = message.querySelectorAll(".U26fgb.mUbCce.fKz7Od.orLAid")
for(let el of elements) {
if(el.getAttribute("data-id") === "quoteInReply") {
el.click();
}
}
})
}
function onChatLoad() {
messageInput = document.querySelector('[g_editable]')
if(messageInput) {
messageInput.tabIndex = 0
}
const messages = document.querySelectorAll("c-wiz.cZICLc.ajCeRb.XbbXmb");
for(let message of messages) {
onNewMessage(message)
}
// Select the node that will be observed for mutations
const messageContainer = document.querySelector('.SvOPqd');
if(!messageContainer) {
return
}
// Callback function to execute when mutations are observed
const callback = (mutationList, observer) => {
for (const mutation of mutationList) {
if (mutation.type === 'childList') {
for(let message of mutation.addedNodes) {
onNewMessage(message)
}
}
}
};
// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(messageContainer, config);
}
// Select the node that will be observed for mutations
const bodyContainer = document.querySelector('body');
// Callback function to execute when mutations are observed
const parseNodesForChats = (mutationList, observer) => {
for (const mutation of mutationList) {
if (mutation.type === 'childList') {
for(const newNode of mutation.addedNodes) {
if(newNode.dataset.groupId) {
setTimeout(onChatLoad, 1000)
}
}
}
}
};
// Create an observer instance linked to the callback function
const findChatsObserver = new MutationObserver(parseNodesForChats);
// Start observing the target node for configured mutations
findChatsObserver.observe(bodyContainer, config);
if(document.querySelector('[data-group-id]')) {
setTimeout(onChatLoad, 1000)
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment