Merge pull request #25502 from overleaf/td-chat-open-bug

Prevent chat opening by default for new user

GitOrigin-RevId: 260050c26f6b9dee7ea52284dadb7ed00ce9eddb
This commit is contained in:
Tim Down
2025-05-13 08:08:11 +00:00
committed by Copybot
parent 8d940ad841
commit 11d964649c
2 changed files with 32 additions and 19 deletions
+11 -14
View File
@@ -36,14 +36,13 @@ describe('Project Sharing', function () {
login('user@example.com') login('user@example.com')
createProject(projectName) createProject(projectName)
// TODO(25342): re-enable // Add chat message
// // Add chat message cy.findByText('Chat').click()
// cy.findByText('Chat').click() // wait for lazy loading of the chat pane
// // wait for lazy loading of the chat pane cy.findByText('Send your first message to your collaborators')
// cy.findByText('Send your first message to your collaborators') cy.get(
// cy.get( 'textarea[placeholder="Send a message to your collaborators…"]'
// 'textarea[placeholder="Send a message to your collaborators…"]' ).type('New Chat Message{enter}')
// ).type('New Chat Message{enter}')
// Get link sharing links // Get link sharing links
enableLinkSharing().then( enableLinkSharing().then(
@@ -95,9 +94,8 @@ describe('Project Sharing', function () {
} }
function expectChatAccess() { function expectChatAccess() {
// TODO(25342): re-enable cy.findByText('Chat').click()
// cy.findByText('Chat').click() cy.findByText('New Chat Message')
// cy.findByText('New Chat Message')
} }
function expectHistoryAccess() { function expectHistoryAccess() {
@@ -111,9 +109,8 @@ describe('Project Sharing', function () {
} }
function expectNoChatAccess() { function expectNoChatAccess() {
// TODO(25342): re-enable cy.findByText('Layout') // wait for lazy loading
// cy.findByText('Layout') // wait for lazy loading cy.findByText('Chat').should('not.exist')
// cy.findByText('Chat').should('not.exist')
} }
function expectNoHistoryAccess() { function expectNoHistoryAccess() {
@@ -1,6 +1,7 @@
import { useLayoutContext } from '@/shared/context/layout-context' import { useLayoutContext } from '@/shared/context/layout-context'
import useCollapsiblePanel from '@/features/ide-react/hooks/use-collapsible-panel' import useCollapsiblePanel from '@/features/ide-react/hooks/use-collapsible-panel'
import { useCallback, useRef, useState } from 'react' import useDebounce from '@/shared/hooks/use-debounce'
import { useCallback, useEffect, useRef, useState } from 'react'
import { ImperativePanelHandle } from 'react-resizable-panels' import { ImperativePanelHandle } from 'react-resizable-panels'
export const useChatPane = () => { export const useChatPane = () => {
@@ -8,6 +9,17 @@ export const useChatPane = () => {
const [resizing, setResizing] = useState(false) const [resizing, setResizing] = useState(false)
const panelRef = useRef<ImperativePanelHandle>(null) const panelRef = useRef<ImperativePanelHandle>(null)
// Keep track of a debounced local state variable for panel openness and
// only update the external openness state when the debounced value changes.
// This prevents successive calls to onCollapse and onExpand from
// react-resizable-panels updating the openness state multiple times in quick
// succession, which causes confusing behaviour that is different in React 17
// and 18. Collapsing the chat pane on initialization is necessary because
// react-resizable-panels does not provide a way to specify both that a panel
// should be collapsed and a default size for the panel when expanded.
const [localIsOpen, setLocalIsOpen] = useState(isOpen)
const debouncedLocalIsOpen = useDebounce(localIsOpen, 100)
useCollapsiblePanel(isOpen, panelRef) useCollapsiblePanel(isOpen, panelRef)
const togglePane = useCallback(() => { const togglePane = useCallback(() => {
@@ -15,12 +27,16 @@ export const useChatPane = () => {
}, [setIsOpen]) }, [setIsOpen])
const handlePaneExpand = useCallback(() => { const handlePaneExpand = useCallback(() => {
setIsOpen(true) setLocalIsOpen(true)
}, [setIsOpen]) }, [])
const handlePaneCollapse = useCallback(() => { const handlePaneCollapse = useCallback(() => {
setIsOpen(false) setLocalIsOpen(false)
}, [setIsOpen]) }, [])
useEffect(() => {
setIsOpen(debouncedLocalIsOpen)
}, [debouncedLocalIsOpen, setIsOpen])
return { return {
isOpen, isOpen,