mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-14 14:13:43 +01:00
[web] Add offline indicator to toolbar (#35368)
GitOrigin-RevId: 81127bff21afb6aadcf175ba1767a2629f01d747
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import OLTooltip from '@/shared/components/ol/ol-tooltip'
|
||||
import { useUnsavedDocsContext } from '@/features/ide-react/context/unsaved-docs-context'
|
||||
import { useFeatureFlag } from '@/shared/context/split-test-context'
|
||||
|
||||
export function OfflineIndicatorContent() {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<OLTooltip
|
||||
id="tooltip-offline-indicator"
|
||||
description={t('changes_saved_in_browser_sync_when_online')}
|
||||
overlayProps={{ delay: 0, placement: 'bottom' }}
|
||||
>
|
||||
<div className="ide-redesign-toolbar-offline-indicator">
|
||||
<MaterialIcon type="wifi_off" />
|
||||
<span>{t('you_re_offline')}</span>
|
||||
</div>
|
||||
</OLTooltip>
|
||||
)
|
||||
}
|
||||
|
||||
export default function OfflineIndicator() {
|
||||
const { t } = useTranslation()
|
||||
const { unsavedDocs } = useUnsavedDocsContext()
|
||||
const improvedFlakyConnections = useFeatureFlag(
|
||||
'intermittent-connection-improvements'
|
||||
)
|
||||
|
||||
if (!improvedFlakyConnections) {
|
||||
return null
|
||||
}
|
||||
|
||||
// TODO: use shared hook for this when merged
|
||||
const MAX_UNSAVED_ALERT_SECONDS = 15
|
||||
const isOffline = [...unsavedDocs.values()].some(
|
||||
seconds => seconds >= MAX_UNSAVED_ALERT_SECONDS
|
||||
)
|
||||
return (
|
||||
<>
|
||||
{isOffline && <OfflineIndicatorContent />}
|
||||
<div className="visually-hidden" role="status">
|
||||
{isOffline && (
|
||||
<>
|
||||
<span>{t('you_re_offline')}</span>
|
||||
<span>{t('changes_saved_in_browser_sync_when_online')}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -19,6 +19,8 @@ export const OnlineUsers = () => {
|
||||
[openDoc]
|
||||
)
|
||||
|
||||
if (!onlineUsersArray.length) return null
|
||||
|
||||
return (
|
||||
<div className="ide-redesign-online-users">
|
||||
<OnlineUsersWidget onlineUsers={onlineUsersArray} goToUser={goToUser} />
|
||||
|
||||
@@ -19,6 +19,7 @@ import { useFeatureFlag } from '@/shared/context/split-test-context'
|
||||
import OLIconButton from '@/shared/components/ol/ol-icon-button'
|
||||
import OLTooltip from '@/shared/components/ol/ol-tooltip'
|
||||
import SplitTestBadge from '@/shared/components/split-test-badge'
|
||||
import OfflineIndicator from './offline-indicator'
|
||||
|
||||
const [publishModalModules] = importOverleafModules('publishModalToolbarButton')
|
||||
const SubmitProjectButton = publishModalModules?.import.default
|
||||
@@ -128,15 +129,18 @@ export const Toolbar = () => {
|
||||
{showUpgradePrompt && upgradeButtonRelocation && <UpgradeButton />}
|
||||
</div>
|
||||
<ToolbarProjectTitle />
|
||||
<div className="ide-redesign-toolbar-actions">
|
||||
<OnlineUsers />
|
||||
{!isRestrictedTokenMember && <ShowHistoryButton />}
|
||||
<ChangeLayoutButton />
|
||||
{shouldDisplaySubmitButton && cobranding && (
|
||||
<SubmitProjectButton cobranding={cobranding} />
|
||||
)}
|
||||
<ShareProjectButton />
|
||||
{showUpgradePrompt && !upgradeButtonRelocation && <UpgradeButton />}
|
||||
<div className="ide-redesign-toolbar-actions-wrapper">
|
||||
<OfflineIndicator />
|
||||
<div className="ide-redesign-toolbar-actions">
|
||||
<OnlineUsers />
|
||||
{!isRestrictedTokenMember && <ShowHistoryButton />}
|
||||
<ChangeLayoutButton />
|
||||
{shouldDisplaySubmitButton && cobranding && (
|
||||
<SubmitProjectButton cobranding={cobranding} />
|
||||
)}
|
||||
<ShareProjectButton />
|
||||
{showUpgradePrompt && !upgradeButtonRelocation && <UpgradeButton />}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
)
|
||||
|
||||
+6
-1
@@ -4,10 +4,14 @@ import { UnsavedDocsAlert } from '@/features/ide-react/components/unsaved-docs/u
|
||||
import { createPortal } from 'react-dom'
|
||||
import { useGlobalAlertsContainer } from '@/features/ide-react/context/global-alerts-context'
|
||||
import { useUnsavedDocsContext } from '@/features/ide-react/context/unsaved-docs-context'
|
||||
import { useFeatureFlag } from '@/shared/context/split-test-context'
|
||||
|
||||
export const UnsavedDocs: FC = () => {
|
||||
const { unsavedDocs, isLocked } = useUnsavedDocsContext()
|
||||
const globalAlertsContainer = useGlobalAlertsContainer()
|
||||
const improvedFlakyConnections = useFeatureFlag(
|
||||
'intermittent-connection-improvements'
|
||||
)
|
||||
|
||||
if (!globalAlertsContainer) {
|
||||
return null
|
||||
@@ -18,7 +22,8 @@ export const UnsavedDocs: FC = () => {
|
||||
{isLocked &&
|
||||
createPortal(<UnsavedDocsLockedAlert />, globalAlertsContainer)}
|
||||
|
||||
{unsavedDocs.size > 0 &&
|
||||
{!improvedFlakyConnections &&
|
||||
unsavedDocs.size > 0 &&
|
||||
createPortal(
|
||||
<UnsavedDocsAlert unsavedDocs={unsavedDocs} />,
|
||||
globalAlertsContainer
|
||||
|
||||
Reference in New Issue
Block a user