mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-29 13:53:40 -05:00
Add translated messages for more connection error states (#19392)
GitOrigin-RevId: 981de624f3964ebe3ff1f0c751fcef9158864d5e
This commit is contained in:
parent
4b708613b6
commit
1e1a8c0bb3
8 changed files with 99 additions and 17 deletions
|
@ -37,8 +37,12 @@ meta(name="ol-hasTrackChangesFeature", data-type="boolean" content=hasTrackChang
|
||||||
meta(name="ol-inactiveTutorials", data-type="json" content=user.inactiveTutorials)
|
meta(name="ol-inactiveTutorials", data-type="json" content=user.inactiveTutorials)
|
||||||
meta(name="ol-projectTags" data-type="json" content=projectTags)
|
meta(name="ol-projectTags" data-type="json" content=projectTags)
|
||||||
meta(name="ol-linkSharingWarning" data-type="boolean" content=linkSharingWarning)
|
meta(name="ol-linkSharingWarning" data-type="boolean" content=linkSharingWarning)
|
||||||
|
|
||||||
|
// translations for the loading page, before i18n has loaded in the client
|
||||||
meta(name="ol-loadingText", data-type="string" content=translate("loading"))
|
meta(name="ol-loadingText", data-type="string" content=translate("loading"))
|
||||||
|
meta(name="ol-translationIoNotLoaded", data-type="string" content=translate("could_not_connect_to_websocket_server"))
|
||||||
meta(name="ol-translationLoadErrorMessage", data-type="string" content=translate("could_not_load_translations"))
|
meta(name="ol-translationLoadErrorMessage", data-type="string" content=translate("could_not_load_translations"))
|
||||||
|
meta(name="ol-translationUnableToJoin", data-type="string" content=translate("could_not_connect_to_collaboration_server"))
|
||||||
|
|
||||||
if (settings.overleaf != null)
|
if (settings.overleaf != null)
|
||||||
meta(name="ol-overallThemes" data-type="json" content=overallThemes)
|
meta(name="ol-overallThemes" data-type="json" content=overallThemes)
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { FC } from 'react'
|
||||||
|
import { ConnectionError } from '@/features/ide-react/connection/types/connection-state'
|
||||||
|
import getMeta from '@/utils/meta'
|
||||||
|
|
||||||
|
// NOTE: i18n translations might not be loaded in the client at this point,
|
||||||
|
// so these translations have to be loaded from meta tags
|
||||||
|
export const LoadingError: FC<{
|
||||||
|
connectionStateError: ConnectionError | ''
|
||||||
|
i18nError?: Error
|
||||||
|
}> = ({ connectionStateError, i18nError }) => {
|
||||||
|
if (connectionStateError) {
|
||||||
|
switch (connectionStateError) {
|
||||||
|
case 'io-not-loaded':
|
||||||
|
return <>{getMeta('ol-translationIoNotLoaded')}</>
|
||||||
|
|
||||||
|
case 'unable-to-join':
|
||||||
|
return <>{getMeta('ol-translationUnableToJoin')}</>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i18nError) {
|
||||||
|
return <>{getMeta('ol-translationLoadErrorMessage')}</>
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import useWaitForI18n from '@/shared/hooks/use-wait-for-i18n'
|
||||||
import getMeta from '@/utils/meta'
|
import getMeta from '@/utils/meta'
|
||||||
import { useConnectionContext } from '../context/connection-context'
|
import { useConnectionContext } from '../context/connection-context'
|
||||||
import { useIdeReactContext } from '@/features/ide-react/context/ide-react-context'
|
import { useIdeReactContext } from '@/features/ide-react/context/ide-react-context'
|
||||||
|
import { LoadingError } from './loading-error'
|
||||||
|
|
||||||
type Part = 'initial' | 'render' | 'connection' | 'translations' | 'project'
|
type Part = 'initial' | 'render' | 'connection' | 'translations' | 'project'
|
||||||
|
|
||||||
|
@ -54,21 +55,6 @@ export const Loading: FC<{
|
||||||
}
|
}
|
||||||
}, [projectJoined])
|
}, [projectJoined])
|
||||||
|
|
||||||
const getLoadingScreenError = (): string => {
|
|
||||||
if (connectionState.error) {
|
|
||||||
// NOTE: translations not ready yet
|
|
||||||
return connectionState.error === 'io-not-loaded'
|
|
||||||
? 'Could not connect to websocket server :('
|
|
||||||
: connectionState.error
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i18n.error) {
|
|
||||||
return getMeta('ol-translationLoadErrorMessage')
|
|
||||||
}
|
|
||||||
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use loading text from the server, because i18n will not be ready initially
|
// Use loading text from the server, because i18n will not be ready initially
|
||||||
const label = getMeta('ol-loadingText')
|
const label = getMeta('ol-loadingText')
|
||||||
|
|
||||||
|
@ -82,7 +68,12 @@ export const Loading: FC<{
|
||||||
hasError={hasError}
|
hasError={hasError}
|
||||||
/>
|
/>
|
||||||
{hasError && (
|
{hasError && (
|
||||||
<p className="loading-screen-error">{getLoadingScreenError()}</p>
|
<p className="loading-screen-error">
|
||||||
|
<LoadingError
|
||||||
|
connectionStateError={connectionState.error}
|
||||||
|
i18nError={i18n.error}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
export type ConnectionError =
|
export type ConnectionError =
|
||||||
|
| 'io-not-loaded'
|
||||||
| 'maintenance'
|
| 'maintenance'
|
||||||
| 'not-logged-in'
|
| 'not-logged-in'
|
||||||
| 'out-of-sync'
|
| 'out-of-sync'
|
||||||
|
@ -7,7 +8,6 @@ export type ConnectionError =
|
||||||
| 'rate-limited'
|
| 'rate-limited'
|
||||||
| 'unable-to-connect'
|
| 'unable-to-connect'
|
||||||
| 'unable-to-join'
|
| 'unable-to-join'
|
||||||
| 'io-not-loaded'
|
|
||||||
|
|
||||||
export type ConnectionState = {
|
export type ConnectionState = {
|
||||||
readyState: WebSocket['CONNECTING'] | WebSocket['OPEN'] | WebSocket['CLOSED']
|
readyState: WebSocket['CONNECTING'] | WebSocket['OPEN'] | WebSocket['CLOSED']
|
||||||
|
|
|
@ -191,6 +191,9 @@ export interface Meta {
|
||||||
'ol-teamInvites': TeamInvite[]
|
'ol-teamInvites': TeamInvite[]
|
||||||
'ol-thirdPartyIds': ThirdPartyIds
|
'ol-thirdPartyIds': ThirdPartyIds
|
||||||
'ol-translationLoadErrorMessage': string
|
'ol-translationLoadErrorMessage': string
|
||||||
|
'ol-translationIoNotLoaded': string
|
||||||
|
'ol-translationUnableToJoin': string
|
||||||
|
'ol-translationMaintenance': string
|
||||||
'ol-useShareJsHash': boolean
|
'ol-useShareJsHash': boolean
|
||||||
'ol-user': User
|
'ol-user': User
|
||||||
'ol-userAffiliations': Affiliation[]
|
'ol-userAffiliations': Affiliation[]
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
import type { Meta, StoryObj } from '@storybook/react'
|
||||||
|
import { LoadingError } from '@/features/ide-react/components/loading-error'
|
||||||
|
|
||||||
|
const meta: Meta<typeof LoadingError> = {
|
||||||
|
title: 'Loading Page / Loading Error',
|
||||||
|
component: LoadingError,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default meta
|
||||||
|
|
||||||
|
type Story = StoryObj<typeof LoadingError>
|
||||||
|
|
||||||
|
export const IoNotLoaded: Story = {
|
||||||
|
render: () => {
|
||||||
|
window.metaAttributesCache.set(
|
||||||
|
'ol-translationIoNotLoaded',
|
||||||
|
'Could not connect to the WebSocket server'
|
||||||
|
)
|
||||||
|
|
||||||
|
return <LoadingError connectionStateError="io-not-loaded" />
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const UnableToJoin: Story = {
|
||||||
|
render: () => {
|
||||||
|
window.metaAttributesCache.set(
|
||||||
|
'ol-translationUnableToJoin',
|
||||||
|
'Could not connect to the collaboration server'
|
||||||
|
)
|
||||||
|
|
||||||
|
return <LoadingError connectionStateError="unable-to-join" />
|
||||||
|
},
|
||||||
|
}
|
23
services/web/frontend/stories/loading/loading.stories.tsx
Normal file
23
services/web/frontend/stories/loading/loading.stories.tsx
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import type { Meta, StoryObj } from '@storybook/react'
|
||||||
|
import { Loading } from '@/features/ide-react/components/loading'
|
||||||
|
import { EditorProviders } from '../../../test/frontend/helpers/editor-providers'
|
||||||
|
|
||||||
|
const meta: Meta<typeof Loading> = {
|
||||||
|
title: 'Loading Page / Loading',
|
||||||
|
component: Loading,
|
||||||
|
argTypes: {
|
||||||
|
setLoaded: { action: 'setLoaded' },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default meta
|
||||||
|
|
||||||
|
type Story = StoryObj<typeof Loading>
|
||||||
|
|
||||||
|
export const LoadingPage: Story = {
|
||||||
|
render: args => (
|
||||||
|
<EditorProviders>
|
||||||
|
<Loading {...args} />
|
||||||
|
</EditorProviders>
|
||||||
|
),
|
||||||
|
}
|
|
@ -349,6 +349,8 @@
|
||||||
"copy_project": "Copy Project",
|
"copy_project": "Copy Project",
|
||||||
"copy_response": "Copy response",
|
"copy_response": "Copy response",
|
||||||
"copying": "Copying",
|
"copying": "Copying",
|
||||||
|
"could_not_connect_to_collaboration_server": "Could not connect to collaboration server",
|
||||||
|
"could_not_connect_to_websocket_server": "Could not connect to WebSocket server",
|
||||||
"could_not_load_translations": "Could not load translations",
|
"could_not_load_translations": "Could not load translations",
|
||||||
"country": "Country",
|
"country": "Country",
|
||||||
"country_flag": "__country__ country flag",
|
"country_flag": "__country__ country flag",
|
||||||
|
|
Loading…
Reference in a new issue