Swipe for chat

Hi :waving_hand:

A small suggestion for the mobile ergonomics of the Discourse chat: are there any plans to integrate a swipe gesture (from left to right) from a channel or a DM to quickly display the side panel (channel list / direct messages list)? This would make navigation on small screens much smoother. Given that you are working on a new composer to make it easier to use on mobile with one hand, I was thinking the same could apply to the chat :sweat_smile:

7 Likes

There are no current plans for this, but worth discussing more what kind of swipe interactions could make it easier to navigate around a site like this.

6 Likes

left/right swipe is complicated because it’s the browser’s back/forward gesture on various devices

2 Likes

I think a good approach was taken by Don in Topic Preview Modal; it is not interfering with the default behavior, and I found it very useful.

3 Likes

I wrote a script for swiping to bring up the sidebar by sliding from left to right, and similarly in chat to bring up the list when you are in a conversation. The goal is to improve the user experience. You need to copy the script into a component assigned to your theme in common\head. After that, I think there is still room for improvement

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

    let startX = 0;
    let startY = 0;

    // Using 'window' to ensure the gesture is captured before the chat
    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. ARE WE IN A CHAT CHANNEL?
        // We check if the URL contains the typical keywords of a Discourse chat channel
        const currentUrl = window.location.pathname;
        const isInChatChannel = currentUrl.includes('/chat/c/') || currentUrl.includes('/chat/channel/');
        
        if (isInChatChannel) {
          // We first try to click the back link if it is standardized
          const chatBackBtn = document.querySelector('.chat-channel-header a, a[href="/chat"]');
          if (chatBackBtn) {
            chatBackBtn.click();
          } else {
            // Fallback method: we ask the browser to go back one page
            window.history.back();
          }
          startX = 0;
          return; // We stop the script here
        }

        // 2. IF WE ARE ELSEWHERE ON THE FORUM (Opening the menu)
        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>