채팅을 위한 스와이프

안녕하세요 :waving_hand:

Discourse 채팅의 모바일 사용성 관련 작은 제안입니다. 채널이나 DM에서 왼쪽에서 오른쪽으로 스와이프하는 제스처를 통해 사이드 패널(채널 목록 / 다이렉트 메시지 목록)을 빠르게 표시할 수 있는 기능이 계획되어 있나요? 이렇게 하면 작은 화면에서의 네비게이션이 훨씬 부드러워질 것입니다. 모바일에서 한 손으로 사용하기 쉽게 하기 위해 새로운 컴포저를 작업하고 계시다고 들었는데요, 채팅도 같은 방향으로 개선되었으면 좋겠습니다 :sweat_smile:

7개의 좋아요

현재这方面的 계획은 없지만, 이 같은 사이트에서 더 쉽게 탐색할 수 있도록 어떤 종류의 스와이프 인터랙션을 도입할 수 있는지 더 논의해 볼 가치가 있습니다.

6개의 좋아요

좌우 스와이프는 다양한 기기에서 브라우저의 뒤로/앞으로 제스처와 충돌하기 때문에 복잡합니다.

2개의 좋아요

Don이 https://meta.discourse.org/t/topic-preview-modal/409712에서 취한 접근 방식이 좋다고 생각합니다. 기본 동작에 간섭하지 않으면서도 매우 유용했습니다.

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>