تقويم Discourse (والحدث)

:partying_face: تم الآن تجميع هذه الإضافة مع Discourse core كجزء من Bundling more popular plugins with Discourse core. إذا كنت تستضيف بنفسك وتستخدم الإضافة، فأنت بحاجة إلى إزالتها من app.yml قبل الترقية التالية.

إعجابَين (2)

بالتأكيد – إليك النسخة المعدلة، الأكثر لطفًا وانفتاحًا قليلاً، لمنشورك باللغة الإنجليزية:


نحن بحاجة ماسة إلى القدرة على تحديد عدد المشاركين في الفعاليات، حيث أن العديد من فعالياتنا محدودة السعة.

حاليًا، لا يسمح نظام الفعاليات لنا بما يلي:

  • تحديد الحد الأقصى لعدد المشاركين،
  • معرفة من سجل أولاً (لا توجد طوابع زمنية للتسجيل)،
  • إدارة قائمة انتظار أو إخطار الأشخاص عند توفر مكان.

سنستفيد كثيرًا من الميزات التالية:

  1. حد المشاركين (سقف) يمنع المزيد من المستخدمين من التسجيل بمجرد اكتمال العدد.
  2. قائمة انتظار لأولئك الذين ما زالوا يرغبون في الحضور بعد اكتمال الفعالية.
  3. إشعارات تلقائية عند توفر مكان.
  4. طوابع زمنية اختيارية لرؤية ترتيب التسجيل (مفيدة للأولوية العادلة).

سيكون هذا مفيدًا للغاية للمجتمعات التي تدير فعاليات شخصية أو محدودة السعة.

هل هناك أي شيء من هذا القبيل مخطط له بالفعل أو قيد التطوير؟
أم أن هناك أي حلول بديلة معروفة لهذه الحالة؟

شكرًا جزيلاً مقدمًا!

4 إعجابات

شكرًا أورورا - متحمس جدًا لسماع أن العمل الأصلي للتقويم نشط مرة أخرى!

نود أيضًا طرح طلب إضافي عالي التأثير ظهر في عدد من مناقشات المجتمع: مزامنة موجز iCal.

تم فصل هذا في موضوعه المخصص هنا:

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

سنكون ممتنين جدًا لأي تعليق من فريق Discourse حول ما إذا كانت أجزاء من هذا الاقتراح - مثل المزامنة أحادية الاتجاه لـ iCal، وإعدادات فترة تحديث الموجز، أو وضع العلامات الاختيارية على الأحداث - ضمن نطاق التنفيذ القادم.

في كلتا الحالتين، شكرًا مرة أخرى على بث حياة جديدة في تقويم Discourse - نحن نتطلع إلى ما هو قادم!

4 إعجابات

إذا كنت ترغب في إظهار زر إنشاء حدث من المنشئ مباشرةً كما هو موضح أدناه، فاستخدم الكود أدناه في رأس السمة الخاصة بك. admin>appearance>theme>edit>edit code>head (تأكد من وضعه بين علامتي <head> و </head>)

تم الاختبار على discourse 3.5.0.beta9-dev على سطح المكتب في فايرفوكس

 <!-- زر إنشاء حدث مخصص (يعتمد على الأيقونة، مقاوم للغة) -->
<script>
(() => {
    const editorButtonContainerSelector = ".d-editor-button-bar";
    const calendarButtonSelector = ".btn.no-text.fk-d-menu__trigger.toolbar-menu__options-trigger.toolbar__button.options.toolbar-popup-menu-options";
    const menuInnerContentSelector = ".fk-d-menu__inner-content";
    const menuModalSelector = ".d-modal.fk-d-menu-modal";

    const getCalendarButton = (container) => {
        const svgIcon = container.querySelector('svg use[href="#calendar-day"]');
        return svgIcon ? svgIcon.closest("button") : null;
    };

    const waitForElement = (selector, findFn, timeout = 4000) =>
        new Promise((resolve, reject) => {
            const element = findFn(selector);
            if (element) return resolve(element);

            const observer = new MutationObserver(() => {
                const foundElement = findFn(selector);
                if (foundElement) {
                    observer.disconnect();
                    resolve(foundElement);
                }
            });
            observer.observe(document.body, { childList: true, subtree: true });
            setTimeout(() => {
                observer.disconnect();
                reject();
            }, timeout);
        });

    const waitForMenuModal = (timeout = 4000) => {
        const observer = new MutationObserver(() => {
            if (document.querySelector(menuModalSelector)) {
                observer.disconnect();
            }
        });
        observer.observe(document.body, { childList: true, subtree: true });
        setTimeout(() => observer.disconnect(), timeout);
    };

    const addCustomCreateEventButton = (container) => {
        if (container.querySelector(".custom-create-event-btn")) return;

        const button = document.createElement("button");
        button.className = "btn no-text btn-icon toolbar__button link custom-create-event-btn";
        button.title = "Create event";
        button.innerHTML = '<svg class="fa d-icon d-icon-calendar-day svg-icon"><use href="#calendar-day"></use></svg>';
        container.appendChild(button);

        button.addEventListener("click", async () => {
            const calendarButton = document.querySelector(calendarButtonSelector);
            if (!calendarButton) return;
            calendarButton.click();

            let menuContent = document.querySelector(menuInnerContentSelector);
            if (!menuContent) {
                await new Promise((resolve, reject) => {
                    const observer = new MutationObserver(() => {
                        menuContent = document.querySelector(menuInnerContentSelector);
                        if (menuContent) {
                            observer.disconnect();
                            resolve();
                        }
                    });
                    observer.observe(document.body, { childList: true, subtree: true });
                    setTimeout(() => {
                        observer.disconnect();
                        reject();
                    }, 2000);
                });
            }

            try {
                (await waitForElement(menuInnerContentSelector, (sel) => document.querySelector(sel)))
                    .click();
                waitForMenuModal();
            } catch {
                // Handle error if needed
            }
        });
    };

    const observer = new MutationObserver(() => {
        const editorContainer = document.querySelector(editorButtonContainerSelector);
        if (editorContainer) {
            addCustomCreateEventButton(editorContainer);
        }
    });
    observer.observe(document.body, { childList: true, subtree: true });

    const initialEditorContainer = document.querySelector(editorButtonContainerSelector);
    if (initialEditorContainer) {
        addCustomCreateEventButton(initialEditorContainer);
    }
})();
</script>

لقد جربت البرنامج النصي، وتم إنشاء زر إنشاء الحدث بشكل جيد ولكن عندما أنقر عليه، أحصل على نفس القائمة السياقية مثل زر الزائد. ربما قمت بإجراء خاطئ

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

بعد التحديث تحسن الأمر، على الأقل يظهر فقط “إنشاء حدث”

الصورة المرفقة بالألمانية، آسف.

مرحبا،

هذا يعمل على أحدث إصدار مع 3.5.0.beta9-dev، لا أعرف إصدارك؟

وهذا جافاسكريبت لذا يجب عليك تقديم خطأ جافاسكريبت من وحدة التحكم عند الضغط على F12 في متصفحك.

لدي نفس الإصدار 3.5.0.beta9-dev
هذه هي رسالة وحدة التحكم


يجب أن أفعل شيئًا خاطئًا بالتأكيد :sweat_smile:

لا أستخدم Edge، هل يمكنك المحاولة مرة أخرى باستخدام البرنامج النصي الذي قمت بتحديثه للتو في المنشور الأصلي حيث وجدت أخطاء قمت بتصحيحها. إذا لم ينجح الأمر، فسأقوم بالتحديث لاحقًا بعد تثبيت Edge.

لقد قمت للتو بتحديث البرنامج النصي ليكون أكثر توافقًا مع الأجهزة المحمولة، ويجب أن يعمل الآن، يرجى نسخ ولصق البرنامج النصي من المنشور الأصلي

أؤكد أن الكود المحدث يعمل بشكل جيد في المتصفح. إذا كان لديك شيء مثل ublock، يمكنك دائمًا تعطيله لصفحة discourse الخاصة بك، لكنني لا أعتقد أن الأمر متعلق بذلك.

آسف، ما زلت أواجه نفس المشكلة، لا بد أنني أفعل شيئًا خاطئًا

ومع ذلك، أنا ألصق النص البرمجي الخاص بك هنا بشكل صحيح

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

حسنًا، بفضل وضع Gilles، تمكنت من إعداد محدد بناءً على فئة .svg للأيقونة التي لا تتكرر بدلاً من سمة عنوان ستختلف حسب اللغة، تم تصغير البرنامج النصي الآن وهو مغلف بـ IIFE.\n\nقد تجد البرنامج النصي المحدث هنا Discourse Calendar (and Event) - #535 by opcourdis

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

شكرا لمساعدتك :+1:

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

سيكون من المفيد جدًا أن يكون النص البرمجي الخاص بك مغلفًا كـ #theme-component، وأن تكون الفئات التي ينطبق عليها قابلة للتحديد.
حالة الاستخدام التي أفكر فيها هي فئة “الأحداث”، حيث أريد أن أجعل نشر الأحداث واضحًا جدًا.

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

يمكنك استخدام ما يلي وتعديل الشروط الأولى لتحديد فئاتك، ولجعل الزر أكثر وضوحًا، سيقوم CSS بما يلي: .btn.no-text.btn-icon.toolbar__button.link.custom-create-event-btn {
order: -1;
}


<script>(()=>{if(!(document.body.classList.contains("category-events")||document.body.classList.contains("category-event2")||document.body.classList.contains("category-event3")))return;const e=".d-editor-button-bar",t=".btn.no-text.fk-d-menu__trigger.toolbar-menu__options-trigger.toolbar__button.options.toolbar-popup-menu-options",n=".fk-d-menu__inner-content",o=".d-modal.fk-d-menu-modal",c=e=> {const t=e.querySelector('svg use[href="#calendar-day"]');return t?t.closest("button"):null},r=(e,t,n=4e3)=>new Promise((o,c)=>{const r=t(e);if(r)return o(r);const l=new MutationObserver(()=>{const n=t(e);n&&(l.disconnect(),o(n))});l.observe(e,{childList:!0,subtree:!0}),setTimeout(()=>{l.disconnect(),c()},n)}),l=(e=4e3)=>{const t=new MutationObserver(()=>{document.querySelector(o)&&t.disconnect()});t.observe(document.body,{childList:!0,subtree:!0}),setTimeout(()=>t.disconnect(),e)},s=e=>{if(e.querySelector(".custom-create-event-btn"))return;const o=document.createElement("button");o.className="btn no-text btn-icon toolbar__button link custom-create-event-btn",o.title="Create event",o.innerHTML='<svg class="fa d-icon d-icon-calendar-day svg-icon"><use href="#calendar-day"></use></svg>',e.appendChild(o),o.addEventListener("click",async()=>{const e=document.querySelector(t);if(!e)return;e.click();let o=document.querySelector(n);o||(await new Promise((e,t)=>{const c=new MutationObserver(()=>{o=document.querySelector(n)&&c.disconnect(),e()});c.observe(document.body,{childList:!0,subtree:!0}),setTimeout(()=>c.disconnect(),t())}));try{(await r(o,c)).click(),l()}catch{}})},u=new MutationObserver(()=>{const t=document.querySelector(e);t&&(s(t))});u.observe(document.body,{childList:!0,subtree:!0});const d=document.querySelector(e);d&&s(d)})()}</script>

شكرًا على الاقتراح، ما زلت جديدًا بعض الشيء على discourse وسأتحقق من مكون السمة، إن موضع الزر أفضل بالفعل ولكن قد لا يكون برنامجي النصي الآخر لحدود مشاركي الحدث ضروريًا قريبًا بسبب هذا FEATURE: introduce max attendees for events by SamSaffron · Pull Request #34313 · discourse/discourse · GitHub

4 إعجابات

بعد الترقية إلى أحدث إصدار من Discourse ومكون discourse-calendar الإضافي، أرى التحذير التالي كمسؤول:\n\n\n⚠️ قد لا يتم عرض المشاركات بشكل صحيح لأن أحد مزينات محتوى المشاركات على موقعك قد أثار خطأ.\nسببه المكون الإضافي 'discourse-calendar'\n(يتم عرض هذه الرسالة فقط لمسؤولي الموقع)\n\n\n* لم يعد المكون الإضافي للتقويم يعمل: لا يتم عرض محتوى التقويم والأحداث في المواضيع.\n* كان المكون الإضافي يعمل بشكل صحيح قبل الترقية الأخيرة.\n* موقع Discourse الخاص بي وجميع المكونات الإضافية الرسمية محدثة الآن.

نحن نستخدم إضافة Discourse Post Event في منتدانا.\nحالياً، عندما ينضم مستخدم (يؤكد حضوره) إلى حدث، يتم تلقائياً تعيين الموضوع إلى “متابعة”، مما يعني أن كل رد جديد على موضوع الحدث يؤدي إلى إرسال إشعار لجميع المشاركين.\n\nنرغب في إبقاء مستوى الإشعارات على “عادي” افتراضياً، حتى بعد انضمام شخص ما إلى حدث.\n\nلقد تحققت من إعدادات الموقع ولكنني لم أجد خياراً يعمل.\nهل هناك طريقة لتعطيل أو تغيير هذا السلوك التلقائي لـ “متابعة” عندما يؤكد المستخدمون حضورهم لحدث ما؟

لا أعتقد ذلك. ولكن هذه ستكون ميزة مفيدة.

قد يكون الحل البديل المفيد هو إغلاق الموضوع لمنع الردود، ولكن مع وجود قناة دردشة مرتبطة به (هذه لا ترسل إشعارات افتراضيًا).

قد يكون النص الموجود على زر “اليوم” مضللاً.

لا ينقل الزر فعليًا إلى اليوم الحالي، بل ينقل إلى العرض الحالي لعلامة تبويب الإطار الزمني النشط (يوم/أسبوع/شهر/سنة). في اليوم والأسبوع والشهر، يؤدي هذا إلى عرض اليوم الحالي. ولكن في السنة، فإنه ينقل فقط إلى السنة الحالية (التي تبدأ دائمًا في يناير).

ربما يجب أن يكون:

  • تمت إعادة تسميته لوصف وظيفته بدقة أكبر، مثل “الحالي”
  • أو، ربما بشكل أفضل، لا ينقل فقط إلى السنة الحالية، بل يقوم بالتمرير إلى اليوم الحالي في قائمة السنة.
إعجاب واحد (1)