ankurk91 / google-chat-electron

An unofficial desktop app for Google Chat :electron:
GNU General Public License v3.0
162 stars 49 forks source link

Feature Request: Follow native theme #87

Closed AdamCoulterOz closed 2 years ago

AdamCoulterOz commented 2 years ago

Toggle the theme setting in the PWA google chat settings based on events from system theme (follow OS system theme):

https://www.electronjs.org/docs/latest/api/native-theme

The app window itself already changes based on system theme, but not the PWA app inside it.

Screen Shot 2022-04-25 at 2 36 42 pm
ankurk91 commented 2 years ago

How to instruct Google chat web interface to change the theme programmatically?

AdamCoulterOz commented 2 years ago

I've just had a play in the last 30 minutes to simulate it in Chrome DevTools.

So it's basically just plain javascript DOM manipulation and simulating a click on an element. I'm not sure which javascript framework the google chat app uses, but when it is compiled / minified, it seems the ids and div references are regenerated. So the only 'static' thing we can attach to is probably the text values of Light mode and Dark mode.

To do this... we need to search the DOM tree as described here:

// custom functions to walk the dom and return an array of matching nodes

function walkTheDOM(node, func) {
    func(node);
    node = node.firstChild;
    while (node) {
        walkTheDOM(node, func);
        node = node.nextSibling;
    }
}

function getElementsByText(node, text) {
    var results = [];

    walkTheDOM(node, function (currentNode) {
        if (currentNode.nodeType === 3 && currentNode.nodeValue === text) {
            results.push(currentNode.parentNode);
        }
    });

    return results;
}

Here is a button clicker which checks for element count (potential errors):

function clickElement(elements) {
    if(elements.length != 1) {
        // error condition
        // currently doesn't happen, but it could if the google chat pwa app changes
        // if it does, the selection code arguments (below) may need to be updated
    }
    elements[0].click();
}

We will need to open and close the setting menu to load in the settings elements (they aren't initially defined in the DOM document)

function openSettings() {
    var settingsButtons = document.querySelectorAll('[data-tooltip="Settings"]');
    clickElement(settingsButtons);
}

function closeSettings() {
    var settingsCloseButtons = document.querySelectorAll('[title="Close"]','[role="button"]');
    clickElement(settingsCloseButtons);
}

Once the settings menu is open, find the node which contains the right theme text, then click it.

// function to click on the theme

function selectTheme(themeText) {
    var themeButtons = getElementsByText(document, themeText);
    clickElement(themeButtons);
}

Then invoke these functions based on the electron theme change event (and initial load check what theme and set it too). You will need to make sure timings are ok between them, and that the page is loaded first.

openSettings();

selectTheme('Dark mode');
//or
selectTheme('Light mode');

closeSettings();
ankurk91 commented 2 years ago

That's too much hacking, not worth to maintain, since The dark theme setting is only one click away.

I would like to see an "Auto" mode by Google itself

AdamCoulterOz commented 2 years ago

This is javascript, isn't it all just hacking?