From 57052f36f4bc5370df032b31dba1f87e4047b20d Mon Sep 17 00:00:00 2001 From: Derek Blank Date: Thu, 14 Dec 2023 05:50:40 +0800 Subject: [PATCH] [RNMobile] Add OfflineStatus component (#56934) * feat: Frame useNetInfo hook foundation This code is non-functioning currently. * feat: Add iOS connection status bridge utilities This bridge will be required for the planned JavaScript Hook to monitor connection status. * feat: Add `useIsConnected` hook Provides React Hook for monitoring the network connection status via the bridge to the host app. * Revert "feat: Frame useNetInfo hook foundation" This reverts commit a8d3660845457787f6b368fe0276bfcfdbd213a6. * refactor: Align with project Swift syntax Semicolon is unnecessary. Co-authored-by: Tanner Stokes * feat: Add Android connection status bridge utilities This bridge enables monitoring the connection status on Android. * feat: Android network connection status request utility Allow the Android platform to request the current network connection status. * fix: Add missing `requestConnectionStatus` bridge method mock The Demo editor fails to build without a mocked bridge method. * Add mobile OfflineStatus component * Add OfflineStatus component to block-list behind __DEV__ flag * Replace offline icon and update OfflineStatus text alignment * Update BEM syntax for OfflineStatus * Update OfflineStatus component colors * test: Import sole native stylesheet to fix test module resolution error The current Jest module resolution configuration will fail when there is only a native-specific file without a web-specific file, e.g. only a `style.native.scss` and no sibling `style.scss` next to it. Explicitly importing the native-specific file avoids the error as Jest does not attempt to seek the non-suffixed file. * test: Mock `useIsConnected` native bridge method The native implementation is not available within the JavaScript testing environment. --------- Co-authored-by: David Calhoun Co-authored-by: Tanner Stokes --- .../src/components/block-list/index.native.js | 5 ++ .../components/offline-status/index.native.js | 46 +++++++++++++++++++ .../offline-status/style.native.scss | 28 +++++++++++ packages/icons/src/index.js | 1 + packages/icons/src/library/offline.js | 22 +++++++++ test/native/setup.js | 1 + 6 files changed, 103 insertions(+) create mode 100644 packages/block-editor/src/components/offline-status/index.native.js create mode 100644 packages/block-editor/src/components/offline-status/style.native.scss create mode 100644 packages/icons/src/library/offline.js diff --git a/packages/block-editor/src/components/block-list/index.native.js b/packages/block-editor/src/components/block-list/index.native.js index 810e23e4c1442a..4c4d7914b18066 100644 --- a/packages/block-editor/src/components/block-list/index.native.js +++ b/packages/block-editor/src/components/block-list/index.native.js @@ -30,6 +30,7 @@ import { import { BlockDraggableWrapper } from '../block-draggable'; import { useEditorWrapperStyles } from '../../hooks/use-editor-wrapper-styles'; import { store as blockEditorStore } from '../../store'; +import OfflineStatus from '../offline-status'; const identity = ( x ) => x; @@ -235,6 +236,10 @@ export default function BlockList( { onLayout={ onLayout } testID="block-list-wrapper" > + { + // eslint-disable-next-line no-undef + __DEV__ && + } { isRootList ? ( { + const { isConnected } = useIsConnected(); + + const containerStyle = usePreferredColorSchemeStyle( + styles.offline, + styles.offline__dark + ); + + const textStyle = usePreferredColorSchemeStyle( + styles[ 'offline--text' ], + styles[ 'offline--text__dark' ] + ); + + const iconStyle = usePreferredColorSchemeStyle( + styles[ 'offline--icon' ], + styles[ 'offline--icon__dark' ] + ); + + return ! isConnected ? ( + + + { __( 'Working Offline' ) } + + ) : null; +}; + +export default OfflineStatus; diff --git a/packages/block-editor/src/components/offline-status/style.native.scss b/packages/block-editor/src/components/offline-status/style.native.scss new file mode 100644 index 00000000000000..529693516653f6 --- /dev/null +++ b/packages/block-editor/src/components/offline-status/style.native.scss @@ -0,0 +1,28 @@ +.offline { + background-color: $gray-lighten-30; + padding: $grid-unit; + justify-content: center; + align-items: center; + flex-direction: row; +} + +.offline__dark { + background-color: $gray-70; +} + +.offline--text { + color: $black; + padding-left: 3; +} + +.offline--text__dark { + color: $white; +} + +.offline--icon { + fill: $gray-70; +} + +.offline--icon__dark { + fill: $gray-10; +} diff --git a/packages/icons/src/index.js b/packages/icons/src/index.js index 36b29714234429..d743299d35a246 100644 --- a/packages/icons/src/index.js +++ b/packages/icons/src/index.js @@ -190,6 +190,7 @@ export { default as postList } from './library/post-list'; export { default as postTerms } from './library/post-terms'; export { default as previous } from './library/previous'; export { default as next } from './library/next'; +export { default as offline } from './library/offline'; export { default as preformatted } from './library/preformatted'; export { default as pullLeft } from './library/pull-left'; export { default as pullRight } from './library/pull-right'; diff --git a/packages/icons/src/library/offline.js b/packages/icons/src/library/offline.js new file mode 100644 index 00000000000000..f0daa1aaeb79ee --- /dev/null +++ b/packages/icons/src/library/offline.js @@ -0,0 +1,22 @@ +/** + * WordPress dependencies + */ +import { SVG, Path } from '@wordpress/primitives'; + +const offline = ( + + + +); + +export default offline; diff --git a/test/native/setup.js b/test/native/setup.js index 3770a4ce3efc6f..0f4c9f9eda20c9 100644 --- a/test/native/setup.js +++ b/test/native/setup.js @@ -107,6 +107,7 @@ jest.mock( '@wordpress/react-native-bridge', () => { subscribeShowEditorHelp: jest.fn(), subscribeOnUndoPressed: jest.fn(), subscribeOnRedoPressed: jest.fn(), + useIsConnected: jest.fn( () => ( { isConnected: true } ) ), editorDidMount: jest.fn(), editorDidAutosave: jest.fn(), subscribeMediaUpload: jest.fn(),