WesselKroos / youtube-ambilight

This browser extension adds ambient light to YouTube videos
MIT License
87 stars 8 forks source link

Auto dark mode #161

Closed avi12 closed 1 year ago

avi12 commented 1 year ago

Is your feature request related to a problem? I wish the extension automatically applied dark mode

Describe alternatives you've considered A content script containing

const instanceDarkMode = matchMedia('(prefers-color-scheme: dark)')
const { documentElement } = document

function setDark(e) {
  if (e.matches) {
    documentElement.setAttribute('dark', true)
    return
  }

  documentElement.removeAttribute('dark')
}

setDark(instanceDarkMode)
instanceDarkMode.addEventListener('change', setDark)

Additional context When YouTube applies dark mode, I believe that the only change is adding [dark] to <html>

WesselKroos commented 1 year ago

Oh nice, this might be possible then. I didn't know that the matchMedia query also fires change events. I'll make sure to take a look at it once I've got some time on my hands.

WesselKroos commented 1 year ago

After a first investigation I came to the conclusion that, to get this to work correctly I'll also need to find a way to detect if the YouTube appearance setting is set to "Device theme". Because I should only change the theme at the change event when the Ambient light appearance setting is set to "Default" AND the YouTube appearance setting is set to "Device theme".

avi12 commented 1 year ago

No need, actually, you can ignore YouTube's theme setting Basically, if the current theme is dark and you need to be light, remove [dark], and vice versa

avi12 commented 1 year ago

The same goes for the detection For example:

function init() {
  if (isYouTubeLight) {
    setAmbientLight();
    addColorThemeListener();
    return;
  }

  setAmbientDark();
  addColorThemeListener();
}

init();
WesselKroos commented 1 year ago

The "Default" option in the Ambient light appearance setting means "do not change the theme, let YouTube decide the theme". But I do see a potential 4th option "Device theme" that also fixes your specific issue. So I might implement that instead if it's not possible to detect the value of the YouTube appearance setting.

WesselKroos commented 1 year ago

I think I'm finally able to reproduce the problem. YouTube does indeed change the theme according to the device theme sometimes, only when the kevlar_refresh_on_theme_change flag in the YouTube config is set to false. When I set it to false, it switches from dark to light theme, but only for a few milliseconds, then the theme is quickly switched back again by the Ambient light extension to the value of the device theme on pageload.

It happens in these lines in YouTube's script:

    e.onDeviceThemeChanged = function() {
        var a = Ar();
        jk(hk(), 185, a);
        if (B("kevlar_refresh_on_theme_change"))
            hk().save();
        else if (Br() && this.isAppDarkTheme() !== a)
            this.onDarkModeToggledAction()
    }
avi12 commented 1 year ago

Interesting, how did you figure it out?

WesselKroos commented 1 year ago

A lot of searching in the files and being lucky while setting the right breakpoints 😀

WesselKroos commented 1 year ago

The theme setting seems to be saved in the parameter f6 of the cookie named PREF. As far as I can extrapolate there are 5 different values for the themes. The YouTube and Device values are merged together:

Old states (logged in states?) Theme Value in cookie PREF parameter F6
YouTube: device theme 80
YouTube: dark 480
YouTube: light 80080
Device: dark 40000000
Device: light 0
Logged out states Device YouTube Value in cookie PREF parameter F6
Dark Device 40000000
Dark Dark 40000400
Dark Light 40080000
Light Device -
Light Dark 400
Light Light 80000
Logged in states Device YouTube Value in cookie PREF parameter F6
Dark Device 40000080
Dark Dark 40000480
Dark Light 40080080
Light Device 80
Light Dark 480
Light Light 80080

@avi12 Are these values the same on your device? Open the DevTools and go to the Application tab, then open the Cookies panel at the left side and search for the PREF cookie. image

WesselKroos commented 1 year ago

I think I have a fix. It's strange that YouTube only changes the PREF cookie once, but I can luckily still read the device theme after the second switch from the matchMedia change event.

https://user-images.githubusercontent.com/31220528/222826825-44bcfee9-1cd2-4417-9910-aad68bbfd1df.mp4

avi12 commented 1 year ago

@avi12 Are these values the same on your device? Open the DevTools and go to the Application tab, then open the Cookies panel at the left side and search for the PREF cookie. image

I just put it in light mode and auto-adjusting the theme by Auto Dark

f6=40080080&tz=Asia.Jerusalem&f7=100&f5=30000
avi12 commented 1 year ago

I'm wondering, why won't this snippet work?

function init() {
  if (isYouTubeLight) {
    setAmbientLight();
    addColorThemeListener();
    return;
  }

  setAmbientDark();
  addColorThemeListener();
}

init();
WesselKroos commented 1 year ago

I don't know what the value of isYouTubeLight is and the functions setAmbientDark and addColorThemeListener do, so I don't know?

avi12 commented 1 year ago
const isYouTubeLight = Boolean(document.documentElement.hasAttribute("dark"));
const instanceDarkmode = matchMedia("(prefers-color-scheme: dark)");

function setAmbientLight() {
  // A function from your codebase that would trigger the ambient effect
}

function addColorThemeListener() {
  instanceDarkMode.addEventListener("change", e => {
    const isDark = e.matches;
    setAmbientLight(/* ... */);
  })
}

function init() {
  if (isYouTubeLight) {
    setAmbientLight();
    addColorThemeListener();
    return;
  }

  setAmbientDark();
  addColorThemeListener();
}

init();
WesselKroos commented 1 year ago

It's probably because the ambientlight.originalTheme value contains the device theme value from the pageload and doesn't change.

WesselKroos commented 1 year ago

@avi12 The fix has now been released for all browsers. Could you verify that it works as expected?

avi12 commented 1 year ago

It works for the most part, but:

If I start from light mode, then transition to dark mode, then transition back to light mode: image

If I start from dark mode, then transition to light mode, then transition back to dark mode: image

WesselKroos commented 1 year ago

Is it happening because you have this snippet still running? #issuecomment-1454141341

Or because of the Dark Reader extension?

Or does it still happen when both are disabled?

avi12 commented 1 year ago

However, I did notice when also using Auto Dark that this issue occurred when switched from light to dark theme while having Ambilight enabled, with the YouTube theme setting set to Light

WesselKroos commented 1 year ago

So, if I understand correctly; The theme is wrong on the like button icon only?

Then I guess YouTube forgets to restyle it after theme switches. I could probably override it without harm.

avi12 commented 1 year ago

The theme is wrong on the like button icon only?

I've only tested this behavior with your extension (not the one I linked above), but I got: image

I.e. some element colors will change while others won't Interestingly, when I scroll a bit, the text colors of the chat section change to the correct color (i.e. on dark it changes to white and vice versa)

WesselKroos commented 1 year ago

Funny, YouTube seems to give up on theming the like icon after 2 theme switches. I can also get a black icon in the light theme:

image

I'll send a report to YouTube, they might fix it. But I'll fix the chat theme myself.

avi12 commented 1 year ago

I love being a bug hunter 😁

WesselKroos commented 1 year ago

Apparently the same happens in the chat windows as in the like button. YouTube just gives up on the theme after 2 switches.

avi12 commented 1 year ago

For some reason, the YouTube home page won't change to dark mode image

avi12 commented 1 year ago

The opposite is also true image

Oxize commented 1 year ago

Wessel, since last week the white theme bug is back again, when you refresh the main page of YT. Can you look into this?

Click with mouse on Youtube NL Home button. Page get white. Press refresh to get it black again. Should be black all times.

avi12 commented 1 year ago

I have a feeling that there is a bug on the YouTube side when it comes to setting the theme cookie - it's inconsistent and the cookie value might change at any point

Oxize commented 1 year ago

didnt we had this problem a year ago also?

avi12 commented 1 year ago

No idea, I tend to use extensions to automatically set the theme, whether it's Dark Reader or Auto Dark for YouTube The former overrides the YouTube colors and a bit breaks the dark theme, e.g. on Shorts, whereas the latter simply applies the YouTube dark theme itself according to the media query "prefers-color-scheme"

WesselKroos commented 1 year ago

@Oxize @avi12 There was a theming bug in 2.37.21. Can you check if it's still bugged in 2.37.22? Google's review of the new version was completed this morning, so it should be available in the Chrome web store.

avi12 commented 1 year ago

Just tried to change it from dark to light mode, did not fix it

avi12 commented 1 year ago

I do recommend trying to implement the algorithm in the main post, i.e. add/remove the [dark] attribute

Oxize commented 1 year ago

@Oxize @avi12 There was a theming bug in 2.37.21. Can you check if it's still bugged in 2.37.22? Google's review of the new version was completed this morning, so it should be available in the Chrome web store.

Nope still bugged.

WesselKroos commented 1 year ago

Nope still bugged.

Then YouTube might have changed something in their site.

I'm currently working, so I'll take a look in the evening.

WesselKroos commented 1 year ago

@Oxize @avi12 I can't reproduce it. Let me know if I missed something in this video: https://user-images.githubusercontent.com/31220528/225099107-35c631e4-c491-4b40-b1a9-450009ccf323.mp4

Alternatively you could check if it is caused by another extension.

Or I have another PREF.f6 cookie value than you. Mine PREF cookie is: f6=40000080&...

Another option could be that YouTube is A/B testing new code. In that case:

  1. Open the DevTools console by pressing F12
  2. Execute this javascript in the Console tab: ytcfg.data_.EXPERIMENT_FLAGS
  3. Right click on the returned flags and click on "Copy object"
  4. Paste it into a file and attach it to a comment to share it with me, so that I can try out YouTube with the same flags enabled.
avi12 commented 1 year ago

Try to reproduce the issue at https://www.youtube.com/feed/subscriptions

WesselKroos commented 1 year ago

Try to reproduce the issue at https://www.youtube.com/feed/subscriptions

Subscriptions page > Watch page > Subscriptions page Watch page > Subscriptions page

Both navigation paths stay in the dark theme on the subscriptions page

WesselKroos commented 1 year ago

@avi12 What is your PREF.f6 cookie value?

Oxize commented 1 year ago

https://youtu.be/J_4F7oP3sUs

ytcfg.data_.EXPERIMENT_FLAGS.txt

avi12 commented 1 year ago

@avi12 What is your PREF.f6 cookie value?

My theme is set to "Device theme"

WesselKroos commented 1 year ago

@avi12 What is your PREF.f6 cookie value?

My theme is set to "Device theme"

PREF.f6 has several values for "Device theme"

WesselKroos commented 1 year ago

https://youtu.be/J_4F7oP3sUs

@Oxize Strange to see that it already switches to the light theme when you navigate to the watch page the second time at 0:09

Oxize commented 1 year ago

Ye, something like we had last year. And with a normal refresh F5, it goes to black again.

WesselKroos commented 1 year ago

ytcfg.data_.EXPERIMENT_FLAGS.txt

@Oxize Even with the flags I cannot reproduce it. Just to be sure, can you verify that it does not happen when you disable my extension in chrome://extensions/ ? And that it does not happen when you uncheck the "Enabled" setting in my extension settings?

Oxize commented 1 year ago

Your extension?

Oxize commented 1 year ago

When disabled, it stays on chrome default black theme.

WesselKroos commented 1 year ago

Pff, it's a though one... What difference are we missing...

@Oxize What is the value of document.querySelector('ytd-app ytd-watch-flexy').querySelector in your browser?

Oxize commented 1 year ago

where to check?

WesselKroos commented 1 year ago

where to check?

Press F12 > Open the Console tab > Type in that piece of code > Press enter

image


@Oxize And what is your PREF cookie value?

Press F12 > Open the Application tab > Filter on "PREF" > Copy the value image


@Oxize Or maybe the cookie value is different the way I check it. Could you check what the value is when you execute (await cookieStore.get('PREF'))?.value in the console tab?

image