[web] close connection permanently when opening out-of-sync modal (#23148)

* [web] close connection permanently when opening out-of-sync modal

* [web] disable generic forceDisconnected behavior for out-of-sync modal

* [web] hide "disconnected" banner when displaying out of sync modal

GitOrigin-RevId: 133b3e24d94279917298ce7fd5d0a76da2265512
This commit is contained in:
Jakob Ackermann
2025-01-31 11:23:51 +00:00
committed by Copybot
parent cebaebc356
commit 8df7f6772c
6 changed files with 28 additions and 15 deletions

View File

@@ -27,7 +27,9 @@ export function Alerts() {
return createPortal(
<>
{connectionState.forceDisconnected ? (
{connectionState.forceDisconnected &&
// hide "disconnected" banner when displaying out of sync modal
connectionState.error !== 'out-of-sync' ? (
<OLNotification
type="error"
content={<strong>{t('disconnected')}</strong>}

View File

@@ -15,10 +15,14 @@ function ForceDisconnected() {
const [show, setShow] = useState(false)
useEffect(() => {
if (connectionState.forceDisconnected) {
if (
connectionState.forceDisconnected &&
// out of sync has its own modal
connectionState.error !== 'out-of-sync'
) {
setShow(true)
}
}, [connectionState.forceDisconnected])
}, [connectionState.forceDisconnected, connectionState.error])
useEffect(() => {
if (connectionState.forceDisconnected) {

View File

@@ -347,7 +347,7 @@ export class ConnectionManager extends EventTarget {
return true
}
disconnect() {
private disconnect() {
this.changeState({
...this.state,
readyState: WebSocket.CLOSED,

View File

@@ -8,6 +8,7 @@ import {
useMemo,
} from 'react'
import {
ConnectionError,
ConnectionState,
SocketDebuggingInfo,
} from '../connection/types/connection-state'
@@ -27,7 +28,7 @@ type ConnectionContextValue = {
secondsUntilReconnect: () => number
tryReconnectNow: () => void
registerUserActivity: () => void
disconnect: () => void
closeConnection: (err: ConnectionError) => void
getSocketDebuggingInfo: () => SocketDebuggingInfo
}
@@ -75,9 +76,10 @@ export const ConnectionProvider: FC = ({ children }) => {
[connectionManager]
)
const disconnect = useCallback(() => {
connectionManager.disconnect()
}, [connectionManager])
const closeConnection = useCallback(
(err: ConnectionError) => connectionManager.close(err),
[connectionManager]
)
const getSocketDebuggingInfo = useCallback(
() => connectionManager.getSocketDebuggingInfo(),
@@ -87,7 +89,11 @@ export const ConnectionProvider: FC = ({ children }) => {
// Reload the page on force disconnect. Doing this in React-land means that we
// can use useLocation(), which provides mockable location methods
useEffect(() => {
if (connectionState.forceDisconnected) {
if (
connectionState.forceDisconnected &&
// keep editor open when out of sync
connectionState.error !== 'out-of-sync'
) {
const timer = window.setTimeout(
() => location.reload(),
connectionState.forcedDisconnectDelay * 1000
@@ -99,6 +105,7 @@ export const ConnectionProvider: FC = ({ children }) => {
}, [
connectionState.forceDisconnected,
connectionState.forcedDisconnectDelay,
connectionState.error,
location,
])
@@ -111,7 +118,7 @@ export const ConnectionProvider: FC = ({ children }) => {
secondsUntilReconnect,
tryReconnectNow,
registerUserActivity,
disconnect,
closeConnection,
getSocketDebuggingInfo,
}),
[
@@ -122,7 +129,7 @@ export const ConnectionProvider: FC = ({ children }) => {
registerUserActivity,
secondsUntilReconnect,
tryReconnectNow,
disconnect,
closeConnection,
getSocketDebuggingInfo,
]
)

View File

@@ -98,7 +98,7 @@ export const EditorManagerProvider: FC = ({ children }) => {
const { projectId } = useIdeReactContext()
const { reportError, eventEmitter, eventLog } = useIdeReactContext()
const { setOutOfSync } = useEditorContext()
const { socket, disconnect, connectionState } = useConnectionContext()
const { socket, closeConnection, connectionState } = useConnectionContext()
const { view, setView } = useLayoutContext()
const { showGenericMessageModal, genericModalVisible, showOutOfSyncModal } =
useModalsContext()
@@ -580,7 +580,7 @@ export const EditorManagerProvider: FC = ({ children }) => {
// Do not re-join after re-connecting.
document.leaveAndCleanUp()
disconnect()
closeConnection('out-of-sync')
reportError(error, meta)
// Tell the user about the error state.
@@ -605,7 +605,7 @@ export const EditorManagerProvider: FC = ({ children }) => {
}
}
}, [
disconnect,
closeConnection,
docError,
docTooLongErrorShown,
eventEmitter,

View File

@@ -184,7 +184,7 @@ const ConnectionProvider: FC = ({ children }) => {
secondsUntilReconnect: () => 0,
tryReconnectNow: () => {},
registerUserActivity: () => {},
disconnect: () => {},
closeConnection: () => {},
getSocketDebuggingInfo: () => ({
client_id: 'fakeClientId',
transport: 'fakeTransport',