Automatischer Dunkelmodus auch für eingebettete Kommentare?

Automatic Dark Mode color scheme switching ist eine fantastische Ergänzung, danke für die Integration!

Da jetzt (automatisches) Umschalten des Farbschemas verfügbar ist, frage ich mich, ob es auch eine Möglichkeit gibt, beim Einbetten als Kommentare in einem Blog zwischen den hellen und dunklen Discourse-Modi hin und her zu wechseln. Mein Ghost-Blog verfügt beispielsweise über einen Schalter, mit dem Nutzer manuell zwischen hellen und dunklen Modi umschalten können. Ich weiß zwar, dass das CSS meines Blogs das CSS innerhalb des Discourse-iframes nicht beeinflussen kann, aber gibt es mit dieser neuen Funktion vielleicht einen anderen Weg, über den der Schalter auch das Discourse-Farbschema umschalten könnte? Ein Beispielbeitrag mit Kommentaren am Ende findest du in diesem Beitrag.

11 „Gefällt mir“

Das ist potenziell machbar, aber ein wenig knifflig. Momentan haben wir für den Endpunkt für eingebettete Kommentare keinen automatischen Wechsel in den Dunkelmodus hinzugefügt. Wir könnten das nachrüsten, und es würde funktionieren, wenn deine Ghost-Seite automatisch in den Dunkelmodus wechselt, sobald der Browser in den Dunkelmodus umschaltet. Aber soweit ich das sehe, verwendet deine Ghost-Seite eine Dunkelmodus-Schaltfläche, was mit der Discourse-Implementierung nicht funktioniert.

Was du in deinem spezifischen Fall tun kannst, ist, beim Klicken auf die Schaltfläche eine Klasse im Discourse-iFrame für eingebettete Kommentare umzuschalten und dann diese Klasse zu verwenden, um die Farben in deinem eingebetteten Stylesheet zu ändern.

13 „Gefällt mir“

Klingt gut. Zwar arbeite ich derzeit an mehreren Dark-Mode-fähigen (Ghost-)Themes für meine Kollegen, die alle dieselbe Discourse-Instanz nutzen werden, aber das ist noch etwas weiter in der Zukunft.

Ich verstehe leider nicht ganz, was du hier vorschlägst. Aktuell werden alle Elemente, die ich innerhalb meines Blogs mit Dark-Mode-Styling nutzen möchte, durch CSS-Regeln verdoppelt, indem ich solche Elemente mit body.dark voranstelle. Also:

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

Meinst du vielleicht, ich solle diesen body.dark-Code verwenden, um Dinge im Discourse-Ifame zu ändern? Denn ich habe versucht, Folgendes in das CSS-Feld für eingebettete Inhalte von Discourse einzufügen, was leider keine Wirkung hatte:

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

In diesem Fall schlägst du vielleicht vor, dass ich separates JavaScript schreibe, damit der Toggle über eine gezielte Auswahl einer Klasse im Iframe eine separate Änderung bewirkt? Denn wie ich in meinem vorherigen Kommentar bereits erwähnt habe, dachte ich, dass externes Coding keinen Einfluss auf CSS innerhalb eines Iframes haben kann – daher meine Verwirrung. Aber ich bin ausschließlich ein HTML/CSS-Amateur, daher besteht kein Zweifel, dass du mehr Ahnung hast als ich und/oder dass ich etwas anderes missverstehe.

Nochmals vielen Dank für alle Hinweise.

7 „Gefällt mir“

Ja, genau das schlage ich vor. Die Stylesheets deines Blogs können nicht auf den iframe angewendet werden, aber du kannst JS nutzen, um die Klasse dark im html- oder body-Element des iframes umzuschalten und dann dein in Discourse eingebettetes Stylesheet entsprechend zu aktualisieren.

11 „Gefällt mir“

Ich habe zwei Seiten gefunden, die erklären, wie man zwischen dem hellen und dunklen Modus für die Einbettung von Discourse umschalten kann. Der Entwickler, der mein JavaScript schreibt, fragt sich jedoch, ob die von dir vorgeschlagene Methode die Verwendung von postMessage erfordert (was die von mir gefundenen Seiten bestätigen) oder etwas anderes.

Hier ist eine Seite, die erklärt, wie man die Kommunikation zwischen Fenstern mit postMessage implementiert:

Diese hier ist tatsächlich ein Tutorial darüber, wie man das CSS innerhalb eines Iframes über postMessage ändert, speziell für den Wechsel zwischen dem hellen und dunklen Modus:

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

Bin ich mit all dem auf dem richtigen Weg?

8 „Gefällt mir“

Entschuldigung, ich habe vergessen, hier zu antworten. Ja, ich denke, postMessage kann für deinen Anwendungsfall funktionieren.

11 „Gefällt mir“

Hallo,

Entschuldigen Sie, dass ich ein so altes Thema aufgreife, aber gibt es Pläne, den Dark-Mode-Automatikwechsel für eingebettete Kommentar-Endpunkte zu implementieren?

1 „Gefällt mir“

Wir haben derzeit keine Pläne, diese Funktion hinzuzufügen. Websites können Dark-Mode-Stile zu ihrem eingebetteten Stylesheet hinzufügen (als Workaround oder die oben diskutierte postMessage-Technik verwenden).

7 „Gefällt mir“

postMessage benötigt ein eingebettetes iframe, um das message-Ereignis zu verarbeiten.
Wo füge ich Code in ein iframe ein, um das Ereignis zu verarbeiten?

2 „Gefällt mir“

Ich habe es mit postMessage implementiert. Der Code und seine Ausführungslogik sind wie folgt:

Codeblock ① fügt einen Event-Listener in den eingebetteten Discourse-iframe ein, der eine Nachricht an meine Website sendet, die den eingebetteten Discourse-iframe enthält, sobald Discourse eingebettet ist.

Wenn meine Website eine Nachricht von eingebettetem Discourse empfängt, führt sie eine Validierung durch, wie in Codeblock ② gezeigt, und wenn diese erfolgreich ist, wird die Funktion setIframeStyle aufgerufen, um eingebettetes Discourse einzustellen.

Die Funktion setIframeStyle, die in Codeblock ③ gezeigt wird, übergibt den Farbmodus, „dark“ oder „light“, an den iframe, indem sie postMessage aufruft. Zusätzlich kann die Funktion aufgerufen werden, um den eingebetteten Discourse im gleichen Farbmodus wie meine Website zu halten, sobald der dunkle Modus umgeschaltet wird.

Codeblock ④ ermöglicht es eingebettetem Discourse, die von meiner Website gesendete Farbmodus-Nachricht zu verarbeiten. Hier schalte ich den Farbmodus um, indem ich den Klassennamen des Body-Tags ändere.

Zusätzlich werden Codeblock ① und ④ über die Discourse-Admin-Seite hinzugefügt, wie unten gezeigt:

Und benutzerdefinierte CSS-Klassen sollten wie folgt hinzugefügt werden:

12 „Gefällt mir“

Weiß jemand, wo man bearbeiten kann, wenn man "Eingebettetes CSS" nicht bearbeiten kann (weil kein offizielles Theme)?

2 „Gefällt mir“

Erstellen Sie gerade eine neue Komponente und verwenden Sie deren eingebetteten Tab?

3 „Gefällt mir“

Vielen Dank für den obigen Überblick, @mikeguo, das ist wunderbar erklärt!

Beachten Sie außerdem, dass Sie die neueste Discourse-Version verwenden müssen, um dies zu erreichen. Die Funktion für eingebettete Header wurde erst vor wenigen Tagen hinzugefügt.

8 „Gefällt mir“

EDIT: Das ist, was ich tun musste Structure of themes and theme components

Das scheint falsch zu sein?

const handleMessageListener = (event:MessageEvent<any>)

2 „Gefällt mir“

Ich kann diesen Code immer noch nicht aktivieren (!) Könnte ihn bitte jemand überarbeiten?

Ich sehe, dass niemand diesen aktivieren kann und fast jeder eine helle erzwungene Darstellung verwendet, das ist sehr schlecht für unsere Augen :frowning:

1 „Gefällt mir“

Ich kann bestätigen, dass die obige Methode immer noch funktioniert, aber es wäre schön gewesen, wenn ich den Code nicht von einem Screenshot hätte abtippen müssen :slight_smile: Hier ist er also, leicht aktualisiert:

Schritte

  1. Der Kommentare-Iframe ist gerendert und sendet eine Nachricht an das Haupt-Browserfenster, dass er fertig ist.
  2. Der Browser fragt seine Dunkel-/Hellmodus-Einstellung ab und sendet den Wert zurück in den Iframe.
  3. Der Iframe empfängt die Nachricht und setzt ein data-Attribut, eine Klasse oder Ähnliches basierend auf der Dunkel-/Hellmodus-Einstellung.

Code

  1. Sobald der Iframe geladen ist, senden Sie eine Benachrichtigung an das übergeordnete Fenster. Dies muss in Discourse unter Admin -> Anpassen -> (Thema auswählen) -> CSS/HTML bearbeiten -> Eingebetteter Header eingegeben werden.
<script type="text/javascript">
    window.addEventListener("load", (event) => {
        window.parent.postMessage("iframe loaded", "*");
    }, false);
</script>
  1. Behandeln Sie diesen eingehenden Trigger im Hauptfenster. Dieser Code befindet sich auf Ihrer Blog-Website:
<script type="text/javascript">
  const discourse_url = "https://your.discourse-instance.org";

  // Hier bestimmen wir das Thema und senden eine Nachricht an den Iframe, um ihn darüber zu informieren
  // Siehe unten, wie wir notifyFrameStyle einrichten
  const notifyIFrameOfTheme = () => {
    const iframe = document.getElementById("discourse-embed-frame");
    if (iframe && iframe.contentWindow) {
      iframe.contentWindow.postMessage(
        {
          // Ändern Sie die folgende Zeile, um die Dunkelmodus-Einstellung abzurufen, je nachdem, wie Sie sie speichern
          theme: document.documentElement.getAttribute("data-theme")
        },
        discourse_url
      );
    }
  };

  // Rufen Sie setFrameStyle auf, wenn wir die Nachricht "iframe loaded" erhalten
  const handleMessageListener = (event) => {
    var origin = event.origin;
    if ((origin === discourse_url) && (event.data == "iframe loaded")) {
      notifyIFrameOfTheme();
    }
  };
</script>
  1. Fügen Sie im script-Block aus (1) einen Listener für die vom notifyFrameStyle gesendete Thema-Nachricht hinzu:
    window.addEventListener("message", (event) => {
        const payload = event.data;
        if (payload.theme) {
          // Tun Sie etwas mit der Thema-Einstellung; ich setze das `data-theme`-Attribut auf dem `html`-Element des Iframes,
          // aber Sie möchten vielleicht ein class-Attribut oder Ähnliches setzen
          document.documentElement.setAttribute("data-theme", payload.theme);
        }
    }, false);

Styling

Unter Admin -> Anpassen -> (Thema auswählen) -> CSS/HTML bearbeiten -> Eingebettetes CSS können Sie nun CSS für jeden Modus bereitstellen. Sie können z. B. die Discourse-Styling-Variablen überschreiben:

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

Ich hoffe, das hilft!

6 „Gefällt mir“

Der obige kopierbare Code enthält die fehlende Hinzufügung des Event Listeners im Einbettungsfenster:

window.addEventListener("message", handleMessageListener);

Und ein Hinweis: Es sind keine speziellen CORS-Einstellungen erforderlich.

Danke, dass Sie das bemerkt haben! Ich kann den obigen Beitrag nicht mehr bearbeiten, aber window.addEventListener gehört am Ende des Code-Snippets unter (2).

Siehe dieses reale Beispiel.

6 „Gefällt mir“