Changing favicon & Darkmode

This and the logo-dock doesn’t work for me. I checked and it doesn’t seem to be a permission issue since every user can read that. So is there any implicit constraint on the png file like it should be of which size?

Ah, Okey I missed this part.

Update: but still, my image is 1024 and it doesn’t work. It doesn’t show any icon now.

Have you checked if the http://<notes.tld>/.client/logo-dock.png url actually gives the plain image file in the right size?

Only other things i can think of would be deleting the browser cache and reinstalling the pwa.
Sorry for not being able to help further, you should probably look for someone for whom pwa’s are not a blackbox :sweat_smile:

Ah, thanks for the reply. No, I can’t see it. It is probably the incompatible png I assume. This shouldn’t be a PWA problem rather the resource not available.

image

Yeah, seems like either your file, file-permissions or proxy settings are broken. I’m getting the same error when trying to load your favicon.
Have you checked if your reverse-proxy can access the file?

I’m sure that 1) permission of the file is set to the same as the reverse proxy user 2) file accessible inside reverse proxies container 3) the proxy seems to be fine (not very familiar but seems working.

So the most likely reason would be the incorrect reverse proxy. I’ll investigate tomorrow. Thanks for helping!

Just attach the reverse proxy if you were curious, it is caddy section:

core.lumeny.io {
    # Serve custom logo image
    handle /.client/logo-dock.png {
        root * /var/www/media/silverbullet
        file_server
    }
    handle /.client/favicon.png {
        root * /var/www/media/silverbullet
        file_server
    }

    # Regular reverse proxy for everything else
    handle /* {
        reverse_proxy http://<silverbullet>:3000 {
            header_up Host {host}
            header_up X-Real-IP {remote_host}
        }
    }
}
1 Like

Lua version to allow switching Dark Mode based on browser preferences:

event.listen {
  name = "editor:pageLoaded",
  run = function(e)
    local darkMode = js.window.matchMedia('(prefers-color-scheme: dark)').matches
    if editor.getUiOption("darkmode") != darkMode then
      editor.setUiOption("darkMode", darkMode)
    end
  end
}

The caveat is that I don’t know if it is possible yet to set a JS listener for dark mode change and then call the appropriate editor.setUIOption("darkmode") command. So with the above you do need to go to another page and then it will change automatically. Not ideal.

1 Like

Adding a change listener works like a charm! :smiley:
Just like it would work in js:

event.listen {
  -- Run at editor:init instead of editor:pageLoaded so we only add the listener once every tab
  name = "editor:init",
  run = function() 
    local mquery = js.window.matchMedia('(prefers-color-scheme: dark)')

    editor.setUiOption("darkMode", mquery.matches)

    mquery.addEventListener("change",
      function(mqChanged)
        editor.setUiOption("darkMode", mqChanged.matches);
      end
    )

  end
}
1 Like

If I understand correctly what it does, it (1) matches for user’s preferred color scheme as set in her browser, (2) if it is set to dark then it sets SilverBullet UI’s darkMode option to true (or to false otherwise), then (3) it adds another “change” listener to the already existing media match and (4) if that changes it sets SilverBullet UI’s darkMode option to either true or false (as in (2)). The (1) and (2) works for me (SilverBullet is indeed using dark style if it is my preferred color scheme). The rest does not seem to work for me. If I use Editor: Toggle Dark Mode when my preferred color scheme in my browser is set to “Dark” the page just flashes to light color scheme and then returns back to the dark mode instead of staying in the light mode. Any ideas, please @22rw ?

I think this happens, because the Editor: Toggle Dark Mode command reloads the page, causing editor:init to happen again, in turn setting the “darkMode” value to your browser-theme preference, which is still set to dark.

I noticed this before with my js code, but never bothered to look for a solution until your comment. Here’s what I came up with:

In javascript:

silverbullet.registerEventListener({name: "editor:init"}, async () => {
  const mquery = window.matchMedia('(prefers-color-scheme: dark)');
  // Initial theme update
  // sessionStorage is tab-specific and persists reloads
  if(sessionStorage.getItem("darkMode") == null) {
    await editor.setUiOption("darkMode", mquery.matches);
    sessionStorage.setItem("darkMode", mquery.matches);
  }
    
  mquery.addEventListener("change", async (mqChanged) => {
    await editor.setUiOption("darkMode", mqChanged.matches);
  });
});

Lua should look something like this (untested):

event.listen {
  -- Run at editor:init instead of editor:pageLoaded so we only add the listener once every tab
  name = "editor:init",
  run = function() 
    local mquery = js.window.matchMedia('(prefers-color-scheme: dark)')

    if js.window.sessionStorage.getItem("darkMode") == nil then
      editor.setUiOption("darkMode", mquery.matches)
      js.window.sessionStorage.setItem("darkMode", mquery.matches)  
    end

    mquery.addEventListener("change",
      function(mqChanged)
        editor.setUiOption("darkMode", mqChanged.matches);
      end
    )

  end
}

This allows you to manually toggle the editor theme using Editor: Toggle Dark Mode, while still matching your browser theme at the initial page load and also reacting to browser theme changes.

Nice one, @22rw!

I adapted it slightly:

```space-lua
event.listen {
  -- Run at editor:init instead of editor:pageLoaded so we only add the listener once every tab
  name = "editor:init",
  run = function() 
    local mquery = js.window.matchMedia('(prefers-color-scheme: dark)')

    local csdm = clientStore.get("darkMode")
    if csdm == nil then
      editor.setUiOption("darkMode", mquery.matches) 
    end

    mquery.addEventListener("change",
      function(mqChanged)
        local csdm = clientStore.get("darkMode")
        if csdm == nil then
          editor.flashNotification('⚡Dark Mode? ' .. mqChanged.matches)
          editor.setUiOption("darkMode", mqChanged.matches);
        end
      end
    )

  end
}

command.define {
  name = 'Editor: Use System Theme',
  run = function()
    clientStore.delete("darkMode")
    editor.reloadUI()
  end
}

-- override the standard Toggle Dark Mode-command to toggle based on system preference.
command.define {
  name = 'Editor: Toggle Dark Mode',
  run = function()
    local csdm = clientStore.get("darkMode")
    local newCsdm 
    if csdm == nil then
      local mquery = js.window.matchMedia('(prefers-color-scheme: dark)')
      newCsdm = mquery.matches == false)
    else
      newCsdm = not csdm
    end

    clientStore.set("darkMode", newCsdm)
    editor.reloadUI()
  end
}

This uses the clientStore api to check if a preference is set. If not, then fallback to the system preferences. The command on the bottom allows the user to then also unset the silverbullet preference to fallback to the system preference.

1 Like

@janssen-io @22rw Great guys! Thanks. Last thing to consider here… It seems to me that if I reset from saved color scheme back to system color scheme which is set to dark and then run toggle dark mode command again then the dark mode remains until I run the command to toggle dark mode once again. Then I get light theme set.

Good idea for an improvement, @mjf!

You can override the standard command to achieve the right toggle behavior after a reset to system preferences:

command.define {
  name = 'Editor: Toggle Dark Mode',
  run = function()
    local csdm = clientStore.get("darkMode")
    local newCsdm 
    if csdm == nil then
      local mquery = js.window.matchMedia('(prefers-color-scheme: dark)')
      newCsdm = mquery.matches == false)
    else
      newCsdm = not csdm
    end

    clientStore.set("darkMode", newCsdm)
    editor.reloadUI()
  end
}

Edit: also needs to of course still update correctly if the preference was already set in SilverBullet!

1 Like

Works! :heart:

Thanks for all the discussions. Am I correct to understand that will this adapted script can help me avoid the sudden white screen when trigger a reload on UI in dark mode?

I believe this is a client side setting, so the server always returns the ‘light mode’ and then the client switches to dark mode. So it’s unfortunately not possible to prevent the white flash. :frowning:

1 Like