Mode sombre automatique également pour les commentaires intégrés ?

Automatic Dark Mode color scheme switching is a fantastic addition, thanks for integrating it!

With (automatic) color scheme switching available, I’m wondering if there might also be some way to switch back and forth between light and dark Discourse modes when embedded as comments in a blog. Specifically, my Ghost blog has a toggle that users can click on to manually switch back and forth between light and dark modes. I know that my blog’s CSS can’t effect the CSS within Discourse’s iframe, but with this new addition might there be another way that the toggle could also switch the Discourse color scheme? You can see an example post with comments at the bottom of this post.

11 « J'aime »

This is potentially doable but a little tricky. At the moment, we haven’t added dark mode auto switching to the embedded comments endpoint. We can add that, and it would work if your Ghost site was auto-switching to dark mode when the browser switches to dark mode. But from what I can tell, your Ghost site uses a dark mode button, which won’t work with the Discourse implementation.

What you can do in your specific case, is toggle a class in the Discourse embedded comments iframe when clicking the button, and then use that class to toggle colors in your embedded stylesheet.

13 « J'aime »

Sounds good. While I am currently putting together several dark mode utilizing (Ghost) themes for colleagues of mine, all of which will share a single Discourse instance, that’s still a bit further down the road.

I unfortunately don’t quite understand what you’re suggesting here. Currently, any elements that I want to utilize dark mode styling within my blog have their CSS doubled up by preceding such items with body.dark. As in

p {
    color: #000;
}
body.dark p {
    color: #FFF;
}

Might you be suggesting that I use that body.dark code to change things in the Discourse iframe? Because I tried inserting the following into Discourse’s Embedded CSS field, which unfortunately had no effect:

.FF2F-discourse p {
    color: #000;
}
body.dark .FF2F-discourse p {
    color: #FFF;
}

That being so, are you instead suggesting that I have some separate JS written so that the toggle will affect a separate change via specific targeting of a class in the iframe? Because like I stated in my previous comment, I didn’t think that external coding could affect CSS within an iframe, hence my confusion. But I’m very much solely an HTML/CSS amateur, so there’s no doubt that you know better than me and/or that I’m misunderstanding something else.

Thanks again for any hints.

6 « J'aime »

Yes, that’s what I am suggesting. Your blog’s stylesheets cannot apply to the iframe, but you can use JS to toggle the dark class in the iframe’s html or body element, and then update your Discourse embedded stylesheet accordingly.

10 « J'aime »

I’ve found two pages explaining how toggling between light and dark modes for Discourse’s embed might be done, but the guy who writes my JS is wondering if the method you’re suggesting entails using postMessage (which the pages I found state) or something else.

Here’s a page explaining how to implement cross-window messaging with postMessage

While this one is actually a tutorial on how to change the CSS within an iframe via postMessage, specifically for switching between light and dark modes:

https://cobwwweb.com/change-css-iframe

Might I be on the right track with all this?

8 « J'aime »

My apologies, I forgot to respond here, yes, I think postMessage can work for your use case.

11 « J'aime »

Salut,

Désolé de déterrer un sujet aussi ancien, mais y a-t-il des projets pour implémenter la commutation automatique du mode sombre pour le point de terminaison des commentaires intégrés ?

1 « J'aime »

Nous n’avons actuellement pas l’intention d’ajouter cette fonctionnalité. Les sites peuvent ajouter des styles de mode sombre à leur feuille de style intégrée comme solution de contournement (ou utiliser la technique postMessage décrite ci-dessus).

7 « J'aime »

postMessage a besoin d’un iframe intégré pour gérer l’événement message.
Où dois-je ajouter du code à un iframe pour gérer l’événement ?

2 « J'aime »

Je l’ai implémenté en utilisant postMessage. Les codes et leur logique d’exécution sont les suivants :

Le bloc de code ① ajoute un écouteur d’événements dans l’iframe Discourse intégrée qui enverra un message à mon site Web contenant l’iframe Discourse intégrée une fois que Discourse intégrée sera chargée.

Lorsque mon site Web reçoit un message de Discourse intégrée, il effectuera une validation, comme montré dans le bloc de code ②, et si elle réussit, appellera la fonction setIframeStyle pour définir Discourse intégrée.

La fonction setIframeStyle, juste montrée dans le bloc de code ③, transmet le mode couleur, « dark » ou « light », à l’iframe en appelant postMessage. De plus, une fois le mode sombre activé, la fonction peut être appelée pour maintenir Discourse intégrée dans le même mode couleur que mon site Web.

Le bloc de code ④ permet à Discourse intégrée de pouvoir traiter le message de mode couleur envoyé depuis mon site Web. Ici, je bascule le mode couleur en changeant le nom de classe du tag body.

De plus, les blocs de code ① et ④ sont ajoutés par la page d’administration de Discourse, comme ci-dessous :

Et des classes CSS personnalisées doivent être ajoutées comme ci-dessous :

12 « J'aime »

Quelqu’un sait où modifier si nous ne pouvons pas modifier le « CSS intégré » (car ce n’est pas un thème officiel) ?

2 « J'aime »

Vous venez de créer un nouveau composant et d’utiliser son onglet intégré ?

3 « J'aime »

Merci pour le plan ci-dessus @mikeguo, c’est merveilleusement expliqué !

Notez également que vous devez utiliser la dernière version de Discourse pour y parvenir, la fonctionnalité d’en-tête intégré n’ayant été ajoutée qu’il y a quelques jours.

8 « J'aime »

EDIT : C’est ce que je devais faire Structure of themes and theme components

Cela semble être faux ?

const handleMessageListener = (event:MessageEvent<any>)

2 « J'aime »

Je n’arrive toujours pas à activer ce code (!) Quelqu’un pourrait-il, s’il vous plaît, le réviser ?

Je vois que personne ne peut activer cela et que presque tout le monde utilise la lumière forcée, ce qui est très mauvais pour nos yeux :frowning:

1 « J'aime »

Je peux confirmer que la méthode ci-dessus fonctionne toujours, mais il aurait été agréable de ne pas avoir à taper le code à partir d’une capture d’écran :slight_smile: Donc, le voici, légèrement mis à jour :

Étapes

  1. L’iframe des commentaires finit de se rendre et envoie un message à la fenêtre principale du navigateur, l’en informant.
  2. Le navigateur interroge son réglage de mode sombre/clair et renvoie la valeur dans l’iframe.
  3. L’iframe reçoit le message et définit un attribut de données, une classe ou similaire, en fonction du réglage du mode sombre/clair.

Code

  1. Une fois l’iframe chargé, envoyez une notification à la fenêtre parente. Cela doit être saisi sur Discourse, sous Admin -> Personnaliser -> (sélectionner le thème) -> Modifier CSS/HTML -> En-tête intégré.
    window.addEventListener("load", (event) => {
        window.parent.postMessage("iframe loaded", "*");
    }, false);
  1. Gérez ce déclencheur entrant dans la fenêtre principale. Ce code se trouve sur votre site de blog :
  const discourse_url = "https://your.discourse-instance.org";

  // Ici, nous déterminons le thème et envoyons un message à l'iframe pour lui faire savoir quel est le thème
  // Voir ci-dessous comment nous configurons notifyFrameStyle
  const notifyIFrameOfTheme = () => {
    const iframe = document.getElementById("discourse-embed-frame");
    if (iframe && iframe.contentWindow) {
      iframe.contentWindow.postMessage(
        {
          // Modifiez la ligne ci-dessous pour récupérer le réglage du mode sombre, en fonction de la façon dont vous le stockez
          theme: document.documentElement.getAttribute("data-theme")
        },
        discourse_url
      );
    }
  };

  // Appelez setFrameStyle lorsque nous recevons le message "iframe loaded"
  const handleMessageListener = (event) => {
    var origin = event.origin;
    if ((origin === discourse_url) && (event.data == "iframe loaded")) {
      notifyIFrameOfTheme();
    }
  };
  1. Dans le bloc <script> de (1), ajoutez un écouteur pour le message de thème envoyé par notifyFrameStyle :
    window.addEventListener("message", (event) => {
        const payload = event.data;
        if (payload.theme) {
          // Faites quelque chose avec le réglage du thème ; j'ai défini l'attribut `data-theme` sur le `<html>` de l'iframe,
          // mais vous voudrez peut-être définir un attribut de classe ou similaire
          document.documentElement.setAttribute("data-theme", payload.theme);
        }
    }, false);

Style

Sous Admin -> Personnaliser -> (sélectionner le thème) -> Modifier CSS/HTML -> CSS intégré, vous pouvez maintenant fournir du CSS pour chaque mode. Par exemple, vous pouvez remplacer les variables de style de Discourse :

html[data-theme="dark"] {
  --primary: #ced6dd;
  --primary-low: #48566b;
  --secondary: #14181e;
  --tertiary: #2b7e8d;
}

J’espère que cela vous aidera !

6 « J'aime »

Le code copiable ci-dessus omet l’ajout de l’écouteur d’événements dans la fenêtre d’intégration :

window.addEventListener("message", handleMessageListener);

Et une note : aucun paramètre CORS spécial n’est nécessaire pour cela.

Merci d’avoir signalé cela ! Je ne peux plus modifier le message ci-dessus, mais window.addEventListener doit être placé en bas de l’extrait de code sous (2).

Voir cet exemple concret.

5 « J'aime »