Connection State: Support browser online state, add animation

This commit is contained in:
Alexander Zinchuk 2021-06-24 18:42:25 +03:00
parent 1cc1893fef
commit c92f7a42df
5 changed files with 57 additions and 17 deletions

View File

@ -1,9 +1,7 @@
import React, { FC } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import React, { memo, FC } from '../../lib/teact/teact';
import { GlobalState } from '../../global/types';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
import Spinner from '../ui/Spinner';
@ -12,12 +10,10 @@ import './ConnectionState.scss';
type StateProps = Pick<GlobalState, 'connectionState'>;
const ConnectionState: FC<StateProps> = ({ connectionState }) => {
const ConnectionState: FC<StateProps> = () => {
const lang = useLang();
const isConnecting = connectionState === 'connectionStateConnecting';
return isConnecting && (
return (
<div id="ConnectionState" dir={lang.isRtl ? 'rtl' : undefined}>
<Spinner color="black" />
<div className="state-text">{lang('WaitingForNetwork')}</div>
@ -25,6 +21,4 @@ const ConnectionState: FC<StateProps> = ({ connectionState }) => {
);
};
export default withGlobal(
(global): StateProps => pick(global, ['connectionState']),
)(ConnectionState);
export default memo(ConnectionState);

View File

@ -6,9 +6,20 @@
overflow: hidden;
z-index: 1;
.connection-state-wrapper {
position: absolute;
top: 3.75rem;
width: 100%;
}
> .Transition {
flex: 1;
overflow: hidden;
transition: transform 300ms ease;
&.pull-down {
transform: translateY(3.75rem);
}
}
.ChatFolders {

View File

@ -1,10 +1,14 @@
import React, {
FC, memo, useState, useRef, useCallback, useEffect,
FC, useState, useRef, useCallback, useEffect,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { GlobalState } from '../../../global/types';
import { LeftColumnContent } from '../../../types';
import { IS_TOUCH_ENV } from '../../../util/environment';
import { pick } from '../../../util/iteratees';
import useBrowserOnline from '../../../hooks/useBrowserOnline';
import Transition from '../../ui/Transition';
import LeftMainHeader from './LeftMainHeader';
@ -13,6 +17,7 @@ import ChatFolders from './ChatFolders';
import LeftSearch from '../search/LeftSearch.async';
import ContactList from './ContactList.async';
import NewChatButton from '../NewChatButton';
import ShowTransition from '../../ui/ShowTransition';
import './LeftMain.scss';
@ -26,7 +31,7 @@ type OwnProps = {
onReset: () => void;
};
type StateProps = {};
type StateProps = Pick<GlobalState, 'connectionState'>;
const TRANSITION_RENDER_COUNT = Object.keys(LeftColumnContent).length / 2;
const BUTTON_CLOSE_DELAY_MS = 250;
@ -40,9 +45,13 @@ const LeftMain: FC<OwnProps & StateProps> = ({
onSearchQuery,
onContentChange,
onReset,
connectionState,
}) => {
const [isNewChatButtonShown, setIsNewChatButtonShown] = useState(IS_TOUCH_ENV);
const isBrowserOnline = useBrowserOnline();
const isConnecting = !isBrowserOnline || connectionState === 'connectionStateConnecting';
const isMouseInside = useRef(false);
const handleSelectSettings = useCallback(() => {
@ -121,13 +130,16 @@ const LeftMain: FC<OwnProps & StateProps> = ({
onSelectArchived={handleSelectArchived}
onReset={onReset}
/>
<ConnectionState />
<ShowTransition isOpen={isConnecting} isCustom className="connection-state-wrapper opacity-transition slow">
{() => <ConnectionState />}
</ShowTransition>
<Transition
name="zoom-fade"
renderCount={TRANSITION_RENDER_COUNT}
activeKey={content}
shouldCleanup
cleanupExceptionKey={LeftColumnContent.ChatList}
className={isConnecting ? 'pull-down' : undefined}
>
{(isActive) => {
switch (content) {
@ -159,4 +171,6 @@ const LeftMain: FC<OwnProps & StateProps> = ({
);
};
export default memo(LeftMain);
export default withGlobal<OwnProps>(
(global): StateProps => pick(global, ['connectionState']),
)(LeftMain);

View File

@ -1,9 +1,9 @@
import { useEffect } from '../lib/teact/teact';
export default (
export default function useBackgroundMode(
onBlur: AnyToVoidFunction,
onFocus: AnyToVoidFunction,
) => {
) {
useEffect(() => {
if (!document.hasFocus()) {
onBlur();
@ -17,4 +17,4 @@ export default (
window.removeEventListener('blur', onBlur);
};
}, [onBlur, onFocus]);
};
}

View File

@ -0,0 +1,21 @@
import { useEffect, useState } from '../lib/teact/teact';
export default function useBrowserOnline() {
const [isOnline, setIsOnline] = useState(window.navigator.onLine);
useEffect(() => {
function handleChange() {
setIsOnline(window.navigator.onLine);
}
window.addEventListener('online', handleChange);
window.addEventListener('offline', handleChange);
return () => {
window.removeEventListener('offline', handleChange);
window.removeEventListener('online', handleChange);
};
}, []);
return isOnline;
}