滑动以打开聊天

你好 :waving_hand:

关于 Discourse 聊天的移动端体验,有个小建议:是否计划支持从频道或私信向左滑动(swipe de gauche à droite)以快速显示侧边栏(频道列表 / 私信列表)?这样在小屏幕上导航会流畅很多。鉴于你们正在开发新的编辑器以方便单手在手机上操作,我觉得聊天功能也可以采用类似的设计 :sweat_smile:

7 个赞

目前尚无相关计划,但值得进一步讨论,哪些类型的滑动交互操作可以让用户在此类网站上更便捷地导航。

6 个赞

左右滑动操作比较复杂,因为在不同设备上,这通常是浏览器的后退/前进手势。

2 个赞

我认为 Don 在 Topic Preview Modal 中采用的方法很不错;它不会干扰默认行为,而且我觉得非常实用。

3 个赞

我写了一个脚本,用于通过从左向右滑动来显示侧边栏,并且在聊天中,当处于对话中时,通过滑动来显示列表。目的是改善用户体验。请将此脚本复制到分配给您主题的 common\head 组件中。之后,我认为仍然有改进的空间

<script>
  (function() {
    if (window.innerWidth > 768) return;

    let startX = 0;
    let startY = 0;

    // 使用 'window' 以确保在聊天之前捕获手势
    window.addEventListener("touchstart", function(e) {
      if (e.touches.length === 1) {
        startX = e.touches[0].clientX;
        startY = e.touches[0].clientY;
      }
    }, { passive: true, capture: true });

    window.addEventListener("touchend", function(e) {
      if (!startX) return;

      const touch = e.changedTouches[0];
      const deltaX = touch.clientX - startX;
      const deltaY = touch.clientY - startY;

      if (startX >= 10 && startX <= 120 && deltaX > 50 && Math.abs(deltaY) < 50) {
        
        // 1. 我们是否在聊天频道中?
        // 检查 URL 是否包含 Discourse 聊天频道的典型关键字
        const currentUrl = window.location.pathname;
        const isInChatChannel = currentUrl.includes('/chat/c/') || currentUrl.includes('/chat/channel/');
        
        if (isInChatChannel) {
          // 首先尝试点击返回链接(如果它是标准化的)
          const chatBackBtn = document.querySelector('.chat-channel-header a, a[href="/chat"]');
          if (chatBackBtn) {
            chatBackBtn.click();
          } else {
            // 万无一失的方法:要求浏览器后退一页
            window.history.back();
          }
          startX = 0;
          return; // 在此处停止脚本
        }

        // 2. 如果我们位于论坛的其他地方(打开菜单)
        const sidebarSelectors = [
          ".btn-sidebar-toggle",
          ".sidebar-toggle",
          "button.header-dropdown-toggle.hamburger-dropdown",
          "#toggle-hamburger-menu"
        ];

        for (const selector of sidebarSelectors) {
          const btn = document.querySelector(selector);
          if (btn && btn.getBoundingClientRect().width > 0) {
            btn.click();
            break; 
          }
        }
      }

      startX = 0;
      startY = 0;
    }, { passive: true, capture: true });
  })();
</script>