Discourse 日历与活动

控制台未显示任何错误。但我录制了一段视频供参考。
此问题出现在 Chrome、Firefox 和 Safari 上。在移动 Safari 上则不会发生。

1 个赞

你的视频链接失效了!

抱歉,我之前没太理解。确实,你说得对:当我们在日历中点击某个日期时,会弹出创建事件的模态框,但其中包含“是否放弃”的按钮。是的,确实有个小问题::sweat_smile:

2 个赞

供参考,我为用户添加了一个“更多信息”按钮,以防他们忘记点击标题以访问主题。我借鉴了 @nathank 在“添加到日历”按钮上的想法。

将脚本放入主题组件的通用部分 /head 中:

<script>
(() => {
    const eventInfoSelector = ".event-header .event-info";
    const eventCardSelector = ".fc-popover, .event-preview, .discourse-post-event";
    // 注入干净且适配 Discourse 主题(浅色/深色)的 CSS
    const style = document.createElement("style");
    style.innerHTML = `
    .custom-topic-info-btn {
        display: flex !important;
        align-items: center;
        justify-content: center;
        width: 40%; /* 占据全部宽度,确保标题下方呈现整洁 */
        box-sizing: border-box;
        margin: 12px 0 6px 0;
        padding: 10px 16px;
        
        /* 使用原生 Discourse 变量 */
        background-color: var(--tertiary) !important; /* 强调色(例如蓝色) */
        color: var(--secondary) !important;          /* 对比度高的文字颜色 */
        
        border-radius: 8px;
        font-weight: 700;
        text-decoration: none !important;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
        transition: background-color 0.2s ease, transform 0.1s ease;
    }
    /* 悬停效果 */
    .custom-topic-info-btn:hover {
        background-color: var(--tertiary-hover) !important;
        color: var(--secondary) !important;
        transform: translateY(-1px);
        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);
    }
    /* 点击效果 */
    .custom-topic-info-btn:active {
        transform: translateY(0);
    }
    /* SVG 图标样式 */
    .custom-topic-info-btn .btn-icon-svg {
        margin-right: 8px;
        width: 16px;
        height: 16px;
        fill: currentColor;
    }
    `;
    document.head.appendChild(style);
    const findTopicLink = (container) => {
        if (!container) return null;
        const links = [...container.querySelectorAll('a[href*="/t/"]')];
        if (links.length) return links[0].href;
        return null;
    };
    const createTopicInfoButton = () => {
        const eventInfo = document.querySelector(eventInfoSelector);
        if (!eventInfo || eventInfo.querySelector(".custom-topic-info-btn")) return;
        const card = eventInfo.closest(eventCardSelector) || document;
        const topicUrl = findTopicLink(card);
        if (!topicUrl) return;
        const button = document.createElement("a");
        button.className = "btn custom-topic-info-btn";
        button.title = "查看完整主题";
        button.href = topicUrl;
        
        // 添加统一的 SVG 信息图标
        button.innerHTML = `
            <svg class="btn-icon-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
                <path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336h24V240h-24c-13.3 0-24-10.7-24-24s10.7-24 24-24h40c13.3 0 24 10.7 24 24v120h24c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144a32 32 0 1 1 0-64 32 32 0 1 1 0 64z"/>
            </svg>
            <span class="d-button-label">更多信息</span>
        `;
        if (eventInfo.firstElementChild) {
            eventInfo.insertBefore(button, eventInfo.firstElementChild.nextSibling);
        } else {
            eventInfo.appendChild(button);
        }
    };
    const observer = new MutationObserver(() => createTopicInfoButton());
    observer.observe(document.body, { childList: true, subtree: true });
    createTopicInfoButton();
})();
</script>

以下是预览效果:

或者,也可以使用以下代码:

<script>
(() => {
    const eventCardSelector = ".fc-popover, .event-preview, .discourse-post-event";

    // 注入 CSS 以实现干净现代的呈现效果
    const style = document.createElement("style");
    style.innerHTML = `
    .custom-topic-info-wrapper {
        margin-top: 16px;
        padding-top: 16px;
        border-top: 1px solid var(--primary-low); /* 微妙的分隔线 */
        width: 100%;
        display: flex;
        justify-content: center;
    }

    .custom-topic-info-btn {
        display: flex !important;
        align-items: center;
        justify-content: center;
        width: 100%;
        box-sizing: border-box;
        padding: 8px 16px;
        
        /* 优雅的 Outline 样式 */
        background-color: transparent !important;
        color: var(--tertiary) !important;
        border: 1px solid var(--tertiary) !important;
        
        border-radius: 6px;
        font-weight: 600;
        text-decoration: none !important;
        transition: all 0.2s ease;
        cursor: pointer;
    }

    /* 悬停效果:按钮填充背景色 */
    .custom-topic-info-btn:hover {
        background-color: var(--tertiary) !important;
        color: var(--secondary) !important;
        border-color: var(--tertiary) !important;
    }

    /* 信息图标对齐 */
    .custom-topic-info-btn .btn-icon-svg {
        margin-right: 8px;
        width: 16px;
        height: 16px;
        fill: currentColor;
    }
    `;
    document.head.appendChild(style);

    const findTopicLink = (container) => {
        if (!container) return null;
        const links = [...container.querySelectorAll('a[href*="/t/"]')];
        if (links.length) return links[0].href;
        return null;
    };

    const createTopicInfoButton = () => {
        const cards = document.querySelectorAll(eventCardSelector);
        
        cards.forEach(card => {
            if (card.querySelector(".custom-topic-info-btn")) return;

            const topicUrl = findTopicLink(card);
            if (!topicUrl) return;

            const wrapper = document.createElement("div");
            wrapper.className = "custom-topic-info-wrapper";

            const button = document.createElement("a");
            button.className = "btn custom-topic-info-btn";
            button.title = "查看完整主题";
            button.href = topicUrl;
            
            // “i”信息图标 + 可操作的新文本
            button.innerHTML = `
                <svg class="btn-icon-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
                    <path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336h24V240h-24c-13.3 0-24-10.7-24-24s10.7-24 24-24h40c13.3 0 24 10.7 24 24v120h24c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144a32 32 0 1 1 0-64 32 32 0 1 1 0 64z"/>
                </svg>
                <span class="d-button-label">查看主题</span>
            `;

            wrapper.appendChild(button);

            // 定位在回复选项(参与等)上方
            const actionsContainer = card.querySelector(".status-and-options, .event-actions");
            const infoContainer = card.querySelector(".event-info");
            
            if (actionsContainer && actionsContainer.parentNode) {
                actionsContainer.parentNode.insertBefore(wrapper, actionsContainer);
            } else if (infoContainer) {
                infoContainer.appendChild(wrapper);
            } else {
                card.appendChild(wrapper);
            }
        });
    };

    const observer = new MutationObserver(() => createTopicInfoButton());
    observer.observe(document.body, { childList: true, subtree: true });

    createTopicInfoButton();
})();
</script>

结果预览:

您可以自行选择:rofl

3 个赞

自从上次更新以来,创建事件的便捷性确实得到了显著提升 :+1:

不过,我想了解一下,是否有一个设置可以防止用户在点击日历时直接创建事件?有时候用户本想点击某个事件,却误点到了旁边,结果弹出了创建事件的对话框 :sweat_smile:

谢谢

2 个赞

我知道我有点烦人,但我还有一个关于过期事件的问题或改进建议。这些事件可以自动删除,因为它们似乎已不再需要存在。我记得“事件”插件以前是自动处理这一点的。

目前我是手动操作的,所以如果有办法节省时间就太好了:sweat_smile:

感谢团队!

1 个赞

事件中的地点是否支持像 Google 日历或 Facebook 事件那样的查找功能?这样既能帮助用户选择地点,又能让地点可点击并跳转到地图应用。

(我尝试搜索但未找到解决方案,可能是我的搜索关键词不够准确。)

1 个赞

Locations Plugin 🌍 确实具备此类功能,但它仅与替代方案 Events Plugin 📅 集成。

开发者(@merefield)可能愿意将其与官方插件集成,但我估计这将需要大量的工作来建立和维护——因此,若要实现这一目标,您肯定需要资助相关工作。

1 个赞

我一直在尝试查看那个 Events 插件,但在以下步骤卡住了:

因为该网站已经宕机好几个月了。

也许值得在 Contribute > Feature(标记为 calendar-and-events)中提交一份正式的功能请求以供考虑。我可以想象这是一件可行的事情——而且它有很高的潜力为许多人带来高价值。


稍后……
@lou 确实已经在这里这样做了:

1 个赞

一篇帖子已合并到现有主题中:事件位置地图支持