活动更好的 Oneboxes

目前,活动的 Oneboxes 有点“一般”。基本上,它们与常规主题 Oneboxes 没有区别,也不包含日期、时间、描述等(除非作为一种变通方法放入主题标题中)。

这是我们网站上的一个活动示例:

是否可以利用日历中点击时出现的新(且出色的)活动卡片,并将它们作为 oneboxes 提供?例如:

这可能完全不可行,但我确实想知道是否可以修改活动帖子的元数据,以便它们以突出关键活动信息(尤其是在内部)的方式进行 Onebox。

7 个赞

我还有0票,但你仍然拥有我的投票:wink:,这确实会让活动推广更加闪耀。

2 个赞

@chapoi / @j.jaffeux 我一直在考虑这个问题。

我认为我们需要进行的一项根本性改变是引入适当的事件 URL,以便您可以使用它们进行一键式链接(onebox),而不是一键式链接:

https://SITE/t/slug/123

我们将一键式链接:

https://SITE/event/slug/1234

这确实打开了一个潘多拉魔盒(不过是好的方面)

  1. 人们如何找到事件链接?(我猜我们会添加到上下文菜单中)
  2. 如果他们直接从 URL 访问事件会怎样?(我猜我们暂时重定向到事件帖子)
2 个赞

同意这个想法——这里绝对可以做得更好

如果你指的是这个:

对我来说,那似乎也是正确的位置。

2 个赞

在摆弄那个上下文菜单时,我想知道“添加到日历”是否可以直接放在卡片上。其他所有东西都相当管理化,但“添加到日历”是所有用户都可以使用的功能,应该在用户界面中突出显示。

1 个赞

在活动帖子中,我将“添加到日历”选项放在显眼的位置;您可以将其添加到可从管理员外观菜单访问的主题 JavaScript 标头中:

<script>
(() => {
    const eventInfoSelector = ".event-header .event-info";
    const submenuButtonSelector = "button.fk-d-menu__trigger.discourse-post-event-more-menu-trigger";
    const menuContentSelector = ".fk-d-menu__inner-content";
    const addToCalendarSelector = "li.add-to-calendar > button";

    // 添加内联 CSS 以在悬停时保持文本和图标为黑色
    const style = document.createElement("style");
    style.innerHTML = `
    .btn.btn-icon-text.custom-add-to-calendar-btn,
    .btn.btn-icon-text.custom-add-to-calendar-btn:hover {
        color: black !important;
    }
    .btn.btn-icon-text.custom-add-to-calendar-btn svg,
    .btn.btn-icon-text.custom-add-to-calendar-btn:hover svg {
        fill: black !important;
    }
    `;
    document.head.appendChild(style);

    // 辅助函数,用于等待 DOM 中的元素
    const waitForElement = (selector, timeout = 3000) => {
        return new Promise((resolve, reject) => {
            const el = document.querySelector(selector);
            if (el) return resolve(el);

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

    const createAddToCalendarButton = async () => {
        const eventInfo = document.querySelector(eventInfoSelector);
        if (!eventInfo || eventInfo.querySelector(".custom-add-to-calendar-btn")) return;

        const button = document.createElement("button");
        button.className = "btn btn-icon-text custom-add-to-calendar-btn";
        button.title = "Add to calendar";
        button.innerHTML = `
            <svg class="fa d-icon d-icon-file svg-icon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
                <use href="#file"></use>
            </svg>
            <span class="d-button-label">Add to calendar</span>
        `;

        // 内联样式用于左对齐
        button.style.display = "inline-flex";
        button.style.justifyContent = "flex-start";
        button.style.marginLeft = "0";
        button.style.marginBottom = "4px";
        button.style.backgroundColor = "#f0f0f0";
        button.style.borderRadius = "6px";
        button.style.transition = "transform 0.2s";
        button.style.cursor = "pointer";

        // 点击逻辑:打开菜单并触发原始的添加到日历
        button.addEventListener("click", async () => {
            const submenuButton = document.querySelector(submenuButtonSelector);
            if (!submenuButton) return;
            submenuButton.click(); // 打开菜单

            let menuContent;
            try {
                menuContent = await waitForElement(menuContentSelector, 2000);
            } catch {
                return;
            }

            const originalButton = menuContent.querySelector(addToCalendarSelector);
            originalButton?.click();
        });

        // 插入到 event-info 中
        if (eventInfo.firstElementChild) {
            eventInfo.insertBefore(button, eventInfo.firstElementChild.nextSibling);
        } else {
            eventInfo.appendChild(button);
        }
    };

    // 观察 DOM 变化(Ember 安全)
    const observer = new MutationObserver(() => createAddToCalendarButton());
    observer.observe(document.body, { childList: true, subtree: true });

    // 首次尝试
    createAddToCalendarButton();
})();
</script>