هل يدعم الوضع المظلم التلقائي للتعليقات المضمنة أيضاً؟

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 إعجابًا

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 إعجابًا

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 إعجابات

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 إعجابات

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 إعجابات

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

11 إعجابًا

مرحباً،

آسف لإثارة موضوع قديم، ولكن هل هناك أي خطط لتطبيق التبديل التلقائي للوضع المظلم لنقطة نهاية التعليقات المضمنة؟

إعجاب واحد (1)

ليس لدينا حاليًا خطط لإضافة هذه الميزة. يمكن للمواقع إضافة أنماط الوضع المظلم إلى ورقة الأنماط المضمنة الخاصة بها كحل بديل (أو استخدام تقنية postMessage التي تمت مناقشتها أعلاه).

7 إعجابات

postMessage يحتاج إلى تضمين iframe لمعالجة حدث message.
أين أضيف الكود إلى iframe لمعالجة الحدث؟

إعجابَين (2)

لقد قمت بتنفيذه باستخدام postMessage. الرموز ومنطق التنفيذ الخاص بها كما يلي:

الكتلة البرمجية ① تضيف مستمع حدث في إطار Discourse المضمن والذي سيقوم بنشر رسالة إلى موقعي الإلكتروني الذي يحتوي على إطار Discourse المضمن بمجرد تحميل Discourse المضمن.

عندما يتلقى موقعي الإلكتروني رسالة من Discourse المضمن، سيقوم بإجراء تحقق، كما هو موضح في الكتلة البرمجية ②، وإذا نجح، يستدعي الدالة setIframeStyle لتعيين Discourse المضمن.

الدالة setIframeStyle، كما هو موضح في الكتلة البرمجية ③، تمرر وضع اللون، “داكن” أو “فاتح”، إلى الإطار عن طريق استدعاء postMessage. بالإضافة إلى ذلك، بمجرد تبديل الوضع الداكن، يمكن استدعاء الدالة للحفاظ على نفس وضع اللون لـ Discourse المضمن مع موقعي الإلكتروني.

الكتلة البرمجية ④ تسمح لـ Discourse المضمن بمعالجة رسالة وضع اللون المرسلة من موقعي الإلكتروني. هنا أقوم بتبديل وضع اللون عن طريق تبديل اسم الفئة إلى علامة الجسم.

بالإضافة إلى ذلك، تتم إضافة الكتلتين البرمجيتين ① و ④ من خلال صفحة مسؤول Discourse، كما يلي:

ويجب إضافة فئات CSS المخصصة كما يلي:

12 إعجابًا

هل يعرف أي شخص أين يمكن التعديل إذا لم نتمكن من تعديل “CSS المضمن” (لأنه ليس سمة رسمية)؟

إعجابَين (2)

هل قمت للتو بإنشاء مكون جديد واستخدمت علامة التبويب المضمنة الخاصة به؟

3 إعجابات

شكرًا على المخطط أعلاه @mikeguo، تم شرحه بشكل رائع!

لاحظ أيضًا أنك بحاجة إلى استخدام أحدث إصدار من Discourse لتحقيق ذلك، حيث تمت إضافة ميزة الرأس المضمن قبل أيام قليلة فقط.

8 إعجابات

\u003e تعديل: هذا ما احتجت لفعله Structure of themes and theme components

هل يبدو هذا خطأ؟

const handleMessageListener = (event:MessageEvent<any>)

إعجابَين (2)

ما زلت لا أستطيع تمكين هذا الرمز (!) هل يمكن لأحد أن يراجعه بلطف؟

أرى أن لا أحد يستطيع تمكين هذا وأن الجميع تقريبًا يستخدمون الإضاءة القسرية، وهذا سيء جدًا لأعيننا :frowning:

إعجاب واحد (1)

يمكنني التأكيد على أن الطريقة المذكورة أعلاه لا تزال تعمل، ولكن كان من الجيد عدم الاضطرار إلى كتابة التعليمات البرمجية من لقطة شاشة :slight_smile: لذا، إليك هي، محدثة قليلاً:

الخطوات

  1. ينتهي عرض إطار iframe الخاص بالتعليقات ويُرسل رسالة إلى نافذة المتصفح الرئيسية، لإعلامها بذلك.
  2. يستعلم المتصفح عن إعداد الوضع الداكن/الفاتح ويرسل القيمة مرة أخرى إلى إطار iframe.
  3. يستقبل إطار iframe الرسالة، ويضبط سمة بيانات (data-attribute) أو فئة (class) أو ما شابه، بناءً على إعداد الوضع الداكن/الفاتح.

التعليمات البرمجية

  1. بمجرد تحميل إطار iframe، أرسل إشعارًا إلى النافذة الأصلية. يجب إدخال هذا على Discourse، ضمن Admin -> Customize -> (select theme) -> Edit CSS/HTML -> Embedded Header.

    window.addEventListener("load", (event) => {
        window.parent.postMessage("iframe loaded", "*");
    }, false);
  1. تعامل مع هذا المشغل الوارد في النافذة الرئيسية. تعيش هذه التعليمات البرمجية في موقع مدونتك:

  const discourse_url = "https://your.discourse-instance.org";

  // هنا، نحدد السمة، ونرسل رسالة إلى إطار iframe لإعلامه بالسمة
  // انظر أدناه لكيفية ربط notifyFrameStyle
  const notifyIFrameOfTheme = () => {
    const iframe = document.getElementById("discourse-embed-frame");
    if (iframe && iframe.contentWindow) {
      iframe.contentWindow.postMessage(
        {
          // قم بتعديل السطر أدناه للحصول على إعداد الوضع المظلم، اعتمادًا على كيفية تخزينه
          theme: document.documentElement.getAttribute("data-theme")
        },
        discourse_url
      );
    }
  };

  // استدعاء setFrameStyle عند تلقي رسالة "iframe loaded"
  const handleMessageListener = (event) => {
    var origin = event.origin;
    if ((origin === discourse_url) && (event.data == "iframe loaded")) {
      notifyIFrameOfTheme();
    }
  };
  1. في كتلة script من (1)، أضف مستمعًا لرسالة السمة التي أرسلتها notifyFrameStyle:
    window.addEventListener("message", (event) => {
        const payload = event.data;
        if (payload.theme) {
          // افعل شيئًا بإعداد السمة؛ لقد قمت بتعيين السمة `data-theme` على `html` الخاص بإطار iframe،
          // ولكن قد ترغب في تعيين سمة فئة أو ما شابه
          document.documentElement.setAttribute("data-theme", payload.theme);
        }
    }, false);

التصميم

ضمن Admin -> Customize -> (select theme) -> Edit CSS/HTML -> Embedded CSS، يمكنك الآن توفير CSS لكل وضع. على سبيل المثال، يمكنك تجاوز متغيرات تصميم Discourse:

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

آمل أن يساعد هذا!

6 إعجابات

الكود أعلاه الذي يمكن نسخه ولصقه يفتقر إلى إضافة مستمع الأحداث في النافذة المضمنة:

window.addEventListener("message", handleMessageListener);

وملاحظة: لا توجد حاجة لإعدادات CORS خاصة لهذا.

شكراً لاكتشاف ذلك! لا يمكنني تعديل المنشور أعلاه بعد الآن، ولكن window.addEventListener يجب أن يوضع في أسفل مقتطف الكود تحت (2).

انظر هذا المثال الواقعي.

5 إعجابات