init
Some checks failed
Close stale issues and PRs / stale (push) Has been cancelled

This commit is contained in:
2025-09-02 14:49:16 +08:00
commit 38ba663466
2885 changed files with 391107 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
import {
default as NetInfo,
type NetInfoState,
type NetInfoSubscription
} from '@react-native-community/netinfo';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import EventEmitter from 'events';
import { ONLINE_STATE_CHANGED_EVENT } from './events';
import type { NetworkInfo } from './types';
/**
* The network info service implementation for iOS and Android. 'react-native-netinfo' seems to support windows as well,
* but that has not been tested and is nto used by jitsi-meet.
*/
export default class NetworkInfoService extends EventEmitter {
/**
* Stores the native subscription for future cleanup.
*/
_subscription?: NetInfoSubscription;
/**
* Converts library's structure to {@link NetworkInfo} used by jitsi-meet.
*
* @param {NetInfoState} netInfoState - The new state given by the native library.
* @private
* @returns {NetworkInfo}
*/
static _convertNetInfoState(netInfoState: NetInfoState): NetworkInfo {
return {
isOnline: Boolean(netInfoState.isInternetReachable),
details: netInfoState.details,
networkType: netInfoState.type
};
}
/**
* Checks for support.
*
* @returns {boolean}
*/
static isSupported() {
return Boolean(NetInfo);
}
/**
* Starts the service.
*
* @returns {void}
*/
start() {
this._subscription = NetInfo.addEventListener(netInfoState => {
super.emit(ONLINE_STATE_CHANGED_EVENT, NetworkInfoService._convertNetInfoState(netInfoState));
});
}
/**
* Stops the service.
*
* @returns {void}
*/
stop() {
if (this._subscription) {
this._subscription();
this._subscription = undefined;
}
}
}

View File

@@ -0,0 +1,60 @@
import EventEmitter from 'events';
import { ONLINE_STATE_CHANGED_EVENT } from './events';
/**
* The network info service implementation for web (Chrome, Firefox and Safari).
*/
export default class NetworkInfoService extends EventEmitter {
_onlineStateListener: any;
_offlineStateListener: any;
/**
* Creates new instance...
*/
constructor() {
super();
this._onlineStateListener = this._handleOnlineStatusChange.bind(this, /* online */ true);
this._offlineStateListener = this._handleOnlineStatusChange.bind(this, /* offline */ false);
}
/**
* Callback function to track the online state.
*
* @param {boolean} isOnline - Is the browser online or not.
* @private
* @returns {void}
*/
_handleOnlineStatusChange(isOnline: boolean) {
this.emit(ONLINE_STATE_CHANGED_EVENT, { isOnline });
}
/**
* Checks for support.
*
* @returns {boolean}
*/
static isSupported() {
return Boolean(window.addEventListener) && typeof navigator.onLine !== 'undefined';
}
/**
* Starts the service.
*
* @returns {void}
*/
start() {
window.addEventListener('online', this._onlineStateListener);
window.addEventListener('offline', this._offlineStateListener);
}
/**
* Stops the service.
*
* @returns {void}
*/
stop() {
window.removeEventListener('online', this._onlineStateListener);
window.removeEventListener('offline', this._offlineStateListener);
}
}

View File

@@ -0,0 +1,13 @@
/**
* The action dispatched when the {@link NetworkInfo} structure is being updated.
*
* @type {string}
*/
export const SET_NETWORK_INFO = 'SET_NETWORK_INFO';
/**
* The action dispatched by 'base/net-info' middleware in order to store the cleanup function for later use.
* @type {string}
* @private
*/
export const _STORE_NETWORK_INFO_CLEANUP = 'STORE_NETWORK_INFO_CLEANUP';

View File

@@ -0,0 +1,39 @@
import { SET_NETWORK_INFO, _STORE_NETWORK_INFO_CLEANUP } from './actionTypes';
import { NetworkInfo } from './types';
/**
* Up[dates the network info state.
*
* @param {NetworkInfo} networkInfo - The new network state to be set.
* @returns {{
* type: SET_NETWORK_INFO,
* isOnline: boolean,
* networkType: string,
* details: Object
* }}
*/
export function setNetworkInfo({ isOnline, networkType, details }: NetworkInfo) {
return {
type: SET_NETWORK_INFO,
isOnline,
networkType,
details
};
}
/**
* Stored the cleanup function used to shutdown the {@code NetworkInfoService}.
*
* @param {Function} cleanup - The cleanup function to be called on {@code APP_WILL_UNMOUNT}.
* @returns {{
* type: _STORE_NETWORK_INFO_CLEANUP,
* cleanup: Function
* }}
* @private
*/
export function _storeNetworkInfoCleanup(cleanup?: Function) {
return {
type: _STORE_NETWORK_INFO_CLEANUP,
cleanup
};
}

View File

@@ -0,0 +1,6 @@
/**
* The name for Redux store key used by the 'base/net-info' feature.
*
* @type {string}
*/
export const STORE_NAME = 'features/base/net-info';

View File

@@ -0,0 +1 @@
export const ONLINE_STATE_CHANGED_EVENT = 'network-info-online-status-change';

View File

@@ -0,0 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/net-info');

View File

@@ -0,0 +1,64 @@
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app/actionTypes';
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
import NetworkInfoService from './NetworkInfoService';
import { _storeNetworkInfoCleanup, setNetworkInfo } from './actions';
import { STORE_NAME } from './constants';
import { ONLINE_STATE_CHANGED_EVENT } from './events';
import logger from './logger';
import type { NetworkInfo } from './types';
/**
* Middleware for 'base/net-info' feature.
*
* @param {Store} store - The redux store.
* @returns {Function}
*/
MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
const result = next(action);
switch (action.type) {
case APP_WILL_MOUNT:
if (NetworkInfoService.isSupported()) {
const networkInfoService = new NetworkInfoService();
const stop = () => {
networkInfoService.stop();
// @ts-ignore
networkInfoService.removeAllListeners();
};
// @ts-ignore
networkInfoService.addListener(
ONLINE_STATE_CHANGED_EVENT,
({ isOnline, networkType, details }: NetworkInfo) => {
logger.info('Network changed', JSON.stringify({
isOnline,
details,
networkType
}));
dispatch(setNetworkInfo({
isOnline,
networkType,
details
}));
});
dispatch(_storeNetworkInfoCleanup(stop));
networkInfoService.start();
}
break;
case APP_WILL_UNMOUNT: {
const { _cleanup } = getState()[STORE_NAME];
if (_cleanup) {
_cleanup();
dispatch(_storeNetworkInfoCleanup(undefined));
}
}
break;
}
return result;
});

View File

@@ -0,0 +1,40 @@
import { NetInfoCellularGeneration, NetInfoStateType } from '@react-native-community/netinfo';
import ReducerRegistry from '../redux/ReducerRegistry';
import { assign } from '../redux/functions';
import { SET_NETWORK_INFO, _STORE_NETWORK_INFO_CLEANUP } from './actionTypes';
import { STORE_NAME } from './constants';
const DEFAULT_STATE = {
isOnline: true
};
export interface INetInfoState {
_cleanup?: Function;
cellularGeneration?: NetInfoCellularGeneration;
details?: Object;
isOnline?: boolean;
networkType?: NetInfoStateType;
}
/**
* The base/net-info feature's reducer.
*/
ReducerRegistry.register<INetInfoState>(STORE_NAME, (state = DEFAULT_STATE, action): INetInfoState => {
switch (action.type) {
case SET_NETWORK_INFO:
return assign(state, {
isOnline: action.isOnline,
networkType: action.networkType,
cellularGeneration: action.cellularGeneration,
details: action.details
});
case _STORE_NETWORK_INFO_CLEANUP:
return assign(state, {
_cleanup: action.cleanup
});
default:
return state;
}
});

View File

@@ -0,0 +1,13 @@
import { IReduxState } from '../../app/types';
import { STORE_NAME } from './constants';
/**
* A selector for the internet online status.
*
* @param {IReduxState} state - The redux state.
* @returns {boolean}
*/
export function isOnline(state: IReduxState) {
return state[STORE_NAME].isOnline;
}

View File

@@ -0,0 +1,37 @@
import { NetInfoCellularGeneration, NetInfoStateType } from '@react-native-community/netinfo';
/**
* Describes the structure which is used by jitsi-meet to store information about the current network type and
* conditions.
*/
export type NetworkInfo = {
/**
* Any extra info provided by the OS. Should be JSON and is OS specific. Reported only by iOS and Android and
* the format is whatever comes out of the 'react-native-netinfo' library which is network type dependent.
*/
details?: {
/**
* If {@link networkType} is {@link NetInfoStateType.cellular} then it may provide the info about the type of
* cellular network.
*/
cellularGeneration?: NetInfoCellularGeneration | null;
/**
* Indicates whether or not the connection is expensive.
*/
isConnectionExpensive?: boolean;
} | null;
/**
* Tells whether or not the internet is reachable.
*/
isOnline: boolean;
/**
* The network type. Currently reported only on Android/iOS. Can be one of the constants defined by
* the 'react-native-netinfo' library.
*/
networkType?: NetInfoStateType;
};